vitest 4.0.15 → 4.0.17

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 (49) hide show
  1. package/dist/browser.d.ts +3 -2
  2. package/dist/browser.js +2 -1
  3. package/dist/chunks/{base.CTp-EStD.js → base.XJJQZiKB.js} +4 -3
  4. package/dist/chunks/{browser.d.DBzUq_Na.d.ts → browser.d.ChKACdzH.d.ts} +3 -1
  5. package/dist/chunks/{cac.BNNpZQl7.js → cac.jRCLJDDc.js} +6 -6
  6. package/dist/chunks/{cli-api.C7sYjHmQ.js → cli-api.Cx2DW4Bc.js} +176 -89
  7. package/dist/chunks/{config.d.CzIjkicf.d.ts → config.d.Cy95HiCx.d.ts} +5 -0
  8. package/dist/chunks/{coverage.CtyeYmKM.js → coverage.AVPTjMgw.js} +6 -1
  9. package/dist/chunks/{index.bFLgAE-Z.js → index.6Qv1eEA6.js} +2 -2
  10. package/dist/chunks/{index.Drsj_6e7.js → index.C5r1PdPD.js} +1 -1
  11. package/dist/chunks/index.Chj8NDwU.js +206 -0
  12. package/dist/chunks/{index.BspFP3mn.js → index.CyBMJtT7.js} +1 -1
  13. package/dist/chunks/{index.456_DGfR.js → index.M8mOzt4Y.js} +26 -2
  14. package/dist/chunks/{init-forks.CKEYp90N.js → init-forks.BC6ZwHQN.js} +1 -1
  15. package/dist/chunks/{init-threads.D8Ok07M7.js → init-threads.CxSxLC0N.js} +1 -1
  16. package/dist/chunks/{init.B04saIIg.js → init.C9kljSTm.js} +5 -7
  17. package/dist/chunks/{modules.DJPjQW6m.js → modules.BJuCwlRJ.js} +4 -3
  18. package/dist/chunks/{plugin.d.CY7CUjf-.d.ts → plugin.d.CtqpEehP.d.ts} +1 -1
  19. package/dist/chunks/{reporters.d.OXEK7y4s.d.ts → reporters.d.CWXNI2jG.d.ts} +6 -5
  20. package/dist/chunks/{rpc.BytlcPfC.js → rpc.BoxB0q7B.js} +1 -1
  21. package/dist/chunks/{startModuleRunner.Iz2V0ESw.js → startModuleRunner.DEj0jb3e.js} +2 -2
  22. package/dist/chunks/{test.BT8LKgU9.js → test.B8ej_ZHS.js} +1 -1
  23. package/dist/chunks/{traces.U4xDYhzZ.js → traces.CCmnQaNT.js} +46 -1
  24. package/dist/chunks/{vm.BwmD1Rql.js → vm.CMjifoPa.js} +2 -2
  25. package/dist/chunks/worker.d.Dyxm8DEL.d.ts +255 -0
  26. package/dist/cli.js +2 -2
  27. package/dist/config.d.ts +6 -6
  28. package/dist/coverage.d.ts +5 -5
  29. package/dist/coverage.js +1 -1
  30. package/dist/environments.js +1 -1
  31. package/dist/index.d.ts +7 -7
  32. package/dist/module-evaluator.js +3 -11
  33. package/dist/module-runner.js +3 -3
  34. package/dist/node.d.ts +20 -11
  35. package/dist/node.js +11 -11
  36. package/dist/reporters.d.ts +4 -4
  37. package/dist/reporters.js +2 -2
  38. package/dist/runners.d.ts +1 -1
  39. package/dist/runners.js +3 -3
  40. package/dist/worker.d.ts +5 -3
  41. package/dist/worker.js +10 -10
  42. package/dist/workers/forks.js +11 -11
  43. package/dist/workers/runVmTests.js +4 -4
  44. package/dist/workers/threads.js +11 -11
  45. package/dist/workers/vmForks.js +9 -9
  46. package/dist/workers/vmThreads.js +9 -9
  47. package/package.json +13 -13
  48. package/dist/chunks/index.0kCJoeWi.js +0 -220
  49. package/dist/chunks/worker.d.B4A26qg6.d.ts +0 -238
@@ -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.456_DGfR.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.M8mOzt4Y.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils/helpers';
8
8
 
@@ -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 };
@@ -603,7 +603,7 @@ function patchAddEventListener(window) {
603
603
  return abortControllers.get(signal);
604
604
  }
605
605
  window.EventTarget.prototype.addEventListener = function addEventListener(type, callback, options) {
606
- if (typeof options === "object" && options.signal != null) {
606
+ if (typeof options === "object" && options?.signal != null) {
607
607
  const { signal, ...otherOptions } = options;
608
608
  // - this happens because AbortSignal is provided by Node.js,
609
609
  // but jsdom APIs require jsdom's AbortSignal, while Node APIs
@@ -2714,6 +2714,17 @@ class Typechecker {
2714
2714
  markTasks(file.tasks);
2715
2715
  }
2716
2716
  async prepareResults(output) {
2717
+ // Detect if tsc output is help text instead of error output
2718
+ // This happens when tsconfig.json is missing and tsc can't find any config
2719
+ if (output.includes("The TypeScript Compiler - Version") || output.includes("COMMON COMMANDS")) {
2720
+ const { typecheck } = this.project.config;
2721
+ const msg = `TypeScript compiler returned help text instead of type checking results.
2722
+ This usually means the tsconfig file was not found.
2723
+
2724
+ Possible solutions:
2725
+ 1. Ensure '${typecheck.tsconfig || "tsconfig.json"}' exists in your project root\n 2. If using a custom tsconfig, verify the path in your Vitest config:\n test: { typecheck: { tsconfig: 'path/to/tsconfig.json' } }\n 3. Check that the tsconfig file is valid JSON`;
2726
+ throw new Error(msg);
2727
+ }
2717
2728
  const typeErrors = await this.parseTscLikeOutput(output);
2718
2729
  const testFiles = new Set(this.getFiles());
2719
2730
  if (!this._tests) this._tests = await this.collectTests();
@@ -2847,6 +2858,7 @@ class Typechecker {
2847
2858
  reject(/* @__PURE__ */ new Error(`Failed to initialize ${typecheck.checker}. This is a bug in Vitest - please, open an issue with reproduction.`));
2848
2859
  return;
2849
2860
  }
2861
+ let resolved = false;
2850
2862
  child.process.stdout.on("data", (chunk) => {
2851
2863
  dataReceived = true;
2852
2864
  this._output += chunk;
@@ -2868,9 +2880,17 @@ class Typechecker {
2868
2880
  this._output = "";
2869
2881
  }
2870
2882
  });
2883
+ // Also capture stderr for configuration errors like missing tsconfig
2884
+ child.process.stderr?.on("data", (chunk) => {
2885
+ this._output += chunk;
2886
+ });
2871
2887
  const timeout = setTimeout(() => reject(/* @__PURE__ */ new Error(`${typecheck.checker} spawn timed out`)), this.project.config.typecheck.spawnTimeout);
2888
+ let winTimeout;
2872
2889
  function onError(cause) {
2890
+ if (resolved) return;
2873
2891
  clearTimeout(timeout);
2892
+ clearTimeout(winTimeout);
2893
+ resolved = true;
2874
2894
  reject(new Error("Spawning typechecker failed - is typescript installed?", { cause }));
2875
2895
  }
2876
2896
  child.process.once("spawn", () => {
@@ -2881,10 +2901,14 @@ class Typechecker {
2881
2901
  // on Windows, the process might be spawned but fail to start
2882
2902
  // we wait for a potential error here. if "close" event didn't trigger,
2883
2903
  // we resolve the promise
2884
- setTimeout(() => {
2904
+ winTimeout = setTimeout(() => {
2905
+ resolved = true;
2885
2906
  resolve({ result: child });
2886
2907
  }, 200);
2887
- else resolve({ result: child });
2908
+ else {
2909
+ resolved = true;
2910
+ resolve({ result: child });
2911
+ }
2888
2912
  });
2889
2913
  if (process.platform === "win32") child.process.once("close", (code) => {
2890
2914
  if (code != null && code !== 0 && !dataReceived) onError(/* @__PURE__ */ new Error(`The ${typecheck.checker} command exited with code ${code}.`));
@@ -1,4 +1,4 @@
1
- import { i as init } from './init.B04saIIg.js';
1
+ import { i as init } from './init.C9kljSTm.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
@@ -1,5 +1,5 @@
1
1
  import { isMainThread, parentPort } from 'node:worker_threads';
2
- import { i as init } from './init.B04saIIg.js';
2
+ import { i as init } from './init.C9kljSTm.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.Iz2V0ESw.js';
7
- import { e as environments } from './index.BspFP3mn.js';
6
+ import { b as VitestTransport } from './startModuleRunner.DEj0jb3e.js';
7
+ import { e as environments } from './index.CyBMJtT7.js';
8
8
  import { serializeError } from '@vitest/utils/error';
9
- import { T as Traces } from './traces.U4xDYhzZ.js';
10
- import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.BytlcPfC.js';
9
+ import { T as Traces } from './traces.CCmnQaNT.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';
@@ -161,16 +161,14 @@ function init(worker) {
161
161
  process.env.VITEST_POOL_ID = String(message.poolId);
162
162
  process.env.VITEST_WORKER_ID = String(message.workerId);
163
163
  reportMemory = message.options.reportMemory;
164
- const tracesStart = performance.now();
165
164
  traces ??= await new Traces({
166
165
  enabled: message.traces.enabled,
167
166
  sdkPath: message.traces.sdkPath
168
167
  }).waitInit();
169
- const tracesEnd = performance.now();
170
168
  const { environment, config, pool } = message.context;
171
169
  const context = traces.getContextFromCarrier(message.traces.otelCarrier);
172
170
  // record telemetry as part of "start"
173
- traces.startSpan("vitest.runtime.traces", { startTime: tracesStart }, context).end(tracesEnd);
171
+ traces.recordInitSpan(context);
174
172
  try {
175
173
  setupContext = {
176
174
  environment,
@@ -10,10 +10,11 @@ const NPM_BUILTIN_NAMESPACE = "npm:";
10
10
  const BUN_BUILTIN_NAMESPACE = "bun:";
11
11
  // Some runtimes like Bun injects namespaced modules here, which is not a node builtin
12
12
  const nodeBuiltins = builtinModules.filter((id) => !id.includes(":"));
13
+ const { bun: isBun, deno: isDeno } = process.versions;
13
14
  // TODO: Use `isBuiltin` from `node:module`, but Deno doesn't support it
14
15
  function isBuiltin(id) {
15
- if (process.versions.deno && id.startsWith(NPM_BUILTIN_NAMESPACE)) return true;
16
- if (process.versions.bun && id.startsWith(BUN_BUILTIN_NAMESPACE)) return true;
16
+ if (isDeno && id.startsWith(NPM_BUILTIN_NAMESPACE)) return true;
17
+ if (isBun && id.startsWith(BUN_BUILTIN_NAMESPACE)) return true;
17
18
  return isNodeBuiltin(id);
18
19
  }
19
20
  function isNodeBuiltin(id) {
@@ -28,7 +29,7 @@ function isBrowserExternal(id) {
28
29
  function toBuiltin(id) {
29
30
  if (id.startsWith(browserExternalId)) id = id.slice(browserExternalLength);
30
31
  if (id.startsWith(NPM_BUILTIN_NAMESPACE) || id.startsWith(BUN_BUILTIN_NAMESPACE) || id.startsWith(NODE_BUILTIN_NAMESPACE)) return id;
31
- if (process.versions.deno || process.versions.bun) return id;
32
+ if (isDeno || isBun) return id;
32
33
  return `node:${id}`;
33
34
  }
34
35
 
@@ -1,5 +1,5 @@
1
1
  import { DevEnvironment } from 'vite';
2
- import { V as Vitest, T as TestProject, b as TestProjectConfiguration } from './reporters.d.OXEK7y4s.js';
2
+ import { V as Vitest, T as TestProject, b as TestProjectConfiguration } from './reporters.d.CWXNI2jG.js';
3
3
 
4
4
  /**
5
5
  * Generate a unique cache identifier.
@@ -3,17 +3,17 @@ import { TestError, SerializedError, Arrayable, ParsedStack, Awaitable } from '@
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
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.DBzUq_Na.js';
6
+ import { S as SerializedTestSpecification, c as SourceModuleDiagnostic, B as BrowserTesterOptions } from './browser.d.ChKACdzH.js';
7
7
  import { MockedModule } from '@vitest/mocker';
8
8
  import { StackTraceParserOptions } from '@vitest/utils/source-map';
9
9
  import { BrowserCommands } from 'vitest/browser';
10
- import { B as BrowserTraceViewMode, S as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.CzIjkicf.js';
10
+ import { B as BrowserTraceViewMode, S as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.Cy95HiCx.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.B4A26qg6.js';
16
+ import { c as ContextTestEnvironment, d as WorkerExecuteContext, e as WorkerTestEnvironment } from './worker.d.Dyxm8DEL.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';
@@ -1924,8 +1924,8 @@ interface PoolWorker {
1924
1924
  stop: () => Promise<void>;
1925
1925
  /**
1926
1926
  * This is called on workers that already satisfy certain constraints:
1927
+ * - The task has the same worker name
1927
1928
  * - The task has the same project
1928
- * - The task has the same environment
1929
1929
  */
1930
1930
  canReuse?: (task: PoolTask) => boolean;
1931
1931
  }
@@ -1944,7 +1944,6 @@ interface PoolTask {
1944
1944
  */
1945
1945
  execArgv: string[];
1946
1946
  context: WorkerExecuteContext;
1947
- environment: ContextTestEnvironment;
1948
1947
  memoryLimit: number | null;
1949
1948
  }
1950
1949
  type WorkerRequest = {
@@ -3035,6 +3034,7 @@ interface InlineConfig {
3035
3034
  openTelemetry?: {
3036
3035
  enabled: boolean;
3037
3036
  sdkPath?: string;
3037
+ browserSdkPath?: string;
3038
3038
  };
3039
3039
  /**
3040
3040
  * Show imports (top 10) that take a long time.
@@ -3187,6 +3187,7 @@ interface ResolvedConfig extends Omit<Required<UserConfig>, "project" | "config"
3187
3187
  poolRunner?: PoolRunnerInitializer;
3188
3188
  reporters: (InlineReporter | ReporterWithOptions)[];
3189
3189
  defines: Record<string, any>;
3190
+ viteDefine: Record<string, any>;
3190
3191
  api: ApiConfig & {
3191
3192
  token: string;
3192
3193
  };
@@ -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;
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import { isBareImport } from '@vitest/utils/helpers';
3
- import { i as isBuiltin, a as isBrowserExternal, t as toBuiltin } from './modules.DJPjQW6m.js';
3
+ import { i as isBuiltin, a as isBrowserExternal, t as toBuiltin } from './modules.BJuCwlRJ.js';
4
4
  import { pathToFileURL } from 'node:url';
5
5
  import { normalize as normalize$1, join as join$1 } from 'pathe';
6
6
  import { distDir } from '../path.js';
@@ -11,7 +11,7 @@ import vm from 'node:vm';
11
11
  import { MockerRegistry, mockObject, RedirectedModule, AutomockedModule } from '@vitest/mocker';
12
12
  import nodeModule from 'node:module';
13
13
  import * as viteModuleRunner from 'vite/module-runner';
14
- import { T as Traces } from './traces.U4xDYhzZ.js';
14
+ import { T as Traces } from './traces.CCmnQaNT.js';
15
15
 
16
16
  class VitestTransport {
17
17
  constructor(options) {
@@ -8,7 +8,7 @@ import { getTests, getNames, getTestName } from '@vitest/runner/utils';
8
8
  import { processError } from '@vitest/utils/error';
9
9
  import { normalize } from 'pathe';
10
10
  import { a as getSnapshotClient, i as inject, c as createExpect, v as vi } from './vi.2VT5v0um.js';
11
- import { r as rpc } from './rpc.BytlcPfC.js';
11
+ import { r as rpc } from './rpc.BoxB0q7B.js';
12
12
 
13
13
  function createBenchmarkResult(name) {
14
14
  return {
@@ -7,6 +7,9 @@ class Traces {
7
7
  #init = null;
8
8
  #noopSpan = createNoopSpan();
9
9
  #noopContext = createNoopContext();
10
+ #initStartTime = performance.now();
11
+ #initEndTime = 0;
12
+ #initRecorded = false;
10
13
  constructor(options) {
11
14
  if (options.enabled) {
12
15
  const apiInit = import('@opentelemetry/api').then((api) => {
@@ -21,7 +24,10 @@ class Traces {
21
24
  }).catch(() => {
22
25
  throw new Error(`"@opentelemetry/api" is not installed locally. Make sure you have setup OpenTelemetry instrumentation: https://vitest.dev/guide/open-telemetry`);
23
26
  });
24
- const sdkInit = (options.sdkPath ? import(options.sdkPath) : Promise.resolve()).catch((cause) => {
27
+ const sdkInit = (options.sdkPath ? import(
28
+ /* @vite-ignore */
29
+ options.sdkPath
30
+ ) : Promise.resolve()).catch((cause) => {
25
31
  throw new Error(`Failed to import custom OpenTelemetry SDK script (${options.sdkPath}): ${cause.message}`);
26
32
  });
27
33
  this.#init = Promise.all([sdkInit, apiInit]).then(([sdk]) => {
@@ -30,6 +36,7 @@ class Traces {
30
36
  else if (options.watchMode !== true && process.env.VITEST_MODE !== "watch") console.warn(`OpenTelemetry instrumentation module (${options.sdkPath}) does not have a default export with a "shutdown" method. Vitest won't be able to ensure that all traces are processed in time. Try running Vitest in watch mode instead.`);
31
37
  }
32
38
  }).finally(() => {
39
+ this.#initEndTime = performance.now();
33
40
  this.#init = null;
34
41
  });
35
42
  }
@@ -47,6 +54,14 @@ class Traces {
47
54
  /**
48
55
  * @internal
49
56
  */
57
+ recordInitSpan(context) {
58
+ if (this.#initRecorded) return;
59
+ this.#initRecorded = true;
60
+ this.startSpan("vitest.runtime.traces", { startTime: this.#initStartTime }, context).end(this.#initEndTime);
61
+ }
62
+ /**
63
+ * @internal
64
+ */
50
65
  startContextSpan(name, currentContext) {
51
66
  if (!this.#otel) return {
52
67
  span: this.#noopSpan,
@@ -71,6 +86,18 @@ class Traces {
71
86
  /**
72
87
  * @internal
73
88
  */
89
+ getContextFromEnv(env) {
90
+ if (!this.#otel) return this.#noopContext;
91
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md
92
+ // some tools sets only `TRACEPARENT` but not `TRACESTATE`
93
+ const carrier = {};
94
+ if (typeof env.TRACEPARENT === "string") carrier.traceparent = env.TRACEPARENT;
95
+ if (typeof env.TRACESTATE === "string") carrier.tracestate = env.TRACESTATE;
96
+ return this.getContextFromCarrier(carrier);
97
+ }
98
+ /**
99
+ * @internal
100
+ */
74
101
  getContextCarrier(context) {
75
102
  if (!this.#otel) return;
76
103
  const carrier = {};
@@ -127,12 +154,30 @@ class Traces {
127
154
  const { tracer } = this.#otel;
128
155
  return tracer.startSpan(name, options, context);
129
156
  }
157
+ // On browser mode, async context is not automatically propagated,
158
+ // so we manually bind the `$` calls to the provided context.
159
+ // TODO: this doesn't bind to user land's `@optelemetry/api` calls
160
+ /**
161
+ * @internal
162
+ */
163
+ bind(context) {
164
+ if (!this.#otel) return;
165
+ const original = this.$.__original ?? this.$;
166
+ this.$ = this.#otel.context.bind(context, original);
167
+ this.$.__original = original;
168
+ }
130
169
  /**
131
170
  * @internal
132
171
  */
133
172
  async finish() {
134
173
  await this.#sdk?.shutdown();
135
174
  }
175
+ /**
176
+ * @internal
177
+ */
178
+ async flush() {
179
+ await this.#sdk?.forceFlush?.();
180
+ }
136
181
  }
137
182
  function noopSpan() {
138
183
  return this;
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath, pathToFileURL } from 'node:url';
2
2
  import vm, { isContext, runInContext } from 'node:vm';
3
3
  import { dirname, basename, extname, normalize, resolve } from 'pathe';
4
- import { l as loadEnvironment } from './init.B04saIIg.js';
4
+ import { l as loadEnvironment } from './init.C9kljSTm.js';
5
5
  import { distDir } from '../path.js';
6
6
  import { createCustomConsole } from './console.Cf-YriPC.js';
7
7
  import fs from 'node:fs';
@@ -11,7 +11,7 @@ import { findNearestPackageData } from '@vitest/utils/resolver';
11
11
  import { dirname as dirname$1 } from 'node:path';
12
12
  import { CSS_LANGS_RE, KNOWN_ASSET_RE } from '@vitest/utils/constants';
13
13
  import { getDefaultRequestStubs } from '../module-evaluator.js';
14
- import { s as startVitestModuleRunner, c as createNodeImportMeta, a as VITEST_VM_CONTEXT_SYMBOL } from './startModuleRunner.Iz2V0ESw.js';
14
+ import { s as startVitestModuleRunner, c as createNodeImportMeta, a as VITEST_VM_CONTEXT_SYMBOL } from './startModuleRunner.DEj0jb3e.js';
15
15
  import { p as provideWorkerState } from './utils.DvEY5TfP.js';
16
16
 
17
17
  function interopCommonJsModule(interopDefault, mod) {