vitest 4.0.7 → 4.0.8

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 (63) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{base.D3GxgUMI.js → base.BgTO2qAg.js} +71 -36
  5. package/dist/chunks/{benchmark.DHKMYAts.js → benchmark.B3N2zMcH.js} +9 -4
  6. package/dist/chunks/{browser.d.-LKfRopd.d.ts → browser.d.DTTM2PTh.d.ts} +1 -1
  7. package/dist/chunks/{cac.G9DAn-c7.js → cac.CfkWq8Qy.js} +115 -42
  8. package/dist/chunks/{cli-api.Csks4as1.js → cli-api.BQ-bjcRi.js} +1857 -839
  9. package/dist/chunks/console.Cf-YriPC.js +146 -0
  10. package/dist/chunks/{coverage.C2LA1DSL.js → coverage.NVjCOln1.js} +273 -103
  11. package/dist/chunks/{creator.cqqifzG7.js → creator.fzVyoMf3.js} +74 -30
  12. package/dist/chunks/{date.-jtEtIeV.js → date.Bq6ZW5rf.js} +17 -6
  13. package/dist/chunks/{git.BFNcloKD.js → git.Bm2pzPAa.js} +3 -3
  14. package/dist/chunks/{global.d.DxtanrNO.d.ts → global.d.DVdCfKp5.d.ts} +1 -1
  15. package/dist/chunks/{globals.BGT_RUsD.js → globals.DOh96BiR.js} +5 -5
  16. package/dist/chunks/{index.DEPqWSIZ.js → index.BY4-tcno.js} +33 -16
  17. package/dist/chunks/{index.Bgo3tNWt.js → index.DAL392Ss.js} +40 -15
  18. package/dist/chunks/{index.RwjEGCQ0.js → index.DIFZf73e.js} +2 -2
  19. package/dist/chunks/{index.CWIFvlX5.js → index.DfKyPFVi.js} +159 -54
  20. package/dist/chunks/{index.CVpyv-Zg.js → index.kotH7DY7.js} +832 -373
  21. package/dist/chunks/{index.jMQYiEWE.js → index.op2Re5rn.js} +22 -12
  22. package/dist/chunks/{init-forks.IU-xQ2_X.js → init-forks.2hx7cf78.js} +14 -4
  23. package/dist/chunks/{init-threads.C_NWvZkU.js → init-threads.Cm4OCIWA.js} +1 -1
  24. package/dist/chunks/{init.fmH9J833.js → init.DMDG-idf.js} +53 -30
  25. package/dist/chunks/{inspector.DLZxSeU3.js → inspector.CvyFGlXm.js} +25 -10
  26. package/dist/chunks/{moduleRunner.d.DEkTotCv.d.ts → moduleRunner.d.CzOZ_4wC.d.ts} +1 -1
  27. package/dist/chunks/{node.BwAWWjHZ.js → node.Ce0vMQM7.js} +1 -1
  28. package/dist/chunks/{plugin.d.Cpes8Bt6.d.ts → plugin.d.D4RrtywJ.d.ts} +1 -1
  29. package/dist/chunks/{reporters.d.CSNcMDxF.d.ts → reporters.d.Da1D1VbQ.d.ts} +6 -5
  30. package/dist/chunks/{rpc.D38ahn14.js → rpc.BUV7uWKJ.js} +20 -7
  31. package/dist/chunks/{setup-common.DR1sucx6.js → setup-common.LGjNSzXp.js} +20 -8
  32. package/dist/chunks/{startModuleRunner.Cn7hCL7D.js → startModuleRunner.BOmUtLIO.js} +206 -83
  33. package/dist/chunks/{test.B6aJd6T3.js → test.ClrAtjMv.js} +48 -22
  34. package/dist/chunks/{utils.CG9h5ccR.js → utils.DvEY5TfP.js} +14 -5
  35. package/dist/chunks/{vi.BZvkKVkM.js → vi.Bgcdy3bQ.js} +261 -111
  36. package/dist/chunks/{vm.BL7_zzOr.js → vm.BIkCDs68.js} +177 -71
  37. package/dist/chunks/{worker.d.D25zYZ7N.d.ts → worker.d.DadbA89M.d.ts} +30 -2
  38. package/dist/cli.js +2 -2
  39. package/dist/config.d.ts +5 -5
  40. package/dist/coverage.d.ts +3 -3
  41. package/dist/coverage.js +1 -1
  42. package/dist/environments.js +1 -1
  43. package/dist/index.d.ts +5 -5
  44. package/dist/index.js +5 -5
  45. package/dist/module-evaluator.d.ts +2 -2
  46. package/dist/module-evaluator.js +85 -35
  47. package/dist/module-runner.js +2 -2
  48. package/dist/node.d.ts +7 -7
  49. package/dist/node.js +16 -12
  50. package/dist/reporters.d.ts +3 -3
  51. package/dist/reporters.js +2 -2
  52. package/dist/runners.js +7 -7
  53. package/dist/snapshot.js +2 -2
  54. package/dist/suite.js +2 -2
  55. package/dist/worker.d.ts +1 -1
  56. package/dist/worker.js +15 -15
  57. package/dist/workers/forks.js +16 -16
  58. package/dist/workers/runVmTests.js +41 -22
  59. package/dist/workers/threads.js +16 -16
  60. package/dist/workers/vmForks.js +11 -11
  61. package/dist/workers/vmThreads.js +11 -11
  62. package/package.json +20 -20
  63. package/dist/chunks/console.CTJL2nuH.js +0 -115
@@ -1,9 +1,9 @@
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.fmH9J833.js';
4
+ import { l as loadEnvironment } from './init.DMDG-idf.js';
5
5
  import { distDir } from '../path.js';
6
- import { createCustomConsole } from './console.CTJL2nuH.js';
6
+ import { createCustomConsole } from './console.Cf-YriPC.js';
7
7
  import fs from 'node:fs';
8
8
  import { createRequire, Module, isBuiltin } from 'node:module';
9
9
  import { toArray, isBareImport } from '@vitest/utils/helpers';
@@ -11,8 +11,8 @@ 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.Cn7hCL7D.js';
15
- import { p as provideWorkerState } from './utils.CG9h5ccR.js';
14
+ import { s as startVitestModuleRunner, c as createNodeImportMeta, a as VITEST_VM_CONTEXT_SYMBOL } from './startModuleRunner.BOmUtLIO.js';
15
+ import { p as provideWorkerState } from './utils.DvEY5TfP.js';
16
16
 
17
17
  function interopCommonJsModule(interopDefault, mod) {
18
18
  if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) return {
@@ -21,8 +21,11 @@ function interopCommonJsModule(interopDefault, mod) {
21
21
  defaultExport: mod
22
22
  };
23
23
  if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) {
24
- const defaultKets = Object.keys(mod.default), moduleKeys = Object.keys(mod), allKeys = new Set([...defaultKets, ...moduleKeys]);
25
- return allKeys.delete("default"), {
24
+ const defaultKets = Object.keys(mod.default);
25
+ const moduleKeys = Object.keys(mod);
26
+ const allKeys = new Set([...defaultKets, ...moduleKeys]);
27
+ allKeys.delete("default");
28
+ return {
26
29
  keys: Array.from(allKeys),
27
30
  moduleExports: new Proxy(mod, { get(mod, prop) {
28
31
  return mod[prop] ?? mod.default?.[prop];
@@ -42,7 +45,8 @@ function isPrimitive(obj) {
42
45
  const SyntheticModule = vm.SyntheticModule;
43
46
  const SourceTextModule = vm.SourceTextModule;
44
47
 
45
- const _require = createRequire(import.meta.url), requiresCache = /* @__PURE__ */ new WeakMap();
48
+ const _require = createRequire(import.meta.url);
49
+ const requiresCache = /* @__PURE__ */ new WeakMap();
46
50
  class CommonjsExecutor {
47
51
  context;
48
52
  requireCache = /* @__PURE__ */ new Map();
@@ -54,8 +58,12 @@ class CommonjsExecutor {
54
58
  Module;
55
59
  interopDefault;
56
60
  constructor(options) {
57
- this.context = options.context, this.fs = options.fileMap, this.interopDefault = options.interopDefault;
58
- const primitives = vm.runInContext("({ Object, Array, Error })", this.context), executor = this;
61
+ this.context = options.context;
62
+ this.fs = options.fileMap;
63
+ this.interopDefault = options.interopDefault;
64
+ const primitives = vm.runInContext("({ Object, Array, Error })", this.context);
65
+ // eslint-disable-next-line ts/no-this-alias
66
+ const executor = this;
59
67
  this.Module = class Module$1 {
60
68
  exports;
61
69
  isPreloading = false;
@@ -67,13 +75,20 @@ class CommonjsExecutor {
67
75
  path;
68
76
  paths = [];
69
77
  constructor(id = "", parent) {
70
- this.exports = primitives.Object.create(Object.prototype), this.path = dirname(id), this.id = id, this.filename = id, this.loaded = false, this.parent = parent;
78
+ this.exports = primitives.Object.create(Object.prototype);
79
+ // in our case the path should always be resolved already
80
+ this.path = dirname(id);
81
+ this.id = id;
82
+ this.filename = id;
83
+ this.loaded = false;
84
+ this.parent = parent;
71
85
  }
72
86
  get require() {
73
87
  const require = requiresCache.get(this);
74
88
  if (require) return require;
75
89
  const _require = Module$1.createRequire(this.id);
76
- return requiresCache.set(this, _require), _require;
90
+ requiresCache.set(this, _require);
91
+ return _require;
77
92
  }
78
93
  static getSourceMapsSupport = () => ({
79
94
  enabled: false,
@@ -90,16 +105,19 @@ class CommonjsExecutor {
90
105
  throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`);
91
106
  };
92
107
  _compile(code, filename) {
93
- const cjsModule = Module$1.wrap(code), script = new vm.Script(cjsModule, {
108
+ const cjsModule = Module$1.wrap(code);
109
+ const script = new vm.Script(cjsModule, {
94
110
  filename,
95
111
  importModuleDynamically: options.importModuleDynamically
96
112
  });
97
113
  // @ts-expect-error mark script with current identifier
98
114
  script.identifier = filename;
99
- const fn = script.runInContext(executor.context), __dirname = dirname(filename);
115
+ const fn = script.runInContext(executor.context);
116
+ const __dirname = dirname(filename);
100
117
  executor.requireCache.set(filename, this);
101
118
  try {
102
- return fn(this.exports, this.require, this, filename, __dirname), this.exports;
119
+ fn(this.exports, this.require, this, filename, __dirname);
120
+ return this.exports;
103
121
  } finally {
104
122
  this.loaded = true;
105
123
  }
@@ -144,7 +162,9 @@ class CommonjsExecutor {
144
162
  static stripTypeScriptTypes = Module.stripTypeScriptTypes;
145
163
  static findPackageJSON = Module.findPackageJSON;
146
164
  static Module = Module$1;
147
- }, this.extensions[".js"] = this.requireJs, this.extensions[".json"] = this.requireJson;
165
+ };
166
+ this.extensions[".js"] = this.requireJs;
167
+ this.extensions[".json"] = this.requireJson;
148
168
  }
149
169
  requireJs = (m, filename) => {
150
170
  const content = this.fs.readFile(filename);
@@ -155,17 +175,22 @@ class CommonjsExecutor {
155
175
  m.exports = JSON.parse(code);
156
176
  };
157
177
  createRequire = (filename) => {
158
- const _require = createRequire(filename), require = ((id) => {
178
+ const _require = createRequire(filename);
179
+ const require = ((id) => {
159
180
  const resolved = _require.resolve(id);
160
181
  if (extname(resolved) === ".node" || isBuiltin(resolved)) return this.requireCoreModule(resolved);
161
182
  const module = new this.Module(resolved);
162
183
  return this.loadCommonJSModule(module, resolved);
163
184
  });
164
- return require.resolve = _require.resolve, Object.defineProperty(require, "extensions", {
185
+ require.resolve = _require.resolve;
186
+ Object.defineProperty(require, "extensions", {
165
187
  get: () => this.extensions,
166
188
  set: () => {},
167
189
  configurable: true
168
- }), require.main = void 0, require.cache = this.publicRequireCache, require;
190
+ });
191
+ require.main = void 0;
192
+ require.cache = this.publicRequireCache;
193
+ return require;
169
194
  };
170
195
  createProxyCache() {
171
196
  return new Proxy(Object.create(null), {
@@ -188,39 +213,51 @@ class CommonjsExecutor {
188
213
  const cached = this.requireCache.get(filename);
189
214
  if (cached) return cached.exports;
190
215
  const extension = this.findLongestRegisteredExtension(filename);
191
- return (this.extensions[extension] || this.extensions[".js"])(module, filename), module.exports;
216
+ (this.extensions[extension] || this.extensions[".js"])(module, filename);
217
+ return module.exports;
192
218
  }
193
219
  findLongestRegisteredExtension(filename) {
194
220
  const name = basename(filename);
195
- let currentExtension, index, startIndex = 0;
221
+ let currentExtension;
222
+ let index;
223
+ let startIndex = 0;
196
224
  // eslint-disable-next-line no-cond-assign
197
225
  while ((index = name.indexOf(".", startIndex)) !== -1) {
198
- if (startIndex = index + 1, index === 0) continue;
199
- if (currentExtension = name.slice(index), this.extensions[currentExtension]) return currentExtension;
226
+ startIndex = index + 1;
227
+ if (index === 0) continue;
228
+ currentExtension = name.slice(index);
229
+ if (this.extensions[currentExtension]) return currentExtension;
200
230
  }
201
231
  return ".js";
202
232
  }
203
233
  getCoreSyntheticModule(identifier) {
204
234
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
205
- const exports = this.require(identifier), keys = Object.keys(exports), module = new SyntheticModule([...keys, "default"], () => {
235
+ const exports = this.require(identifier);
236
+ const keys = Object.keys(exports);
237
+ const module = new SyntheticModule([...keys, "default"], () => {
206
238
  for (const key of keys) module.setExport(key, exports[key]);
207
239
  module.setExport("default", exports);
208
240
  }, {
209
241
  context: this.context,
210
242
  identifier
211
243
  });
212
- return this.moduleCache.set(identifier, module), module;
244
+ this.moduleCache.set(identifier, module);
245
+ return module;
213
246
  }
214
247
  getCjsSyntheticModule(path, identifier) {
215
248
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
216
- const exports = this.require(path), { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports), module = new SyntheticModule([...keys, "default"], function() {
249
+ const exports = this.require(path);
250
+ // TODO: technically module should be parsed to find static exports, implement for strict mode in #2854
251
+ const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports);
252
+ const module = new SyntheticModule([...keys, "default"], function() {
217
253
  for (const key of keys) this.setExport(key, moduleExports[key]);
218
254
  this.setExport("default", defaultExport);
219
255
  }, {
220
256
  context: this.context,
221
257
  identifier
222
258
  });
223
- return this.moduleCache.set(identifier, module), module;
259
+ this.moduleCache.set(identifier, module);
260
+ return module;
224
261
  }
225
262
  // TODO: use this in strict mode, when available in #2854
226
263
  // private _getNamedCjsExports(path: string): Set<string> {
@@ -269,10 +306,13 @@ class CommonjsExecutor {
269
306
  const moduleExports = _require(identifier);
270
307
  if (identifier === "node:module" || identifier === "module") {
271
308
  const module = new this.Module("/module.js");
272
- return module.exports = this.Module, this.builtinCache[normalized] = module, module.exports;
309
+ module.exports = this.Module;
310
+ this.builtinCache[normalized] = module;
311
+ return module.exports;
273
312
  }
313
+ this.builtinCache[normalized] = _require.cache[normalized];
274
314
  // TODO: should we wrap module to rethrow context errors?
275
- return this.builtinCache[normalized] = _require.cache[normalized], moduleExports;
315
+ return moduleExports;
276
316
  }
277
317
  }
278
318
 
@@ -283,18 +323,21 @@ class EsmExecutor {
283
323
  context;
284
324
  #httpIp = IPnumber("127.0.0.0");
285
325
  constructor(executor, options) {
286
- this.executor = executor, this.context = options.context;
326
+ this.executor = executor;
327
+ this.context = options.context;
287
328
  }
288
329
  async evaluateModule(m) {
289
330
  if (m.status === "unlinked") this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)));
290
- if (await this.esmLinkMap.get(m), m.status === "linked") await m.evaluate();
331
+ await this.esmLinkMap.get(m);
332
+ if (m.status === "linked") await m.evaluate();
291
333
  return m;
292
334
  }
293
335
  async createEsModule(fileURL, getCode) {
294
336
  const cached = this.moduleCache.get(fileURL);
295
337
  if (cached) return cached;
296
338
  const promise = this.loadEsModule(fileURL, getCode);
297
- return this.moduleCache.set(fileURL, promise), promise;
339
+ this.moduleCache.set(fileURL, promise);
340
+ return promise;
298
341
  }
299
342
  async loadEsModule(fileURL, getCode) {
300
343
  const code = await getCode();
@@ -304,29 +347,34 @@ class EsmExecutor {
304
347
  const result = JSON.parse(code);
305
348
  this.setExport("default", result);
306
349
  });
307
- return this.moduleCache.set(fileURL, m), m;
350
+ this.moduleCache.set(fileURL, m);
351
+ return m;
308
352
  }
309
353
  const m = new SourceTextModule(code, {
310
354
  identifier: fileURL,
311
355
  context: this.context,
312
356
  importModuleDynamically: this.executor.importModuleDynamically,
313
357
  initializeImportMeta: (meta, mod) => {
314
- if (meta.url = mod.identifier, mod.identifier.startsWith("file:")) {
358
+ meta.url = mod.identifier;
359
+ if (mod.identifier.startsWith("file:")) {
315
360
  const filename = fileURLToPath(mod.identifier);
316
- meta.filename = filename, meta.dirname = dirname$1(filename);
361
+ meta.filename = filename;
362
+ meta.dirname = dirname$1(filename);
317
363
  }
318
364
  meta.resolve = (specifier, importer) => {
319
365
  return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier);
320
366
  };
321
367
  }
322
368
  });
323
- return this.moduleCache.set(fileURL, m), m;
369
+ this.moduleCache.set(fileURL, m);
370
+ return m;
324
371
  }
325
372
  async createWebAssemblyModule(fileUrl, getCode) {
326
373
  const cached = this.moduleCache.get(fileUrl);
327
374
  if (cached) return cached;
328
375
  const m = this.loadWebAssemblyModule(getCode(), fileUrl);
329
- return this.moduleCache.set(fileUrl, m), m;
376
+ this.moduleCache.set(fileUrl, m);
377
+ return m;
330
378
  }
331
379
  async createNetworkModule(fileUrl) {
332
380
  // https://nodejs.org/api/esm.html#https-and-http-imports
@@ -342,14 +390,18 @@ class EsmExecutor {
342
390
  async loadWebAssemblyModule(source, identifier) {
343
391
  const cached = this.moduleCache.get(identifier);
344
392
  if (cached) return cached;
345
- const wasmModule = await WebAssembly.compile(source), exports = WebAssembly.Module.exports(wasmModule), imports = WebAssembly.Module.imports(wasmModule), moduleLookup = {};
393
+ const wasmModule = await WebAssembly.compile(source);
394
+ const exports = WebAssembly.Module.exports(wasmModule);
395
+ const imports = WebAssembly.Module.imports(wasmModule);
396
+ const moduleLookup = {};
346
397
  for (const { module } of imports) if (moduleLookup[module] === void 0) moduleLookup[module] = await this.executor.resolveModule(module, identifier);
347
398
  const evaluateModule = (module) => this.evaluateModule(module);
348
399
  return new SyntheticModule(exports.map(({ name }) => name), async function() {
349
400
  const importsObject = {};
350
401
  for (const { module, name } of imports) {
351
402
  if (!importsObject[module]) importsObject[module] = {};
352
- await evaluateModule(moduleLookup[module]), importsObject[module][name] = moduleLookup[module].namespace[name];
403
+ await evaluateModule(moduleLookup[module]);
404
+ importsObject[module][name] = moduleLookup[module].namespace[name];
353
405
  }
354
406
  const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject);
355
407
  for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]);
@@ -369,12 +421,14 @@ class EsmExecutor {
369
421
  if (cached) return cached;
370
422
  const match = identifier.match(dataURIRegex);
371
423
  if (!match || !match.groups) throw new Error("Invalid data URI");
372
- const mime = match.groups.mime, encoding = match.groups.encoding;
424
+ const mime = match.groups.mime;
425
+ const encoding = match.groups.encoding;
373
426
  if (mime === "application/wasm") {
374
427
  if (!encoding) throw new Error("Missing data URI encoding");
375
428
  if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`);
376
429
  const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier);
377
- return this.moduleCache.set(identifier, module), module;
430
+ this.moduleCache.set(identifier, module);
431
+ return module;
378
432
  }
379
433
  let code = match.groups.code;
380
434
  if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code);
@@ -388,7 +442,8 @@ class EsmExecutor {
388
442
  context: this.context,
389
443
  identifier
390
444
  });
391
- return this.moduleCache.set(identifier, module), module;
445
+ this.moduleCache.set(identifier, module);
446
+ return module;
392
447
  }
393
448
  return this.createEsModule(identifier, () => code);
394
449
  }
@@ -402,11 +457,13 @@ function IPmask(maskSize) {
402
457
  return -1 << 32 - maskSize;
403
458
  }
404
459
 
405
- const CLIENT_ID = "/@vite/client", CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
460
+ const CLIENT_ID = "/@vite/client";
461
+ const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
406
462
  class ViteExecutor {
407
463
  esm;
408
464
  constructor(options) {
409
- this.options = options, this.esm = options.esmExecutor;
465
+ this.options = options;
466
+ this.esm = options.esmExecutor;
410
467
  }
411
468
  resolve = (identifier) => {
412
469
  if (identifier === CLIENT_ID) return identifier;
@@ -415,7 +472,10 @@ class ViteExecutor {
415
472
  return this.options.context.__vitest_worker__;
416
473
  }
417
474
  async createViteModule(fileUrl) {
418
- return fileUrl === CLIENT_FILE || fileUrl === CLIENT_ID ? this.createViteClientModule() : this.esm.resolveCachedModule(fileUrl) || this.esm.createEsModule(fileUrl, async () => {
475
+ if (fileUrl === CLIENT_FILE || fileUrl === CLIENT_ID) return this.createViteClientModule();
476
+ const cached = this.esm.resolveCachedModule(fileUrl);
477
+ if (cached) return cached;
478
+ return this.esm.createEsModule(fileUrl, async () => {
419
479
  try {
420
480
  const result = await this.options.transform(fileUrl);
421
481
  if (result.code) return result.code;
@@ -423,16 +483,20 @@ class ViteExecutor {
423
483
  // rethrow vite error if it cannot load the module because it's not resolved
424
484
  if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) {
425
485
  const error = new Error(`Cannot find module '${fileUrl}'`, { cause });
426
- throw error.code = "ERR_MODULE_NOT_FOUND", error;
486
+ error.code = "ERR_MODULE_NOT_FOUND";
487
+ throw error;
427
488
  }
428
489
  }
429
490
  throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
430
491
  });
431
492
  }
432
493
  createViteClientModule() {
433
- const identifier = CLIENT_ID, cached = this.esm.resolveCachedModule(identifier);
494
+ const identifier = CLIENT_ID;
495
+ const cached = this.esm.resolveCachedModule(identifier);
434
496
  if (cached) return cached;
435
- const stub = this.options.viteClientModule, moduleKeys = Object.keys(stub), module = new SyntheticModule(moduleKeys, function() {
497
+ const stub = this.options.viteClientModule;
498
+ const moduleKeys = Object.keys(stub);
499
+ const module = new SyntheticModule(moduleKeys, function() {
436
500
  moduleKeys.forEach((key) => {
437
501
  this.setExport(key, stub[key]);
438
502
  });
@@ -440,16 +504,23 @@ class ViteExecutor {
440
504
  context: this.options.context,
441
505
  identifier
442
506
  });
443
- return this.esm.cacheModule(identifier, module), module;
507
+ this.esm.cacheModule(identifier, module);
508
+ return module;
444
509
  }
445
510
  canResolve = (fileUrl) => {
446
511
  if (fileUrl === CLIENT_FILE) return true;
447
- const config = this.workerState.config.deps?.web || {}, [modulePath] = fileUrl.split("?");
448
- return !!(config.transformCss && CSS_LANGS_RE.test(modulePath) || config.transformAssets && KNOWN_ASSET_RE.test(modulePath) || toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath)));
512
+ const config = this.workerState.config.deps?.web || {};
513
+ const [modulePath] = fileUrl.split("?");
514
+ if (config.transformCss && CSS_LANGS_RE.test(modulePath)) return true;
515
+ if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) return true;
516
+ if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) return true;
517
+ return false;
449
518
  };
450
519
  }
451
520
 
452
- const { existsSync } = fs, nativeResolve = import.meta.resolve;
521
+ const { existsSync } = fs;
522
+ // always defined when we use vm pool
523
+ const nativeResolve = import.meta.resolve;
453
524
  // TODO: improve Node.js strict mode support in #2854
454
525
  class ExternalModulesExecutor {
455
526
  cjs;
@@ -460,21 +531,28 @@ class ExternalModulesExecutor {
460
531
  resolvers = [];
461
532
  #networkSupported = null;
462
533
  constructor(options) {
463
- this.options = options, this.context = options.context, this.fs = options.fileMap, this.esm = new EsmExecutor(this, { context: this.context }), this.cjs = new CommonjsExecutor({
534
+ this.options = options;
535
+ this.context = options.context;
536
+ this.fs = options.fileMap;
537
+ this.esm = new EsmExecutor(this, { context: this.context });
538
+ this.cjs = new CommonjsExecutor({
464
539
  context: this.context,
465
540
  importModuleDynamically: this.importModuleDynamically,
466
541
  fileMap: options.fileMap,
467
542
  interopDefault: options.interopDefault
468
- }), this.vite = new ViteExecutor({
543
+ });
544
+ this.vite = new ViteExecutor({
469
545
  esmExecutor: this.esm,
470
546
  context: this.context,
471
547
  transform: options.transform,
472
548
  viteClientModule: options.viteClientModule
473
- }), this.resolvers = [this.vite.resolve];
549
+ });
550
+ this.resolvers = [this.vite.resolve];
474
551
  }
475
552
  async import(identifier) {
476
553
  const module = await this.createModule(identifier);
477
- return await this.esm.evaluateModule(module), module.namespace;
554
+ await this.esm.evaluateModule(module);
555
+ return module.namespace;
478
556
  }
479
557
  require(identifier) {
480
558
  return this.cjs.require(identifier);
@@ -517,7 +595,9 @@ class ExternalModulesExecutor {
517
595
  url: identifier,
518
596
  path: identifier
519
597
  };
520
- const isFileUrl = identifier.startsWith("file://"), pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier, fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
598
+ const isFileUrl = identifier.startsWith("file://");
599
+ const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
600
+ const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
521
601
  let type;
522
602
  if (this.vite.canResolve(fileUrl)) type = "vite";
523
603
  else if (extension === ".mjs") type = "module";
@@ -539,7 +619,8 @@ class ExternalModulesExecutor {
539
619
  // https://github.com/nodejs/node/pull/49038
540
620
  if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) {
541
621
  const error = /* @__PURE__ */ new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
542
- throw error.code = "ERR_MODULE_NOT_FOUND", error;
622
+ error.code = "ERR_MODULE_NOT_FOUND";
623
+ throw error;
543
624
  }
544
625
  switch (type) {
545
626
  case "data": return this.esm.createDataModule(identifier);
@@ -568,48 +649,70 @@ class FileMap {
568
649
  const cached = this.fsCache.get(path);
569
650
  if (cached != null) return cached;
570
651
  const source = await promises.readFile(path, "utf-8");
571
- return this.fsCache.set(path, source), source;
652
+ this.fsCache.set(path, source);
653
+ return source;
572
654
  }
573
655
  readFile(path) {
574
656
  const cached = this.fsCache.get(path);
575
657
  if (cached != null) return cached;
576
658
  const source = readFileSync(path, "utf-8");
577
- return this.fsCache.set(path, source), source;
659
+ this.fsCache.set(path, source);
660
+ return source;
578
661
  }
579
662
  readBuffer(path) {
580
663
  const cached = this.fsBufferCache.get(path);
581
664
  if (cached != null) return cached;
582
665
  const buffer = readFileSync(path);
583
- return this.fsBufferCache.set(path, buffer), buffer;
666
+ this.fsBufferCache.set(path, buffer);
667
+ return buffer;
584
668
  }
585
669
  }
586
670
 
587
- const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href, fileMap = new FileMap(), packageCache = /* @__PURE__ */ new Map();
671
+ const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
672
+ const fileMap = new FileMap();
673
+ const packageCache = /* @__PURE__ */ new Map();
588
674
  async function runVmTests(method, state) {
589
- const { ctx, rpc } = state, beforeEnvironmentTime = performance.now(), { environment } = await loadEnvironment(ctx.environment.name, ctx.config.root, rpc);
590
- if (state.environment = environment, !environment.setupVM) {
591
- const envName = ctx.environment.name, packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
675
+ const { ctx, rpc } = state;
676
+ const beforeEnvironmentTime = performance.now();
677
+ const { environment } = await loadEnvironment(ctx.environment.name, ctx.config.root, rpc);
678
+ state.environment = environment;
679
+ if (!environment.setupVM) {
680
+ const envName = ctx.environment.name;
681
+ const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
592
682
  throw new TypeError(`Environment "${ctx.environment.name}" is not a valid environment. Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`);
593
683
  }
594
684
  const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {});
595
- if (state.durations.environment = performance.now() - beforeEnvironmentTime, process.env.VITEST_VM_POOL = "1", !vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
685
+ state.durations.environment = performance.now() - beforeEnvironmentTime;
686
+ process.env.VITEST_VM_POOL = "1";
687
+ if (!vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
596
688
  const context = vm.getVmContext();
597
689
  if (!isContext(context)) throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
598
- provideWorkerState(context, state), context.process = process, context.global = context, context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state), context.setImmediate = setImmediate, context.clearImmediate = clearImmediate;
599
- const stubs = getDefaultRequestStubs(context), externalModulesExecutor = new ExternalModulesExecutor({
690
+ provideWorkerState(context, state);
691
+ // this is unfortunately needed for our own dependencies
692
+ // we need to find a way to not rely on this by default
693
+ // because browser doesn't provide these globals
694
+ context.process = process;
695
+ context.global = context;
696
+ context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state);
697
+ // TODO: don't hardcode setImmediate in fake timers defaults
698
+ context.setImmediate = setImmediate;
699
+ context.clearImmediate = clearImmediate;
700
+ const stubs = getDefaultRequestStubs(context);
701
+ const externalModulesExecutor = new ExternalModulesExecutor({
600
702
  context,
601
703
  fileMap,
602
704
  packageCache,
603
705
  transform: rpc.transform,
604
706
  viteClientModule: stubs["/@vite/client"]
605
- }), moduleRunner = startVitestModuleRunner({
707
+ });
708
+ const moduleRunner = startVitestModuleRunner({
606
709
  context,
607
710
  evaluatedModules: state.evaluatedModules,
608
711
  state,
609
712
  externalModulesExecutor,
610
713
  createImportMeta: createNodeImportMeta
611
714
  });
612
- if (Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
715
+ Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
613
716
  value: {
614
717
  context,
615
718
  externalModulesExecutor
@@ -617,13 +720,16 @@ async function runVmTests(method, state) {
617
720
  configurable: true,
618
721
  enumerable: false,
619
722
  writable: false
620
- }), context.__vitest_mocker__ = moduleRunner.mocker, ctx.config.serializedDefines) try {
723
+ });
724
+ context.__vitest_mocker__ = moduleRunner.mocker;
725
+ if (ctx.config.serializedDefines) try {
621
726
  runInContext(ctx.config.serializedDefines, context, { filename: "virtual:load-defines.js" });
622
727
  } catch (error) {
623
728
  throw new Error(`Failed to load custom "defines": ${error.message}`);
624
729
  }
625
730
  await moduleRunner.mocker.initializeSpyModule();
626
- const { run } = await moduleRunner.import(entryFile), fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
731
+ const { run } = await moduleRunner.import(entryFile);
732
+ const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
627
733
  filepath: f,
628
734
  testLocations: void 0
629
735
  } : f);
@@ -43,7 +43,8 @@ type LabelColor = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "c
43
43
  type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
44
44
  type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
45
45
  type PromisifyFn<T> = ReturnType<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType<T>>>;
46
- type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined;
46
+ type Thenable<T> = T | PromiseLike<T>;
47
+ type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => Thenable<((...args: unknown[]) => unknown) | undefined>;
47
48
  interface ChannelOptions {
48
49
  /**
49
50
  * Function to post raw message
@@ -91,6 +92,14 @@ interface EventOptions<Remote> {
91
92
  * For advanced use cases only
92
93
  */
93
94
  resolver?: BirpcResolver;
95
+ /**
96
+ * Hook triggered before an event is sent to the remote
97
+ *
98
+ * @param req - Request parameters
99
+ * @param next - Function to continue the request
100
+ * @param resolve - Function to resolve the response directly
101
+ */
102
+ onRequest?: (req: Request, next: (req?: Request) => Promise<any>, resolve: (res: any) => void) => void | Promise<void>;
94
103
  /**
95
104
  * Custom error handler
96
105
  *
@@ -121,7 +130,7 @@ type BirpcFn<T> = PromisifyFn<T> & {
121
130
  /**
122
131
  * Send event without asking for response
123
132
  */
124
- asEvent: (...args: ArgumentsType<T>) => void;
133
+ asEvent: (...args: ArgumentsType<T>) => Promise<void>;
125
134
  };
126
135
  type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
127
136
  [K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
@@ -138,6 +147,25 @@ interface PromiseEntry {
138
147
  method: string;
139
148
  timeoutId?: ReturnType<typeof setTimeout>;
140
149
  }
150
+ declare const TYPE_REQUEST: "q";
151
+ interface Request {
152
+ /**
153
+ * Type
154
+ */
155
+ t: typeof TYPE_REQUEST;
156
+ /**
157
+ * ID
158
+ */
159
+ i?: string;
160
+ /**
161
+ * Method
162
+ */
163
+ m: string;
164
+ /**
165
+ * Arguments
166
+ */
167
+ a: any[];
168
+ }
141
169
  declare const setTimeout: typeof globalThis.setTimeout;
142
170
 
143
171
  interface RuntimeRPC {
package/dist/cli.js CHANGED
@@ -1,10 +1,10 @@
1
- import { c as createCLI } from './chunks/cac.G9DAn-c7.js';
1
+ import { c as createCLI } from './chunks/cac.CfkWq8Qy.js';
2
2
  import '@vitest/utils/helpers';
3
3
  import 'events';
4
4
  import 'pathe';
5
5
  import 'tinyrainbow';
6
6
  import './chunks/constants.D_Q9UYh-.js';
7
- import './chunks/index.CVpyv-Zg.js';
7
+ import './chunks/index.kotH7DY7.js';
8
8
  import 'node:fs';
9
9
  import 'node:fs/promises';
10
10
  import 'node:perf_hooks';
package/dist/config.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { HookHandler, ConfigEnv, UserConfig } from 'vite';
2
2
  export { ConfigEnv, Plugin, UserConfig as ViteUserConfig, mergeConfig } from 'vite';
3
- import { I as InlineConfig, c as CoverageV8Options, R as ResolvedCoverageOptions, U as UserWorkspaceConfig, d as UserProjectConfigFn, e as UserProjectConfigExport } from './chunks/reporters.d.CSNcMDxF.js';
4
- export { a as TestProjectConfiguration, g as TestProjectInlineConfiguration, f as TestUserConfig, W as WatcherTriggerPattern } from './chunks/reporters.d.CSNcMDxF.js';
5
- import { V as VitestPluginContext } from './chunks/plugin.d.Cpes8Bt6.js';
3
+ import { I as InlineConfig, c as CoverageV8Options, R as ResolvedCoverageOptions, U as UserWorkspaceConfig, d as UserProjectConfigFn, e as UserProjectConfigExport } from './chunks/reporters.d.Da1D1VbQ.js';
4
+ export { a as TestProjectConfiguration, g as TestProjectInlineConfiguration, f as TestUserConfig, W as WatcherTriggerPattern } from './chunks/reporters.d.Da1D1VbQ.js';
5
+ import { V as VitestPluginContext } from './chunks/plugin.d.D4RrtywJ.js';
6
6
  import { F as FakeTimerInstallOpts } from './chunks/config.d.BTfZNUu9.js';
7
7
  import '@vitest/runner';
8
8
  import '@vitest/utils';
9
- import './chunks/worker.d.D25zYZ7N.js';
9
+ import './chunks/worker.d.DadbA89M.js';
10
10
  import 'vite/module-runner';
11
11
  import './chunks/environment.d.CrsxCzP1.js';
12
12
  import '@vitest/snapshot';
@@ -14,7 +14,7 @@ import 'node:stream';
14
14
  import '@vitest/mocker';
15
15
  import '@vitest/utils/source-map';
16
16
  import 'vitest/browser';
17
- import './chunks/browser.d.-LKfRopd.js';
17
+ import './chunks/browser.d.DTTM2PTh.js';
18
18
  import '@vitest/pretty-format';
19
19
  import '@vitest/utils/diff';
20
20
  import '@vitest/expect';