vitest 4.0.14 → 4.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/browser.js +2 -2
  3. package/dist/chunks/{base.BEv8sRbK.js → base.Bin-9uYm.js} +7 -6
  4. package/dist/chunks/browser.d.Bz3lxTX-.d.ts +57 -0
  5. package/dist/chunks/{cac.DnEx6DOX.js → cac.BGonGPac.js} +10 -25
  6. package/dist/chunks/{cli-api.CbjxIXjQ.js → cli-api.BKg19Fvw.js} +469 -124
  7. package/dist/chunks/{config.d.g6OOauRt.d.ts → config.d.CzIjkicf.d.ts} +1 -0
  8. package/dist/chunks/{coverage.CtyeYmKM.js → coverage.BuJUwVtg.js} +2 -1
  9. package/dist/chunks/evaluatedModules.d.BxJ5omdx.d.ts +7 -0
  10. package/dist/chunks/{globals.C0izxiX3.js → globals.DOayXfHP.js} +3 -3
  11. package/dist/chunks/{index.D6PC4Dpu.js → index.456_DGfR.js} +128 -18
  12. package/dist/chunks/{index.CQwQ_SLL.js → index.6Qv1eEA6.js} +3 -3
  13. package/dist/chunks/index.Chj8NDwU.js +206 -0
  14. package/dist/chunks/{index.B88tjlE5.js → index.Drsj_6e7.js} +1 -1
  15. package/dist/chunks/{index.DBx1AtPJ.js → index.Z5E_ObnR.js} +1 -1
  16. package/dist/chunks/{init-forks.DmvIFK4U.js → init-forks.v9UONQS6.js} +11 -2
  17. package/dist/chunks/{init-threads.De6b3S3g.js → init-threads.DqYg3Trk.js} +1 -1
  18. package/dist/chunks/{init.a5SCIJ0x.js → init.KmQZdqFg.js} +2 -2
  19. package/dist/chunks/modules.BJuCwlRJ.js +36 -0
  20. package/dist/chunks/{plugin.d.B6hlg3fN.d.ts → plugin.d.v1sC_bv1.d.ts} +1 -1
  21. package/dist/chunks/{reporters.d.DeFcIuza.d.ts → reporters.d.Rsi0PyxX.d.ts} +27 -4
  22. package/dist/chunks/{rpc.BytlcPfC.js → rpc.BoxB0q7B.js} +1 -1
  23. package/dist/chunks/{setup-common.DGHc_BUK.js → setup-common.Cm-kSBVi.js} +1 -1
  24. package/dist/chunks/{startModuleRunner.W28wBIgJ.js → startModuleRunner.DpqpB8k3.js} +8 -9
  25. package/dist/chunks/{test.DqQZzsWf.js → test.B8ej_ZHS.js} +9 -4
  26. package/dist/chunks/{vi.BiaV1qII.js → vi.2VT5v0um.js} +40 -30
  27. package/dist/chunks/{vm.BbVD4fJ5.js → vm.qFl6P1nF.js} +2 -2
  28. package/dist/chunks/worker.d.5JNaocaN.d.ts +254 -0
  29. package/dist/cli.js +2 -2
  30. package/dist/config.d.ts +7 -7
  31. package/dist/coverage.d.ts +8 -8
  32. package/dist/coverage.js +1 -1
  33. package/dist/index.d.ts +22 -14
  34. package/dist/index.js +3 -3
  35. package/dist/module-evaluator.d.ts +5 -0
  36. package/dist/module-evaluator.js +23 -16
  37. package/dist/module-runner.js +2 -1
  38. package/dist/node.d.ts +17 -10
  39. package/dist/node.js +10 -9
  40. package/dist/reporters.d.ts +7 -7
  41. package/dist/reporters.js +2 -2
  42. package/dist/runners.d.ts +2 -1
  43. package/dist/runners.js +4 -4
  44. package/dist/worker.d.ts +5 -3
  45. package/dist/worker.js +11 -10
  46. package/dist/workers/forks.js +12 -11
  47. package/dist/workers/runVmTests.js +7 -7
  48. package/dist/workers/threads.js +12 -11
  49. package/dist/workers/vmForks.js +7 -6
  50. package/dist/workers/vmThreads.js +7 -6
  51. package/package.json +15 -15
  52. package/dist/chunks/browser.d.F6jMf15V.d.ts +0 -18
  53. package/dist/chunks/index.0kCJoeWi.js +0 -220
  54. package/dist/chunks/worker.d.DhEa3KzY.d.ts +0 -238
@@ -182,6 +182,7 @@ interface SerializedConfig {
182
182
  serializedDefines: string;
183
183
  experimental: {
184
184
  fsModuleCache: boolean;
185
+ printImportBreakdown: boolean | undefined;
185
186
  };
186
187
  }
187
188
  interface SerializedCoverageConfig {
@@ -2474,6 +2474,7 @@ function resolveConfig$1(vitest, options, viteConfig) {
2474
2474
  resolved.pool = options.pool.name;
2475
2475
  resolved.poolRunner = options.pool;
2476
2476
  }
2477
+ if ("poolOptions" in resolved) logger.deprecate("`test.poolOptions` was removed in Vitest 4. All previous `poolOptions` are now top-level options. Please, refer to the migration guide: https://vitest.dev/guide/migration#pool-rework");
2477
2478
  resolved.pool ??= "forks";
2478
2479
  resolved.project = toArray(resolved.project);
2479
2480
  resolved.provide ??= {};
@@ -2790,7 +2791,7 @@ function resolveConfig$1(vitest, options, viteConfig) {
2790
2791
  const userFolder = resolved.server.debug?.dump || process.env.VITEST_DEBUG_DUMP;
2791
2792
  resolved.dumpDir = resolve(resolved.root, typeof userFolder === "string" && userFolder !== "true" ? userFolder : ".vitest-dump", resolved.name || "root");
2792
2793
  }
2793
- resolved.testTimeout ??= resolved.browser.enabled ? 3e4 : 5e3;
2794
+ resolved.testTimeout ??= resolved.browser.enabled ? 15e3 : 5e3;
2794
2795
  resolved.hookTimeout ??= resolved.browser.enabled ? 3e4 : 1e4;
2795
2796
  resolved.experimental ??= {};
2796
2797
  if (resolved.experimental.openTelemetry?.sdkPath) {
@@ -0,0 +1,7 @@
1
+ import { EvaluatedModules } from 'vite/module-runner';
2
+
3
+ declare class VitestEvaluatedModules extends EvaluatedModules {
4
+ getModuleSourceMapById(id: string): any;
5
+ }
6
+
7
+ export { VitestEvaluatedModules as V };
@@ -1,11 +1,11 @@
1
1
  import { g as globalApis } from './constants.D_Q9UYh-.js';
2
- import { i as index } from './index.DBx1AtPJ.js';
3
- import './vi.BiaV1qII.js';
2
+ import { i as index } from './index.Z5E_ObnR.js';
3
+ import './vi.2VT5v0um.js';
4
4
  import '@vitest/expect';
5
5
  import '@vitest/runner';
6
- import '@vitest/runner/utils';
7
6
  import './utils.DvEY5TfP.js';
8
7
  import '@vitest/utils/timers';
8
+ import '@vitest/runner/utils';
9
9
  import '@vitest/snapshot';
10
10
  import '@vitest/utils/error';
11
11
  import '@vitest/utils/helpers';
@@ -285,6 +285,62 @@ async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
285
285
  };
286
286
  }
287
287
 
288
+ function groupBy(collection, iteratee) {
289
+ return collection.reduce((acc, item) => {
290
+ const key = iteratee(item);
291
+ acc[key] ||= [];
292
+ acc[key].push(item);
293
+ return acc;
294
+ }, {});
295
+ }
296
+ function stdout() {
297
+ // @ts-expect-error Node.js maps process.stdout to console._stdout
298
+ // eslint-disable-next-line no-console
299
+ return console._stdout || process.stdout;
300
+ }
301
+ function escapeRegExp(s) {
302
+ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
303
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
304
+ }
305
+ function wildcardPatternToRegExp(pattern) {
306
+ const negated = pattern[0] === "!";
307
+ if (negated) pattern = pattern.slice(1);
308
+ let regexp = `${pattern.split("*").map(escapeRegExp).join(".*")}$`;
309
+ if (negated) regexp = `(?!${regexp})`;
310
+ return new RegExp(`^${regexp}`, "i");
311
+ }
312
+ function createIndexLocationsMap(source) {
313
+ const map = /* @__PURE__ */ new Map();
314
+ let index = 0;
315
+ let line = 1;
316
+ let column = 1;
317
+ for (const char of source) {
318
+ map.set(index++, {
319
+ line,
320
+ column
321
+ });
322
+ if (char === "\n" || char === "\r\n") {
323
+ line++;
324
+ column = 0;
325
+ } else column++;
326
+ }
327
+ return map;
328
+ }
329
+ function createLocationsIndexMap(source) {
330
+ const map = /* @__PURE__ */ new Map();
331
+ let index = 0;
332
+ let line = 1;
333
+ let column = 1;
334
+ for (const char of source) {
335
+ map.set(`${line}:${column}`, index++);
336
+ if (char === "\n" || char === "\r\n") {
337
+ line++;
338
+ column = 0;
339
+ } else column++;
340
+ }
341
+ return map;
342
+ }
343
+
288
344
  function hasFailedSnapshot(suite) {
289
345
  return getTests(suite).some((s) => {
290
346
  return s.result?.errors?.some((e) => typeof e?.message === "string" && e.message.match(/Snapshot .* mismatched/));
@@ -808,7 +864,76 @@ class BaseReporter {
808
864
  this.log(padSummaryTitle("Duration"), formatTime(executionTime) + c.dim(` (${timers})`));
809
865
  if (blobs?.executionTimes) this.log(padSummaryTitle("Per blob") + blobs.executionTimes.map((time) => ` ${formatTime(time)}`).join(""));
810
866
  }
867
+ if (this.ctx.config.experimental.printImportBreakdown) this.printImportsBreakdown();
868
+ this.log();
869
+ }
870
+ printImportsBreakdown() {
871
+ const testModules = this.ctx.state.getTestModules();
872
+ const allImports = [];
873
+ for (const testModule of testModules) {
874
+ const importDurations = testModule.diagnostic().importDurations;
875
+ for (const filePath in importDurations) {
876
+ const duration = importDurations[filePath];
877
+ allImports.push({
878
+ importedModuleId: filePath,
879
+ testModule,
880
+ selfTime: duration.selfTime,
881
+ totalTime: duration.totalTime,
882
+ external: duration.external
883
+ });
884
+ }
885
+ }
886
+ if (allImports.length === 0) return;
887
+ const sortedImports = allImports.sort((a, b) => b.totalTime - a.totalTime);
888
+ const maxTotalTime = sortedImports[0].totalTime;
889
+ const topImports = sortedImports.slice(0, 10);
890
+ const totalSelfTime = allImports.reduce((sum, imp) => sum + imp.selfTime, 0);
891
+ const totalTotalTime = allImports.reduce((sum, imp) => sum + imp.totalTime, 0);
892
+ const slowestImport = sortedImports[0];
893
+ this.log();
894
+ this.log(c.bold("Import Duration Breakdown") + c.dim(" (ordered by Total Time) (Top 10)"));
895
+ // if there are multiple files, it's highly possible that some of them will import the same large file
896
+ // we group them to show the distinction between those files more easily
897
+ // Import Duration Breakdown (ordered by Total Time) (Top 10)
898
+ // .../fields/FieldFile/__tests__/FieldFile.spec.ts self: 7ms total: 1.01s ████████████████████
899
+ // ↳ tests/support/components/index.ts self: 0ms total: 861ms █████████████████░░░
900
+ // ↳ tests/support/components/renderComponent.ts self: 59ms total: 861ms █████████████████░░░
901
+ // ...s__/apps/desktop/form-updater.desktop.spec.ts self: 8ms total: 991ms ████████████████████
902
+ // ...sts__/apps/mobile/form-updater.mobile.spec.ts self: 11ms total: 990ms ████████████████████
903
+ // shared/components/Form/__tests__/Form.spec.ts self: 5ms total: 988ms ████████████████████
904
+ // ↳ tests/support/components/index.ts self: 0ms total: 935ms ███████████████████░
905
+ // ↳ tests/support/components/renderComponent.ts self: 61ms total: 935ms ███████████████████░
906
+ // ...ditor/features/link/__test__/LinkForm.spec.ts self: 7ms total: 972ms ███████████████████░
907
+ // ↳ tests/support/components/renderComponent.ts self: 56ms total: 936ms ███████████████████░
908
+ const groupedImports = Object.entries(
909
+ groupBy(topImports, (i) => i.testModule.id)
910
+ // the first one is always the highest because the modules are already sorted
911
+ ).sort(([, imps1], [, imps2]) => imps2[0].totalTime - imps1[0].totalTime);
912
+ for (const [_, group] of groupedImports) group.forEach((imp, index) => {
913
+ const barWidth = 20;
914
+ const filledWidth = Math.round(imp.totalTime / maxTotalTime * barWidth);
915
+ const bar = c.cyan("█".repeat(filledWidth)) + c.dim("░".repeat(barWidth - filledWidth));
916
+ // only show the arrow if there is more than 1 group
917
+ const pathDisplay = this.ellipsisPath(imp.importedModuleId, imp.external, groupedImports.length > 1 && index > 0);
918
+ this.log(`${pathDisplay} ${c.dim("self:")} ${this.importDurationTime(imp.selfTime)} ${c.dim("total:")} ${this.importDurationTime(imp.totalTime)} ${bar}`);
919
+ });
811
920
  this.log();
921
+ this.log(c.dim("Total imports: ") + allImports.length);
922
+ this.log(c.dim("Slowest import (total-time): ") + formatTime(slowestImport.totalTime));
923
+ this.log(c.dim("Total import time (self/total): ") + formatTime(totalSelfTime) + c.dim(" / ") + formatTime(totalTotalTime));
924
+ }
925
+ importDurationTime(duration) {
926
+ return (duration >= 500 ? c.red : duration >= 100 ? c.yellow : (c) => c)(formatTime(duration).padStart(6));
927
+ }
928
+ ellipsisPath(path, external, nested) {
929
+ const pathDisplay = this.relative(path);
930
+ const color = external ? c.magenta : (c) => c;
931
+ const slicedPath = pathDisplay.slice(-44);
932
+ let title = "";
933
+ if (pathDisplay.length > slicedPath.length) title += "...";
934
+ if (nested) title = ` ${F_DOWN_RIGHT} ${title}`;
935
+ title += slicedPath;
936
+ return color(title.padEnd(50));
812
937
  }
813
938
  printErrorsSummary(files, errors) {
814
939
  const suites = getSuites(files);
@@ -2526,21 +2651,6 @@ async function getRawErrsMapFromTsCompile(tscErrorStdout) {
2526
2651
  return rawErrsMap;
2527
2652
  }
2528
2653
 
2529
- function createIndexMap(source) {
2530
- const map = /* @__PURE__ */ new Map();
2531
- let index = 0;
2532
- let line = 1;
2533
- let column = 1;
2534
- for (const char of source) {
2535
- map.set(`${line}:${column}`, index++);
2536
- if (char === "\n" || char === "\r\n") {
2537
- line++;
2538
- column = 0;
2539
- } else column++;
2540
- }
2541
- return map;
2542
- }
2543
-
2544
2654
  class TypeCheckError extends Error {
2545
2655
  name = "TypeCheckError";
2546
2656
  constructor(message, stacks) {
@@ -2620,7 +2730,7 @@ class Typechecker {
2620
2730
  const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)];
2621
2731
  // has no map for ".js" files that use // @ts-check
2622
2732
  const traceMap = map && new TraceMap(map);
2623
- const indexMap = createIndexMap(parsed);
2733
+ const indexMap = createLocationsIndexMap(parsed);
2624
2734
  const markState = (task, state) => {
2625
2735
  task.result = { state: task.mode === "run" || task.mode === "only" ? state : task.mode };
2626
2736
  if (task.suite) markState(task.suite, state);
@@ -3141,7 +3251,7 @@ class GithubActionsReporter {
3141
3251
  const title = getFullName(task, " > ");
3142
3252
  for (const error of task.result?.errors ?? []) projectErrors.push({
3143
3253
  project,
3144
- title,
3254
+ title: project.name ? `[${project.name}] ${title}` : title,
3145
3255
  error,
3146
3256
  file
3147
3257
  });
@@ -3702,4 +3812,4 @@ const ReportersMap = {
3702
3812
  "github-actions": GithubActionsReporter
3703
3813
  };
3704
3814
 
3705
- export { BlobReporter as B, DefaultReporter as D, F_RIGHT as F, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, ReportersMap as R, TapFlatReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapReporter as c, stringify as d, TraceMap as e, formatProjectName as f, getStateSymbol as g, ancestor as h, printError as i, errorBanner as j, divider as k, Typechecker as l, generateCodeFrame as m, createDefinesScript as n, originalPositionFor as o, parse$1 as p, convertTasksToEvents as q, readBlobs as r, separator as s, truncateString as t, utils as u, withLabel as w };
3815
+ export { utils as A, BlobReporter as B, DefaultReporter as D, F_RIGHT as F, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, ReportersMap as R, TapFlatReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapReporter as c, stringify as d, createIndexLocationsMap as e, formatProjectName as f, getStateSymbol as g, TraceMap as h, ancestor as i, printError as j, errorBanner as k, divider as l, Typechecker as m, generateCodeFrame as n, originalPositionFor as o, parse$1 as p, escapeRegExp as q, createDefinesScript as r, separator as s, truncateString as t, groupBy as u, readBlobs as v, withLabel as w, convertTasksToEvents as x, wildcardPatternToRegExp as y, stdout as z };
@@ -1,8 +1,8 @@
1
1
  import { chai } from '@vitest/expect';
2
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.DGHc_BUK.js';
3
- import { r as rpc } from './rpc.BytlcPfC.js';
2
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.Cm-kSBVi.js';
3
+ import { r as rpc } from './rpc.BoxB0q7B.js';
4
4
  import { g as getWorkerState } from './utils.DvEY5TfP.js';
5
- import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.DqQZzsWf.js';
5
+ import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.B8ej_ZHS.js';
6
6
 
7
7
  function setupChaiConfig(config) {
8
8
  Object.assign(chai.config, config);
@@ -0,0 +1,206 @@
1
+ //#region src/messages.ts
2
+ const TYPE_REQUEST = "q";
3
+ const TYPE_RESPONSE = "s";
4
+
5
+ //#endregion
6
+ //#region src/utils.ts
7
+ function createPromiseWithResolvers() {
8
+ let resolve;
9
+ let reject;
10
+ return {
11
+ promise: new Promise((res, rej) => {
12
+ resolve = res;
13
+ reject = rej;
14
+ }),
15
+ resolve,
16
+ reject
17
+ };
18
+ }
19
+ const random = Math.random.bind(Math);
20
+ const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
21
+ function nanoid(size = 21) {
22
+ let id = "";
23
+ let i = size;
24
+ while (i--) id += urlAlphabet[random() * 64 | 0];
25
+ return id;
26
+ }
27
+
28
+ //#endregion
29
+ //#region src/main.ts
30
+ const DEFAULT_TIMEOUT = 6e4;
31
+ const defaultSerialize = (i) => i;
32
+ const defaultDeserialize = defaultSerialize;
33
+ const { clearTimeout, setTimeout } = globalThis;
34
+ function createBirpc($functions, options) {
35
+ const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT, proxify = true } = options;
36
+ let $closed = false;
37
+ const _rpcPromiseMap = /* @__PURE__ */ new Map();
38
+ let _promiseInit;
39
+ let rpc;
40
+ async function _call(method, args, event, optional) {
41
+ if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
42
+ const req = {
43
+ m: method,
44
+ a: args,
45
+ t: TYPE_REQUEST
46
+ };
47
+ if (optional) req.o = true;
48
+ const send = async (_req) => post(serialize(_req));
49
+ if (event) {
50
+ await send(req);
51
+ return;
52
+ }
53
+ if (_promiseInit) try {
54
+ await _promiseInit;
55
+ } finally {
56
+ _promiseInit = void 0;
57
+ }
58
+ let { promise, resolve, reject } = createPromiseWithResolvers();
59
+ const id = nanoid();
60
+ req.i = id;
61
+ let timeoutId;
62
+ async function handler(newReq = req) {
63
+ if (timeout >= 0) {
64
+ timeoutId = setTimeout(() => {
65
+ try {
66
+ if (options.onTimeoutError?.call(rpc, method, args) !== true) throw new Error(`[birpc] timeout on calling "${method}"`);
67
+ } catch (e) {
68
+ reject(e);
69
+ }
70
+ _rpcPromiseMap.delete(id);
71
+ }, timeout);
72
+ if (typeof timeoutId === "object") timeoutId = timeoutId.unref?.();
73
+ }
74
+ _rpcPromiseMap.set(id, {
75
+ resolve,
76
+ reject,
77
+ timeoutId,
78
+ method
79
+ });
80
+ await send(newReq);
81
+ return promise;
82
+ }
83
+ try {
84
+ if (options.onRequest) await options.onRequest.call(rpc, req, handler, resolve);
85
+ else await handler();
86
+ } catch (e) {
87
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
88
+ return;
89
+ } finally {
90
+ clearTimeout(timeoutId);
91
+ _rpcPromiseMap.delete(id);
92
+ }
93
+ return promise;
94
+ }
95
+ const builtinMethods = {
96
+ $call: (method, ...args) => _call(method, args, false),
97
+ $callOptional: (method, ...args) => _call(method, args, false, true),
98
+ $callEvent: (method, ...args) => _call(method, args, true),
99
+ $callRaw: (options$1) => _call(options$1.method, options$1.args, options$1.event, options$1.optional),
100
+ $rejectPendingCalls,
101
+ get $closed() {
102
+ return $closed;
103
+ },
104
+ get $meta() {
105
+ return options.meta;
106
+ },
107
+ $close,
108
+ $functions
109
+ };
110
+ if (proxify) rpc = new Proxy({}, { get(_, method) {
111
+ if (Object.prototype.hasOwnProperty.call(builtinMethods, method)) return builtinMethods[method];
112
+ if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
113
+ const sendEvent = (...args) => _call(method, args, true);
114
+ if (eventNames.includes(method)) {
115
+ sendEvent.asEvent = sendEvent;
116
+ return sendEvent;
117
+ }
118
+ const sendCall = (...args) => _call(method, args, false);
119
+ sendCall.asEvent = sendEvent;
120
+ return sendCall;
121
+ } });
122
+ else rpc = builtinMethods;
123
+ function $close(customError) {
124
+ $closed = true;
125
+ _rpcPromiseMap.forEach(({ reject, method }) => {
126
+ const error = /* @__PURE__ */ new Error(`[birpc] rpc is closed, cannot call "${method}"`);
127
+ if (customError) {
128
+ customError.cause ??= error;
129
+ return reject(customError);
130
+ }
131
+ reject(error);
132
+ });
133
+ _rpcPromiseMap.clear();
134
+ off(onMessage);
135
+ }
136
+ function $rejectPendingCalls(handler) {
137
+ const handlerResults = Array.from(_rpcPromiseMap.values()).map(({ method, reject }) => {
138
+ if (!handler) return reject(/* @__PURE__ */ new Error(`[birpc]: rejected pending call "${method}".`));
139
+ return handler({
140
+ method,
141
+ reject
142
+ });
143
+ });
144
+ _rpcPromiseMap.clear();
145
+ return handlerResults;
146
+ }
147
+ async function onMessage(data, ...extra) {
148
+ let msg;
149
+ try {
150
+ msg = deserialize(data);
151
+ } catch (e) {
152
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
153
+ return;
154
+ }
155
+ if (msg.t === TYPE_REQUEST) {
156
+ const { m: method, a: args, o: optional } = msg;
157
+ let result, error;
158
+ let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
159
+ if (optional) fn ||= () => void 0;
160
+ if (!fn) error = /* @__PURE__ */ new Error(`[birpc] function "${method}" not found`);
161
+ else try {
162
+ result = await fn.apply(bind === "rpc" ? rpc : $functions, args);
163
+ } catch (e) {
164
+ error = e;
165
+ }
166
+ if (msg.i) {
167
+ if (error && options.onFunctionError) {
168
+ if (options.onFunctionError.call(rpc, error, method, args) === true) return;
169
+ }
170
+ if (!error) try {
171
+ await post(serialize({
172
+ t: TYPE_RESPONSE,
173
+ i: msg.i,
174
+ r: result
175
+ }), ...extra);
176
+ return;
177
+ } catch (e) {
178
+ error = e;
179
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
180
+ }
181
+ try {
182
+ await post(serialize({
183
+ t: TYPE_RESPONSE,
184
+ i: msg.i,
185
+ e: error
186
+ }), ...extra);
187
+ } catch (e) {
188
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
189
+ }
190
+ }
191
+ } else {
192
+ const { i: ack, r: result, e: error } = msg;
193
+ const promise = _rpcPromiseMap.get(ack);
194
+ if (promise) {
195
+ clearTimeout(promise.timeoutId);
196
+ if (error) promise.reject(error);
197
+ else promise.resolve(result);
198
+ }
199
+ _rpcPromiseMap.delete(ack);
200
+ }
201
+ }
202
+ _promiseInit = on(onMessage);
203
+ return rpc;
204
+ }
205
+
206
+ export { createBirpc as c };
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import { getTasks, getFullName, getTests } from '@vitest/runner/utils';
3
3
  import * as pathe from 'pathe';
4
4
  import c from 'tinyrainbow';
5
- import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.D6PC4Dpu.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.456_DGfR.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils/helpers';
8
8
 
@@ -1,4 +1,4 @@
1
- import { b as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, d as vitest } from './vi.BiaV1qII.js';
1
+ import { b as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, d as vitest } from './vi.2VT5v0um.js';
2
2
  import { b as bench } from './benchmark.B3N2zMcH.js';
3
3
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
4
4
  import { expectTypeOf } from 'expect-type';
@@ -1,4 +1,4 @@
1
- import { i as init } from './init.a5SCIJ0x.js';
1
+ import { i as init } from './init.KmQZdqFg.js';
2
2
 
3
3
  if (!process.send) throw new Error("Expected worker to be run in node:child_process");
4
4
  // Store globals in case tests overwrite them
@@ -9,13 +9,17 @@ const processOff = process.off.bind(process);
9
9
  const processRemoveAllListeners = process.removeAllListeners.bind(process);
10
10
  // Work-around for nodejs/node#55094
11
11
  if (process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir"))) processOn("SIGTERM", () => processExit());
12
+ processOn("error", onError);
12
13
  function workerInit(options) {
13
14
  const { runTests } = options;
14
15
  init({
15
16
  post: (v) => processSend(v),
16
17
  on: (cb) => processOn("message", cb),
17
18
  off: (cb) => processOff("message", cb),
18
- teardown: () => processRemoveAllListeners("message"),
19
+ teardown: () => {
20
+ processRemoveAllListeners("message");
21
+ processOff("error", onError);
22
+ },
19
23
  runTests: (state, traces) => executeTests("run", state, traces),
20
24
  collectTests: (state, traces) => executeTests("collect", state, traces),
21
25
  setup: options.setup
@@ -28,5 +32,10 @@ function workerInit(options) {
28
32
  }
29
33
  }
30
34
  }
35
+ // Prevent leaving worker in loops where it tries to send message to closed main
36
+ // thread, errors, and tries to send the error.
37
+ function onError(error) {
38
+ if (error?.code === "ERR_IPC_CHANNEL_CLOSED" || error?.code === "EPIPE") processExit(1);
39
+ }
31
40
 
32
41
  export { workerInit as w };
@@ -1,5 +1,5 @@
1
1
  import { isMainThread, parentPort } from 'node:worker_threads';
2
- import { i as init } from './init.a5SCIJ0x.js';
2
+ import { i as init } from './init.KmQZdqFg.js';
3
3
 
4
4
  if (isMainThread || !parentPort) throw new Error("Expected worker to be run in node:worker_threads");
5
5
  function workerInit(options) {
@@ -3,11 +3,11 @@ import { isBuiltin } from 'node:module';
3
3
  import { pathToFileURL } from 'node:url';
4
4
  import { resolve } from 'pathe';
5
5
  import { ModuleRunner } from 'vite/module-runner';
6
- import { b as VitestTransport } from './startModuleRunner.W28wBIgJ.js';
6
+ import { b as VitestTransport } from './startModuleRunner.DpqpB8k3.js';
7
7
  import { e as environments } from './index.BspFP3mn.js';
8
8
  import { serializeError } from '@vitest/utils/error';
9
9
  import { T as Traces } from './traces.U4xDYhzZ.js';
10
- import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.BytlcPfC.js';
10
+ import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.BoxB0q7B.js';
11
11
  import { createStackString, parseStacktrace } from '@vitest/utils/source-map';
12
12
  import { s as setupInspect } from './inspector.CvyFGlXm.js';
13
13
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
@@ -0,0 +1,36 @@
1
+ import { builtinModules } from 'node:module';
2
+
3
+ // copied from vite
4
+ // https://github.com/vitejs/vite/blob/814120f2ad387ca3d1e16c7dd403b04ca4b97f75/packages/vite/src/node/utils.ts#L106
5
+ // Supported by Node, Deno, Bun
6
+ const NODE_BUILTIN_NAMESPACE = "node:";
7
+ // Supported by Deno
8
+ const NPM_BUILTIN_NAMESPACE = "npm:";
9
+ // Supported by Bun
10
+ const BUN_BUILTIN_NAMESPACE = "bun:";
11
+ // Some runtimes like Bun injects namespaced modules here, which is not a node builtin
12
+ const nodeBuiltins = builtinModules.filter((id) => !id.includes(":"));
13
+ const { bun: isBun, deno: isDeno } = process.versions;
14
+ // TODO: Use `isBuiltin` from `node:module`, but Deno doesn't support it
15
+ function isBuiltin(id) {
16
+ if (isDeno && id.startsWith(NPM_BUILTIN_NAMESPACE)) return true;
17
+ if (isBun && id.startsWith(BUN_BUILTIN_NAMESPACE)) return true;
18
+ return isNodeBuiltin(id);
19
+ }
20
+ function isNodeBuiltin(id) {
21
+ if (id.startsWith(NODE_BUILTIN_NAMESPACE)) return true;
22
+ return nodeBuiltins.includes(id);
23
+ }
24
+ const browserExternalId = "__vite-browser-external";
25
+ const browserExternalLength = 24;
26
+ function isBrowserExternal(id) {
27
+ return id.startsWith(browserExternalId);
28
+ }
29
+ function toBuiltin(id) {
30
+ if (id.startsWith(browserExternalId)) id = id.slice(browserExternalLength);
31
+ if (id.startsWith(NPM_BUILTIN_NAMESPACE) || id.startsWith(BUN_BUILTIN_NAMESPACE) || id.startsWith(NODE_BUILTIN_NAMESPACE)) return id;
32
+ if (isDeno || isBun) return id;
33
+ return `node:${id}`;
34
+ }
35
+
36
+ export { isBrowserExternal as a, isBuiltin as i, toBuiltin as t };
@@ -1,5 +1,5 @@
1
1
  import { DevEnvironment } from 'vite';
2
- import { V as Vitest, T as TestProject, b as TestProjectConfiguration } from './reporters.d.DeFcIuza.js';
2
+ import { V as Vitest, T as TestProject, b as TestProjectConfiguration } from './reporters.d.Rsi0PyxX.js';
3
3
 
4
4
  /**
5
5
  * Generate a unique cache identifier.
@@ -2,18 +2,18 @@ import { TaskMeta, Suite, File, TestAnnotation, TestArtifact, ImportDuration, Te
2
2
  import { TestError, SerializedError, Arrayable, ParsedStack, Awaitable } from '@vitest/utils';
3
3
  import { A as AfterSuiteRunMeta, U as UserConsoleLog, P as ProvidedContext, L as LabelColor } from './rpc.d.RH3apGEf.js';
4
4
  import { Writable } from 'node:stream';
5
- import { TransformResult as TransformResult$1, ViteDevServer, Plugin, UserConfig as UserConfig$1, DepOptimizationConfig, ServerOptions, ConfigEnv, AliasOptions } from 'vite';
5
+ import { DevEnvironment, TransformResult as TransformResult$1, ViteDevServer, Plugin, UserConfig as UserConfig$1, DepOptimizationConfig, ServerOptions, ConfigEnv, AliasOptions } from 'vite';
6
+ import { S as SerializedTestSpecification, c as SourceModuleDiagnostic, B as BrowserTesterOptions } from './browser.d.Bz3lxTX-.js';
6
7
  import { MockedModule } from '@vitest/mocker';
7
8
  import { StackTraceParserOptions } from '@vitest/utils/source-map';
8
9
  import { BrowserCommands } from 'vitest/browser';
9
- import { B as BrowserTraceViewMode, S as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.g6OOauRt.js';
10
- import { S as SerializedTestSpecification, B as BrowserTesterOptions } from './browser.d.F6jMf15V.js';
10
+ import { B as BrowserTraceViewMode, S as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.CzIjkicf.js';
11
11
  import { PrettyFormatOptions } from '@vitest/pretty-format';
12
12
  import { SnapshotSummary, SnapshotStateOptions } from '@vitest/snapshot';
13
13
  import { SerializedDiffOptions } from '@vitest/utils/diff';
14
14
  import { chai } from '@vitest/expect';
15
15
  import { happyDomTypes, jsdomTypes } from 'vitest/optional-types.js';
16
- import { c as ContextTestEnvironment, d as WorkerExecuteContext, e as WorkerTestEnvironment } from './worker.d.DhEa3KzY.js';
16
+ import { c as ContextTestEnvironment, d as WorkerExecuteContext, e as WorkerTestEnvironment } from './worker.d.5JNaocaN.js';
17
17
  import { O as OTELCarrier } from './traces.d.402V_yFI.js';
18
18
  import { B as BenchmarkResult } from './benchmark.d.DAaHLpsq.js';
19
19
  import { a as RuntimeCoverageProviderModule } from './coverage.d.BZtK59WP.js';
@@ -239,6 +239,12 @@ declare class TestModule extends SuiteImplementation {
239
239
  readonly location: undefined;
240
240
  readonly type = "module";
241
241
  /**
242
+ * The Vite environment that processes files on the server.
243
+ *
244
+ * Can be empty if test module did not run yet.
245
+ */
246
+ readonly viteEnvironment: DevEnvironment | undefined;
247
+ /**
242
248
  * This is usually an absolute UNIX file path.
243
249
  * It can be a virtual ID if the file is not on the disk.
244
250
  * This value corresponds to the ID in the Vite's module graph.
@@ -1278,6 +1284,14 @@ declare class Vitest {
1278
1284
  */
1279
1285
  rerunTestSpecifications(specifications: TestSpecification[], allTestsRun?: boolean): Promise<TestRunResult>;
1280
1286
  private runFiles;
1287
+ /**
1288
+ * Returns module's diagnostic. If `testModule` is not provided, `selfTime` and `totalTime` will be aggregated across all tests.
1289
+ *
1290
+ * If the module was not transformed or executed, the diagnostic will be empty.
1291
+ * @experimental
1292
+ * @see {@link https://vitest.dev/api/advanced/vitest#getsourcemodulediagnostic}
1293
+ */
1294
+ experimental_getSourceModuleDiagnostic(moduleId: string, testModule?: TestModule): Promise<SourceModuleDiagnostic>;
1281
1295
  experimental_parseSpecifications(specifications: TestSpecification[], options?: {
1282
1296
  /** @default os.availableParallelism() */
1283
1297
  concurrency?: number;
@@ -2025,6 +2039,9 @@ declare abstract class BaseReporter implements Reporter {
2025
2039
  onServerRestart(reason?: string): void;
2026
2040
  reportSummary(files: File[], errors: unknown[]): void;
2027
2041
  reportTestSummary(files: File[], errors: unknown[]): void;
2042
+ private printImportsBreakdown;
2043
+ private importDurationTime;
2044
+ private ellipsisPath;
2028
2045
  private printErrorsSummary;
2029
2046
  reportBenchmarkSummary(files: File[]): void;
2030
2047
  private printTaskErrors;
@@ -3019,6 +3036,12 @@ interface InlineConfig {
3019
3036
  enabled: boolean;
3020
3037
  sdkPath?: string;
3021
3038
  };
3039
+ /**
3040
+ * Show imports (top 10) that take a long time.
3041
+ *
3042
+ * Enabling this will also show a breakdown by default in UI, but you can always press a button to toggle it.
3043
+ */
3044
+ printImportBreakdown?: boolean;
3022
3045
  };
3023
3046
  }
3024
3047
  interface TypecheckConfig {
@@ -1,5 +1,5 @@
1
1
  import { getSafeTimers } from '@vitest/utils/timers';
2
- import { c as createBirpc } from './index.0kCJoeWi.js';
2
+ import { c as createBirpc } from './index.Chj8NDwU.js';
3
3
  import { g as getWorkerState } from './utils.DvEY5TfP.js';
4
4
 
5
5
  const { get } = Reflect;
@@ -26,7 +26,7 @@ async function setupCommonEnv(config) {
26
26
  if (globalSetup) return;
27
27
  globalSetup = true;
28
28
  setSafeTimers();
29
- if (config.globals) (await import('./globals.C0izxiX3.js')).registerApiGlobally();
29
+ if (config.globals) (await import('./globals.DOayXfHP.js')).registerApiGlobally();
30
30
  }
31
31
  function setupDefines(config) {
32
32
  for (const key in config.defines) globalThis[key] = config.defines[key];