diff --git a/packages/@n8n/agents/package.json b/packages/@n8n/agents/package.json index aee9abe0c6c..2e549352038 100644 --- a/packages/@n8n/agents/package.json +++ b/packages/@n8n/agents/package.json @@ -111,6 +111,7 @@ "dotenv": "catalog:", "cross-env": "catalog:", "nock": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/agents/tsconfig.json b/packages/@n8n/agents/tsconfig.json index 1e07f95211b..5dea163cf85 100644 --- a/packages/@n8n/agents/tsconfig.json +++ b/packages/@n8n/agents/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts"], "exclude": ["dist/**/*", "node_modules/**/*"] diff --git a/packages/@n8n/ai-utilities/package.json b/packages/@n8n/ai-utilities/package.json index 9d7e1f6d04d..6d46f1a322f 100644 --- a/packages/@n8n/ai-utilities/package.json +++ b/packages/@n8n/ai-utilities/package.json @@ -88,6 +88,7 @@ "@types/json-schema": "catalog:", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", "@types/mime-types": "catalog:", diff --git a/packages/@n8n/ai-utilities/tsconfig.json b/packages/@n8n/ai-utilities/tsconfig.json index 2908b03a1e8..ef6d9f9c35e 100644 --- a/packages/@n8n/ai-utilities/tsconfig.json +++ b/packages/@n8n/ai-utilities/tsconfig.json @@ -10,7 +10,7 @@ }, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts", "integration-tests/**/*.ts"] } diff --git a/packages/@n8n/ai-workflow-builder.ee/package.json b/packages/@n8n/ai-workflow-builder.ee/package.json index 8403ab49422..0c13fdb43e6 100644 --- a/packages/@n8n/ai-workflow-builder.ee/package.json +++ b/packages/@n8n/ai-workflow-builder.ee/package.json @@ -97,6 +97,7 @@ "cli-table3": "^0.6.3", "madge": "^8.0.0", "tsx": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/ai-workflow-builder.ee/tsconfig.json b/packages/@n8n/ai-workflow-builder.ee/tsconfig.json index 2ffa784905d..5308ccbc472 100644 --- a/packages/@n8n/ai-workflow-builder.ee/tsconfig.json +++ b/packages/@n8n/ai-workflow-builder.ee/tsconfig.json @@ -11,7 +11,7 @@ "paths": { "@/*": ["./src/*"] }, - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts", "evaluations/**/*.ts", "scripts/**/*.ts"] } diff --git a/packages/@n8n/api-types/package.json b/packages/@n8n/api-types/package.json index 2f25da10d51..242373482df 100644 --- a/packages/@n8n/api-types/package.json +++ b/packages/@n8n/api-types/package.json @@ -27,6 +27,7 @@ "@n8n/config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", "minifaker": "1.34.1" diff --git a/packages/@n8n/api-types/tsconfig.json b/packages/@n8n/api-types/tsconfig.json index 35487f800a9..f729e4443c3 100644 --- a/packages/@n8n/api-types/tsconfig.json +++ b/packages/@n8n/api-types/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts"], "references": [ diff --git a/packages/@n8n/client-oauth2/package.json b/packages/@n8n/client-oauth2/package.json index ba0d416a4a2..6aeace27e57 100644 --- a/packages/@n8n/client-oauth2/package.json +++ b/packages/@n8n/client-oauth2/package.json @@ -30,6 +30,7 @@ "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", "nock": "catalog:" diff --git a/packages/@n8n/client-oauth2/tsconfig.json b/packages/@n8n/client-oauth2/tsconfig.json index 36f8f0ffe6d..67684248ccb 100644 --- a/packages/@n8n/client-oauth2/tsconfig.json +++ b/packages/@n8n/client-oauth2/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vite/client"], "paths": { "@/*": ["./src/*"] } diff --git a/packages/@n8n/computer-use/package.json b/packages/@n8n/computer-use/package.json index e226aeaf007..0b426b4daa0 100644 --- a/packages/@n8n/computer-use/package.json +++ b/packages/@n8n/computer-use/package.json @@ -61,6 +61,7 @@ "@types/node": "catalog:", "@types/yargs-parser": "21.0.0", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:" }, "license": "LicenseRef-n8n-sustainable-use" diff --git a/packages/@n8n/computer-use/tsconfig.json b/packages/@n8n/computer-use/tsconfig.json index 801a1e65587..84eecb91d87 100644 --- a/packages/@n8n/computer-use/tsconfig.json +++ b/packages/@n8n/computer-use/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts"] } diff --git a/packages/@n8n/config/package.json b/packages/@n8n/config/package.json index b9aa19eacf5..3fa36a50a21 100644 --- a/packages/@n8n/config/package.json +++ b/packages/@n8n/config/package.json @@ -32,6 +32,7 @@ "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/config/tsconfig.json b/packages/@n8n/config/tsconfig.json index 0e71f865c75..030c4b4a073 100644 --- a/packages/@n8n/config/tsconfig.json +++ b/packages/@n8n/config/tsconfig.json @@ -4,7 +4,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "strictPropertyInitialization": false, - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts"], "references": [{ "path": "../di/tsconfig.build.json" }] diff --git a/packages/@n8n/db/package.json b/packages/@n8n/db/package.json index 039f14e0253..d16ea4d5eee 100644 --- a/packages/@n8n/db/package.json +++ b/packages/@n8n/db/package.json @@ -61,6 +61,7 @@ "express": "catalog:", "testcontainers": "catalog:", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/db/tsconfig.json b/packages/@n8n/db/tsconfig.json index 16de2b4c1c4..a6780dbdae1 100644 --- a/packages/@n8n/db/tsconfig.json +++ b/packages/@n8n/db/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vite/client"], "experimentalDecorators": true, "emitDecoratorMetadata": true, diff --git a/packages/@n8n/decorators/vitest.config.ts b/packages/@n8n/decorators/vitest.config.ts index 0dc81b94b75..24fd17cd0a1 100644 --- a/packages/@n8n/decorators/vitest.config.ts +++ b/packages/@n8n/decorators/vitest.config.ts @@ -1,5 +1,3 @@ import { createVitestConfigWithDecorators } from '@n8n/vitest-config/node-decorators'; -export default createVitestConfigWithDecorators({ - coveragePathIgnorePatterns: ['index.ts'], -}); +export default createVitestConfigWithDecorators({}); diff --git a/packages/@n8n/instance-ai/package.json b/packages/@n8n/instance-ai/package.json index 095bdfc8b3a..661c7517909 100644 --- a/packages/@n8n/instance-ai/package.json +++ b/packages/@n8n/instance-ai/package.json @@ -94,6 +94,7 @@ "@types/turndown": "catalog:", "@vitest/coverage-v8": "catalog:", "tsx": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/instance-ai/tsconfig.json b/packages/@n8n/instance-ai/tsconfig.json index 04180dd9ab8..4568ab2ab90 100644 --- a/packages/@n8n/instance-ai/tsconfig.json +++ b/packages/@n8n/instance-ai/tsconfig.json @@ -11,7 +11,7 @@ "paths": { "@/*": ["./src/*"] }, - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts"] } diff --git a/packages/@n8n/node-cli/vite.config.ts b/packages/@n8n/node-cli/vite.config.ts index a99f7251d2f..196d1aa438d 100644 --- a/packages/@n8n/node-cli/vite.config.ts +++ b/packages/@n8n/node-cli/vite.config.ts @@ -13,7 +13,6 @@ export default defineConfig({ enabled: true, provider: 'v8', reporter: process.env.CI === 'true' ? ['cobertura'] : ['text-summary'], - all: true, }, } : {}), diff --git a/packages/@n8n/permissions/package.json b/packages/@n8n/permissions/package.json index ef4aadb7fbd..43c39cbe4cd 100644 --- a/packages/@n8n/permissions/package.json +++ b/packages/@n8n/permissions/package.json @@ -29,6 +29,7 @@ "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/permissions/tsconfig.json b/packages/@n8n/permissions/tsconfig.json index 6c32c1071e4..2dd279da359 100644 --- a/packages/@n8n/permissions/tsconfig.json +++ b/packages/@n8n/permissions/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vite/client"], "paths": { "@/*": ["./src/*"] } diff --git a/packages/@n8n/syslog-client/package.json b/packages/@n8n/syslog-client/package.json index 5f299c89ee4..dbcb3ec69db 100644 --- a/packages/@n8n/syslog-client/package.json +++ b/packages/@n8n/syslog-client/package.json @@ -29,6 +29,7 @@ "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", "get-port": "^7.1.0" diff --git a/packages/@n8n/syslog-client/tsconfig.json b/packages/@n8n/syslog-client/tsconfig.json index 0e71f865c75..030c4b4a073 100644 --- a/packages/@n8n/syslog-client/tsconfig.json +++ b/packages/@n8n/syslog-client/tsconfig.json @@ -4,7 +4,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "strictPropertyInitialization": false, - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts"], "references": [{ "path": "../di/tsconfig.build.json" }] diff --git a/packages/@n8n/task-runner/package.json b/packages/@n8n/task-runner/package.json index 31f4dda1df7..c18b495e03e 100644 --- a/packages/@n8n/task-runner/package.json +++ b/packages/@n8n/task-runner/package.json @@ -58,6 +58,7 @@ "@types/luxon": "catalog:", "@types/ws": "catalog:", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/@n8n/task-runner/tsconfig.json b/packages/@n8n/task-runner/tsconfig.json index f2b56412047..cd7b90f0dc4 100644 --- a/packages/@n8n/task-runner/tsconfig.json +++ b/packages/@n8n/task-runner/tsconfig.json @@ -6,7 +6,7 @@ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true, - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vite/client"], "paths": { "@/*": ["./src/*"] } diff --git a/packages/@n8n/tournament/package.json b/packages/@n8n/tournament/package.json index c3e23d65ea7..00c35aadeab 100644 --- a/packages/@n8n/tournament/package.json +++ b/packages/@n8n/tournament/package.json @@ -47,6 +47,7 @@ "@types/node": "^18.13.0", "@n8n/vitest-config": "workspace:*", "@vitest/coverage-v8": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", "nodemon": "^2.0.20", diff --git a/packages/@n8n/tournament/tsconfig.json b/packages/@n8n/tournament/tsconfig.json index 923bc2beb81..cb0f863d9a5 100644 --- a/packages/@n8n/tournament/tsconfig.json +++ b/packages/@n8n/tournament/tsconfig.json @@ -21,7 +21,7 @@ "sourceMap": true, "skipLibCheck": true, "tsBuildInfoFile": "dist/typecheck.tsbuildinfo", - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts"], "exclude": ["**/dist/**/*", "**/node_modules/**/*"] diff --git a/packages/@n8n/typescript-config/tsconfig.backend.json b/packages/@n8n/typescript-config/tsconfig.backend.json index 77e27254fae..57c1cd3c3c4 100644 --- a/packages/@n8n/typescript-config/tsconfig.backend.json +++ b/packages/@n8n/typescript-config/tsconfig.backend.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.common.json", "compilerOptions": { - "types": ["node", "vitest/globals"] + "types": ["node"] } } diff --git a/packages/core/package.json b/packages/core/package.json index 68ade720486..364d7a71589 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -48,6 +48,7 @@ "axios": "catalog:", "nock": "catalog:", "reflect-metadata": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:" }, diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index d477f4d23fe..4b561af66b6 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -11,9 +11,9 @@ }, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "types": ["node", "vitest/globals"], // TODO: remove all options below this line - "useUnknownInCatchVariables": false + "useUnknownInCatchVariables": false, + "types": ["node", "vitest/globals", "vite/client"] }, "include": ["src/**/*.ts", "test/**/*.ts"], "references": [ diff --git a/packages/node-dev/tsconfig.json b/packages/node-dev/tsconfig.json index 85e6bc12b4e..aee8a3343c7 100644 --- a/packages/node-dev/tsconfig.json +++ b/packages/node-dev/tsconfig.json @@ -7,7 +7,8 @@ "outDir": "dist", "preserveSymlinks": true, // TODO: remove all options below this line - "useUnknownInCatchVariables": false + "useUnknownInCatchVariables": false, + "types": ["node"] }, "include": ["commands/**/*.ts", "src/**/*.ts"] } diff --git a/packages/testing/performance/benchmarks/bench-options.ts b/packages/testing/performance/benchmarks/bench-options.ts new file mode 100644 index 00000000000..7c5b95f51a7 --- /dev/null +++ b/packages/testing/performance/benchmarks/bench-options.ts @@ -0,0 +1,16 @@ +import type { BenchOptions } from 'vitest'; + +/** + * Shared tinybench tuning for every `bench()` call. + * + * In Vitest 4 these knobs are per-benchmark options (3rd arg to `bench()`), + * not `test.benchmark` config — setting them there is a silent no-op. + */ +export const BENCH_OPTIONS: BenchOptions = { + // Run each benchmark longer for more stable results (default 500ms) — ~2x more samples. + time: 1000, + // Ensure JIT compilation is complete before measuring (default 5 iterations). + warmupIterations: 100, + // Longer warmup for stability (default 100ms). + warmupTime: 500, +}; diff --git a/packages/testing/performance/benchmarks/expression-engine/fixtures/pattern-benchmarks.ts b/packages/testing/performance/benchmarks/expression-engine/fixtures/pattern-benchmarks.ts index 542b745c35a..2ea3b97b1f7 100644 --- a/packages/testing/performance/benchmarks/expression-engine/fixtures/pattern-benchmarks.ts +++ b/packages/testing/performance/benchmarks/expression-engine/fixtures/pattern-benchmarks.ts @@ -9,6 +9,7 @@ import { bench } from 'vitest'; import type { Workflow, INodeExecutionData } from 'n8n-workflow'; +import { BENCH_OPTIONS } from '../../bench-options'; import { SIMPLE_PROPERTY, NESTED_PROPERTY, @@ -28,59 +29,111 @@ export function definePatternBenchmarks( largeData: INodeExecutionData[], ) { // Simple Property - bench(`${engine}: Simple Property - small data`, () => { - evalFn(workflow, SIMPLE_PROPERTY[0], smallData); - }); + bench( + `${engine}: Simple Property - small data`, + () => { + evalFn(workflow, SIMPLE_PROPERTY[0], smallData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Simple Property - medium data`, () => { - evalFn(workflow, SIMPLE_PROPERTY[0], mediumData); - }); + bench( + `${engine}: Simple Property - medium data`, + () => { + evalFn(workflow, SIMPLE_PROPERTY[0], mediumData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Simple Property - large data`, () => { - evalFn(workflow, SIMPLE_PROPERTY[0], largeData); - }); + bench( + `${engine}: Simple Property - large data`, + () => { + evalFn(workflow, SIMPLE_PROPERTY[0], largeData); + }, + BENCH_OPTIONS, + ); // Nested Property - bench(`${engine}: Nested Property - depth 3`, () => { - evalFn(workflow, NESTED_PROPERTY[0], smallData); - }); + bench( + `${engine}: Nested Property - depth 3`, + () => { + evalFn(workflow, NESTED_PROPERTY[0], smallData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Nested Property - depth 4`, () => { - evalFn(workflow, NESTED_PROPERTY[1], smallData); - }); + bench( + `${engine}: Nested Property - depth 4`, + () => { + evalFn(workflow, NESTED_PROPERTY[1], smallData); + }, + BENCH_OPTIONS, + ); // Extension Call - bench(`${engine}: Extension Call - toUpperCase`, () => { - evalFn(workflow, EXTENSION_CALL[0], smallData); - }); + bench( + `${engine}: Extension Call - toUpperCase`, + () => { + evalFn(workflow, EXTENSION_CALL[0], smallData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Extension Call - isEmpty`, () => { - evalFn(workflow, EXTENSION_CALL[1], smallData); - }); + bench( + `${engine}: Extension Call - isEmpty`, + () => { + evalFn(workflow, EXTENSION_CALL[1], smallData); + }, + BENCH_OPTIONS, + ); // Array Iteration - bench(`${engine}: Array Iteration - map 100 items`, () => { - evalFn(workflow, ARRAY_ITERATION[0], mediumData); - }); + bench( + `${engine}: Array Iteration - map 100 items`, + () => { + evalFn(workflow, ARRAY_ITERATION[0], mediumData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Array Iteration - filter 100 items`, () => { - evalFn(workflow, ARRAY_ITERATION[1], mediumData); - }); + bench( + `${engine}: Array Iteration - filter 100 items`, + () => { + evalFn(workflow, ARRAY_ITERATION[1], mediumData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Array Iteration - filter+map 100 items`, () => { - evalFn(workflow, ARRAY_ITERATION[2], mediumData); - }); + bench( + `${engine}: Array Iteration - filter+map 100 items`, + () => { + evalFn(workflow, ARRAY_ITERATION[2], mediumData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Array Iteration - map 10k items`, () => { - evalFn(workflow, ARRAY_ITERATION[0], largeData); - }); + bench( + `${engine}: Array Iteration - map 10k items`, + () => { + evalFn(workflow, ARRAY_ITERATION[0], largeData); + }, + BENCH_OPTIONS, + ); // Conditional - bench(`${engine}: Conditional - nullish coalescing`, () => { - evalFn(workflow, CONDITIONAL[0], smallData); - }); + bench( + `${engine}: Conditional - nullish coalescing`, + () => { + evalFn(workflow, CONDITIONAL[0], smallData); + }, + BENCH_OPTIONS, + ); - bench(`${engine}: Conditional - ternary`, () => { - evalFn(workflow, CONDITIONAL[1], smallData); - }); + bench( + `${engine}: Conditional - ternary`, + () => { + evalFn(workflow, CONDITIONAL[1], smallData); + }, + BENCH_OPTIONS, + ); } diff --git a/packages/testing/performance/benchmarks/expression-engine/micro.bench.ts b/packages/testing/performance/benchmarks/expression-engine/micro.bench.ts index fd550ff38c6..613165767c3 100644 --- a/packages/testing/performance/benchmarks/expression-engine/micro.bench.ts +++ b/packages/testing/performance/benchmarks/expression-engine/micro.bench.ts @@ -18,6 +18,8 @@ import { ThisSanitizer, } from 'n8n-workflow/expression-sandboxing'; +import { BENCH_OPTIONS } from '../bench-options'; + // Top-level await — vitest bench doesn't support beforeAll const evaluator = new ExpressionEvaluator({ createBridge: () => new IsolatedVmBridge({ timeout: 5000 }), @@ -38,14 +40,22 @@ const testData: Record = { }; // Script Compilation -bench('vm micro: Script Compilation - cache hit (repeated expression)', () => { - evaluator.evaluate('$json.id', testData, caller); -}); +bench( + 'vm micro: Script Compilation - cache hit (repeated expression)', + () => { + evaluator.evaluate('$json.id', testData, caller); + }, + BENCH_OPTIONS, +); let counter = 0; -bench('vm micro: Script Compilation - cache miss (unique expressions)', () => { - evaluator.evaluate(`$json.id + ${counter++}`, testData, caller); -}); +bench( + 'vm micro: Script Compilation - cache miss (unique expressions)', + () => { + evaluator.evaluate(`$json.id + ${counter++}`, testData, caller); + }, + BENCH_OPTIONS, +); // Data Complexity const shallowData: Record = { @@ -56,13 +66,21 @@ const deepData: Record = { $json: { a: { b: { c: { d: { e: { value: 42 } } } } } }, }; -bench('vm micro: Data Complexity - shallow access (depth 1)', () => { - evaluator.evaluate('$json.value', shallowData, caller); -}); +bench( + 'vm micro: Data Complexity - shallow access (depth 1)', + () => { + evaluator.evaluate('$json.value', shallowData, caller); + }, + BENCH_OPTIONS, +); -bench('vm micro: Data Complexity - deep access (depth 6)', () => { - evaluator.evaluate('$json.a.b.c.d.e.value', deepData, caller); -}); +bench( + 'vm micro: Data Complexity - deep access (depth 6)', + () => { + evaluator.evaluate('$json.a.b.c.d.e.value', deepData, caller); + }, + BENCH_OPTIONS, +); // Array Element Access const arrayData: Record = { @@ -71,10 +89,18 @@ const arrayData: Record = { }, }; -bench('vm micro: Array Element Access - single element', () => { - evaluator.evaluate('$json.items[0].id', arrayData, caller); -}); +bench( + 'vm micro: Array Element Access - single element', + () => { + evaluator.evaluate('$json.items[0].id', arrayData, caller); + }, + BENCH_OPTIONS, +); -bench('vm micro: Array Element Access - map 100 elements', () => { - evaluator.evaluate('$json.items.map(i => i.id)', arrayData, caller); -}); +bench( + 'vm micro: Array Element Access - map 100 elements', + () => { + evaluator.evaluate('$json.items.map(i => i.id)', arrayData, caller); + }, + BENCH_OPTIONS, +); diff --git a/packages/testing/performance/benchmarks/workflow-graph/traversal.bench.ts b/packages/testing/performance/benchmarks/workflow-graph/traversal.bench.ts index 5a79e867dad..ab79df1861d 100644 --- a/packages/testing/performance/benchmarks/workflow-graph/traversal.bench.ts +++ b/packages/testing/performance/benchmarks/workflow-graph/traversal.bench.ts @@ -10,6 +10,8 @@ import { bench, describe } from 'vitest'; import { getChildNodes, getParentNodes, mapConnectionsByDestination } from 'n8n-workflow'; import type { IConnections } from 'n8n-workflow'; +import { BENCH_OPTIONS } from '../bench-options'; + const MAIN = 'main'; function link(conn: IConnections, from: string, to: string): void { @@ -53,23 +55,39 @@ function wideFanOut(width: number): IConnections { describe('Workflow graph traversal', () => { const linear = linearChain(500); - bench('getChildNodes: linear chain (501 nodes)', () => { - getChildNodes(linear, 'n0'); - }); + bench( + 'getChildNodes: linear chain (501 nodes)', + () => { + getChildNodes(linear, 'n0'); + }, + BENCH_OPTIONS, + ); const wide = wideFanOut(184); - bench('getChildNodes: wide fan-out (184 branches into one sink)', () => { - getChildNodes(wide, 'trigger'); - }); + bench( + 'getChildNodes: wide fan-out (184 branches into one sink)', + () => { + getChildNodes(wide, 'trigger'); + }, + BENCH_OPTIONS, + ); // exponential paths, must stay linear. const diamonds = diamondChain(14); // 2^14 ≈ 16k paths, 43 nodes - bench('getChildNodes: diamond chain (14 diamonds, 43 nodes)', () => { - getChildNodes(diamonds, 'start'); - }); + bench( + 'getChildNodes: diamond chain (14 diamonds, 43 nodes)', + () => { + getChildNodes(diamonds, 'start'); + }, + BENCH_OPTIONS, + ); const diamondsByDestination = mapConnectionsByDestination(diamonds); - bench('getParentNodes: diamond chain (14 diamonds, 43 nodes)', () => { - getParentNodes(diamondsByDestination, 'm13'); - }); + bench( + 'getParentNodes: diamond chain (14 diamonds, 43 nodes)', + () => { + getParentNodes(diamondsByDestination, 'm13'); + }, + BENCH_OPTIONS, + ); }); diff --git a/packages/testing/performance/vitest.config.ts b/packages/testing/performance/vitest.config.ts index ec80db965f0..af3eca8419d 100644 --- a/packages/testing/performance/vitest.config.ts +++ b/packages/testing/performance/vitest.config.ts @@ -6,14 +6,6 @@ export default defineConfig({ test: { benchmark: { include: ['benchmarks/**/*.bench.ts'], - // Run each benchmark longer for more stable results - // Default is 500ms - we use 1000ms for ~2x more samples - time: 1000, - // Warmup: ensure JIT compilation is complete before measuring - // Default is 5 iterations - we use 100 for more thorough warmup - warmupIterations: 100, - // Default warmup time is 100ms - we use 500ms for stability - warmupTime: 500, }, }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acfd67a99ac..ba5d52a7bfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -984,6 +984,9 @@ importers: nock: specifier: 'catalog:' version: 14.0.14 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1097,6 +1100,9 @@ importers: tsx: specifier: 'catalog:' version: 4.19.3 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1224,6 +1230,9 @@ importers: tsx: specifier: 'catalog:' version: 4.19.3 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1264,6 +1273,9 @@ importers: minifaker: specifier: 1.34.1 version: 1.34.1(patch_hash=bc707e2c34a2464da2c9c93ead33e80fd9883a00434ef64907ddc45208a08b33) + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1544,6 +1556,9 @@ importers: nock: specifier: 'catalog:' version: 14.0.14 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1737,6 +1752,9 @@ importers: '@vitest/coverage-v8': specifier: 'catalog:' version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1765,6 +1783,9 @@ importers: '@vitest/coverage-v8': specifier: 'catalog:' version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -1900,6 +1921,9 @@ importers: typescript: specifier: 6.0.2 version: 6.0.2 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -2411,6 +2435,9 @@ importers: tsx: specifier: 'catalog:' version: 4.19.3 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -3106,6 +3133,9 @@ importers: '@vitest/coverage-v8': specifier: 'catalog:' version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -3236,6 +3266,9 @@ importers: get-port: specifier: ^7.1.0 version: 7.1.0 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -3303,6 +3336,9 @@ importers: '@vitest/coverage-v8': specifier: 'catalog:' version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -3343,6 +3379,9 @@ importers: typescript: specifier: 6.0.2 version: 6.0.2 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -4373,6 +4412,9 @@ importers: reflect-metadata: specifier: 'catalog:' version: 0.2.2 + vite: + specifier: 'catalog:' + version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) diff --git a/tsconfig.configs.json b/tsconfig.configs.json new file mode 100644 index 00000000000..8ae9ba1e920 --- /dev/null +++ b/tsconfig.configs.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/vite.config.ts", + "**/vitest.config.ts" + ], + "compilerOptions": { + "noEmit": true, + "module": "ESNext", + "moduleResolution": "bundler", + "types": ["node"] + } +}