Refactor benchmark script (#6376)
* Add timer setting * Setup benchmark code * Setup memory benchmark * Add compare function * Add result preview * Setup results preview * Simplify script for CI * Update CI * Cleanup * Temp remove fork guard * Fix stuff * Fix again * Fix quotes * Fix multiline output * Simplify title * Fix memory numbers * Remove astro bin dir * Fix gc * Add repo guards * Fix wrong call * Set max space size * Remove guard * Bump memory a bit * Organize neatly * Update readme * Try large md * Try no gc * Revert markdown and gc changes * Test sha * Try ref * Try 128mb * Set 256 * Add guard * Apply suggestions from code review Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Add docs comment --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
045262ee99
commit
f4937949d6
25 changed files with 719 additions and 37 deletions
|
@ -38,5 +38,11 @@ module.exports = {
|
||||||
'no-console': ['error', { allow: ['warn', 'error', 'info', 'debug'] }],
|
'no-console': ['error', { allow: ['warn', 'error', 'info', 'debug'] }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: ['benchmark/**/*.js'],
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
50
.github/workflows/benchmark.yml
vendored
50
.github/workflows/benchmark.yml
vendored
|
@ -16,19 +16,14 @@ jobs:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
outputs:
|
outputs:
|
||||||
PR-BENCH-16: ${{ steps.benchmark-pr.outputs.BENCH_RESULT16 }}
|
PR-BENCH: ${{ steps.benchmark-pr.outputs.BENCH_RESULT }}
|
||||||
PR-BENCH-18: ${{ steps.benchmark-pr.outputs.BENCH_RESULT18 }}
|
MAIN-BENCH: ${{ steps.benchmark-main.outputs.BENCH_RESULT }}
|
||||||
MAIN-BENCH-16: ${{ steps.benchmark-main.outputs.BENCH_RESULT16 }}
|
|
||||||
MAIN-BENCH-18: ${{ steps.benchmark-main.outputs.BENCH_RESULT18 }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [16, 18]
|
|
||||||
steps:
|
steps:
|
||||||
|
# https://github.com/actions/checkout/issues/331#issuecomment-1438220926
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
ref: ${{github.event.pull_request.head.sha}}
|
ref: refs/pull/${{ github.event.issue.number }}/head
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Setup PNPM
|
- name: Setup PNPM
|
||||||
uses: pnpm/action-setup@v2
|
uses: pnpm/action-setup@v2
|
||||||
|
@ -45,13 +40,22 @@ jobs:
|
||||||
- name: Build Packages
|
- name: Build Packages
|
||||||
run: pnpm run build
|
run: pnpm run build
|
||||||
|
|
||||||
|
- name: Get bench command
|
||||||
|
id: bench-command
|
||||||
|
run: |
|
||||||
|
benchcmd=$(echo "${{ github.event.comment.body }}" | grep '!bench' | awk -F ' ' '{print $2}')
|
||||||
|
echo "bench=$benchcmd" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Run benchmark
|
- name: Run benchmark
|
||||||
id: benchmark-pr
|
id: benchmark-pr
|
||||||
run: |
|
run: |
|
||||||
pnpm run --silent benchmark 2> ./bench-result.md
|
result=$(pnpm run --silent benchmark ${{ steps.bench-command.outputs.bench }})
|
||||||
result=$(awk '/requests in/' ./bench-result.md)
|
processed=$(node ./benchmark/ci-helper.js "$result")
|
||||||
echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$result"
|
echo "BENCH_RESULT<<BENCHEOF" >> $GITHUB_OUTPUT
|
||||||
echo "$result"
|
echo "### PR Benchmark" >> $GITHUB_OUTPUT
|
||||||
|
echo "$processed" >> $GITHUB_OUTPUT
|
||||||
|
echo "BENCHEOF" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
# main benchmark
|
# main benchmark
|
||||||
|
@ -70,10 +74,12 @@ jobs:
|
||||||
- name: Run benchmark
|
- name: Run benchmark
|
||||||
id: benchmark-main
|
id: benchmark-main
|
||||||
run: |
|
run: |
|
||||||
pnpm run --silent benchmark 2> ./bench-result.md
|
result=$(pnpm run --silent benchmark ${{ steps.bench-command.outputs.bench }})
|
||||||
result=$(awk '/requests in/' ./bench-result.md)
|
processed=$(node ./benchmark/ci-helper.js "$result")
|
||||||
echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$result"
|
echo "BENCH_RESULT<<BENCHEOF" >> $GITHUB_OUTPUT
|
||||||
echo "$result"
|
echo "### Main Benchmark" >> $GITHUB_OUTPUT
|
||||||
|
echo "$processed" >> $GITHUB_OUTPUT
|
||||||
|
echo "BENCHEOF" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
output-benchmark:
|
output-benchmark:
|
||||||
|
@ -89,12 +95,6 @@ jobs:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
pr_number: ${{ github.event.issue.number }}
|
pr_number: ${{ github.event.issue.number }}
|
||||||
message: |
|
message: |
|
||||||
**Node**: 16
|
${{ needs.benchmark.outputs.PR-BENCH }}
|
||||||
**PR**: ${{ needs.benchmark.outputs.PR-BENCH-16 }}
|
|
||||||
**MAIN**: ${{ needs.benchmark.outputs.MAIN-BENCH-16 }}
|
|
||||||
|
|
||||||
---
|
${{ needs.benchmark.outputs.MAIN-BENCH }}
|
||||||
|
|
||||||
**Node**: 18
|
|
||||||
**PR**: ${{ needs.benchmark.outputs.PR-BENCH-18 }}
|
|
||||||
**MAIN**: ${{ needs.benchmark.outputs.MAIN-BENCH-18 }}
|
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,6 +6,8 @@ dist/
|
||||||
_site/
|
_site/
|
||||||
scripts/smoke/*-main/
|
scripts/smoke/*-main/
|
||||||
scripts/memory/project/src/pages/
|
scripts/memory/project/src/pages/
|
||||||
|
benchmark/projects/
|
||||||
|
benchmark/results/
|
||||||
*.log
|
*.log
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.turbo/
|
.turbo/
|
||||||
|
|
5
benchmark/README.md
Normal file
5
benchmark/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# benchmark
|
||||||
|
|
||||||
|
Astro's main benchmark suite. It exposes the `astro-benchmark` CLI command. Run `astro-benchmark --help` to see all available commands!
|
||||||
|
|
||||||
|
If you'd like to understand how the benchmark works, check out the other READMEs in the subfolders.
|
7
benchmark/bench/README.md
Normal file
7
benchmark/bench/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# bench
|
||||||
|
|
||||||
|
This `bench` folder contains different benchmarking files that you can run via `astro-benchmark <bench-file-name>`, e.g. `astro-benchmark memory`. Files that start with an underscore are not benchmarking files.
|
||||||
|
|
||||||
|
Benchmarking files will run against a project to measure its performance, and write the results down as JSON in the `results` folder. The `results` folder is gitignored and its result files can be safely deleted if you're not using them.
|
||||||
|
|
||||||
|
You can duplicate `_template.js` to start a new benchmark test. All shared utilities are kept in `_util.js`.
|
12
benchmark/bench/_template.js
Normal file
12
benchmark/bench/_template.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** Default project to run for this benchmark if not specified */
|
||||||
|
export const defaultProject = 'project-name';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run benchmark on `projectDir` and write results to `outputFile`.
|
||||||
|
* Use `console.log` to report the results too. Logs that start with 10 `=`
|
||||||
|
* and end with 10 `=` will be extracted by CI to display in the PR comment.
|
||||||
|
* Usually after the first 10 `=` you'll want to add a title like `#### Test`.
|
||||||
|
* @param {URL} projectDir
|
||||||
|
* @param {URL} outputFile
|
||||||
|
*/
|
||||||
|
export async function run(projectDir, outputFile) {}
|
3
benchmark/bench/_util.js
Normal file
3
benchmark/bench/_util.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { createRequire } from 'module';
|
||||||
|
|
||||||
|
export const astroBin = createRequire(import.meta.url).resolve('astro');
|
58
benchmark/bench/memory.js
Normal file
58
benchmark/bench/memory.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { execaCommand } from 'execa';
|
||||||
|
import { markdownTable } from 'markdown-table';
|
||||||
|
import { astroBin } from './_util.js';
|
||||||
|
|
||||||
|
/** @typedef {Record<string, import('../../packages/astro/src/core/config/timer').Stat>} AstroTimerStat */
|
||||||
|
|
||||||
|
/** Default project to run for this benchmark if not specified */
|
||||||
|
export const defaultProject = 'memory-default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {URL} projectDir
|
||||||
|
* @param {URL} outputFile
|
||||||
|
*/
|
||||||
|
export async function run(projectDir, outputFile) {
|
||||||
|
const root = fileURLToPath(projectDir);
|
||||||
|
const outputFilePath = fileURLToPath(outputFile);
|
||||||
|
|
||||||
|
console.log('Building and benchmarking...');
|
||||||
|
await execaCommand(`node --expose-gc --max_old_space_size=256 ${astroBin} build`, {
|
||||||
|
cwd: root,
|
||||||
|
stdio: 'inherit',
|
||||||
|
env: {
|
||||||
|
ASTRO_TIMER_PATH: outputFilePath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Raw results written to', outputFilePath);
|
||||||
|
|
||||||
|
console.log('Result preview:');
|
||||||
|
console.log('='.repeat(10));
|
||||||
|
console.log(`#### Memory\n\n`);
|
||||||
|
console.log(printResult(JSON.parse(await fs.readFile(outputFilePath, 'utf-8'))));
|
||||||
|
console.log('='.repeat(10));
|
||||||
|
|
||||||
|
console.log('Done!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {AstroTimerStat} output
|
||||||
|
*/
|
||||||
|
function printResult(output) {
|
||||||
|
return markdownTable(
|
||||||
|
[
|
||||||
|
['', 'Elapsed time (s)', 'Memory used (MB)', 'Final memory (MB)'],
|
||||||
|
...Object.entries(output).map(([name, stat]) => [
|
||||||
|
name,
|
||||||
|
(stat.elapsedTime / 1000).toFixed(2),
|
||||||
|
(stat.heapUsedChange / 1024 / 1024).toFixed(2),
|
||||||
|
(stat.heapUsedTotal / 1024 / 1024).toFixed(2),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
align: ['l', 'r', 'r', 'r'],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
85
benchmark/bench/server-stress.js
Normal file
85
benchmark/bench/server-stress.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import autocannon from 'autocannon';
|
||||||
|
import { execaCommand } from 'execa';
|
||||||
|
import { waitUntilBusy } from 'port-authority';
|
||||||
|
import { astroBin } from './_util.js';
|
||||||
|
|
||||||
|
const port = 4321;
|
||||||
|
|
||||||
|
export const defaultProject = 'server-stress-default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {URL} projectDir
|
||||||
|
* @param {URL} outputFile
|
||||||
|
*/
|
||||||
|
export async function run(projectDir, outputFile) {
|
||||||
|
const root = fileURLToPath(projectDir);
|
||||||
|
|
||||||
|
console.log('Building...');
|
||||||
|
await execaCommand(`${astroBin} build`, {
|
||||||
|
cwd: root,
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Previewing...');
|
||||||
|
const previewProcess = execaCommand(`${astroBin} preview --port ${port}`, {
|
||||||
|
cwd: root,
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Waiting for server ready...');
|
||||||
|
await waitUntilBusy(port, { timeout: 5000 });
|
||||||
|
|
||||||
|
console.log('Running benchmark...');
|
||||||
|
const result = await benchmarkCannon();
|
||||||
|
|
||||||
|
console.log('Killing server...');
|
||||||
|
if (!previewProcess.kill('SIGTERM')) {
|
||||||
|
console.warn('Failed to kill server process id:', previewProcess.pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Writing results to', fileURLToPath(outputFile));
|
||||||
|
await fs.writeFile(outputFile, JSON.stringify(result, null, 2));
|
||||||
|
|
||||||
|
console.log('Result preview:');
|
||||||
|
console.log('='.repeat(10));
|
||||||
|
console.log(`#### Server stress\n\n`);
|
||||||
|
let text = autocannon.printResult(result);
|
||||||
|
// Truncate the logs in CI so that the generated comment from the `!bench` command
|
||||||
|
// is shortened. Also we only need this information when comparing runs.
|
||||||
|
// Full log example: https://github.com/mcollina/autocannon#command-line
|
||||||
|
if (process.env.CI) {
|
||||||
|
text = text.match(/^.*?requests in.*?read$/m)?.[0];
|
||||||
|
}
|
||||||
|
console.log(text);
|
||||||
|
console.log('='.repeat(10));
|
||||||
|
|
||||||
|
console.log('Done!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<import('autocannon').Result>}
|
||||||
|
*/
|
||||||
|
async function benchmarkCannon() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const instance = autocannon(
|
||||||
|
{
|
||||||
|
url: `http://localhost:${port}`,
|
||||||
|
connections: 100,
|
||||||
|
duration: 30,
|
||||||
|
pipelining: 10,
|
||||||
|
},
|
||||||
|
(err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
// @ts-expect-error untyped but documented
|
||||||
|
instance.stop();
|
||||||
|
resolve(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
autocannon.track(instance, { renderResultsTable: false });
|
||||||
|
});
|
||||||
|
}
|
13
benchmark/ci-helper.js
Normal file
13
benchmark/ci-helper.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// This script helps extract the benchmark logs that are between the `==========` lines.
|
||||||
|
// They are a convention defined in the `./bench/_template.js` file, which are used to log
|
||||||
|
// out with the `!bench` command. See `/.github/workflows/benchmark.yml` to see how it's used.
|
||||||
|
const benchLogs = process.argv[2];
|
||||||
|
const resultRegex = /==========(.*?)==========/gs;
|
||||||
|
|
||||||
|
let processedLog = '';
|
||||||
|
let m;
|
||||||
|
while ((m = resultRegex.exec(benchLogs))) {
|
||||||
|
processedLog += m[1] + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(processedLog);
|
79
benchmark/index.js
Executable file
79
benchmark/index.js
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
import { pathToFileURL } from 'url';
|
||||||
|
import mri from 'mri';
|
||||||
|
|
||||||
|
const args = mri(process.argv.slice(2));
|
||||||
|
|
||||||
|
if (args.help || args.h) {
|
||||||
|
console.log(`\
|
||||||
|
astro-benchmark <command> [options]
|
||||||
|
|
||||||
|
Command
|
||||||
|
[empty] Run all benchmarks
|
||||||
|
memory Run build memory and speed test
|
||||||
|
server-stress Run server stress test
|
||||||
|
|
||||||
|
Options
|
||||||
|
--project <project-name> Project to use for benchmark, see benchmark/make-project/ for available names
|
||||||
|
--output <output-file> Output file to write results to
|
||||||
|
`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const commandName = args._[0];
|
||||||
|
const benchmarks = {
|
||||||
|
memory: () => import('./bench/memory.js'),
|
||||||
|
'server-stress': () => import('./bench/server-stress.js'),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (commandName && !(commandName in benchmarks)) {
|
||||||
|
console.error(`Invalid benchmark name: ${commandName}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandName) {
|
||||||
|
// Run single benchmark
|
||||||
|
const bench = benchmarks[commandName];
|
||||||
|
const benchMod = await bench();
|
||||||
|
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||||
|
const outputFile = await getOutputFile(commandName);
|
||||||
|
await benchMod.run(projectDir, outputFile);
|
||||||
|
} else {
|
||||||
|
// Run all benchmarks
|
||||||
|
for (const name in benchmarks) {
|
||||||
|
const bench = benchmarks[name];
|
||||||
|
const benchMod = await bench();
|
||||||
|
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||||
|
const outputFile = await getOutputFile(name);
|
||||||
|
await benchMod.run(projectDir, outputFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeProject(name) {
|
||||||
|
console.log('Making project:', name);
|
||||||
|
const projectDir = new URL(`./projects/${name}/`, import.meta.url);
|
||||||
|
|
||||||
|
const makeProjectMod = await import(`./make-project/${name}.js`);
|
||||||
|
await makeProjectMod.run(projectDir);
|
||||||
|
|
||||||
|
console.log('Finished making project:', name);
|
||||||
|
return projectDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} benchmarkName
|
||||||
|
*/
|
||||||
|
async function getOutputFile(benchmarkName) {
|
||||||
|
let file;
|
||||||
|
if (args.output) {
|
||||||
|
file = pathToFileURL(path.resolve(args.output));
|
||||||
|
} else {
|
||||||
|
file = new URL(`./results/${benchmarkName}-bench-${Date.now()}.json`, import.meta.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare output file directory
|
||||||
|
await fs.mkdir(new URL('./', file), { recursive: true });
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
7
benchmark/make-project/README.md
Normal file
7
benchmark/make-project/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# make-project
|
||||||
|
|
||||||
|
This `make-project` folder contains different files to programmatically create a new Astro project. They are created inside the `projects` folder and are gitignored. These projects are used by benchmarks for testing.
|
||||||
|
|
||||||
|
Each benchmark can specify the default project to run in its `defaultProject` export, but it can be overriden if `--project <project-name>` is passed through the CLI.
|
||||||
|
|
||||||
|
You can duplicate `_template.js` to start a new project script. All shared utilities are kept in `_util.js`.
|
6
benchmark/make-project/_template.js
Normal file
6
benchmark/make-project/_template.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Create a new project in the `projectDir` directory. Make sure to clean up the
|
||||||
|
* previous artifacts here before generating files.
|
||||||
|
* @param {URL} projectDir
|
||||||
|
*/
|
||||||
|
export async function run(projectDir) {}
|
2
benchmark/make-project/_util.js
Normal file
2
benchmark/make-project/_util.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const loremIpsum =
|
||||||
|
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
|
59
benchmark/make-project/memory-default.js
Normal file
59
benchmark/make-project/memory-default.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import { loremIpsum } from './_util.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {URL} projectDir
|
||||||
|
*/
|
||||||
|
export async function run(projectDir) {
|
||||||
|
await fs.rm(projectDir, { recursive: true, force: true });
|
||||||
|
await fs.mkdir(new URL('./src/pages/blog', projectDir), { recursive: true });
|
||||||
|
await fs.mkdir(new URL('./src/content/blog', projectDir), { recursive: true });
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const content = `\
|
||||||
|
---
|
||||||
|
const i = ${i};
|
||||||
|
---
|
||||||
|
|
||||||
|
<span>{i}</span>
|
||||||
|
`;
|
||||||
|
promises.push(
|
||||||
|
fs.writeFile(new URL(`./src/pages/page-${i}.astro`, projectDir), content, 'utf-8')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const content = `\
|
||||||
|
# Article ${i}
|
||||||
|
|
||||||
|
${loremIpsum}
|
||||||
|
`;
|
||||||
|
promises.push(
|
||||||
|
fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.writeFile(
|
||||||
|
new URL(`./src/pages/blog/[...slug].astro`, projectDir),
|
||||||
|
`\
|
||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const blogEntries = await getCollection('blog');
|
||||||
|
return blogEntries.map(entry => ({
|
||||||
|
params: { slug: entry.slug }, props: { entry },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const { entry } = Astro.props;
|
||||||
|
const { Content } = await entry.render();
|
||||||
|
---
|
||||||
|
<h1>{entry.data.title}</h1>
|
||||||
|
<Content />
|
||||||
|
`,
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
47
benchmark/make-project/server-stress-default.js
Normal file
47
benchmark/make-project/server-stress-default.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import { loremIpsum } from './_util.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {URL} projectDir
|
||||||
|
*/
|
||||||
|
export async function run(projectDir) {
|
||||||
|
await fs.rm(projectDir, { recursive: true, force: true });
|
||||||
|
await fs.mkdir(new URL('./src/pages', projectDir), { recursive: true });
|
||||||
|
|
||||||
|
await fs.writeFile(
|
||||||
|
new URL('./src/pages/index.astro', projectDir),
|
||||||
|
`\
|
||||||
|
---
|
||||||
|
const content = "${loremIpsum}"
|
||||||
|
---
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<title>Astro</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Astro</h1>
|
||||||
|
<div>
|
||||||
|
${Array.from({ length: 60 }).map(() => '<p>{content}</p>')}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`,
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
await fs.writeFile(
|
||||||
|
new URL('./astro.config.js', projectDir),
|
||||||
|
`\
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import nodejs from '@astrojs/node';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
output: 'server',
|
||||||
|
adapter: nodejs({ mode: 'standalone' }),
|
||||||
|
});`,
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
}
|
18
benchmark/package.json
Normal file
18
benchmark/package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "astro-benchmark",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"bin": {
|
||||||
|
"astro-benchmark": "./index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/node": "workspace:*",
|
||||||
|
"astro": "workspace:*",
|
||||||
|
"autocannon": "^7.10.0",
|
||||||
|
"execa": "^6.1.0",
|
||||||
|
"markdown-table": "^3.0.3",
|
||||||
|
"mri": "^1.2.0",
|
||||||
|
"port-authority": "^2.0.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
"test:vite-ci": "turbo run test --filter=astro --output-logs=new-only --no-deps --concurrency=1",
|
"test:vite-ci": "turbo run test --filter=astro --output-logs=new-only --no-deps --concurrency=1",
|
||||||
"test:e2e": "cd packages/astro && pnpm playwright install && pnpm run test:e2e",
|
"test:e2e": "cd packages/astro && pnpm playwright install && pnpm run test:e2e",
|
||||||
"test:e2e:match": "cd packages/astro && pnpm playwright install && pnpm run test:e2e:match",
|
"test:e2e:match": "cd packages/astro && pnpm playwright install && pnpm run test:e2e:match",
|
||||||
"benchmark": "pnpm --filter @benchmark/simple run build && pnpm dlx concurrently -k -s first --raw \"node packages/astro/test/benchmark/simple/server.mjs\" \"pnpm dlx autocannon -c 100 -d 30 -p 10 localhost:3002/\"",
|
"benchmark": "astro-benchmark",
|
||||||
"lint": "eslint --cache .",
|
"lint": "eslint --cache .",
|
||||||
"version": "changeset version && pnpm install --no-frozen-lockfile && pnpm run format",
|
"version": "changeset version && pnpm install --no-frozen-lockfile && pnpm run format",
|
||||||
"preinstall": "npx only-allow pnpm"
|
"preinstall": "npx only-allow pnpm"
|
||||||
|
@ -76,7 +76,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/webapi": "workspace:*"
|
"@astrojs/webapi": "workspace:*",
|
||||||
|
"astro-benchmark": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/changelog-github": "0.4.4",
|
"@changesets/changelog-github": "0.4.4",
|
||||||
|
|
|
@ -16,6 +16,7 @@ import type { z } from 'zod';
|
||||||
import type { SerializedSSRManifest } from '../core/app/types';
|
import type { SerializedSSRManifest } from '../core/app/types';
|
||||||
import type { PageBuildData } from '../core/build/types';
|
import type { PageBuildData } from '../core/build/types';
|
||||||
import type { AstroConfigSchema } from '../core/config';
|
import type { AstroConfigSchema } from '../core/config';
|
||||||
|
import type { AstroTimer } from '../core/config/timer';
|
||||||
import type { AstroCookies } from '../core/cookies';
|
import type { AstroCookies } from '../core/cookies';
|
||||||
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
|
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
|
||||||
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
||||||
|
@ -992,6 +993,7 @@ export interface AstroSettings {
|
||||||
tsConfigPath: string | undefined;
|
tsConfigPath: string | undefined;
|
||||||
watchFiles: string[];
|
watchFiles: string[];
|
||||||
forceDisableTelemetry: boolean;
|
forceDisableTelemetry: boolean;
|
||||||
|
timer: AstroTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AsyncRendererComponentFn<U> = (
|
export type AsyncRendererComponentFn<U> = (
|
||||||
|
|
|
@ -167,6 +167,9 @@ class AstroBuilder {
|
||||||
buildMode: this.settings.config.output,
|
buildMode: this.settings.config.output,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Benchmark results
|
||||||
|
this.settings.timer.writeStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Build the given Astro project. */
|
/** Build the given Astro project. */
|
||||||
|
|
|
@ -33,6 +33,8 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
throw new AstroError(AstroErrorData.NoAdapterInstalled);
|
throw new AstroError(AstroErrorData.NoAdapterInstalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.timer.start('SSR build');
|
||||||
|
|
||||||
// The pages to be built for rendering purposes.
|
// The pages to be built for rendering purposes.
|
||||||
const pageInput = new Set<string>();
|
const pageInput = new Set<string>();
|
||||||
|
|
||||||
|
@ -43,10 +45,6 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
// Build internals needed by the CSS plugin
|
// Build internals needed by the CSS plugin
|
||||||
const internals = createBuildInternals();
|
const internals = createBuildInternals();
|
||||||
|
|
||||||
const timer: Record<string, number> = {};
|
|
||||||
|
|
||||||
timer.buildStart = performance.now();
|
|
||||||
|
|
||||||
for (const [component, pageData] of Object.entries(allPages)) {
|
for (const [component, pageData] of Object.entries(allPages)) {
|
||||||
const astroModuleURL = new URL('./' + component, settings.config.root);
|
const astroModuleURL = new URL('./' + component, settings.config.root);
|
||||||
const astroModuleId = prependForwardSlash(component);
|
const astroModuleId = prependForwardSlash(component);
|
||||||
|
@ -70,10 +68,13 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
registerAllPlugins(container);
|
registerAllPlugins(container);
|
||||||
|
|
||||||
// Build your project (SSR application code, assets, client JS, etc.)
|
// Build your project (SSR application code, assets, client JS, etc.)
|
||||||
timer.ssr = performance.now();
|
const ssrTime = performance.now();
|
||||||
info(opts.logging, 'build', `Building ${settings.config.output} entrypoints...`);
|
info(opts.logging, 'build', `Building ${settings.config.output} entrypoints...`);
|
||||||
const ssrOutput = await ssrBuild(opts, internals, pageInput, container);
|
const ssrOutput = await ssrBuild(opts, internals, pageInput, container);
|
||||||
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));
|
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(ssrTime, performance.now())}.`));
|
||||||
|
|
||||||
|
settings.timer.end('SSR build');
|
||||||
|
settings.timer.start('Client build');
|
||||||
|
|
||||||
const rendererClientEntrypoints = settings.renderers
|
const rendererClientEntrypoints = settings.renderers
|
||||||
.map((r) => r.clientEntrypoint)
|
.map((r) => r.clientEntrypoint)
|
||||||
|
@ -91,23 +92,27 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run client build first, so the assets can be fed into the SSR rendered version.
|
// Run client build first, so the assets can be fed into the SSR rendered version.
|
||||||
timer.clientBuild = performance.now();
|
|
||||||
const clientOutput = await clientBuild(opts, internals, clientInput, container);
|
const clientOutput = await clientBuild(opts, internals, clientInput, container);
|
||||||
|
|
||||||
timer.generate = performance.now();
|
|
||||||
await runPostBuildHooks(container, ssrOutput, clientOutput);
|
await runPostBuildHooks(container, ssrOutput, clientOutput);
|
||||||
|
|
||||||
|
settings.timer.end('Client build');
|
||||||
|
|
||||||
switch (settings.config.output) {
|
switch (settings.config.output) {
|
||||||
case 'static': {
|
case 'static': {
|
||||||
|
settings.timer.start('Static generate');
|
||||||
await generatePages(opts, internals);
|
await generatePages(opts, internals);
|
||||||
await cleanServerOutput(opts);
|
await cleanServerOutput(opts);
|
||||||
|
settings.timer.end('Static generate');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'server': {
|
case 'server': {
|
||||||
|
settings.timer.start('Server generate');
|
||||||
await generatePages(opts, internals);
|
await generatePages(opts, internals);
|
||||||
await cleanStaticOutput(opts, internals);
|
await cleanStaticOutput(opts, internals);
|
||||||
info(opts.logging, null, `\n${bgMagenta(black(' finalizing server assets '))}\n`);
|
info(opts.logging, null, `\n${bgMagenta(black(' finalizing server assets '))}\n`);
|
||||||
await ssrMoveAssets(opts);
|
await ssrMoveAssets(opts);
|
||||||
|
settings.timer.end('Server generate');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import jsxRenderer from '../../jsx/renderer.js';
|
import jsxRenderer from '../../jsx/renderer.js';
|
||||||
import { createDefaultDevConfig } from './config.js';
|
import { createDefaultDevConfig } from './config.js';
|
||||||
import { loadTSConfig } from './tsconfig.js';
|
import { loadTSConfig } from './tsconfig.js';
|
||||||
|
import { AstroTimer } from './timer.js';
|
||||||
|
|
||||||
export function createBaseSettings(config: AstroConfig): AstroSettings {
|
export function createBaseSettings(config: AstroConfig): AstroSettings {
|
||||||
return {
|
return {
|
||||||
|
@ -19,6 +20,7 @@ export function createBaseSettings(config: AstroConfig): AstroSettings {
|
||||||
scripts: [],
|
scripts: [],
|
||||||
watchFiles: [],
|
watchFiles: [],
|
||||||
forceDisableTelemetry: false,
|
forceDisableTelemetry: false,
|
||||||
|
timer: new AstroTimer(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
packages/astro/src/core/config/timer.ts
Normal file
65
packages/astro/src/core/config/timer.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
// Type used by `bench-memory.js`
|
||||||
|
export interface Stat {
|
||||||
|
elapsedTime: number;
|
||||||
|
heapUsedChange: number;
|
||||||
|
heapUsedTotal: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OngoingStat {
|
||||||
|
startTime: number;
|
||||||
|
startHeap: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer to track certain operations' performance. Used by Astro's scripts only.
|
||||||
|
* Set `process.env.ASTRO_TIMER_PATH` truthy to enable.
|
||||||
|
*/
|
||||||
|
export class AstroTimer {
|
||||||
|
private enabled: boolean;
|
||||||
|
private ongoingTimers: Map<string, OngoingStat> = new Map();
|
||||||
|
private stats: Record<string, Stat> = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.enabled = !!process.env.ASTRO_TIMER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a timer for a scope with a given name.
|
||||||
|
*/
|
||||||
|
start(name: string) {
|
||||||
|
if (!this.enabled) return;
|
||||||
|
globalThis.gc?.();
|
||||||
|
this.ongoingTimers.set(name, {
|
||||||
|
startTime: performance.now(),
|
||||||
|
startHeap: process.memoryUsage().heapUsed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a timer for a scope with a given name.
|
||||||
|
*/
|
||||||
|
end(name: string) {
|
||||||
|
if (!this.enabled) return;
|
||||||
|
const stat = this.ongoingTimers.get(name);
|
||||||
|
if (!stat) return;
|
||||||
|
globalThis.gc?.();
|
||||||
|
const endHeap = process.memoryUsage().heapUsed;
|
||||||
|
this.stats[name] = {
|
||||||
|
elapsedTime: performance.now() - stat.startTime,
|
||||||
|
heapUsedChange: endHeap - stat.startHeap,
|
||||||
|
heapUsedTotal: endHeap,
|
||||||
|
};
|
||||||
|
this.ongoingTimers.delete(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write stats to `process.env.ASTRO_TIMER_PATH`
|
||||||
|
*/
|
||||||
|
writeStats() {
|
||||||
|
if (!this.enabled) return;
|
||||||
|
// @ts-expect-error
|
||||||
|
fs.writeFileSync(process.env.ASTRO_TIMER_PATH, JSON.stringify(this.stats, null, 2));
|
||||||
|
}
|
||||||
|
}
|
198
pnpm-lock.yaml
198
pnpm-lock.yaml
|
@ -21,6 +21,7 @@ importers:
|
||||||
'@types/node': ^18.7.21
|
'@types/node': ^18.7.21
|
||||||
'@typescript-eslint/eslint-plugin': ^5.27.1
|
'@typescript-eslint/eslint-plugin': ^5.27.1
|
||||||
'@typescript-eslint/parser': ^5.27.1
|
'@typescript-eslint/parser': ^5.27.1
|
||||||
|
astro-benchmark: workspace:*
|
||||||
del: ^7.0.0
|
del: ^7.0.0
|
||||||
esbuild: ^0.15.18
|
esbuild: ^0.15.18
|
||||||
eslint: ^8.17.0
|
eslint: ^8.17.0
|
||||||
|
@ -38,6 +39,7 @@ importers:
|
||||||
typescript: ~4.7.3
|
typescript: ~4.7.3
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/webapi': link:packages/webapi
|
'@astrojs/webapi': link:packages/webapi
|
||||||
|
astro-benchmark: link:benchmark
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@changesets/changelog-github': 0.4.4
|
'@changesets/changelog-github': 0.4.4
|
||||||
'@changesets/cli': 2.23.0_kcozqtpxuwjzskw6zg5royevn4
|
'@changesets/cli': 2.23.0_kcozqtpxuwjzskw6zg5royevn4
|
||||||
|
@ -61,6 +63,24 @@ importers:
|
||||||
turbo: 1.2.5
|
turbo: 1.2.5
|
||||||
typescript: 4.7.4
|
typescript: 4.7.4
|
||||||
|
|
||||||
|
benchmark:
|
||||||
|
specifiers:
|
||||||
|
'@astrojs/node': workspace:*
|
||||||
|
astro: workspace:*
|
||||||
|
autocannon: ^7.10.0
|
||||||
|
execa: ^6.1.0
|
||||||
|
markdown-table: ^3.0.3
|
||||||
|
mri: ^1.2.0
|
||||||
|
port-authority: ^2.0.1
|
||||||
|
dependencies:
|
||||||
|
'@astrojs/node': link:../packages/integrations/node
|
||||||
|
astro: link:../packages/astro
|
||||||
|
autocannon: 7.10.0
|
||||||
|
execa: 6.1.0
|
||||||
|
markdown-table: 3.0.3
|
||||||
|
mri: 1.2.0
|
||||||
|
port-authority: 2.0.1
|
||||||
|
|
||||||
examples/basics:
|
examples/basics:
|
||||||
specifiers:
|
specifiers:
|
||||||
astro: ^2.0.16
|
astro: ^2.0.16
|
||||||
|
@ -3878,6 +3898,10 @@ packages:
|
||||||
leven: 3.1.0
|
leven: 3.1.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@assemblyscript/loader/0.19.23:
|
||||||
|
resolution: {integrity: sha512-ulkCYfFbYj01ie1MDOyxv2F6SpRN1TOj7fQxbP07D6HmeR+gr2JLSmINKjga2emB+b1L2KGrFKBTc+e00p54nw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@astro-community/astro-embed-integration/0.1.2_astro@packages+astro:
|
/@astro-community/astro-embed-integration/0.1.2_astro@packages+astro:
|
||||||
resolution: {integrity: sha512-ONBDHkOUZ7ssQNzRc5XRZtBBJR0zC68Gm2FCm5w6fxxciDkRkU9Zn9BSssgaNrLPfsXycxFLtQZT3dX9ZPsAxw==}
|
resolution: {integrity: sha512-ONBDHkOUZ7ssQNzRc5XRZtBBJR0zC68Gm2FCm5w6fxxciDkRkU9Zn9BSssgaNrLPfsXycxFLtQZT3dX9ZPsAxw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -5632,6 +5656,13 @@ packages:
|
||||||
mime: 3.0.0
|
mime: 3.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@colors/colors/1.5.0:
|
||||||
|
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||||
|
engines: {node: '>=0.1.90'}
|
||||||
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
|
||||||
/@csstools/postcss-cascade-layers/1.1.1_postcss@8.4.21:
|
/@csstools/postcss-cascade-layers/1.1.1_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==}
|
resolution: {integrity: sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==}
|
||||||
engines: {node: ^12 || ^14 || >=16}
|
engines: {node: ^12 || ^14 || >=16}
|
||||||
|
@ -8139,11 +8170,44 @@ packages:
|
||||||
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
|
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/asynckit/0.4.0:
|
||||||
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/at-least-node/1.0.0:
|
/at-least-node/1.0.0:
|
||||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/autocannon/7.10.0:
|
||||||
|
resolution: {integrity: sha512-PY1UrXL4NHE7J0hA6GGN2r8xjiAePS/bii3Hz7NOvp4JO3xDNBgRftDjfAxj1t6FDWXiXEOuKF/pdDiisIS8ZA==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
chalk: 4.1.2
|
||||||
|
char-spinner: 1.0.1
|
||||||
|
cli-table3: 0.6.3
|
||||||
|
color-support: 1.1.3
|
||||||
|
cross-argv: 2.0.0
|
||||||
|
form-data: 4.0.0
|
||||||
|
has-async-hooks: 1.0.0
|
||||||
|
hdr-histogram-js: 3.0.0
|
||||||
|
hdr-histogram-percentiles-obj: 3.0.0
|
||||||
|
http-parser-js: 0.5.8
|
||||||
|
hyperid: 3.1.1
|
||||||
|
lodash.chunk: 4.2.0
|
||||||
|
lodash.clonedeep: 4.5.0
|
||||||
|
lodash.flatten: 4.4.0
|
||||||
|
manage-path: 2.0.0
|
||||||
|
on-net-listen: 1.1.2
|
||||||
|
pretty-bytes: 5.6.0
|
||||||
|
progress: 2.0.3
|
||||||
|
reinterval: 1.1.0
|
||||||
|
retimer: 3.0.0
|
||||||
|
semver: 7.3.8
|
||||||
|
subarg: 1.0.0
|
||||||
|
timestring: 6.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/autoprefixer/10.4.13_postcss@8.4.21:
|
/autoprefixer/10.4.13_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
|
resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
@ -8524,6 +8588,10 @@ packages:
|
||||||
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/char-spinner/1.0.1:
|
||||||
|
resolution: {integrity: sha512-acv43vqJ0+N0rD+Uw3pDHSxP30FHrywu2NO6/wBaHChJIizpDeBUd6NjqhNhy9LGaEAhZAXn46QzmlAvIWd16g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/character-entities-html4/2.1.0:
|
/character-entities-html4/2.1.0:
|
||||||
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
|
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
|
||||||
|
|
||||||
|
@ -8622,6 +8690,15 @@ packages:
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/cli-table3/0.6.3:
|
||||||
|
resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==}
|
||||||
|
engines: {node: 10.* || >= 12.*}
|
||||||
|
dependencies:
|
||||||
|
string-width: 4.2.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@colors/colors': 1.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cliui/6.0.0:
|
/cliui/6.0.0:
|
||||||
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -8696,6 +8773,13 @@ packages:
|
||||||
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
|
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/combined-stream/1.0.8:
|
||||||
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
|
engines: {node: '>= 0.8'}
|
||||||
|
dependencies:
|
||||||
|
delayed-stream: 1.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/comma-separated-tokens/2.0.3:
|
/comma-separated-tokens/2.0.3:
|
||||||
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -8774,6 +8858,10 @@ packages:
|
||||||
resolution: {integrity: sha512-izfGgKyzzIyLaeb1EtZ3KbglkS6AKp9cv7LxmiyoOu+fXfol1tQDC0Cof0enVZGNtudTHW+3lfuW9ZkLQss4Wg==}
|
resolution: {integrity: sha512-izfGgKyzzIyLaeb1EtZ3KbglkS6AKp9cv7LxmiyoOu+fXfol1tQDC0Cof0enVZGNtudTHW+3lfuW9ZkLQss4Wg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cross-argv/2.0.0:
|
||||||
|
resolution: {integrity: sha512-YIaY9TR5Nxeb8SMdtrU8asWVM4jqJDNDYlKV21LxtYcfNJhp1kEsgSa6qXwXgzN0WQWGODps0+TlGp2xQSHwOg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cross-spawn/5.1.0:
|
/cross-spawn/5.1.0:
|
||||||
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -9046,6 +9134,11 @@ packages:
|
||||||
slash: 4.0.0
|
slash: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/delayed-stream/1.0.0:
|
||||||
|
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/delegates/1.0.0:
|
/delegates/1.0.0:
|
||||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -10030,6 +10123,15 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-callable: 1.2.7
|
is-callable: 1.2.7
|
||||||
|
|
||||||
|
/form-data/4.0.0:
|
||||||
|
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dependencies:
|
||||||
|
asynckit: 0.4.0
|
||||||
|
combined-stream: 1.0.8
|
||||||
|
mime-types: 2.1.35
|
||||||
|
dev: false
|
||||||
|
|
||||||
/format/0.2.2:
|
/format/0.2.2:
|
||||||
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
||||||
engines: {node: '>=0.4.x'}
|
engines: {node: '>=0.4.x'}
|
||||||
|
@ -10376,6 +10478,10 @@ packages:
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/has-async-hooks/1.0.0:
|
||||||
|
resolution: {integrity: sha512-YF0VPGjkxr7AyyQQNykX8zK4PvtEDsUJAPqwu06UFz1lb6EvI53sPh5H1kWxg8NXI5LsfRCZ8uX9NkYDZBb/mw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/has-bigints/1.0.2:
|
/has-bigints/1.0.2:
|
||||||
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
|
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
|
||||||
|
|
||||||
|
@ -10579,6 +10685,19 @@ packages:
|
||||||
space-separated-tokens: 2.0.2
|
space-separated-tokens: 2.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/hdr-histogram-js/3.0.0:
|
||||||
|
resolution: {integrity: sha512-/EpvQI2/Z98mNFYEnlqJ8Ogful8OpArLG/6Tf2bPnkutBVLIeMVNHjk1ZDfshF2BUweipzbk+dB1hgSB7SIakw==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
dependencies:
|
||||||
|
'@assemblyscript/loader': 0.19.23
|
||||||
|
base64-js: 1.5.1
|
||||||
|
pako: 1.0.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/hdr-histogram-percentiles-obj/3.0.0:
|
||||||
|
resolution: {integrity: sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/he/1.2.0:
|
/he/1.2.0:
|
||||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -10629,6 +10748,10 @@ packages:
|
||||||
statuses: 2.0.1
|
statuses: 2.0.1
|
||||||
toidentifier: 1.0.1
|
toidentifier: 1.0.1
|
||||||
|
|
||||||
|
/http-parser-js/0.5.8:
|
||||||
|
resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/http-proxy-agent/4.0.1:
|
/http-proxy-agent/4.0.1:
|
||||||
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
|
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
@ -10662,6 +10785,13 @@ packages:
|
||||||
resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==}
|
resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==}
|
||||||
engines: {node: '>=12.20.0'}
|
engines: {node: '>=12.20.0'}
|
||||||
|
|
||||||
|
/hyperid/3.1.1:
|
||||||
|
resolution: {integrity: sha512-RveV33kIksycSf7HLkq1sHB5wW0OwuX8ot8MYnY++gaaPXGFfKpBncHrAWxdpuEeRlazUMGWefwP1w6o6GaumA==}
|
||||||
|
dependencies:
|
||||||
|
uuid: 8.3.2
|
||||||
|
uuid-parse: 1.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/iconv-lite/0.4.24:
|
/iconv-lite/0.4.24:
|
||||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -11265,10 +11395,22 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
|
|
||||||
|
/lodash.chunk/4.2.0:
|
||||||
|
resolution: {integrity: sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/lodash.clonedeep/4.5.0:
|
||||||
|
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lodash.debounce/4.0.8:
|
/lodash.debounce/4.0.8:
|
||||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/lodash.flatten/4.4.0:
|
||||||
|
resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lodash.merge/4.6.2:
|
/lodash.merge/4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -11372,6 +11514,10 @@ packages:
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/manage-path/2.0.0:
|
||||||
|
resolution: {integrity: sha512-NJhyB+PJYTpxhxZJ3lecIGgh4kwIY2RAh44XvAz9UlqthlQwtPBf62uBVR8XaD8CRuSjQ6TnZH2lNJkbLPZM2A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/map-obj/1.0.1:
|
/map-obj/1.0.1:
|
||||||
resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
|
resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -11974,14 +12120,12 @@ packages:
|
||||||
/mime-db/1.52.0:
|
/mime-db/1.52.0:
|
||||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/mime-types/2.1.35:
|
/mime-types/2.1.35:
|
||||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.52.0
|
mime-db: 1.52.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/mime/1.6.0:
|
/mime/1.6.0:
|
||||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||||
|
@ -12082,6 +12226,10 @@ packages:
|
||||||
/minimist/1.2.7:
|
/minimist/1.2.7:
|
||||||
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
|
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
|
||||||
|
|
||||||
|
/minimist/1.2.8:
|
||||||
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/minipass/3.3.6:
|
/minipass/3.3.6:
|
||||||
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -12381,6 +12529,11 @@ packages:
|
||||||
ee-first: 1.1.1
|
ee-first: 1.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/on-net-listen/1.1.2:
|
||||||
|
resolution: {integrity: sha512-y1HRYy8s/RlcBvDUwKXSmkODMdx4KSuIvloCnQYJ2LdBBC1asY4HtfhXwe3UWknLakATZDnbzht2Ijw3M1EqFg==}
|
||||||
|
engines: {node: '>=9.4.0 || ^8.9.4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/once/1.4.0:
|
/once/1.4.0:
|
||||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -12553,6 +12706,10 @@ packages:
|
||||||
netmask: 2.0.2
|
netmask: 2.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pako/1.0.11:
|
||||||
|
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/parent-module/1.0.1:
|
/parent-module/1.0.1:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -12723,6 +12880,10 @@ packages:
|
||||||
playwright-core: 1.30.0
|
playwright-core: 1.30.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/port-authority/2.0.1:
|
||||||
|
resolution: {integrity: sha512-Hz/WvSNt5+7x+Rq1Cn6DetJOZxKtLDehJ1mLCYge6ju4QvSF/PHvRgy94e1SKJVI96AJTcqEdNwkkaAFad+TXQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-attribute-case-insensitive/5.0.2_postcss@8.4.21:
|
/postcss-attribute-case-insensitive/5.0.2_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==}
|
resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==}
|
||||||
engines: {node: ^12 || ^14 || >=16}
|
engines: {node: ^12 || ^14 || >=16}
|
||||||
|
@ -13227,6 +13388,11 @@ packages:
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/progress/2.0.3:
|
||||||
|
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prompts/2.4.2:
|
/prompts/2.4.2:
|
||||||
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
@ -13529,6 +13695,10 @@ packages:
|
||||||
unified: 10.1.2
|
unified: 10.1.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/reinterval/1.1.0:
|
||||||
|
resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/remark-code-titles/0.1.2:
|
/remark-code-titles/0.1.2:
|
||||||
resolution: {integrity: sha512-KsHQbaI4FX8Ozxqk7YErxwmBiveUqloKuVqyPG2YPLHojpgomodWgRfG4B+bOtmn/5bfJ8khw4rR0lvgVFl2Uw==}
|
resolution: {integrity: sha512-KsHQbaI4FX8Ozxqk7YErxwmBiveUqloKuVqyPG2YPLHojpgomodWgRfG4B+bOtmn/5bfJ8khw4rR0lvgVFl2Uw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -13691,6 +13861,10 @@ packages:
|
||||||
unified: 10.1.2
|
unified: 10.1.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/retimer/3.0.0:
|
||||||
|
resolution: {integrity: sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/reusify/1.0.4:
|
/reusify/1.0.4:
|
||||||
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
||||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||||
|
@ -14334,6 +14508,12 @@ packages:
|
||||||
inline-style-parser: 0.1.1
|
inline-style-parser: 0.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/subarg/1.0.0:
|
||||||
|
resolution: {integrity: sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==}
|
||||||
|
dependencies:
|
||||||
|
minimist: 1.2.8
|
||||||
|
dev: false
|
||||||
|
|
||||||
/suf-log/2.5.3:
|
/suf-log/2.5.3:
|
||||||
resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
|
resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -14513,6 +14693,11 @@ packages:
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/timestring/6.0.0:
|
||||||
|
resolution: {integrity: sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tiny-glob/0.2.9:
|
/tiny-glob/0.2.9:
|
||||||
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
|
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -15087,6 +15272,15 @@ packages:
|
||||||
/util-deprecate/1.0.2:
|
/util-deprecate/1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
/uuid-parse/1.1.0:
|
||||||
|
resolution: {integrity: sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/uuid/8.3.2:
|
||||||
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/uvu/0.5.6:
|
/uvu/0.5.6:
|
||||||
resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==}
|
resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
|
@ -3,3 +3,4 @@ packages:
|
||||||
- 'examples/**/*'
|
- 'examples/**/*'
|
||||||
- 'smoke/**/*'
|
- 'smoke/**/*'
|
||||||
- 'scripts'
|
- 'scripts'
|
||||||
|
- 'benchmark'
|
||||||
|
|
Loading…
Reference in a new issue