From 0f69e2bd84f6d2d664c719989731dffbb5312184 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Thu, 16 Apr 2026 20:49:45 +0200 Subject: [PATCH 1/2] ci: add CodSpeed benchmarks for intent CLI --- .github/workflows/benchmarks.yml | 44 +++ benchmarks/intent/bench-utils.ts | 522 +++++++++++++++++++++++++++++++ benchmarks/intent/package.json | 21 ++ benchmarks/intent/speed.bench.ts | 35 +++ benchmarks/intent/tsconfig.json | 8 + benchmarks/intent/vite.config.ts | 18 ++ pnpm-lock.yaml | 519 +++++++++++++++++++++++++++++- pnpm-workspace.yaml | 1 + 8 files changed, 1161 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/benchmarks.yml create mode 100644 benchmarks/intent/bench-utils.ts create mode 100644 benchmarks/intent/package.json create mode 100644 benchmarks/intent/speed.bench.ts create mode 100644 benchmarks/intent/tsconfig.json create mode 100644 benchmarks/intent/vite.config.ts diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 00000000..33484859 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,44 @@ +name: Benchmarks + +on: + push: + branches: + - 'main' + paths: + - 'packages/**' + - 'benchmarks/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + pull_request: + paths: + - 'packages/**' + - 'benchmarks/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + workflow_dispatch: + +permissions: + contents: read + id-token: write + +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + NX_NO_CLOUD: true + +jobs: + benchmarks: + name: Run intent CodSpeed benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6.0.1 + + - name: Setup Tools + uses: tanstack/config/.github/setup@main + + - name: Run intent CodSpeed benchmark + continue-on-error: true + uses: CodSpeedHQ/action@v4 + with: + mode: simulation + run: WITH_INSTRUMENTATION=1 pnpm --dir benchmarks/intent test:perf diff --git a/benchmarks/intent/bench-utils.ts b/benchmarks/intent/bench-utils.ts new file mode 100644 index 00000000..0e904ccb --- /dev/null +++ b/benchmarks/intent/bench-utils.ts @@ -0,0 +1,522 @@ +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { main } from '../../packages/intent/src/cli.js' + +type SkillOptions = { + description: string + bodyLines?: number + type?: 'core' | 'framework' + requires?: Array + libraryVersion?: string + sources?: Array +} + +type PackageOptions = { + dependencies?: Record + peerDependencies?: Record + skills?: Array + requires?: Array + useDerivedIntent?: boolean + brokenIntent?: boolean +} + +type Fixtures = { + listRoot: string + listGlobalNodeModules: string + staleRoot: string + validateRoot: string +} + +type ConsoleSnapshot = { + error: typeof console.error + info: typeof console.info + log: typeof console.log + warn: typeof console.warn +} + +export type BenchmarkSuite = { + setup: () => void + teardown: () => void + runListLoop: () => Promise + runStaleLoop: () => Promise + runValidateLoop: () => Promise +} + +const noop = () => {} + +export function createBenchmarkSuite(): BenchmarkSuite { + let consoleSnapshot: ConsoleSnapshot | null = null + let fixtures: Fixtures | null = null + + function silenceConsole() { + if (consoleSnapshot) return + + consoleSnapshot = { + log: console.log, + info: console.info, + warn: console.warn, + error: console.error, + } + + console.log = noop as typeof console.log + console.info = noop as typeof console.info + console.warn = noop as typeof console.warn + console.error = noop as typeof console.error + } + + function restoreConsole() { + if (!consoleSnapshot) return + console.log = consoleSnapshot.log + console.info = consoleSnapshot.info + console.warn = consoleSnapshot.warn + console.error = consoleSnapshot.error + consoleSnapshot = null + } + + function getFixtures() { + if (fixtures) return fixtures + + silenceConsole() + fixtures = { + ...createListFixture(), + validateRoot: createValidateFixture(), + staleRoot: createStaleFixture(), + } + + return fixtures + } + + return { + setup() { + getFixtures() + }, + teardown() { + if (fixtures) { + rmSync(fixtures.listRoot, { recursive: true, force: true }) + rmSync(fixtures.listGlobalNodeModules, { recursive: true, force: true }) + rmSync(fixtures.validateRoot, { recursive: true, force: true }) + rmSync(fixtures.staleRoot, { recursive: true, force: true }) + fixtures = null + } + + restoreConsole() + }, + async runListLoop() { + const state = getFixtures() + + for (let index = 0; index < 3; index++) { + await runCli( + ['list', '--json'], + state.listRoot, + state.listGlobalNodeModules, + ) + } + }, + async runValidateLoop() { + const state = getFixtures() + + for (let index = 0; index < 3; index++) { + await runCli(['validate'], state.validateRoot) + } + }, + async runStaleLoop() { + const state = getFixtures() + + for (let index = 0; index < 3; index++) { + await runCli(['stale', '--json'], state.staleRoot) + } + }, + } +} + +async function runCli( + argv: Array, + cwd: string, + globalNodeModules?: string, +): Promise { + const previousCwd = process.cwd() + const previousGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES + + try { + process.chdir(cwd) + + if (globalNodeModules) { + process.env.INTENT_GLOBAL_NODE_MODULES = globalNodeModules + } else { + delete process.env.INTENT_GLOBAL_NODE_MODULES + } + + const exitCode = await main(argv) + if (exitCode !== 0) { + throw new Error( + `intent ${argv.join(' ')} failed with exit code ${exitCode}`, + ) + } + } finally { + process.chdir(previousCwd) + + if (previousGlobalNodeModules === undefined) { + delete process.env.INTENT_GLOBAL_NODE_MODULES + } else { + process.env.INTENT_GLOBAL_NODE_MODULES = previousGlobalNodeModules + } + } +} + +function createListFixture(): Pick< + Fixtures, + 'listGlobalNodeModules' | 'listRoot' +> { + const root = createTempDir('list') + const globalNodeModules = createTempDir('global-node-modules') + + writeJson(join(root, 'package.json'), { + name: 'intent-list-benchmark', + private: true, + workspaces: ['packages/*'], + dependencies: { + '@bench/root-direct': '1.0.0', + '@bench/wrapper-one': '1.0.0', + }, + devDependencies: { + '@bench/dev-helper': '1.0.0', + }, + }) + writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") + writeFile(join(root, 'pnpm-lock.yaml'), 'lockfileVersion: "9.0"\n') + + writeJson(join(root, 'packages', 'app', 'package.json'), { + name: '@consumer/app', + version: '1.0.0', + dependencies: { + '@bench/root-direct': '1.0.0', + '@bench/wrapper-one': '1.0.0', + }, + }) + + writeJson(join(root, 'packages', 'tool', 'package.json'), { + name: '@consumer/tool', + version: '1.0.0', + dependencies: { + '@bench/local-only': '1.0.0', + '@bench/wrapper-two': '1.0.0', + }, + }) + + writePackage(join(root, 'node_modules'), '@bench/shared-core', '1.4.0', { + skills: ['shared-core', 'shared-core/caching', 'shared-core/errors'], + }) + writePackage(join(root, 'node_modules'), '@bench/root-direct', '1.2.0', { + requires: ['@bench/shared-core'], + skills: ['root-direct', 'root-direct/cli', 'root-direct/config'], + }) + writePackage(join(root, 'node_modules'), '@bench/leaf-one', '1.1.0', { + requires: ['@bench/shared-core'], + skills: ['leaf-one', 'leaf-one/batching', 'leaf-one/runtime'], + }) + writePackage(join(root, 'node_modules'), '@bench/leaf-two', '1.0.0', { + skills: ['leaf-two', 'leaf-two/streaming', 'leaf-two/debugging'], + useDerivedIntent: true, + }) + writePackage(join(root, 'node_modules'), '@bench/local-only', '1.0.0', { + skills: ['local-only', 'local-only/testing'], + }) + writePackage(join(root, 'node_modules'), '@bench/broken-skill', '1.0.0', { + brokenIntent: true, + skills: ['broken-skill'], + }) + writePackage(join(root, 'node_modules'), '@bench/wrapper-one', '1.0.0', { + dependencies: { + '@bench/leaf-one': '1.1.0', + '@bench/shared-core': '1.4.0', + }, + }) + writePackage(join(root, 'node_modules'), '@bench/wrapper-two', '1.0.0', { + dependencies: { + '@bench/leaf-two': '1.0.0', + }, + }) + writePackage(join(root, 'node_modules'), '@bench/dev-helper', '1.0.0', { + dependencies: { + '@bench/local-only': '1.0.0', + '@bench/wrapper-two': '1.0.0', + }, + }) + + writePackage( + join(root, 'packages', 'tool', 'node_modules'), + '@bench/workspace-addon', + '1.0.0', + { + skills: ['workspace-addon', 'workspace-addon/runtime'], + }, + ) + + writePackage(globalNodeModules, '@bench/global-only', '2.0.0', { + skills: ['global-only', 'global-only/setup', 'global-only/migrations'], + }) + writePackage(globalNodeModules, '@bench/shared-core', '9.9.0', { + skills: ['shared-core', 'shared-core/caching'], + }) + + return { + listRoot: root, + listGlobalNodeModules: globalNodeModules, + } +} + +function createValidateFixture(): string { + const root = createTempDir('validate') + + writeJson(join(root, 'package.json'), { + name: '@bench/validate-package', + version: '1.0.0', + keywords: ['tanstack-intent'], + files: ['dist', 'skills', '!skills/_artifacts'], + devDependencies: { + '@tanstack/intent': 'workspace:*', + }, + }) + + const domains = [ + 'foundations', + 'routing', + 'data', + 'testing', + 'tooling', + 'releases', + ] + + for (const domain of domains) { + writeSkill(root, domain, { + description: `${domain} overview and guardrails`, + bodyLines: 20, + type: 'core', + }) + + for (let index = 1; index <= 4; index++) { + const skillName = `${domain}/workflow-${index}` + const isFrameworkSkill = index % 2 === 0 + + writeSkill(root, skillName, { + description: `${domain} workflow ${index}`, + bodyLines: 18, + type: isFrameworkSkill ? 'framework' : 'core', + requires: isFrameworkSkill ? [domain] : undefined, + }) + } + } + + writeFile( + join(root, 'skills', '_artifacts', 'domain_map.yaml'), + [ + 'domains:', + ...domains.map((domain) => ` - ${JSON.stringify(domain)}`), + '', + ].join('\n'), + ) + writeFile( + join(root, 'skills', '_artifacts', 'skill_spec.md'), + '# Skill specification\n\nGenerated for the benchmark fixture.\n', + ) + writeFile( + join(root, 'skills', '_artifacts', 'skill_tree.yaml'), + [ + 'skills:', + ...domains.flatMap((domain) => [ + ` - ${JSON.stringify(domain)}`, + ` - ${JSON.stringify(`${domain}/workflow-1`)}`, + ` - ${JSON.stringify(`${domain}/workflow-2`)}`, + ` - ${JSON.stringify(`${domain}/workflow-3`)}`, + ` - ${JSON.stringify(`${domain}/workflow-4`)}`, + ]), + '', + ].join('\n'), + ) + + return root +} + +function createStaleFixture(): string { + const root = createTempDir('stale') + + writeJson(join(root, 'package.json'), { + name: 'intent-stale-benchmark', + private: true, + workspaces: ['packages/*'], + }) + writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") + + writeStalePackage(root, { + name: '@bench/alpha', + packageDir: 'alpha', + packageVersion: '3.2.0', + skillVersion: '3.1.0', + skills: ['alpha/core', 'alpha/cache', 'alpha/streaming', 'alpha/runtime'], + }) + writeStalePackage(root, { + name: '@bench/beta', + packageDir: 'beta', + packageVersion: '2.4.2', + skillVersion: '2.4.0', + skills: ['beta/core', 'beta/forms', 'beta/mutations', 'beta/testing'], + }) + writeStalePackage(root, { + name: '@bench/gamma', + packageDir: 'gamma', + packageVersion: '1.5.0', + skillVersion: '1.5.0', + skills: ['gamma/core', 'gamma/queries', 'gamma/cache', 'gamma/offline'], + }) + writeStalePackage(root, { + name: '@bench/delta', + packageDir: 'delta', + packageVersion: '5.0.1', + skillVersion: '5.0.0', + skills: ['delta/core', 'delta/commands', 'delta/migrations', 'delta/docs'], + }) + + return root +} + +function writeStalePackage( + root: string, + opts: { + name: string + packageDir: string + packageVersion: string + skillVersion: string + skills: Array + }, +) { + const packageRoot = join(root, 'packages', opts.packageDir) + + writeJson(join(packageRoot, 'package.json'), { + name: opts.name, + version: opts.packageVersion, + }) + + const syncState: { + library_version: string + skills: Record }> + } = { + library_version: opts.skillVersion, + skills: {}, + } + + for (const skill of opts.skills) { + const sources = [ + `docs/${skill.replace(/\//g, '-')}.md`, + 'docs/shared-guide.md', + ] + + writeSkill(packageRoot, skill, { + description: `${skill} maintenance guide`, + bodyLines: 16, + libraryVersion: opts.skillVersion, + sources, + }) + + syncState.skills[skill] = { + sources_sha: { + [sources[0]!]: 'sha-1', + }, + } + } + + writeJson(join(packageRoot, 'skills', 'sync-state.json'), syncState) +} + +function writePackage( + nodeModulesDir: string, + name: string, + version: string, + opts: PackageOptions, +) { + const packageRoot = join(nodeModulesDir, ...name.split('/')) + const packageJson: Record = { + name, + version, + dependencies: opts.dependencies, + peerDependencies: opts.peerDependencies, + } + + if (opts.skills?.length) { + if (opts.brokenIntent) { + packageJson.description = `Broken skill fixture for ${name}` + } else if (opts.useDerivedIntent) { + packageJson.repository = `https://github.com/example/${name.replace('@', '').replace('/', '-')}` + packageJson.homepage = `https://example.com/${name.replace('@', '').replace('/', '-')}` + } else { + packageJson.intent = { + version: 1, + repo: `example/${name.replace('@', '').replace('/', '-')}`, + docs: 'docs/', + requires: opts.requires, + } + } + } + + writeJson(join(packageRoot, 'package.json'), packageJson) + + for (const skill of opts.skills ?? []) { + writeSkill(packageRoot, skill, { + description: `${skill} benchmark guidance`, + bodyLines: 14, + type: skill.includes('/') ? 'framework' : 'core', + requires: skill.includes('/') ? [skill.split('/')[0]!] : undefined, + }) + } +} + +function writeSkill(root: string, skillName: string, opts: SkillOptions) { + const frontmatter = [ + `name: ${JSON.stringify(skillName)}`, + `description: ${JSON.stringify(opts.description)}`, + ] + + if (opts.type) { + frontmatter.push(`type: ${JSON.stringify(opts.type)}`) + } + + if (opts.requires) { + frontmatter.push('requires:') + for (const requirement of opts.requires) { + frontmatter.push(` - ${JSON.stringify(requirement)}`) + } + } + + if (opts.libraryVersion) { + frontmatter.push(`library_version: ${JSON.stringify(opts.libraryVersion)}`) + } + + if (opts.sources) { + frontmatter.push('sources:') + for (const source of opts.sources) { + frontmatter.push(` - ${JSON.stringify(source)}`) + } + } + + const bodyLines = Array.from({ length: opts.bodyLines ?? 12 }, (_, index) => { + return `${index + 1}. Keep ${skillName} aligned with the documented workflow.` + }) + + writeFile( + join(root, 'skills', ...skillName.split('/'), 'SKILL.md'), + `---\n${frontmatter.join('\n')}\n---\n\n${bodyLines.join('\n')}\n`, + ) +} + +function createTempDir(name: string): string { + return mkdtempSync(join(tmpdir(), `intent-bench-${name}-`)) +} + +function writeFile(filePath: string, content: string) { + mkdirSync(dirname(filePath), { recursive: true }) + writeFileSync(filePath, content) +} + +function writeJson(filePath: string, value: unknown) { + writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`) +} diff --git a/benchmarks/intent/package.json b/benchmarks/intent/package.json new file mode 100644 index 00000000..082be808 --- /dev/null +++ b/benchmarks/intent/package.json @@ -0,0 +1,21 @@ +{ + "name": "@benchmarks/intent", + "private": true, + "type": "module", + "scripts": { + "test:perf": "vitest bench --config ./vite.config.ts ./speed.bench.ts" + }, + "devDependencies": { + "@codspeed/vitest-plugin": "^5.0.1", + "typescript": "^5.9.3", + "vite": "^8.0.0", + "vitest": "^4.0.17" + }, + "nx": { + "targets": { + "test:perf": { + "cache": false + } + } + } +} diff --git a/benchmarks/intent/speed.bench.ts b/benchmarks/intent/speed.bench.ts new file mode 100644 index 00000000..16948f17 --- /dev/null +++ b/benchmarks/intent/speed.bench.ts @@ -0,0 +1,35 @@ +import { afterAll, beforeAll, bench, describe } from 'vitest' +import { createBenchmarkSuite } from './bench-utils.js' + +const suite = createBenchmarkSuite() + +describe('intent-cli', () => { + /** + * Running `vitest bench` ignores suite hooks, so we mirror setup and teardown + * through tinybench. CodSpeed does the inverse and relies on `beforeAll` and + * `afterAll`, so both are required. + */ + beforeAll(suite.setup) + afterAll(suite.teardown) + + bench('intent list scans a consumer workspace', suite.runListLoop, { + warmupIterations: 100, + time: 10_000, + setup: suite.setup, + teardown: suite.teardown, + }) + + bench('intent validate checks a shipped skills tree', suite.runValidateLoop, { + warmupIterations: 100, + time: 10_000, + setup: suite.setup, + teardown: suite.teardown, + }) + + bench('intent stale reports workspace drift', suite.runStaleLoop, { + warmupIterations: 100, + time: 10_000, + setup: suite.setup, + teardown: suite.teardown, + }) +}) diff --git a/benchmarks/intent/tsconfig.json b/benchmarks/intent/tsconfig.json new file mode 100644 index 00000000..fa8caa6e --- /dev/null +++ b/benchmarks/intent/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "noEmit": true + }, + "include": ["*.ts"] +} diff --git a/benchmarks/intent/vite.config.ts b/benchmarks/intent/vite.config.ts new file mode 100644 index 00000000..b4f8e806 --- /dev/null +++ b/benchmarks/intent/vite.config.ts @@ -0,0 +1,18 @@ +import { fileURLToPath } from 'node:url' +import codspeedPlugin from '@codspeed/vitest-plugin' +import { defineConfig } from 'vitest/config' + +const rootDir = fileURLToPath(new URL('.', import.meta.url)) + +export default defineConfig({ + root: rootDir, + plugins: [ + !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) && + codspeedPlugin(), + ], + test: { + name: '@benchmarks/intent', + watch: false, + environment: 'node', + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1849c7b8..73e39706 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,11 +62,26 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.17 - version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2) + version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) yaml: specifier: ^2.7.0 version: 2.8.2 + benchmarks/intent: + devDependencies: + '@codspeed/vitest-plugin': + specifier: ^5.0.1 + version: 5.2.0(tinybench@2.9.0)(vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: ^8.0.0 + version: 8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2) + vitest: + specifier: ^4.0.17 + version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) + packages/intent: dependencies: cac: @@ -171,6 +186,16 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@codspeed/core@5.2.0': + resolution: {integrity: sha512-CmDhpWjcOJg2iBOQ/BmBnSBq8qxlM3r4h8uvYDkoUaba+EKRT3T73BZtKuml/48jZMsB+4/FG2UbTBinDWtuvw==} + + '@codspeed/vitest-plugin@5.2.0': + resolution: {integrity: sha512-soXKIQBqJzjVQyWRwe2HNfhCaBgxhG25m8+PI3F5zFFsV3FQxMJXHsMECNtrgm+SRiCiWv/OFTcfCMZRy4nKtw==} + peerDependencies: + tinybench: '>=2.9.0' + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vitest: ^3.2 || ^4 + '@cypress/request@3.0.10': resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==} engines: {node: '>= 6'} @@ -178,12 +203,21 @@ packages: '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/runtime@1.8.1': resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -482,6 +516,12 @@ packages: '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -550,6 +590,9 @@ packages: '@oxc-project/types@0.112.0': resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} + '@oxc-project/types@0.124.0': + resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@oxc-resolver/binding-android-arm-eabi@11.16.3': resolution: {integrity: sha512-CVyWHu6ACDqDcJxR4nmGiG8vDF4TISJHqRNzac5z/gPQycs/QrP/1pDsJBy0MD7jSw8nVq2E5WqeHQKabBG/Jg==} cpu: [arm] @@ -662,6 +705,12 @@ packages: cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-android-arm64@1.0.0-rc.3': resolution: {integrity: sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -674,6 +723,12 @@ packages: cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.0-rc.3': resolution: {integrity: sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -686,6 +741,12 @@ packages: cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.15': + resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.3': resolution: {integrity: sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -698,6 +759,12 @@ packages: cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.0-rc.3': resolution: {integrity: sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==} engines: {node: ^20.19.0 || >=22.12.0} @@ -710,6 +777,12 @@ packages: cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': resolution: {integrity: sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==} engines: {node: ^20.19.0 || >=22.12.0} @@ -722,6 +795,12 @@ packages: cpu: [arm64] os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': resolution: {integrity: sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -734,18 +813,42 @@ packages: cpu: [arm64] os: [linux] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': resolution: {integrity: sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': resolution: {integrity: sha512-VlfwJ/HCskPmQi8R0JuAFndySKVFX7yPhE658o27cjSDWWbXVtGkSbwaxstii7Q+3Rz87ZXN+HLnb1kd4R9Img==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': resolution: {integrity: sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -758,6 +861,12 @@ packages: cpu: [x64] os: [linux] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': resolution: {integrity: sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -770,6 +879,12 @@ packages: cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': resolution: {integrity: sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -781,6 +896,11 @@ packages: engines: {node: '>=14.0.0'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': resolution: {integrity: sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==} engines: {node: '>=14.0.0'} @@ -792,6 +912,12 @@ packages: cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': resolution: {integrity: sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -804,6 +930,12 @@ packages: cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': resolution: {integrity: sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -813,6 +945,9 @@ packages: '@rolldown/pluginutils@1.0.0-beta.59': resolution: {integrity: sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==} + '@rolldown/pluginutils@1.0.0-rc.15': + resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} + '@rolldown/pluginutils@1.0.0-rc.3': resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} @@ -1895,6 +2030,10 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + devalue@5.6.2: resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} @@ -2281,6 +2420,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -2708,6 +2851,76 @@ packages: light-my-request@5.14.0: resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + lines-and-columns@2.0.3: resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2726,6 +2939,10 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lockfile@1.0.4: resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} @@ -2963,6 +3180,10 @@ packages: encoding: optional: true + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} @@ -3057,6 +3278,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -3065,6 +3290,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -3100,6 +3329,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -3134,6 +3367,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -3169,6 +3406,10 @@ packages: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -3373,6 +3614,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.0.0-rc.15: + resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rolldown@1.0.0-rc.3: resolution: {integrity: sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3947,6 +4193,49 @@ packages: yaml: optional: true + vite@8.0.8: + resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitest@4.0.17: resolution: {integrity: sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -4077,6 +4366,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + yup@0.32.11: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} @@ -4263,6 +4556,24 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 + '@codspeed/core@5.2.0': + dependencies: + axios: 1.13.2 + find-up: 6.3.0 + form-data: 4.0.5 + node-gyp-build: 4.8.4 + transitivePeerDependencies: + - debug + + '@codspeed/vitest-plugin@5.2.0(tinybench@2.9.0)(vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))': + dependencies: + '@codspeed/core': 5.2.0 + tinybench: 2.9.0 + vite: 8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2) + vitest: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) + transitivePeerDependencies: + - debug + '@cypress/request@3.0.10': dependencies: aws-sign2: 0.7.0 @@ -4289,14 +4600,30 @@ snapshots: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.27.2': optional: true @@ -4538,6 +4865,13 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4584,6 +4918,8 @@ snapshots: '@oxc-project/types@0.112.0': {} + '@oxc-project/types@0.124.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.16.3': optional: true @@ -4655,60 +4991,96 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-beta.59': optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.15': + optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.3': optional: true '@rolldown/binding-darwin-arm64@1.0.0-beta.59': optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.3': optional: true '@rolldown/binding-darwin-x64@1.0.0-beta.59': optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.15': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.3': optional: true '@rolldown/binding-freebsd-x64@1.0.0-beta.59': optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': optional: true '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': optional: true @@ -4717,6 +5089,13 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.1 optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': dependencies: '@napi-rs/wasm-runtime': 1.1.1 @@ -4725,17 +5104,25 @@ snapshots: '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': optional: true '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': optional: true '@rolldown/pluginutils@1.0.0-beta.59': {} + '@rolldown/pluginutils@1.0.0-rc.15': {} + '@rolldown/pluginutils@1.0.0-rc.3': {} '@rollup/rollup-android-arm-eabi@4.55.1': @@ -5526,13 +5913,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2))': + '@vitest/mocker@4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.17 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.17': dependencies: @@ -6050,6 +6437,8 @@ snapshots: detect-indent@6.1.0: {} + detect-libc@2.1.2: {} + devalue@5.6.2: {} dir-glob@3.0.1: @@ -6565,6 +6954,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat-cache@4.0.1: dependencies: flatted: 3.3.3 @@ -7016,6 +7410,55 @@ snapshots: process-warning: 3.0.0 set-cookie-parser: 2.7.2 + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + lines-and-columns@2.0.3: {} linkify-it@5.0.0: @@ -7032,6 +7475,10 @@ snapshots: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lockfile@1.0.4: dependencies: signal-exit: 3.0.7 @@ -7206,6 +7653,8 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-gyp-build@4.8.4: {} + node-machine-id@1.1.12: {} normalize-url@6.1.0: {} @@ -7358,6 +7807,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -7366,6 +7819,10 @@ snapshots: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-map@2.1.0: {} p-try@2.2.0: {} @@ -7397,6 +7854,8 @@ snapshots: path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-key@3.1.1: {} path-to-regexp@0.1.12: {} @@ -7421,6 +7880,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.4: {} + pify@3.0.0: {} pify@4.0.1: {} @@ -7485,6 +7946,12 @@ snapshots: sonic-boom: 4.2.1 thread-stream: 3.1.0 + postcss@8.5.10: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -7689,6 +8156,27 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.59 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.59 + rolldown@1.0.0-rc.15: + dependencies: + '@oxc-project/types': 0.124.0 + '@rolldown/pluginutils': 1.0.0-rc.15 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-x64': 1.0.0-rc.15 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + rolldown@1.0.0-rc.3: dependencies: '@oxc-project/types': 0.112.0 @@ -8353,7 +8841,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2): + vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) @@ -8365,12 +8853,27 @@ snapshots: '@types/node': 25.0.9 fsevents: 2.3.3 jiti: 2.6.1 + lightningcss: 1.32.0 + yaml: 2.8.2 + + vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.10 + rolldown: 1.0.0-rc.15 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.0.9 + esbuild: 0.27.2 + fsevents: 2.3.3 + jiti: 2.6.1 yaml: 2.8.2 - vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2): + vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.17 - '@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2)) + '@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.17 '@vitest/runner': 4.0.17 '@vitest/snapshot': 4.0.17 @@ -8387,7 +8890,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.0.9 @@ -8483,6 +8986,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yup@0.32.11: dependencies: '@babel/runtime': 7.28.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5add109e..a12bf303 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,5 +3,6 @@ linkWorkspacePackages: true preferWorkspacePackages: true packages: + - 'benchmarks/*' - 'examples/**/*' - 'packages/*' From a3f2bfaeffd471e30dba3e062d7b48e7659ea676 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Thu, 16 Apr 2026 21:58:17 +0200 Subject: [PATCH 2/2] setup complete --- .github/workflows/benchmarks.yml | 2 +- benchmarks/intent/bench-utils.ts | 522 ------------------ benchmarks/intent/helpers.ts | 252 +++++++++ benchmarks/intent/list.bench.ts | 161 ++++++ benchmarks/intent/package.json | 15 +- benchmarks/intent/speed.bench.ts | 35 -- benchmarks/intent/stale.bench.ts | 152 +++++ benchmarks/intent/validate.bench.ts | 133 +++++ .../{vite.config.ts => vitest.config.ts} | 4 - pnpm-lock.yaml | 306 +--------- pnpm-workspace.yaml | 7 +- 11 files changed, 729 insertions(+), 860 deletions(-) delete mode 100644 benchmarks/intent/bench-utils.ts create mode 100644 benchmarks/intent/helpers.ts create mode 100644 benchmarks/intent/list.bench.ts delete mode 100644 benchmarks/intent/speed.bench.ts create mode 100644 benchmarks/intent/stale.bench.ts create mode 100644 benchmarks/intent/validate.bench.ts rename benchmarks/intent/{vite.config.ts => vitest.config.ts} (73%) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 33484859..a1a9b428 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -41,4 +41,4 @@ jobs: uses: CodSpeedHQ/action@v4 with: mode: simulation - run: WITH_INSTRUMENTATION=1 pnpm --dir benchmarks/intent test:perf + run: WITH_INSTRUMENTATION=1 pnpm exec nx run @benchmarks/intent:test:perf diff --git a/benchmarks/intent/bench-utils.ts b/benchmarks/intent/bench-utils.ts deleted file mode 100644 index 0e904ccb..00000000 --- a/benchmarks/intent/bench-utils.ts +++ /dev/null @@ -1,522 +0,0 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { dirname, join } from 'node:path' -import { main } from '../../packages/intent/src/cli.js' - -type SkillOptions = { - description: string - bodyLines?: number - type?: 'core' | 'framework' - requires?: Array - libraryVersion?: string - sources?: Array -} - -type PackageOptions = { - dependencies?: Record - peerDependencies?: Record - skills?: Array - requires?: Array - useDerivedIntent?: boolean - brokenIntent?: boolean -} - -type Fixtures = { - listRoot: string - listGlobalNodeModules: string - staleRoot: string - validateRoot: string -} - -type ConsoleSnapshot = { - error: typeof console.error - info: typeof console.info - log: typeof console.log - warn: typeof console.warn -} - -export type BenchmarkSuite = { - setup: () => void - teardown: () => void - runListLoop: () => Promise - runStaleLoop: () => Promise - runValidateLoop: () => Promise -} - -const noop = () => {} - -export function createBenchmarkSuite(): BenchmarkSuite { - let consoleSnapshot: ConsoleSnapshot | null = null - let fixtures: Fixtures | null = null - - function silenceConsole() { - if (consoleSnapshot) return - - consoleSnapshot = { - log: console.log, - info: console.info, - warn: console.warn, - error: console.error, - } - - console.log = noop as typeof console.log - console.info = noop as typeof console.info - console.warn = noop as typeof console.warn - console.error = noop as typeof console.error - } - - function restoreConsole() { - if (!consoleSnapshot) return - console.log = consoleSnapshot.log - console.info = consoleSnapshot.info - console.warn = consoleSnapshot.warn - console.error = consoleSnapshot.error - consoleSnapshot = null - } - - function getFixtures() { - if (fixtures) return fixtures - - silenceConsole() - fixtures = { - ...createListFixture(), - validateRoot: createValidateFixture(), - staleRoot: createStaleFixture(), - } - - return fixtures - } - - return { - setup() { - getFixtures() - }, - teardown() { - if (fixtures) { - rmSync(fixtures.listRoot, { recursive: true, force: true }) - rmSync(fixtures.listGlobalNodeModules, { recursive: true, force: true }) - rmSync(fixtures.validateRoot, { recursive: true, force: true }) - rmSync(fixtures.staleRoot, { recursive: true, force: true }) - fixtures = null - } - - restoreConsole() - }, - async runListLoop() { - const state = getFixtures() - - for (let index = 0; index < 3; index++) { - await runCli( - ['list', '--json'], - state.listRoot, - state.listGlobalNodeModules, - ) - } - }, - async runValidateLoop() { - const state = getFixtures() - - for (let index = 0; index < 3; index++) { - await runCli(['validate'], state.validateRoot) - } - }, - async runStaleLoop() { - const state = getFixtures() - - for (let index = 0; index < 3; index++) { - await runCli(['stale', '--json'], state.staleRoot) - } - }, - } -} - -async function runCli( - argv: Array, - cwd: string, - globalNodeModules?: string, -): Promise { - const previousCwd = process.cwd() - const previousGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES - - try { - process.chdir(cwd) - - if (globalNodeModules) { - process.env.INTENT_GLOBAL_NODE_MODULES = globalNodeModules - } else { - delete process.env.INTENT_GLOBAL_NODE_MODULES - } - - const exitCode = await main(argv) - if (exitCode !== 0) { - throw new Error( - `intent ${argv.join(' ')} failed with exit code ${exitCode}`, - ) - } - } finally { - process.chdir(previousCwd) - - if (previousGlobalNodeModules === undefined) { - delete process.env.INTENT_GLOBAL_NODE_MODULES - } else { - process.env.INTENT_GLOBAL_NODE_MODULES = previousGlobalNodeModules - } - } -} - -function createListFixture(): Pick< - Fixtures, - 'listGlobalNodeModules' | 'listRoot' -> { - const root = createTempDir('list') - const globalNodeModules = createTempDir('global-node-modules') - - writeJson(join(root, 'package.json'), { - name: 'intent-list-benchmark', - private: true, - workspaces: ['packages/*'], - dependencies: { - '@bench/root-direct': '1.0.0', - '@bench/wrapper-one': '1.0.0', - }, - devDependencies: { - '@bench/dev-helper': '1.0.0', - }, - }) - writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") - writeFile(join(root, 'pnpm-lock.yaml'), 'lockfileVersion: "9.0"\n') - - writeJson(join(root, 'packages', 'app', 'package.json'), { - name: '@consumer/app', - version: '1.0.0', - dependencies: { - '@bench/root-direct': '1.0.0', - '@bench/wrapper-one': '1.0.0', - }, - }) - - writeJson(join(root, 'packages', 'tool', 'package.json'), { - name: '@consumer/tool', - version: '1.0.0', - dependencies: { - '@bench/local-only': '1.0.0', - '@bench/wrapper-two': '1.0.0', - }, - }) - - writePackage(join(root, 'node_modules'), '@bench/shared-core', '1.4.0', { - skills: ['shared-core', 'shared-core/caching', 'shared-core/errors'], - }) - writePackage(join(root, 'node_modules'), '@bench/root-direct', '1.2.0', { - requires: ['@bench/shared-core'], - skills: ['root-direct', 'root-direct/cli', 'root-direct/config'], - }) - writePackage(join(root, 'node_modules'), '@bench/leaf-one', '1.1.0', { - requires: ['@bench/shared-core'], - skills: ['leaf-one', 'leaf-one/batching', 'leaf-one/runtime'], - }) - writePackage(join(root, 'node_modules'), '@bench/leaf-two', '1.0.0', { - skills: ['leaf-two', 'leaf-two/streaming', 'leaf-two/debugging'], - useDerivedIntent: true, - }) - writePackage(join(root, 'node_modules'), '@bench/local-only', '1.0.0', { - skills: ['local-only', 'local-only/testing'], - }) - writePackage(join(root, 'node_modules'), '@bench/broken-skill', '1.0.0', { - brokenIntent: true, - skills: ['broken-skill'], - }) - writePackage(join(root, 'node_modules'), '@bench/wrapper-one', '1.0.0', { - dependencies: { - '@bench/leaf-one': '1.1.0', - '@bench/shared-core': '1.4.0', - }, - }) - writePackage(join(root, 'node_modules'), '@bench/wrapper-two', '1.0.0', { - dependencies: { - '@bench/leaf-two': '1.0.0', - }, - }) - writePackage(join(root, 'node_modules'), '@bench/dev-helper', '1.0.0', { - dependencies: { - '@bench/local-only': '1.0.0', - '@bench/wrapper-two': '1.0.0', - }, - }) - - writePackage( - join(root, 'packages', 'tool', 'node_modules'), - '@bench/workspace-addon', - '1.0.0', - { - skills: ['workspace-addon', 'workspace-addon/runtime'], - }, - ) - - writePackage(globalNodeModules, '@bench/global-only', '2.0.0', { - skills: ['global-only', 'global-only/setup', 'global-only/migrations'], - }) - writePackage(globalNodeModules, '@bench/shared-core', '9.9.0', { - skills: ['shared-core', 'shared-core/caching'], - }) - - return { - listRoot: root, - listGlobalNodeModules: globalNodeModules, - } -} - -function createValidateFixture(): string { - const root = createTempDir('validate') - - writeJson(join(root, 'package.json'), { - name: '@bench/validate-package', - version: '1.0.0', - keywords: ['tanstack-intent'], - files: ['dist', 'skills', '!skills/_artifacts'], - devDependencies: { - '@tanstack/intent': 'workspace:*', - }, - }) - - const domains = [ - 'foundations', - 'routing', - 'data', - 'testing', - 'tooling', - 'releases', - ] - - for (const domain of domains) { - writeSkill(root, domain, { - description: `${domain} overview and guardrails`, - bodyLines: 20, - type: 'core', - }) - - for (let index = 1; index <= 4; index++) { - const skillName = `${domain}/workflow-${index}` - const isFrameworkSkill = index % 2 === 0 - - writeSkill(root, skillName, { - description: `${domain} workflow ${index}`, - bodyLines: 18, - type: isFrameworkSkill ? 'framework' : 'core', - requires: isFrameworkSkill ? [domain] : undefined, - }) - } - } - - writeFile( - join(root, 'skills', '_artifacts', 'domain_map.yaml'), - [ - 'domains:', - ...domains.map((domain) => ` - ${JSON.stringify(domain)}`), - '', - ].join('\n'), - ) - writeFile( - join(root, 'skills', '_artifacts', 'skill_spec.md'), - '# Skill specification\n\nGenerated for the benchmark fixture.\n', - ) - writeFile( - join(root, 'skills', '_artifacts', 'skill_tree.yaml'), - [ - 'skills:', - ...domains.flatMap((domain) => [ - ` - ${JSON.stringify(domain)}`, - ` - ${JSON.stringify(`${domain}/workflow-1`)}`, - ` - ${JSON.stringify(`${domain}/workflow-2`)}`, - ` - ${JSON.stringify(`${domain}/workflow-3`)}`, - ` - ${JSON.stringify(`${domain}/workflow-4`)}`, - ]), - '', - ].join('\n'), - ) - - return root -} - -function createStaleFixture(): string { - const root = createTempDir('stale') - - writeJson(join(root, 'package.json'), { - name: 'intent-stale-benchmark', - private: true, - workspaces: ['packages/*'], - }) - writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") - - writeStalePackage(root, { - name: '@bench/alpha', - packageDir: 'alpha', - packageVersion: '3.2.0', - skillVersion: '3.1.0', - skills: ['alpha/core', 'alpha/cache', 'alpha/streaming', 'alpha/runtime'], - }) - writeStalePackage(root, { - name: '@bench/beta', - packageDir: 'beta', - packageVersion: '2.4.2', - skillVersion: '2.4.0', - skills: ['beta/core', 'beta/forms', 'beta/mutations', 'beta/testing'], - }) - writeStalePackage(root, { - name: '@bench/gamma', - packageDir: 'gamma', - packageVersion: '1.5.0', - skillVersion: '1.5.0', - skills: ['gamma/core', 'gamma/queries', 'gamma/cache', 'gamma/offline'], - }) - writeStalePackage(root, { - name: '@bench/delta', - packageDir: 'delta', - packageVersion: '5.0.1', - skillVersion: '5.0.0', - skills: ['delta/core', 'delta/commands', 'delta/migrations', 'delta/docs'], - }) - - return root -} - -function writeStalePackage( - root: string, - opts: { - name: string - packageDir: string - packageVersion: string - skillVersion: string - skills: Array - }, -) { - const packageRoot = join(root, 'packages', opts.packageDir) - - writeJson(join(packageRoot, 'package.json'), { - name: opts.name, - version: opts.packageVersion, - }) - - const syncState: { - library_version: string - skills: Record }> - } = { - library_version: opts.skillVersion, - skills: {}, - } - - for (const skill of opts.skills) { - const sources = [ - `docs/${skill.replace(/\//g, '-')}.md`, - 'docs/shared-guide.md', - ] - - writeSkill(packageRoot, skill, { - description: `${skill} maintenance guide`, - bodyLines: 16, - libraryVersion: opts.skillVersion, - sources, - }) - - syncState.skills[skill] = { - sources_sha: { - [sources[0]!]: 'sha-1', - }, - } - } - - writeJson(join(packageRoot, 'skills', 'sync-state.json'), syncState) -} - -function writePackage( - nodeModulesDir: string, - name: string, - version: string, - opts: PackageOptions, -) { - const packageRoot = join(nodeModulesDir, ...name.split('/')) - const packageJson: Record = { - name, - version, - dependencies: opts.dependencies, - peerDependencies: opts.peerDependencies, - } - - if (opts.skills?.length) { - if (opts.brokenIntent) { - packageJson.description = `Broken skill fixture for ${name}` - } else if (opts.useDerivedIntent) { - packageJson.repository = `https://github.com/example/${name.replace('@', '').replace('/', '-')}` - packageJson.homepage = `https://example.com/${name.replace('@', '').replace('/', '-')}` - } else { - packageJson.intent = { - version: 1, - repo: `example/${name.replace('@', '').replace('/', '-')}`, - docs: 'docs/', - requires: opts.requires, - } - } - } - - writeJson(join(packageRoot, 'package.json'), packageJson) - - for (const skill of opts.skills ?? []) { - writeSkill(packageRoot, skill, { - description: `${skill} benchmark guidance`, - bodyLines: 14, - type: skill.includes('/') ? 'framework' : 'core', - requires: skill.includes('/') ? [skill.split('/')[0]!] : undefined, - }) - } -} - -function writeSkill(root: string, skillName: string, opts: SkillOptions) { - const frontmatter = [ - `name: ${JSON.stringify(skillName)}`, - `description: ${JSON.stringify(opts.description)}`, - ] - - if (opts.type) { - frontmatter.push(`type: ${JSON.stringify(opts.type)}`) - } - - if (opts.requires) { - frontmatter.push('requires:') - for (const requirement of opts.requires) { - frontmatter.push(` - ${JSON.stringify(requirement)}`) - } - } - - if (opts.libraryVersion) { - frontmatter.push(`library_version: ${JSON.stringify(opts.libraryVersion)}`) - } - - if (opts.sources) { - frontmatter.push('sources:') - for (const source of opts.sources) { - frontmatter.push(` - ${JSON.stringify(source)}`) - } - } - - const bodyLines = Array.from({ length: opts.bodyLines ?? 12 }, (_, index) => { - return `${index + 1}. Keep ${skillName} aligned with the documented workflow.` - }) - - writeFile( - join(root, 'skills', ...skillName.split('/'), 'SKILL.md'), - `---\n${frontmatter.join('\n')}\n---\n\n${bodyLines.join('\n')}\n`, - ) -} - -function createTempDir(name: string): string { - return mkdtempSync(join(tmpdir(), `intent-bench-${name}-`)) -} - -function writeFile(filePath: string, content: string) { - mkdirSync(dirname(filePath), { recursive: true }) - writeFileSync(filePath, content) -} - -function writeJson(filePath: string, value: unknown) { - writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`) -} diff --git a/benchmarks/intent/helpers.ts b/benchmarks/intent/helpers.ts new file mode 100644 index 00000000..011fd52b --- /dev/null +++ b/benchmarks/intent/helpers.ts @@ -0,0 +1,252 @@ +import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' + +let builtCliMainPromise: Promise< + (argv?: Array) => Promise +> | null = null + +type CliRunnerOptions = { + cwd: string + globalNodeModules?: string +} + +type ConsoleSnapshot = { + error: typeof console.error + info: typeof console.info + log: typeof console.log + warn: typeof console.warn +} + +export type SkillOptions = { + description: string + bodyLines?: number + type?: 'core' | 'framework' + requires?: Array + libraryVersion?: string + sources?: Array +} + +export type PackageOptions = { + dependencies?: Record + peerDependencies?: Record + skills?: Array + requires?: Array + useDerivedIntent?: boolean + brokenIntent?: boolean +} + +const noop = () => undefined + +export function createBenchOptions( + setup: () => void | Promise, + teardown: () => void | Promise, +) { + return { + warmupIterations: 100, + time: 10_000, + setup, + teardown, + } +} + +export function createConsoleSilencer() { + let snapshot: ConsoleSnapshot | null = null + + return { + silence() { + if (snapshot) return + + snapshot = { + log: console.log, + info: console.info, + warn: console.warn, + error: console.error, + } + + console.log = noop as typeof console.log + console.info = noop as typeof console.info + console.warn = noop as typeof console.warn + console.error = noop as typeof console.error + }, + restore() { + if (!snapshot) return + + console.log = snapshot.log + console.info = snapshot.info + console.warn = snapshot.warn + console.error = snapshot.error + snapshot = null + }, + } +} + +export function createCliRunner(options: CliRunnerOptions) { + let main: ((argv?: Array) => Promise) | null = null + let previousCwd = '' + let previousGlobalNodeModules: string | undefined + + return { + async setup() { + if (main) return + + previousCwd = process.cwd() + previousGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES + + process.chdir(options.cwd) + if (options.globalNodeModules) { + process.env.INTENT_GLOBAL_NODE_MODULES = options.globalNodeModules + } else { + delete process.env.INTENT_GLOBAL_NODE_MODULES + } + + main = await loadBuiltCliMain() + }, + teardown() { + if (!main) return + + process.chdir(previousCwd) + if (previousGlobalNodeModules === undefined) { + delete process.env.INTENT_GLOBAL_NODE_MODULES + } else { + process.env.INTENT_GLOBAL_NODE_MODULES = previousGlobalNodeModules + } + + previousCwd = '' + previousGlobalNodeModules = undefined + main = null + }, + async run(argv: Array) { + if (!main) { + throw new Error('CLI runner must be set up before running benchmarks') + } + + const exitCode = await main(argv) + if (exitCode !== 0) { + throw new Error( + `intent ${argv.join(' ')} failed with exit code ${exitCode}`, + ) + } + }, + } +} + +async function loadBuiltCliMain(): Promise< + (argv?: Array) => Promise +> { + builtCliMainPromise ??= import('../../packages/intent/dist/cli.mjs').then( + (module) => { + if (typeof module.main !== 'function') { + throw new TypeError( + 'Expected packages/intent/dist/cli.mjs to export main()', + ) + } + + return module.main as (argv?: Array) => Promise + }, + ) + + return builtCliMainPromise +} + +export function createTempDir(name: string): string { + return mkdtempSync(join(tmpdir(), `intent-bench-${name}-`)) +} + +export function writeFile(filePath: string, content: string): void { + mkdirSync(dirname(filePath), { recursive: true }) + writeFileSync(filePath, content) +} + +export function writeJson(filePath: string, value: unknown): void { + writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`) +} + +export function writeSkill( + root: string, + skillName: string, + options: SkillOptions, +): void { + const frontmatter = [ + `name: ${JSON.stringify(skillName)}`, + `description: ${JSON.stringify(options.description)}`, + ] + + if (options.type) { + frontmatter.push(`type: ${JSON.stringify(options.type)}`) + } + + if (options.requires) { + frontmatter.push('requires:') + for (const requirement of options.requires) { + frontmatter.push(` - ${JSON.stringify(requirement)}`) + } + } + + if (options.libraryVersion) { + frontmatter.push( + `library_version: ${JSON.stringify(options.libraryVersion)}`, + ) + } + + if (options.sources) { + frontmatter.push('sources:') + for (const source of options.sources) { + frontmatter.push(` - ${JSON.stringify(source)}`) + } + } + + const bodyLines = Array.from( + { length: options.bodyLines ?? 12 }, + (_, index) => + `${index + 1}. Keep ${skillName} aligned with the documented workflow.`, + ) + + writeFile( + join(root, 'skills', ...skillName.split('/'), 'SKILL.md'), + `---\n${frontmatter.join('\n')}\n---\n\n${bodyLines.join('\n')}\n`, + ) +} + +export function writePackage( + nodeModulesDir: string, + name: string, + version: string, + options: PackageOptions, +): void { + const packageRoot = join(nodeModulesDir, ...name.split('/')) + const packageJson: Record = { + name, + version, + dependencies: options.dependencies, + peerDependencies: options.peerDependencies, + } + + if (options.skills?.length) { + if (options.brokenIntent) { + packageJson.description = `Broken skill fixture for ${name}` + } else if (options.useDerivedIntent) { + const packageSlug = name.replace('@', '').replace('/', '-') + packageJson.repository = `https://github.com/example/${packageSlug}` + packageJson.homepage = `https://example.com/${packageSlug}` + } else { + packageJson.intent = { + version: 1, + repo: `example/${name.replace('@', '').replace('/', '-')}`, + docs: 'docs/', + requires: options.requires, + } + } + } + + writeJson(join(packageRoot, 'package.json'), packageJson) + + for (const skill of options.skills ?? []) { + writeSkill(packageRoot, skill, { + description: `${skill} benchmark guidance`, + bodyLines: 14, + type: skill.includes('/') ? 'framework' : 'core', + requires: skill.includes('/') ? [skill.split('/')[0]!] : undefined, + }) + } +} diff --git a/benchmarks/intent/list.bench.ts b/benchmarks/intent/list.bench.ts new file mode 100644 index 00000000..48d09c9a --- /dev/null +++ b/benchmarks/intent/list.bench.ts @@ -0,0 +1,161 @@ +import { rmSync } from 'node:fs' +import { join } from 'node:path' +import { afterAll, beforeAll, bench, describe } from 'vitest' +import { + createBenchOptions, + createCliRunner, + createConsoleSilencer, + createTempDir, + writeFile, + writeJson, + writePackage, +} from './helpers.js' + +type ListFixture = { + globalNodeModules: string + root: string + runner: ReturnType +} + +const consoleSilencer = createConsoleSilencer() +let fixture: ListFixture | null = null + +function createFixture(): ListFixture { + const root = createTempDir('list') + const globalNodeModules = createTempDir('global-node-modules') + + writeJson(join(root, 'package.json'), { + name: 'intent-list-benchmark', + private: true, + workspaces: ['packages/*'], + dependencies: { + '@bench/root-direct': '1.0.0', + '@bench/wrapper-one': '1.0.0', + }, + devDependencies: { + '@bench/dev-helper': '1.0.0', + }, + }) + writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") + writeFile(join(root, 'pnpm-lock.yaml'), 'lockfileVersion: "9.0"\n') + + writeJson(join(root, 'packages', 'app', 'package.json'), { + name: '@consumer/app', + version: '1.0.0', + dependencies: { + '@bench/root-direct': '1.0.0', + '@bench/wrapper-one': '1.0.0', + }, + }) + + writeJson(join(root, 'packages', 'tool', 'package.json'), { + name: '@consumer/tool', + version: '1.0.0', + dependencies: { + '@bench/local-only': '1.0.0', + '@bench/wrapper-two': '1.0.0', + }, + }) + + writePackage(join(root, 'node_modules'), '@bench/shared-core', '1.4.0', { + skills: ['shared-core', 'shared-core/caching', 'shared-core/errors'], + }) + writePackage(join(root, 'node_modules'), '@bench/root-direct', '1.2.0', { + requires: ['@bench/shared-core'], + skills: ['root-direct', 'root-direct/cli', 'root-direct/config'], + }) + writePackage(join(root, 'node_modules'), '@bench/leaf-one', '1.1.0', { + requires: ['@bench/shared-core'], + skills: ['leaf-one', 'leaf-one/batching', 'leaf-one/runtime'], + }) + writePackage(join(root, 'node_modules'), '@bench/leaf-two', '1.0.0', { + skills: ['leaf-two', 'leaf-two/streaming', 'leaf-two/debugging'], + useDerivedIntent: true, + }) + writePackage(join(root, 'node_modules'), '@bench/local-only', '1.0.0', { + skills: ['local-only', 'local-only/testing'], + }) + writePackage(join(root, 'node_modules'), '@bench/broken-skill', '1.0.0', { + brokenIntent: true, + skills: ['broken-skill'], + }) + writePackage(join(root, 'node_modules'), '@bench/wrapper-one', '1.0.0', { + dependencies: { + '@bench/leaf-one': '1.1.0', + '@bench/shared-core': '1.4.0', + }, + }) + writePackage(join(root, 'node_modules'), '@bench/wrapper-two', '1.0.0', { + dependencies: { + '@bench/leaf-two': '1.0.0', + }, + }) + writePackage(join(root, 'node_modules'), '@bench/dev-helper', '1.0.0', { + dependencies: { + '@bench/local-only': '1.0.0', + '@bench/wrapper-two': '1.0.0', + }, + }) + + writePackage( + join(root, 'packages', 'tool', 'node_modules'), + '@bench/workspace-addon', + '1.0.0', + { + skills: ['workspace-addon', 'workspace-addon/runtime'], + }, + ) + + writePackage(globalNodeModules, '@bench/global-only', '2.0.0', { + skills: ['global-only', 'global-only/setup', 'global-only/migrations'], + }) + writePackage(globalNodeModules, '@bench/shared-core', '9.9.0', { + skills: ['shared-core', 'shared-core/caching'], + }) + + return { + root, + globalNodeModules, + runner: createCliRunner({ cwd: root, globalNodeModules }), + } +} + +function getFixture(): ListFixture { + if (!fixture) { + consoleSilencer.silence() + fixture = createFixture() + } + + return fixture +} + +async function setup(): Promise { + await getFixture().runner.setup() +} + +function teardown(): void { + if (fixture) { + fixture.runner.teardown() + rmSync(fixture.root, { recursive: true, force: true }) + rmSync(fixture.globalNodeModules, { recursive: true, force: true }) + fixture = null + } + + consoleSilencer.restore() +} + +describe('intent list', () => { + beforeAll(setup) + afterAll(teardown) + + bench( + 'scans a consumer workspace', + async () => { + const state = getFixture() + for (let index = 0; index < 3; index++) { + await state.runner.run(['list', '--json']) + } + }, + createBenchOptions(setup, teardown), + ) +}) diff --git a/benchmarks/intent/package.json b/benchmarks/intent/package.json index 082be808..87dee6f2 100644 --- a/benchmarks/intent/package.json +++ b/benchmarks/intent/package.json @@ -3,18 +3,25 @@ "private": true, "type": "module", "scripts": { - "test:perf": "vitest bench --config ./vite.config.ts ./speed.bench.ts" + "test:perf": "vitest bench --config ./vitest.config.ts ./*.bench.ts" }, "devDependencies": { "@codspeed/vitest-plugin": "^5.0.1", - "typescript": "^5.9.3", - "vite": "^8.0.0", + "typescript": "5.9.3", "vitest": "^4.0.17" }, "nx": { "targets": { "test:perf": { - "cache": false + "cache": false, + "dependsOn": [ + { + "projects": [ + "@tanstack/intent" + ], + "target": "build" + } + ] } } } diff --git a/benchmarks/intent/speed.bench.ts b/benchmarks/intent/speed.bench.ts deleted file mode 100644 index 16948f17..00000000 --- a/benchmarks/intent/speed.bench.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { afterAll, beforeAll, bench, describe } from 'vitest' -import { createBenchmarkSuite } from './bench-utils.js' - -const suite = createBenchmarkSuite() - -describe('intent-cli', () => { - /** - * Running `vitest bench` ignores suite hooks, so we mirror setup and teardown - * through tinybench. CodSpeed does the inverse and relies on `beforeAll` and - * `afterAll`, so both are required. - */ - beforeAll(suite.setup) - afterAll(suite.teardown) - - bench('intent list scans a consumer workspace', suite.runListLoop, { - warmupIterations: 100, - time: 10_000, - setup: suite.setup, - teardown: suite.teardown, - }) - - bench('intent validate checks a shipped skills tree', suite.runValidateLoop, { - warmupIterations: 100, - time: 10_000, - setup: suite.setup, - teardown: suite.teardown, - }) - - bench('intent stale reports workspace drift', suite.runStaleLoop, { - warmupIterations: 100, - time: 10_000, - setup: suite.setup, - teardown: suite.teardown, - }) -}) diff --git a/benchmarks/intent/stale.bench.ts b/benchmarks/intent/stale.bench.ts new file mode 100644 index 00000000..9de8bbef --- /dev/null +++ b/benchmarks/intent/stale.bench.ts @@ -0,0 +1,152 @@ +import { rmSync } from 'node:fs' +import { join } from 'node:path' +import { afterAll, beforeAll, bench, describe } from 'vitest' +import { + createBenchOptions, + createCliRunner, + createConsoleSilencer, + createTempDir, + writeFile, + writeJson, + writeSkill, +} from './helpers.js' + +type StaleFixture = { + root: string + runner: ReturnType +} + +const consoleSilencer = createConsoleSilencer() +let fixture: StaleFixture | null = null + +function createFixture(): StaleFixture { + const root = createTempDir('stale') + + writeJson(join(root, 'package.json'), { + name: 'intent-stale-benchmark', + private: true, + workspaces: ['packages/*'], + }) + writeFile(join(root, 'pnpm-workspace.yaml'), "packages:\n - 'packages/*'\n") + + writeStalePackage(root, { + name: '@bench/alpha', + packageDir: 'alpha', + packageVersion: '3.2.0', + skillVersion: '3.1.0', + skills: ['alpha/core', 'alpha/cache', 'alpha/streaming', 'alpha/runtime'], + }) + writeStalePackage(root, { + name: '@bench/beta', + packageDir: 'beta', + packageVersion: '2.4.2', + skillVersion: '2.4.0', + skills: ['beta/core', 'beta/forms', 'beta/mutations', 'beta/testing'], + }) + writeStalePackage(root, { + name: '@bench/gamma', + packageDir: 'gamma', + packageVersion: '1.5.0', + skillVersion: '1.5.0', + skills: ['gamma/core', 'gamma/queries', 'gamma/cache', 'gamma/offline'], + }) + writeStalePackage(root, { + name: '@bench/delta', + packageDir: 'delta', + packageVersion: '5.0.1', + skillVersion: '5.0.0', + skills: ['delta/core', 'delta/commands', 'delta/migrations', 'delta/docs'], + }) + + return { + root, + runner: createCliRunner({ cwd: root }), + } +} + +function writeStalePackage( + root: string, + options: { + name: string + packageDir: string + packageVersion: string + skillVersion: string + skills: Array + }, +): void { + const packageRoot = join(root, 'packages', options.packageDir) + + writeJson(join(packageRoot, 'package.json'), { + name: options.name, + version: options.packageVersion, + }) + + const syncState: { + library_version: string + skills: Record }> + } = { + library_version: options.skillVersion, + skills: {}, + } + + for (const skill of options.skills) { + const sources = [ + `docs/${skill.replace(/\//g, '-')}.md`, + 'docs/shared-guide.md', + ] + + writeSkill(packageRoot, skill, { + description: `${skill} maintenance guide`, + bodyLines: 16, + libraryVersion: options.skillVersion, + sources, + }) + + syncState.skills[skill] = { + sources_sha: { + [sources[0]!]: 'sha-1', + }, + } + } + + writeJson(join(packageRoot, 'skills', 'sync-state.json'), syncState) +} + +function getFixture(): StaleFixture { + if (!fixture) { + consoleSilencer.silence() + fixture = createFixture() + } + + return fixture +} + +async function setup(): Promise { + await getFixture().runner.setup() +} + +function teardown(): void { + if (fixture) { + fixture.runner.teardown() + rmSync(fixture.root, { recursive: true, force: true }) + fixture = null + } + + consoleSilencer.restore() +} + +describe('intent stale', () => { + beforeAll(setup) + afterAll(teardown) + + bench( + 'reports workspace drift', + async () => { + const state = getFixture() + for (let index = 0; index < 3; index++) { + await state.runner.run(['stale', '--json']) + } + }, + createBenchOptions(setup, teardown), + ) +}) diff --git a/benchmarks/intent/validate.bench.ts b/benchmarks/intent/validate.bench.ts new file mode 100644 index 00000000..b05e998e --- /dev/null +++ b/benchmarks/intent/validate.bench.ts @@ -0,0 +1,133 @@ +import { rmSync } from 'node:fs' +import { join } from 'node:path' +import { afterAll, beforeAll, bench, describe } from 'vitest' +import { + createBenchOptions, + createCliRunner, + createConsoleSilencer, + createTempDir, + writeFile, + writeJson, + writeSkill, +} from './helpers.js' + +type ValidateFixture = { + root: string + runner: ReturnType +} + +const consoleSilencer = createConsoleSilencer() +let fixture: ValidateFixture | null = null + +function createFixture(): ValidateFixture { + const root = createTempDir('validate') + const domains = [ + 'foundations', + 'routing', + 'data', + 'testing', + 'tooling', + 'releases', + ] + + writeJson(join(root, 'package.json'), { + name: '@bench/validate-package', + version: '1.0.0', + keywords: ['tanstack-intent'], + files: ['dist', 'skills', '!skills/_artifacts'], + devDependencies: { + '@tanstack/intent': 'workspace:*', + }, + }) + + for (const domain of domains) { + writeSkill(root, domain, { + description: `${domain} overview and guardrails`, + bodyLines: 20, + type: 'core', + }) + + for (let index = 1; index <= 4; index++) { + const skillName = `${domain}/workflow-${index}` + const isFrameworkSkill = index % 2 === 0 + + writeSkill(root, skillName, { + description: `${domain} workflow ${index}`, + bodyLines: 18, + type: isFrameworkSkill ? 'framework' : 'core', + requires: isFrameworkSkill ? [domain] : undefined, + }) + } + } + + writeFile( + join(root, 'skills', '_artifacts', 'domain_map.yaml'), + [ + 'domains:', + ...domains.map((domain) => ` - ${JSON.stringify(domain)}`), + '', + ].join('\n'), + ) + writeFile( + join(root, 'skills', '_artifacts', 'skill_spec.md'), + '# Skill specification\n\nGenerated for the benchmark fixture.\n', + ) + writeFile( + join(root, 'skills', '_artifacts', 'skill_tree.yaml'), + [ + 'skills:', + ...domains.flatMap((domain) => [ + ` - ${JSON.stringify(domain)}`, + ` - ${JSON.stringify(`${domain}/workflow-1`)}`, + ` - ${JSON.stringify(`${domain}/workflow-2`)}`, + ` - ${JSON.stringify(`${domain}/workflow-3`)}`, + ` - ${JSON.stringify(`${domain}/workflow-4`)}`, + ]), + '', + ].join('\n'), + ) + + return { + root, + runner: createCliRunner({ cwd: root }), + } +} + +function getFixture(): ValidateFixture { + if (!fixture) { + consoleSilencer.silence() + fixture = createFixture() + } + + return fixture +} + +async function setup(): Promise { + await getFixture().runner.setup() +} + +function teardown(): void { + if (fixture) { + fixture.runner.teardown() + rmSync(fixture.root, { recursive: true, force: true }) + fixture = null + } + + consoleSilencer.restore() +} + +describe('intent validate', () => { + beforeAll(setup) + afterAll(teardown) + + bench( + 'checks a shipped skills tree', + async () => { + const state = getFixture() + for (let index = 0; index < 3; index++) { + await state.runner.run(['validate']) + } + }, + createBenchOptions(setup, teardown), + ) +}) diff --git a/benchmarks/intent/vite.config.ts b/benchmarks/intent/vitest.config.ts similarity index 73% rename from benchmarks/intent/vite.config.ts rename to benchmarks/intent/vitest.config.ts index b4f8e806..d37b1780 100644 --- a/benchmarks/intent/vite.config.ts +++ b/benchmarks/intent/vitest.config.ts @@ -1,11 +1,7 @@ -import { fileURLToPath } from 'node:url' import codspeedPlugin from '@codspeed/vitest-plugin' import { defineConfig } from 'vitest/config' -const rootDir = fileURLToPath(new URL('.', import.meta.url)) - export default defineConfig({ - root: rootDir, plugins: [ !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) && codspeedPlugin(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73e39706..81eb4324 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,8 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +packageExtensionsChecksum: sha256-RTw5AJ+OM+YIsEdtsFGhLkoKUR+JYXJDfUxe9dr2paA= + importers: .: @@ -71,13 +73,10 @@ importers: devDependencies: '@codspeed/vitest-plugin': specifier: ^5.0.1 - version: 5.2.0(tinybench@2.9.0)(vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2)) + version: 5.2.0(tinybench@2.9.0)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2)) typescript: - specifier: ^5.9.3 + specifier: 5.9.3 version: 5.9.3 - vite: - specifier: ^8.0.0 - version: 8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2) vitest: specifier: ^4.0.17 version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) @@ -195,6 +194,9 @@ packages: tinybench: '>=2.9.0' vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 vitest: ^3.2 || ^4 + peerDependenciesMeta: + vite: + optional: true '@cypress/request@3.0.10': resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==} @@ -203,21 +205,12 @@ packages: '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} - '@emnapi/runtime@1.8.1': resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} - '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -516,12 +509,6 @@ packages: '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -590,9 +577,6 @@ packages: '@oxc-project/types@0.112.0': resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} - '@oxc-project/types@0.124.0': - resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} - '@oxc-resolver/binding-android-arm-eabi@11.16.3': resolution: {integrity: sha512-CVyWHu6ACDqDcJxR4nmGiG8vDF4TISJHqRNzac5z/gPQycs/QrP/1pDsJBy0MD7jSw8nVq2E5WqeHQKabBG/Jg==} cpu: [arm] @@ -705,12 +689,6 @@ packages: cpu: [arm64] os: [android] - '@rolldown/binding-android-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - '@rolldown/binding-android-arm64@1.0.0-rc.3': resolution: {integrity: sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -723,12 +701,6 @@ packages: cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': resolution: {integrity: sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -741,12 +713,6 @@ packages: cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.15': - resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.3': resolution: {integrity: sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -759,12 +725,6 @@ packages: cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': - resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': resolution: {integrity: sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==} engines: {node: ^20.19.0 || >=22.12.0} @@ -777,12 +737,6 @@ packages: cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': - resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': resolution: {integrity: sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==} engines: {node: ^20.19.0 || >=22.12.0} @@ -795,12 +749,6 @@ packages: cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': resolution: {integrity: sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -813,42 +761,18 @@ packages: cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': resolution: {integrity: sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': resolution: {integrity: sha512-VlfwJ/HCskPmQi8R0JuAFndySKVFX7yPhE658o27cjSDWWbXVtGkSbwaxstii7Q+3Rz87ZXN+HLnb1kd4R9Img==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': resolution: {integrity: sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -861,12 +785,6 @@ packages: cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': resolution: {integrity: sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -879,12 +797,6 @@ packages: cpu: [arm64] os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': resolution: {integrity: sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -896,11 +808,6 @@ packages: engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': - resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': resolution: {integrity: sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==} engines: {node: '>=14.0.0'} @@ -912,12 +819,6 @@ packages: cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': resolution: {integrity: sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -930,12 +831,6 @@ packages: cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': resolution: {integrity: sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -945,9 +840,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.59': resolution: {integrity: sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==} - '@rolldown/pluginutils@1.0.0-rc.15': - resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} - '@rolldown/pluginutils@1.0.0-rc.3': resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} @@ -3367,10 +3259,6 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -3406,10 +3294,6 @@ packages: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true - postcss@8.5.10: - resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -3614,11 +3498,6 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rolldown@1.0.0-rc.15: - resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rolldown@1.0.0-rc.3: resolution: {integrity: sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4193,49 +4072,6 @@ packages: yaml: optional: true - vite@8.0.8: - resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 - esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vitest@4.0.17: resolution: {integrity: sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -4565,12 +4401,13 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@5.2.0(tinybench@2.9.0)(vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))': + '@codspeed/vitest-plugin@5.2.0(tinybench@2.9.0)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))(vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2))': dependencies: '@codspeed/core': 5.2.0 tinybench: 2.9.0 - vite: 8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2) vitest: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) + optionalDependencies: + vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2) transitivePeerDependencies: - debug @@ -4600,30 +4437,14 @@ snapshots: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 - '@emnapi/core@1.9.2': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 - '@emnapi/runtime@1.9.2': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 - optional: true - '@esbuild/aix-ppc64@0.27.2': optional: true @@ -4865,13 +4686,6 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': - dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@tybys/wasm-util': 0.10.1 - optional: true - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4918,8 +4732,6 @@ snapshots: '@oxc-project/types@0.112.0': {} - '@oxc-project/types@0.124.0': {} - '@oxc-resolver/binding-android-arm-eabi@11.16.3': optional: true @@ -4991,96 +4803,60 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-beta.59': optional: true - '@rolldown/binding-android-arm64@1.0.0-rc.15': - optional: true - '@rolldown/binding-android-arm64@1.0.0-rc.3': optional: true '@rolldown/binding-darwin-arm64@1.0.0-beta.59': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': - optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': optional: true '@rolldown/binding-darwin-x64@1.0.0-beta.59': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.15': - optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.3': optional: true '@rolldown/binding-freebsd-x64@1.0.0-beta.59': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': - optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': - optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': optional: true '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': - optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': optional: true @@ -5089,13 +4865,6 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': - dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) - optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': dependencies: '@napi-rs/wasm-runtime': 1.1.1 @@ -5104,25 +4873,17 @@ snapshots: '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': - optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': optional: true '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': - optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': optional: true '@rolldown/pluginutils@1.0.0-beta.59': {} - '@rolldown/pluginutils@1.0.0-rc.15': {} - '@rolldown/pluginutils@1.0.0-rc.3': {} '@rollup/rollup-android-arm-eabi@4.55.1': @@ -6437,7 +6198,8 @@ snapshots: detect-indent@6.1.0: {} - detect-libc@2.1.2: {} + detect-libc@2.1.2: + optional: true devalue@5.6.2: {} @@ -7458,6 +7220,7 @@ snapshots: lightningcss-linux-x64-musl: 1.32.0 lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + optional: true lines-and-columns@2.0.3: {} @@ -7880,8 +7643,6 @@ snapshots: picomatch@4.0.3: {} - picomatch@4.0.4: {} - pify@3.0.0: {} pify@4.0.1: {} @@ -7946,12 +7707,6 @@ snapshots: sonic-boom: 4.2.1 thread-stream: 3.1.0 - postcss@8.5.10: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -8156,27 +7911,6 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.59 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.59 - rolldown@1.0.0-rc.15: - dependencies: - '@oxc-project/types': 0.124.0 - '@rolldown/pluginutils': 1.0.0-rc.15 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-x64': 1.0.0-rc.15 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 - rolldown@1.0.0-rc.3: dependencies: '@oxc-project/types': 0.112.0 @@ -8856,20 +8590,6 @@ snapshots: lightningcss: 1.32.0 yaml: 2.8.2 - vite@8.0.8(@types/node@25.0.9)(esbuild@0.27.2)(jiti@2.6.1)(yaml@2.8.2): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.10 - rolldown: 1.0.0-rc.15 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 25.0.9 - esbuild: 0.27.2 - fsevents: 2.3.3 - jiti: 2.6.1 - yaml: 2.8.2 - vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.17 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a12bf303..9edf8c76 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,7 +2,12 @@ cleanupUnusedCatalogs: true linkWorkspacePackages: true preferWorkspacePackages: true +packageExtensions: + '@codspeed/vitest-plugin@*': + peerDependenciesMeta: + vite: + optional: true + packages: - 'benchmarks/*' - - 'examples/**/*' - 'packages/*'