From 5d8f2c99b6dc4ccfa85ad1cc6541def0ff985eef Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Tue, 29 Apr 2025 18:45:18 +0300 Subject: [PATCH] ci: using `codspeed` for benchmarks (#19476) --- .github/workflows/test.yml | 24 +- cspell.json | 1 + package.json | 3 +- test/BenchmarkTestCases.benchmark.mjs | 339 +++++++++++++++----------- yarn.lock | 130 +++++++++- 5 files changed, 331 insertions(+), 166 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3b73ebe42..a0583c726 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,7 @@ on: pull_request: branches: - main + workflow_dispatch: permissions: contents: read @@ -76,24 +77,13 @@ jobs: - run: yarn --frozen-lockfile - run: yarn link --frozen-lockfile || true - run: yarn link webpack --frozen-lockfile - - run: yarn benchmark --ci - - name: Find Comment - if: github.event_name == 'pull_request' - uses: peter-evans/find-comment@v3 - id: fc + - name: Run benchmarks + uses: CodSpeedHQ/action@v3 with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: "github-actions[bot]" - body-includes: Benchmarks - - name: Create or update comment - if: github.event_name == 'pull_request' - uses: peter-evans/create-or-update-comment@v4 - with: - token: ${{ secrets.PAT }} - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body-path: "./test/js/benchmark.md" - edit-mode: replace + run: yarn benchmark --ci --only-head + token: ${{ secrets.CODSPEED_TOKEN }} + env: + CODSPEED: 1 basic: runs-on: ubuntu-latest steps: diff --git a/cspell.json b/cspell.json index 05c6b2dc7..c2337662e 100644 --- a/cspell.json +++ b/cspell.json @@ -42,6 +42,7 @@ "chunkname", "cmodule", "codecov", + "codspeed", "cofounder", "Collet's", "compat", diff --git a/package.json b/package.json index 26f56a1d0..ba4402181 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "devDependencies": { "@babel/core": "^7.26.8", "@babel/preset-react": "^7.25.7", + "@codspeed/benchmark.js-plugin": "^4.0.1", "@eslint/js": "^9.21.0", "@stylistic/eslint-plugin": "^4.2.0", "@types/glob-to-regexp": "^0.4.4", @@ -169,7 +170,7 @@ "pretty-lint": "yarn pretty-lint-base --check", "yarn-lint": "yarn-deduplicate --fail --list -s highest yarn.lock", "yarn-lint-fix": "yarn-deduplicate -s highest yarn.lock", - "benchmark": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.benchmark.mjs\" --runInBand", + "benchmark": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation --hash-seed=1 --random-seed=1 --no-opt --predictable --predictable-gc-schedule --interpreted-frames-native-stack --allow-natives-syntax --expose-gc --no-concurrent-sweeping ./test/BenchmarkTestCases.benchmark.mjs", "cover": "yarn cover:all && yarn cover:report", "cover:clean": "rimraf .nyc_output coverage", "cover:all": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --coverage", diff --git a/test/BenchmarkTestCases.benchmark.mjs b/test/BenchmarkTestCases.benchmark.mjs index 06467dedc..b9296f22d 100644 --- a/test/BenchmarkTestCases.benchmark.mjs +++ b/test/BenchmarkTestCases.benchmark.mjs @@ -2,14 +2,13 @@ import path from "path"; import fs from "fs/promises"; -import { createWriteStream, constants } from "fs"; +import { constants } from "fs"; import Benchmark from "benchmark"; -import { remove } from "./helpers/remove"; +import { remove } from "./helpers/remove.js"; import { dirname } from "path"; import { fileURLToPath } from "url"; import simpleGit from "simple-git"; -// eslint-disable-next-line n/no-extraneous-import -import { jest } from "@jest/globals"; +import { withCodSpeed } from "@codspeed/benchmark.js-plugin"; const __dirname = dirname(fileURLToPath(import.meta.url)); const rootPath = path.join(__dirname, ".."); @@ -17,7 +16,45 @@ const git = simpleGit(rootPath); const REV_LIST_REGEXP = /^([a-f0-9]+)\s*([a-f0-9]+)\s*([a-f0-9]+)?\s*$/; -new Error().cause = 1; +const getV8Flags = () => { + const nodeVersionMajor = Number.parseInt( + process.version.slice(1).split(".")[0] + ); + const flags = [ + "--hash-seed=1", + "--random-seed=1", + "--no-opt", + "--predictable", + "--predictable-gc-schedule", + "--interpreted-frames-native-stack", + "--allow-natives-syntax", + "--expose-gc", + "--no-concurrent-sweeping", + "--max-old-space-size=4096" + ]; + if (nodeVersionMajor < 18) { + flags.push("--no-randomize-hashes"); + } + if (nodeVersionMajor < 20) { + flags.push("--no-scavenge-task"); + } + return flags; +}; + +const checkV8Flags = () => { + const requiredFlags = getV8Flags(); + const actualFlags = process.execArgv; + const missingFlags = requiredFlags.filter( + flag => !actualFlags.includes(flag) + ); + if (missingFlags.length > 0) { + console.warn(`Missing required flags: ${missingFlags.join(", ")}`); + } +}; + +checkV8Flags(); + +const CODSPEED = typeof process.env.CODSPEED !== "undefined"; /** * @param {(string | undefined)[]} revList rev list @@ -87,6 +124,16 @@ async function getBaselineRevs() { if (!revList) throw new Error("Invalid result from git rev-list"); const head = await getHead(revList); + + if (CODSPEED) { + return [ + { + name: "HEAD", + rev: head + } + ]; + } + const base = await getBase(revList); if (!head || !base) { @@ -105,64 +152,6 @@ async function getBaselineRevs() { ]; } -function runBenchmark(webpack, config, callback) { - // warmup - const warmupCompiler = webpack(config, (err, stats) => { - if (err) { - callback(err); - return; - } - - warmupCompiler.purgeInputFileSystem(); - - const bench = new Benchmark( - function (deferred) { - const compiler = webpack(config, (err, stats) => { - compiler.purgeInputFileSystem(); - if (err) { - callback(err); - return; - } - - if (stats.hasErrors()) { - callback(new Error(stats.toString())); - return; - } - - deferred.resolve(); - }); - }, - { - maxTime: 30, - defer: true, - initCount: 1, - onComplete() { - const stats = bench.stats; - const n = stats.sample.length; - const nSqrt = Math.sqrt(n); - const z = tDistribution(n - 1); - - stats.sampleCount = stats.sample.length; - stats.minConfidence = stats.mean - (z * stats.deviation) / nSqrt; - stats.maxConfidence = stats.mean + (z * stats.deviation) / nSqrt; - stats.text = `${Math.round(stats.mean * 1000)} ms ± ${Math.round( - stats.deviation * 1000 - )} ms [${Math.round(stats.minConfidence * 1000)} ms; ${Math.round( - stats.maxConfidence * 1000 - )} ms]`; - - callback(null, bench.stats); - }, - onError: callback - } - ); - - bench.run({ - async: true - }); - }); -} - /** * @param {number} n number of runs * @returns {number} distribution @@ -193,27 +182,6 @@ function tDistribution(n) { return 1.645; } -const casesPath = path.join(__dirname, "benchmarkCases"); - -const tests = []; - -for (const folder of await fs.readdir(casesPath)) { - if (folder.includes("_")) { - continue; - } - - try { - await fs.access( - path.resolve(casesPath, folder, "webpack.config.js"), - constants.R_OK - ); - } catch (_err) { - continue; - } - - tests.push(folder); -} - const output = path.join(__dirname, "js"); const baselinesPath = path.join(output, "benchmark-baselines"); const baselines = []; @@ -228,12 +196,35 @@ for (const baselineInfo of baselineRevisions) { /** * @returns {void} */ - function doLoadWebpack() { + function addBaseline() { baselines.push({ name: baselineInfo.name, rev: baselineRevision, - webpack: () => - jest.requireActual(path.resolve(baselinePath, "lib/index.js")) + webpack: async config => { + const webpack = ( + await import( + path.resolve( + baselinePath, + `./lib/index.js?nocache=${Math.random()}` + ) + ) + ).default; + + await new Promise((resolve, reject) => { + const warmupCompiler = webpack(config, (err, _stats) => { + if (err) { + reject(err); + return; + } + + warmupCompiler.purgeInputFileSystem(); + + resolve(); + }); + }); + + return webpack; + } }); } @@ -262,76 +253,134 @@ for (const baselineInfo of baselineRevisions) { await git.raw(["reset", "--soft", prevHead.split("\n")[0]]); await fs.writeFile(gitIndex, index); } finally { - doLoadWebpack(); + addBaseline(); } } -const reportFilePath = path.resolve(output, "benchmark.md"); -const report = createWriteStream(reportFilePath, { flags: "w" }); +async function registerBenchmarks(suite, test, baselines) { + for (const baseline of baselines) { + const outputDirectory = path.join( + __dirname, + "js", + "benchmark", + `baseline-${baseline.name}`, + test + ); + const testDirectory = path.join(casesPath, test); + const config = + ( + await import( + path.join(testDirectory, `webpack.config.js?nocache=${Math.random()}`) + ) + ).default || {}; -report.write("### Benchmarks:\n\n"); + config.mode = config.mode || "production"; + config.output = config.output || {}; -describe("BenchmarkTestCases", function () { - for (const testName of tests) { - const testDirectory = path.join(casesPath, testName); - let headStats = null; + if (!config.context) config.context = testDirectory; + if (!config.output.path) config.output.path = outputDirectory; - describe(`${testName} create benchmarks`, function () { - for (const baseline of baselines) { - let baselineStats = null; + const suiteName = `benchmark "${test}"${CODSPEED ? "" : ` ${baseline.name} (${baseline.rev})`}`; + const webpack = await baseline.webpack(config); - // eslint-disable-next-line no-loop-func - it(`should benchmark ${baseline.name} (${baseline.rev})`, done => { - const outputDirectory = path.join( - __dirname, - "js", - "benchmark", - `baseline-${baseline.name}`, - testName - ); - const config = - jest.requireActual(path.join(testDirectory, "webpack.config.js")) || - {}; + suite.add(suiteName, { + baseTestName: test, + defer: true, + fn(deferred) { + const compiler = webpack(config, (err, stats) => { + compiler.purgeInputFileSystem(); - config.mode = config.mode || "production"; - config.output = config.output || {}; + if (err) { + throw err; + } - if (!config.context) config.context = testDirectory; - if (!config.output.path) config.output.path = outputDirectory; - runBenchmark(baseline.webpack(), config, (err, stats) => { - if (err) return done(err); - report.write( - `- "${testName}": ${baseline.name} (${baseline.rev}) ${stats.text} (${stats.sampleCount} runs)\n` - ); - if (baseline.name === "HEAD") headStats = stats; - else baselineStats = stats; - done(); - }); - }, 180000); + if (stats.hasErrors()) { + throw new Error(stats.toString()); + } - if (baseline.name !== "HEAD") { - // eslint-disable-next-line no-loop-func - it(`HEAD and ${baseline.name} (${baseline.rev}) results`, function () { - if (!baselineStats) { - throw new Error("No baseline stats"); - } - - report.write(`- "${testName}" change: `); - report.write( - `HEAD (${headStats.text}) is ${Math.round( - (baselineStats.mean / headStats.mean) * 100 - 100 - )}% ${baselineStats.maxConfidence < headStats.minConfidence ? "slower than" : baselineStats.minConfidence > headStats.maxConfidence ? "faster than" : "the same as"} BASE (${baseline.name}) (${baselineStats.text})\n` - ); - - report.write(`-----\n`); - }); - } + deferred.resolve(); + }); } }); } +} - afterAll(() => { - remove(baselinesPath); - report.end(); - }); +const suite = withCodSpeed( + new Benchmark.Suite({ + maxTime: 30, + initCount: 1, + onError: event => { + throw new Error(event.error); + } + }) +); + +const casesPath = path.join(__dirname, "benchmarkCases"); + +const tests = []; + +for (const folder of await fs.readdir(casesPath)) { + if (folder.includes("_")) { + continue; + } + + try { + await fs.access( + path.resolve(casesPath, folder, "webpack.config.js"), + constants.R_OK + ); + } catch (_err) { + continue; + } + + tests.push(folder); +} + +for (const test of tests) { + await registerBenchmarks(suite, test, baselines); +} + +const statsByTests = new Map(); + +suite.on("cycle", event => { + const target = event.target; + const stats = target.stats; + const n = stats.sample.length; + const nSqrt = Math.sqrt(n); + const z = tDistribution(n - 1); + + stats.sampleCount = stats.sample.length; + stats.minConfidence = stats.mean - (z * stats.deviation) / nSqrt; + stats.maxConfidence = stats.mean + (z * stats.deviation) / nSqrt; + stats.text = `${target.name} ${Math.round(stats.mean * 1000)} ms ± ${Math.round( + stats.deviation * 1000 + )} ms [${Math.round(stats.minConfidence * 1000)} ms; ${Math.round( + stats.maxConfidence * 1000 + )} ms]`; + + const baseTestName = target.baseTestName; + const allStats = statsByTests.get(baseTestName); + + if (!allStats) { + console.log(String(target)); + statsByTests.set(baseTestName, [stats]); + return; + } + + allStats.push(stats); + + const headStats = allStats[0]; + const baselineStats = allStats[1]; + + console.log( + `Benchmark "${baseTestName}" result: ${headStats.text} is ${Math.round( + (baselineStats.mean / headStats.mean) * 100 - 100 + )}% ${baselineStats.maxConfidence < headStats.minConfidence ? "slower than" : baselineStats.minConfidence > headStats.maxConfidence ? "faster than" : "the same as"} ${baselineStats.text}` + ); +}); + +suite.run({ async: true }); + +suite.on("complete", () => { + remove(baselinesPath); }); diff --git a/yarn.lock b/yarn.lock index a4090ffd4..91c5a92f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -335,6 +335,25 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@codspeed/benchmark.js-plugin@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@codspeed/benchmark.js-plugin/-/benchmark.js-plugin-4.0.1.tgz#ac7233491794761d476f364470a55d22887a6a06" + integrity sha512-qN7JrOnOC6WAePUVUFXhux0P6r85fqhROINnfv6OIdXDWoxwmCMzTNhAepAKyuDeQgOtAAUITk3fAwfnXDGE/w== + dependencies: + "@codspeed/core" "^4.0.1" + lodash "^4.17.10" + stack-trace "1.0.0-pre2" + +"@codspeed/core@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@codspeed/core/-/core-4.0.1.tgz#91049cce17b8c1d1b4b6cbc481f5ddc1145d6e1e" + integrity sha512-fJ53arfgtzCDZa8DuGJhpTZ3Ll9A1uW5nQ2jSJnfO4Hl5MRD2cP8P4vPvIUAGbdbjwCxR1jat6cW8OloMJkJXw== + dependencies: + axios "^1.4.0" + find-up "^6.3.0" + form-data "^4.0.0" + node-gyp-build "^4.6.0" + "@cspell/cspell-bundled-dicts@8.18.1": version "8.18.1" resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.18.1.tgz#ab64a7ef5dd53826231d96ab090969e1c5bad65a" @@ -1774,6 +1793,20 @@ async@1.x: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +axios@^1.4.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901" + integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2202,6 +2235,13 @@ colorette@^2.0.14, colorette@^2.0.20: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" @@ -2533,6 +2573,11 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -2668,6 +2713,16 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: dependencies: es-errors "^1.3.0" +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14, es5-ext@~0.10.2: version "0.10.64" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" @@ -3181,6 +3236,14 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + flat-cache@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" @@ -3207,6 +3270,11 @@ flatted@^3.2.9, flatted@^3.3.1: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + foreground-child@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" @@ -3241,6 +3309,16 @@ fork-ts-checker-webpack-plugin@^9.0.2: semver "^7.3.5" tapable "^2.2.1" +form-data@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c" + integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + mime-types "^2.1.12" + fromentries@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" @@ -3302,7 +3380,7 @@ get-east-asian-width@^1.0.0: resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== -get-intrinsic@^1.3.0: +get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== @@ -4537,6 +4615,13 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + lodash-es@^4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -4552,7 +4637,7 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: +lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4702,7 +4787,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27: +mime-types@^2.1.12, mime-types@^2.1.27: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -4893,6 +4978,11 @@ node-abort-controller@^3.0.1: resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== +node-gyp-build@^4.6.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + node-gyp@^11.2.0: version "11.2.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-11.2.0.tgz#fe2ee7f0511424d6ad70f7a0c88d7346f2fc6a6e" @@ -5084,6 +5174,13 @@ p-limit@^3.0.2, p-limit@^3.1.0: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -5098,6 +5195,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + p-map@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" @@ -5172,6 +5276,11 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -5388,6 +5497,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -5963,6 +6077,11 @@ ssri@^12.0.0: dependencies: minipass "^7.0.3" +stack-trace@1.0.0-pre2: + version "1.0.0-pre2" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-1.0.0-pre2.tgz#46a83a79f1b287807e9aaafc6a5dd8bcde626f9c" + integrity sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A== + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -6763,3 +6882,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yocto-queue@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" + integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==