vitest 1.1.3 → 1.2.1

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/dist/browser.d.ts +1 -1
  2. package/dist/browser.js +5 -31
  3. package/dist/chunks/{api-setup.mFKdEKxa.js → api-setup.omeaEsoT.js} +60 -6
  4. package/dist/chunks/{integrations-globals.tnKXwyh5.js → integrations-globals.9QpVy4UR.js} +9 -8
  5. package/dist/chunks/{runtime-console.hf2msWA9.js → runtime-console.Iloo9fIt.js} +2 -2
  6. package/dist/{entry.js → chunks/runtime-runBaseTests.S8ZSFig3.js} +20 -18
  7. package/dist/cli-wrapper.js +1 -1
  8. package/dist/cli.js +15 -15
  9. package/dist/config.cjs +12 -1
  10. package/dist/config.d.ts +1 -71
  11. package/dist/config.js +12 -2
  12. package/dist/coverage.d.ts +1 -1
  13. package/dist/environments.d.ts +1 -1
  14. package/dist/environments.js +1 -1
  15. package/dist/execute.d.ts +8 -6
  16. package/dist/execute.js +4 -7
  17. package/dist/index.d.ts +4 -4
  18. package/dist/index.js +8 -7
  19. package/dist/node.d.ts +3 -3
  20. package/dist/node.js +13 -13
  21. package/dist/{reporters-qc5Smpt5.d.ts → reporters-rzC174PQ.d.ts} +188 -29
  22. package/dist/reporters.d.ts +1 -1
  23. package/dist/reporters.js +5 -5
  24. package/dist/runners.d.ts +1 -1
  25. package/dist/runners.js +7 -5
  26. package/dist/{suite-WwpgKT7k.d.ts → suite-MFRDkZcV.d.ts} +1 -1
  27. package/dist/suite.d.ts +2 -2
  28. package/dist/suite.js +3 -3
  29. package/dist/vendor/base.4sEqnqgY.js +38 -0
  30. package/dist/vendor/{base._79unx2z.js → base.QYERqzkH.js} +10 -1
  31. package/dist/vendor/{benchmark.WVm6DARl.js → benchmark.IlKmJkUU.js} +1 -1
  32. package/dist/vendor/{constants.WSvnD_fn.js → constants.i1PoEnhr.js} +9 -1
  33. package/dist/vendor/{coverage.v6aD8iAh.js → coverage.E7sG1b3r.js} +1 -1
  34. package/dist/vendor/{environments.QJtma9XQ.js → environments.sU0TD7wX.js} +19 -7
  35. package/dist/vendor/execute.edwByI27.js +589 -0
  36. package/dist/vendor/{global.L7JRz1qU.js → global.CkGT_TMy.js} +10 -1
  37. package/dist/vendor/{index.h0j9y5vy.js → index.kwCLJK4i.js} +5 -5
  38. package/dist/vendor/{index.XU72Rmy8.js → index.rJjbcrrp.js} +1 -1
  39. package/dist/vendor/{index.IhksUGLR.js → index.vs_-lzuF.js} +6 -6
  40. package/dist/vendor/{node.wTZytysZ.js → node.p6h5JSuL.js} +694 -286
  41. package/dist/vendor/{reporters.7Y4WN6gc.js → reporters.cA9x-5v-.js} +8 -5
  42. package/dist/vendor/{rpc.Bl-ysZIr.js → rpc.w4v8oCkK.js} +23 -2
  43. package/dist/vendor/{run-once.X3E7xx3F.js → run-once.Olz_Zkd8.js} +2 -2
  44. package/dist/vendor/setup-common.4GIL70qB.js +29 -0
  45. package/dist/vendor/utils.GbToHGHI.js +41 -0
  46. package/dist/vendor/{vi.DTC--YO5.js → vi.Bw2UL9c9.js} +21 -8
  47. package/dist/vendor/vm.9N6CwTZh.js +696 -0
  48. package/dist/worker.js +109 -82
  49. package/dist/workers/forks.js +33 -0
  50. package/dist/{entry-vm.js → workers/runVmTests.js} +20 -16
  51. package/dist/workers/threads.js +26 -0
  52. package/dist/workers/vmForks.js +43 -0
  53. package/dist/workers/vmThreads.js +36 -0
  54. package/dist/workers.d.ts +36 -0
  55. package/dist/workers.js +30 -0
  56. package/package.json +12 -8
  57. package/workers.d.ts +1 -0
  58. package/dist/child.js +0 -125
  59. package/dist/vendor/execute.cedv4NLQ.js +0 -1235
  60. package/dist/vendor/inspector.lFAeuaAt.js +0 -26
  61. package/dist/vendor/loader.L9CYwKn1.js +0 -39
  62. package/dist/vm.js +0 -126
  63. /package/dist/{paths.js → path.js} +0 -0
@@ -1,10 +1,10 @@
1
- import { relative, resolve, basename, dirname, join, extname, normalize, toNamespacedPath } from 'pathe';
1
+ import { resolve, relative, basename, dirname, join, extname, normalize, toNamespacedPath } from 'pathe';
2
2
  import { parseAstAsync, loadConfigFromFile, searchForWorkspaceRoot, version as version$2, createServer, mergeConfig } from 'vite';
3
3
  import path$8 from 'node:path';
4
4
  import url, { fileURLToPath } from 'node:url';
5
5
  import process$2 from 'node:process';
6
6
  import fs$8, { promises, existsSync, readFileSync } from 'node:fs';
7
- import { E as EXIT_CODE_RESTART, c as configFiles, d as defaultPort, a as defaultBrowserPort, w as workspacesFiles, C as CONFIG_NAMES } from './constants.WSvnD_fn.js';
7
+ import { c as configFiles, d as defaultPort, e as extraInlineDeps, a as defaultBrowserPort, E as EXIT_CODE_RESTART, w as workspacesFiles, C as CONFIG_NAMES } from './constants.i1PoEnhr.js';
8
8
  import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './_commonjsHelpers.jjO7Zipk.js';
9
9
  import require$$0 from 'os';
10
10
  import p$1 from 'path';
@@ -13,39 +13,39 @@ import require$$0$1 from 'stream';
13
13
  import require$$2 from 'events';
14
14
  import require$$0$2 from 'fs';
15
15
  import c from 'picocolors';
16
- import { slash as slash$2, normalizeRequestId, cleanUrl } from 'vite-node/utils';
17
16
  import { ViteNodeRunner } from 'vite-node/client';
18
17
  import { SnapshotManager } from '@vitest/snapshot/manager';
19
18
  import { ViteNodeServer } from 'vite-node/server';
20
- import { r as removeUndefinedValues, a as isWindows } from './index.XU72Rmy8.js';
21
- import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.v6aD8iAh.js';
22
- import { rootDir } from '../paths.js';
19
+ import { r as removeUndefinedValues, a as isWindows } from './index.rJjbcrrp.js';
20
+ import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.E7sG1b3r.js';
21
+ import { rootDir } from '../path.js';
23
22
  import v8 from 'node:v8';
24
23
  import * as nodeos from 'node:os';
25
24
  import nodeos__default from 'node:os';
26
25
  import EventEmitter from 'node:events';
27
26
  import Tinypool$1, { Tinypool } from 'tinypool';
28
27
  import { c as createBirpc } from './index.cAUulNDf.js';
29
- import { g as groupBy, A as AggregateErrorPonyfill, s as slash$1, t as toArray, i as isPrimitive, d as deepMerge, n as noop$1, a as stdout } from './base._79unx2z.js';
28
+ import { g as groupBy, A as AggregateErrorPonyfill, b as slash$1, t as toArray, a as isPrimitive, d as deepMerge, n as noop$1, c as stdout } from './base.QYERqzkH.js';
30
29
  import { MessageChannel } from 'node:worker_threads';
31
- import { createDefer, shuffle, inspect, positionToOffset, lineSplitRE, toArray as toArray$1, notNullish } from '@vitest/utils';
30
+ import { createDefer, shuffle, highlight, inspect, positionToOffset, lineSplitRE, toArray as toArray$1, notNullish } from '@vitest/utils';
32
31
  import { writeFile, rm } from 'node:fs/promises';
33
32
  import { performance } from 'node:perf_hooks';
34
33
  import { execa } from 'execa';
35
34
  import { TraceMap, generatedPositionFor, parseErrorStacktrace } from '@vitest/utils/source-map';
36
- import { createRequire } from 'node:module';
37
- import { isPackageExists, resolveModule } from 'local-pkg';
38
- import { isCI, provider as provider$1 } from 'std-env';
39
35
  import ge from 'module';
40
36
  import { ancestor, findNodeAround } from 'acorn-walk';
41
- import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks, hasFailed } from '@vitest/runner/utils';
42
- import { R as ReportersMap, B as BenchmarkReportsMap, s as stripAnsi, a as ansiStyles, b as sliceAnsi, d as divider, F as F_POINTER, c as cliTruncate } from './reporters.7Y4WN6gc.js';
37
+ import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks, hasFailed, getTests } from '@vitest/runner/utils';
38
+ import { R as ReportersMap, B as BenchmarkReportsMap, s as stripAnsi, a as ansiStyles, b as sliceAnsi, d as divider, F as F_POINTER, c as cliTruncate } from './reporters.cA9x-5v-.js';
39
+ import { resolveModule, isPackageExists } from 'local-pkg';
40
+ import { isCI, provider as provider$1 } from 'std-env';
43
41
  import crypto, { createHash } from 'node:crypto';
42
+ import { slash as slash$2, normalizeRequestId, cleanUrl } from 'vite-node/utils';
44
43
  import require$$0$3 from 'assert';
45
44
  import MagicString from 'magic-string';
46
45
  import { esmWalker } from '@vitest/utils/ast';
47
46
  import { stripLiteral } from 'strip-literal';
48
- import { g as getEnvPackageName } from './environments.QJtma9XQ.js';
47
+ import { createRequire } from 'node:module';
48
+ import { g as getEnvPackageName } from './environments.sU0TD7wX.js';
49
49
  import readline from 'node:readline';
50
50
  import require$$0$4 from 'readline';
51
51
 
@@ -64,42 +64,7 @@ function _mergeNamespaces(n, m) {
64
64
  return Object.freeze(n);
65
65
  }
66
66
 
67
- var version$1 = "1.1.3";
68
-
69
- const __dirname$1 = url.fileURLToPath(new URL(".", import.meta.url));
70
- async function ensurePackageInstalled(dependency, root) {
71
- if (process.versions.pnp) {
72
- const targetRequire = createRequire(__dirname$1);
73
- try {
74
- targetRequire.resolve(dependency, { paths: [root, __dirname$1] });
75
- return true;
76
- } catch (error) {
77
- }
78
- }
79
- if (isPackageExists(dependency, { paths: [root, __dirname$1] }))
80
- return true;
81
- const promptInstall = !isCI && process.stdout.isTTY;
82
- process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'
83
-
84
- `));
85
- if (!promptInstall)
86
- return false;
87
- const prompts = await Promise.resolve().then(function () { return index; });
88
- const { install } = await prompts.prompt({
89
- type: "confirm",
90
- name: "install",
91
- message: c.reset(`Do you want to install ${c.green(dependency)}?`)
92
- });
93
- if (install) {
94
- await (await import('../chunks/install-pkg.LE8oaA1t.js')).installPackage(dependency, { dev: true });
95
- process.stderr.write(c.yellow(`
96
- Package ${dependency} installed, re-run the command to start.
97
- `));
98
- process.exit(EXIT_CODE_RESTART);
99
- return true;
100
- }
101
- return false;
102
- }
67
+ var version$1 = "1.2.1";
103
68
 
104
69
  /*
105
70
  How it works:
@@ -3142,14 +3107,15 @@ async function groupFilesByEnv(files) {
3142
3107
  const transformMode = getTransformMode(project.config.testTransformMode, file);
3143
3108
  const envOptions = JSON.parse(((_b = code.match(/@(?:vitest|jest)-environment-options\s+?(.+)/)) == null ? void 0 : _b[1]) || "null");
3144
3109
  const envKey = env === "happy-dom" ? "happyDOM" : env;
3110
+ const environment = {
3111
+ name: env,
3112
+ transformMode,
3113
+ options: envOptions ? { [envKey]: envOptions } : null
3114
+ };
3145
3115
  return {
3146
3116
  file,
3147
3117
  project,
3148
- environment: {
3149
- name: env,
3150
- transformMode,
3151
- options: envOptions ? { [envKey]: envOptions } : null
3152
- }
3118
+ environment
3153
3119
  };
3154
3120
  }));
3155
3121
  return groupBy(filesWithEnv, ({ environment }) => environment.name);
@@ -3158,10 +3124,6 @@ async function groupFilesByEnv(files) {
3158
3124
  function createMethodsRPC(project) {
3159
3125
  const ctx = project.ctx;
3160
3126
  return {
3161
- async onWorkerExit(error, code) {
3162
- await ctx.logger.printError(error, { type: "Unexpected Exit", fullStack: true });
3163
- process.exit(code || 1);
3164
- },
3165
3127
  snapshotSaved(snapshot) {
3166
3128
  ctx.snapshot.add(snapshot);
3167
3129
  },
@@ -3188,11 +3150,11 @@ function createMethodsRPC(project) {
3188
3150
  },
3189
3151
  onPathsCollected(paths) {
3190
3152
  ctx.state.collectPaths(paths);
3191
- return project.report("onPathsCollected", paths);
3153
+ return ctx.report("onPathsCollected", paths);
3192
3154
  },
3193
3155
  onCollected(files) {
3194
3156
  ctx.state.collectFiles(files);
3195
- return project.report("onCollected", files);
3157
+ return ctx.report("onCollected", files);
3196
3158
  },
3197
3159
  onAfterSuiteRun(meta) {
3198
3160
  var _a;
@@ -3200,17 +3162,17 @@ function createMethodsRPC(project) {
3200
3162
  },
3201
3163
  onTaskUpdate(packs) {
3202
3164
  ctx.state.updateTasks(packs);
3203
- return project.report("onTaskUpdate", packs);
3165
+ return ctx.report("onTaskUpdate", packs);
3204
3166
  },
3205
3167
  onUserConsoleLog(log) {
3206
3168
  ctx.state.updateUserLog(log);
3207
- return project.report("onUserConsoleLog", log);
3169
+ ctx.report("onUserConsoleLog", log);
3208
3170
  },
3209
3171
  onUnhandledError(err, type) {
3210
3172
  ctx.state.catchError(err, type);
3211
3173
  },
3212
3174
  onFinished(files) {
3213
- return project.report("onFinished", files, ctx.state.getUnhandledErrors());
3175
+ return ctx.report("onFinished", files, ctx.state.getUnhandledErrors());
3214
3176
  },
3215
3177
  onCancel(reason) {
3216
3178
  ctx.cancelCurrentRun(reason);
@@ -3221,7 +3183,7 @@ function createMethodsRPC(project) {
3221
3183
  };
3222
3184
  }
3223
3185
 
3224
- function createChildProcessChannel(project) {
3186
+ function createChildProcessChannel$1(project) {
3225
3187
  const emitter = new EventEmitter();
3226
3188
  const cleanup = () => emitter.removeAllListeners();
3227
3189
  const events = { message: "message", response: "response" };
@@ -3246,21 +3208,22 @@ function createChildProcessChannel(project) {
3246
3208
  project.ctx.onCancel((reason) => rpc.onCancel(reason));
3247
3209
  return { channel, cleanup };
3248
3210
  }
3249
- function stringifyRegex(input) {
3211
+ function stringifyRegex$1(input) {
3250
3212
  if (typeof input === "string")
3251
3213
  return input;
3252
3214
  return `$$vitest:${input.toString()}`;
3253
3215
  }
3254
- function createChildProcessPool(ctx, { execArgv, env, forksPath }) {
3216
+ function createForksPool(ctx, { execArgv, env }) {
3255
3217
  var _a;
3256
3218
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
3257
3219
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
3258
3220
  const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.forks) ?? {};
3259
3221
  const maxThreads = poolOptions.maxForks ?? ctx.config.maxWorkers ?? threadsCount;
3260
3222
  const minThreads = poolOptions.minForks ?? ctx.config.minWorkers ?? threadsCount;
3223
+ const worker = resolve(ctx.distPath, "workers/forks.js");
3261
3224
  const options = {
3262
3225
  runtime: "child_process",
3263
- filename: forksPath,
3226
+ filename: resolve(ctx.distPath, "worker.js"),
3264
3227
  maxThreads,
3265
3228
  minThreads,
3266
3229
  env,
@@ -3283,9 +3246,11 @@ function createChildProcessPool(ctx, { execArgv, env, forksPath }) {
3283
3246
  let id = 0;
3284
3247
  async function runFiles(project, config, files, environment, invalidates = []) {
3285
3248
  ctx.state.clearFiles(project, files);
3286
- const { channel, cleanup } = createChildProcessChannel(project);
3249
+ const { channel, cleanup } = createChildProcessChannel$1(project);
3287
3250
  const workerId = ++id;
3288
3251
  const data = {
3252
+ pool: "forks",
3253
+ worker,
3289
3254
  config,
3290
3255
  files,
3291
3256
  invalidates,
@@ -3317,7 +3282,7 @@ function createChildProcessPool(ctx, { execArgv, env, forksPath }) {
3317
3282
  const config = {
3318
3283
  ..._config,
3319
3284
  // v8 serialize does not support regex
3320
- testNamePattern: _config.testNamePattern ? stringifyRegex(_config.testNamePattern) : void 0
3285
+ testNamePattern: _config.testNamePattern ? stringifyRegex$1(_config.testNamePattern) : void 0
3321
3286
  };
3322
3287
  configs.set(project, config);
3323
3288
  return config;
@@ -3346,7 +3311,7 @@ function createChildProcessPool(ctx, { execArgv, env, forksPath }) {
3346
3311
  const grouped = groupBy(files, ({ project, environment }) => project.getName() + environment.name + JSON.stringify(environment.options));
3347
3312
  for (const group of Object.values(grouped)) {
3348
3313
  results.push(...await Promise.allSettled(group.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates))));
3349
- await new Promise((resolve) => pool.queueSize === 0 ? resolve() : pool.once("drain", resolve));
3314
+ await new Promise((resolve2) => pool.queueSize === 0 ? resolve2() : pool.once("drain", resolve2));
3350
3315
  await pool.recycleWorkers();
3351
3316
  }
3352
3317
  }
@@ -3376,9 +3341,7 @@ function createChildProcessPool(ctx, { execArgv, env, forksPath }) {
3376
3341
  return {
3377
3342
  name: "forks",
3378
3343
  runTests: runWithFiles("run"),
3379
- close: async () => {
3380
- await pool.destroy();
3381
- }
3344
+ close: () => pool.destroy()
3382
3345
  };
3383
3346
  }
3384
3347
 
@@ -3401,15 +3364,16 @@ function createWorkerChannel$1(project) {
3401
3364
  project.ctx.onCancel((reason) => rpc.onCancel(reason));
3402
3365
  return { workerPort, port };
3403
3366
  }
3404
- function createThreadsPool(ctx, { execArgv, env, workerPath }) {
3367
+ function createThreadsPool(ctx, { execArgv, env }) {
3405
3368
  var _a;
3406
3369
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
3407
3370
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
3408
3371
  const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.threads) ?? {};
3409
3372
  const maxThreads = poolOptions.maxThreads ?? ctx.config.maxWorkers ?? threadsCount;
3410
3373
  const minThreads = poolOptions.minThreads ?? ctx.config.minWorkers ?? threadsCount;
3374
+ const worker = resolve(ctx.distPath, "workers/threads.js");
3411
3375
  const options = {
3412
- filename: workerPath,
3376
+ filename: resolve(ctx.distPath, "worker.js"),
3413
3377
  // TODO: investigate further
3414
3378
  // It seems atomics introduced V8 Fatal Error https://github.com/vitest-dev/vitest/issues/1191
3415
3379
  useAtomics: poolOptions.useAtomics ?? false,
@@ -3438,6 +3402,8 @@ function createThreadsPool(ctx, { execArgv, env, workerPath }) {
3438
3402
  const { workerPort, port } = createWorkerChannel$1(project);
3439
3403
  const workerId = ++id;
3440
3404
  const data = {
3405
+ pool: "threads",
3406
+ worker,
3441
3407
  port: workerPort,
3442
3408
  config,
3443
3409
  files,
@@ -3495,7 +3461,7 @@ function createThreadsPool(ctx, { execArgv, env, workerPath }) {
3495
3461
  const grouped = groupBy(files, ({ project, environment }) => project.getName() + environment.name + JSON.stringify(environment.options));
3496
3462
  for (const group of Object.values(grouped)) {
3497
3463
  results.push(...await Promise.allSettled(group.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates))));
3498
- await new Promise((resolve) => pool.queueSize === 0 ? resolve() : pool.once("drain", resolve));
3464
+ await new Promise((resolve2) => pool.queueSize === 0 ? resolve2() : pool.once("drain", resolve2));
3499
3465
  await pool.recycleWorkers();
3500
3466
  }
3501
3467
  }
@@ -3525,12 +3491,7 @@ function createThreadsPool(ctx, { execArgv, env, workerPath }) {
3525
3491
  return {
3526
3492
  name: "threads",
3527
3493
  runTests: runWithFiles("run"),
3528
- close: async () => {
3529
- var _a2;
3530
- const nodeVersion = Number((_a2 = process.version.match(/v(\d+)\.(\d+)/)) == null ? void 0 : _a2[0].slice(1));
3531
- if (nodeVersion >= 16.17)
3532
- await pool.destroy();
3533
- }
3494
+ close: () => pool.destroy()
3534
3495
  };
3535
3496
  }
3536
3497
 
@@ -3562,7 +3523,8 @@ function createBrowserPool(ctx) {
3562
3523
  });
3563
3524
  const provider = project.browserProvider;
3564
3525
  providers.add(provider);
3565
- const origin = `http://${((_a = ctx.config.browser.api) == null ? void 0 : _a.host) || "localhost"}:${project.browser.config.server.port}`;
3526
+ const resolvedUrls = (_a = project.browser) == null ? void 0 : _a.resolvedUrls;
3527
+ const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
3566
3528
  const paths = files.map((file) => relative(project.config.root, file));
3567
3529
  if (project.config.browser.isolate) {
3568
3530
  for (const path of paths) {
@@ -3668,7 +3630,7 @@ function stringToBytes(input, percentageReference) {
3668
3630
  return null;
3669
3631
  }
3670
3632
 
3671
- const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
3633
+ const suppressWarningsPath$1 = resolve(rootDir, "./suppress-warnings.cjs");
3672
3634
  function createWorkerChannel(project) {
3673
3635
  const channel = new MessageChannel();
3674
3636
  const port = channel.port2;
@@ -3688,15 +3650,16 @@ function createWorkerChannel(project) {
3688
3650
  project.ctx.onCancel((reason) => rpc.onCancel(reason));
3689
3651
  return { workerPort, port };
3690
3652
  }
3691
- function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3653
+ function createVmThreadsPool(ctx, { execArgv, env }) {
3692
3654
  var _a;
3693
3655
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
3694
3656
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
3695
3657
  const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.vmThreads) ?? {};
3696
3658
  const maxThreads = poolOptions.maxThreads ?? ctx.config.maxWorkers ?? threadsCount;
3697
3659
  const minThreads = poolOptions.minThreads ?? ctx.config.minWorkers ?? threadsCount;
3660
+ const worker = resolve(ctx.distPath, "workers/vmThreads.js");
3698
3661
  const options = {
3699
- filename: vmPath,
3662
+ filename: resolve(ctx.distPath, "worker.js"),
3700
3663
  // TODO: investigate further
3701
3664
  // It seems atomics introduced V8 Fatal Error https://github.com/vitest-dev/vitest/issues/1191
3702
3665
  useAtomics: poolOptions.useAtomics ?? false,
@@ -3707,13 +3670,13 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3707
3670
  "--experimental-import-meta-resolve",
3708
3671
  "--experimental-vm-modules",
3709
3672
  "--require",
3710
- suppressWarningsPath,
3673
+ suppressWarningsPath$1,
3711
3674
  ...poolOptions.execArgv ?? [],
3712
3675
  ...execArgv
3713
3676
  ],
3714
3677
  terminateTimeout: ctx.config.teardownTimeout,
3715
3678
  concurrentTasksPerWorker: 1,
3716
- maxMemoryLimitBeforeRecycle: getMemoryLimit(ctx.config) || void 0
3679
+ maxMemoryLimitBeforeRecycle: getMemoryLimit$1(ctx.config) || void 0
3717
3680
  };
3718
3681
  if (poolOptions.singleThread || !ctx.config.fileParallelism) {
3719
3682
  options.maxThreads = 1;
@@ -3727,6 +3690,8 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3727
3690
  const { workerPort, port } = createWorkerChannel(project);
3728
3691
  const workerId = ++id;
3729
3692
  const data = {
3693
+ pool: "vmThreads",
3694
+ worker,
3730
3695
  port: workerPort,
3731
3696
  config,
3732
3697
  files,
@@ -3771,15 +3736,10 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3771
3736
  return {
3772
3737
  name: "vmThreads",
3773
3738
  runTests: runWithFiles("run"),
3774
- close: async () => {
3775
- var _a2;
3776
- const nodeVersion = Number((_a2 = process.version.match(/v(\d+)\.(\d+)/)) == null ? void 0 : _a2[0].slice(1));
3777
- if (nodeVersion >= 16.17)
3778
- await pool.destroy();
3779
- }
3739
+ close: () => pool.destroy()
3780
3740
  };
3781
3741
  }
3782
- function getMemoryLimit(config) {
3742
+ function getMemoryLimit$1(config) {
3783
3743
  const memory = nodeos.totalmem();
3784
3744
  const limit = getWorkerMemoryLimit(config);
3785
3745
  if (typeof memory === "number") {
@@ -3799,7 +3759,7 @@ function B(e){return e.startsWith("\\\\?\\")?e:e.replace(/\\/g,"/")}const x=e=>{
3799
3759
  `;break;case 114:u+="\r";break;case 116:u+=" ";break;case 117:const O=L(4,!0);O>=0?u+=String.fromCharCode(O):c=4;break;default:c=5;}g=n;continue}if(f>=0&&f<=31)if(_(f)){u+=e.substring(g,n),c=2;break}else c=6;n++;}return u}function A(){if(t="",c=0,l=n,r=m,v=b,n>=i)return l=i,s=17;let u=e.charCodeAt(n);if(J(u)){do n++,t+=String.fromCharCode(u),u=e.charCodeAt(n);while(J(u));return s=15}if(_(u))return n++,t+=String.fromCharCode(u),u===13&&e.charCodeAt(n)===10&&(n++,t+=`
3800
3760
  `),m++,b=n,s=14;switch(u){case 123:return n++,s=1;case 125:return n++,s=2;case 91:return n++,s=3;case 93:return n++,s=4;case 58:return n++,s=6;case 44:return n++,s=5;case 34:return n++,t=k(),s=10;case 47:const g=n-1;if(e.charCodeAt(n+1)===47){for(n+=2;n<i&&!_(e.charCodeAt(n));)n++;return t=e.substring(g,n),s=12}if(e.charCodeAt(n+1)===42){n+=2;const f=i-1;let $=!1;for(;n<f;){const O=e.charCodeAt(n);if(O===42&&e.charCodeAt(n+1)===47){n+=2,$=!0;break}n++,_(O)&&(O===13&&e.charCodeAt(n)===10&&n++,m++,b=n);}return $||(n++,c=1),t=e.substring(g,n),s=13}return t+=String.fromCharCode(u),n++,s=16;case 45:if(t+=String.fromCharCode(u),n++,n===i||!N(e.charCodeAt(n)))return s=16;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return t+=w(),s=11;default:for(;n<i&&U(u);)n++,u=e.charCodeAt(n);if(l!==n){switch(t=e.substring(l,n),t){case"true":return s=8;case"false":return s=9;case"null":return s=7}return s=16}return t+=String.fromCharCode(u),n++,s=16}}function U(u){if(J(u)||_(u))return !1;switch(u){case 125:case 93:case 123:case 91:case 34:case 58:case 44:case 47:return !1}return !0}function F(){let u;do u=A();while(u>=12&&u<=15);return u}return {setPosition:T,getPosition:()=>n,scan:o?F:A,getToken:()=>s,getTokenValue:()=>t,getTokenOffset:()=>l,getTokenLength:()=>n-l,getTokenStartLine:()=>r,getTokenStartCharacter:()=>l-v,getTokenError:()=>c}}function J(e){return e===32||e===9}function _(e){return e===10||e===13}function N(e){return e>=48&&e<=57}var q;(function(e){e[e.lineFeed=10]="lineFeed",e[e.carriageReturn=13]="carriageReturn",e[e.space=32]="space",e[e._0=48]="_0",e[e._1=49]="_1",e[e._2=50]="_2",e[e._3=51]="_3",e[e._4=52]="_4",e[e._5=53]="_5",e[e._6=54]="_6",e[e._7=55]="_7",e[e._8=56]="_8",e[e._9=57]="_9",e[e.a=97]="a",e[e.b=98]="b",e[e.c=99]="c",e[e.d=100]="d",e[e.e=101]="e",e[e.f=102]="f",e[e.g=103]="g",e[e.h=104]="h",e[e.i=105]="i",e[e.j=106]="j",e[e.k=107]="k",e[e.l=108]="l",e[e.m=109]="m",e[e.n=110]="n",e[e.o=111]="o",e[e.p=112]="p",e[e.q=113]="q",e[e.r=114]="r",e[e.s=115]="s",e[e.t=116]="t",e[e.u=117]="u",e[e.v=118]="v",e[e.w=119]="w",e[e.x=120]="x",e[e.y=121]="y",e[e.z=122]="z",e[e.A=65]="A",e[e.B=66]="B",e[e.C=67]="C",e[e.D=68]="D",e[e.E=69]="E",e[e.F=70]="F",e[e.G=71]="G",e[e.H=72]="H",e[e.I=73]="I",e[e.J=74]="J",e[e.K=75]="K",e[e.L=76]="L",e[e.M=77]="M",e[e.N=78]="N",e[e.O=79]="O",e[e.P=80]="P",e[e.Q=81]="Q",e[e.R=82]="R",e[e.S=83]="S",e[e.T=84]="T",e[e.U=85]="U",e[e.V=86]="V",e[e.W=87]="W",e[e.X=88]="X",e[e.Y=89]="Y",e[e.Z=90]="Z",e[e.asterisk=42]="asterisk",e[e.backslash=92]="backslash",e[e.closeBrace=125]="closeBrace",e[e.closeBracket=93]="closeBracket",e[e.colon=58]="colon",e[e.comma=44]="comma",e[e.dot=46]="dot",e[e.doubleQuote=34]="doubleQuote",e[e.minus=45]="minus",e[e.openBrace=123]="openBrace",e[e.openBracket=91]="openBracket",e[e.plus=43]="plus",e[e.slash=47]="slash",e[e.formFeed=12]="formFeed",e[e.tab=9]="tab";})(q||(q={}));var I;(function(e){e.DEFAULT={allowTrailingComma:!1};})(I||(I={}));function Te(e,o=[],i=I.DEFAULT){let n=null,t=[];const l=[];function s(r){Array.isArray(t)?t.push(r):n!==null&&(t[n]=r);}return we(e,{onObjectBegin:()=>{const r={};s(r),l.push(t),t=r,n=null;},onObjectProperty:r=>{n=r;},onObjectEnd:()=>{t=l.pop();},onArrayBegin:()=>{const r=[];s(r),l.push(t),t=r,n=null;},onArrayEnd:()=>{t=l.pop();},onLiteralValue:s,onError:(r,b,v)=>{o.push({error:r,offset:b,length:v});}},i),t[0]}function we(e,o,i=I.DEFAULT){const n=be(e,!1),t=[];function l(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function s(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>t.slice()):()=>!0}function m(a){return a?j=>a(j,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function r(a){return a?j=>a(j,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>t.slice()):()=>!0}const b=s(o.onObjectBegin),v=r(o.onObjectProperty),c=l(o.onObjectEnd),L=s(o.onArrayBegin),T=l(o.onArrayEnd),w=r(o.onLiteralValue),k=m(o.onSeparator),A=l(o.onComment),U=m(o.onError),F=i&&i.disallowComments,u=i&&i.allowTrailingComma;function g(){for(;;){const a=n.scan();switch(n.getTokenError()){case 4:f(14);break;case 5:f(15);break;case 3:f(13);break;case 1:F||f(11);break;case 2:f(12);break;case 6:f(16);break}switch(a){case 12:case 13:F?f(10):A();break;case 16:f(1);break;case 15:case 14:break;default:return a}}}function f(a,j=[],Y=[]){if(U(a),j.length+Y.length>0){let y=n.getToken();for(;y!==17;){if(j.indexOf(y)!==-1){g();break}else if(Y.indexOf(y)!==-1)break;y=g();}}}function $(a){const j=n.getTokenValue();return a?w(j):(v(j),t.push(j)),g(),!0}function O(){switch(n.getToken()){case 11:const a=n.getTokenValue();let j=Number(a);isNaN(j)&&(f(2),j=0),w(j);break;case 7:w(null);break;case 8:w(!0);break;case 9:w(!1);break;default:return !1}return g(),!0}function ce(){return n.getToken()!==10?(f(3,[],[2,5]),!1):($(!1),n.getToken()===6?(k(":"),g(),V()||f(4,[],[2,5])):f(5,[],[2,5]),t.pop(),!0)}function fe(){b(),g();let a=!1;for(;n.getToken()!==2&&n.getToken()!==17;){if(n.getToken()===5){if(a||f(4,[],[]),k(","),g(),n.getToken()===2&&u)break}else a&&f(6,[],[]);ce()||f(4,[],[2,5]),a=!0;}return c(),n.getToken()!==2?f(7,[2],[]):g(),!0}function pe(){L(),g();let a=!0,j=!1;for(;n.getToken()!==4&&n.getToken()!==17;){if(n.getToken()===5){if(j||f(4,[],[]),k(","),g(),n.getToken()===4&&u)break}else j&&f(6,[],[]);a?(t.push(0),a=!1):t[t.length-1]++,V()||f(4,[],[4,5]),j=!0;}return T(),a||t.pop(),n.getToken()!==4?f(8,[4],[]):g(),!0}function V(){switch(n.getToken()){case 3:return pe();case 1:return fe();case 10:return $(!0);default:return O()}}return g(),n.getToken()===17?i.allowEmptyContent?!0:(f(4,[],[]),!1):V()?(n.getToken()!==17&&f(9,[],[]),!0):(f(4,[],[]),!1)}var K;(function(e){e[e.None=0]="None",e[e.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=2]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",e[e.InvalidUnicode=4]="InvalidUnicode",e[e.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",e[e.InvalidCharacter=6]="InvalidCharacter";})(K||(K={}));var C;(function(e){e[e.OpenBraceToken=1]="OpenBraceToken",e[e.CloseBraceToken=2]="CloseBraceToken",e[e.OpenBracketToken=3]="OpenBracketToken",e[e.CloseBracketToken=4]="CloseBracketToken",e[e.CommaToken=5]="CommaToken",e[e.ColonToken=6]="ColonToken",e[e.NullKeyword=7]="NullKeyword",e[e.TrueKeyword=8]="TrueKeyword",e[e.FalseKeyword=9]="FalseKeyword",e[e.StringLiteral=10]="StringLiteral",e[e.NumericLiteral=11]="NumericLiteral",e[e.LineCommentTrivia=12]="LineCommentTrivia",e[e.BlockCommentTrivia=13]="BlockCommentTrivia",e[e.LineBreakTrivia=14]="LineBreakTrivia",e[e.Trivia=15]="Trivia",e[e.Unknown=16]="Unknown",e[e.EOF=17]="EOF";})(C||(C={}));const ve=Te;var ee;(function(e){e[e.InvalidSymbol=1]="InvalidSymbol",e[e.InvalidNumberFormat=2]="InvalidNumberFormat",e[e.PropertyNameExpected=3]="PropertyNameExpected",e[e.ValueExpected=4]="ValueExpected",e[e.ColonExpected=5]="ColonExpected",e[e.CommaExpected=6]="CommaExpected",e[e.CloseBraceExpected=7]="CloseBraceExpected",e[e.CloseBracketExpected=8]="CloseBracketExpected",e[e.EndOfFileExpected=9]="EndOfFileExpected",e[e.InvalidCommentToken=10]="InvalidCommentToken",e[e.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=12]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",e[e.InvalidUnicode=14]="InvalidUnicode",e[e.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",e[e.InvalidCharacter=16]="InvalidCharacter";})(ee||(ee={}));const ne=(e,o)=>ve(ke(o,e,"utf8")),M=Symbol("implicitBaseUrl"),Oe=()=>{const{findPnpApi:e}=ge;return e&&e(process.cwd())},R=(e,o,i,n)=>{const t=`resolveFromPackageJsonPath:${e}:${o}:${i}`;if(n!=null&&n.has(t))return n.get(t);const l=ne(e,n);if(!l)return;let s=o||"tsconfig.json";if(!i&&l.exports)try{const[m]=v(l.exports,o,["require","types"]);s=m;}catch{return !1}else !o&&l.tsconfig&&(s=l.tsconfig);return s=p$1.join(e,"..",s),n==null||n.set(t,s),s},G="package.json",z="tsconfig.json",je=(e,o,i)=>{let n=e;if(e===".."&&(n=p$1.join(n,z)),e[0]==="."&&(n=p$1.resolve(o,n)),p$1.isAbsolute(n)){if(E(i,n)){if(P(i,n).isFile())return n}else if(!n.endsWith(".json")){const T=`${n}.json`;if(E(i,T))return T}return}const[t,...l]=e.split("/"),s=t[0]==="@"?`${t}/${l.shift()}`:t,m=l.join("/"),r=Oe();if(r){const{resolveRequest:T}=r;try{if(s===e){const w=T(p$1.join(s,G),o);if(w){const k=R(w,m,!1,i);if(k&&E(i,k))return k}}else {let w;try{w=T(e,o,{extensions:[".json"]});}catch{w=T(p$1.join(e,z),o);}if(w)return w}}catch{}}const b=Z(o,p$1.join("node_modules",s),i);if(!b||!P(i,b).isDirectory())return;const v=p$1.join(b,G);if(E(i,v)){const T=R(v,m,!1,i);if(T===!1)return;if(T&&E(i,T)&&P(i,T).isFile())return T}const c=p$1.join(b,m),L=c.endsWith(".json");if(!L){const T=`${c}.json`;if(E(i,T))return T}if(E(i,c)){if(P(i,c).isDirectory()){const T=p$1.join(c,G);if(E(i,T)){const k=R(T,"",!0,i);if(k&&E(i,k))return k}const w=p$1.join(c,z);if(E(i,w))return w}else if(L)return c}},Ae=(e,o,i,n)=>{const t=je(e,o,n);if(!t)throw new Error(`File '${e}' not found.`);if(i.has(t))throw new Error(`Circularity detected while resolving configuration: ${t}`);i.add(t);const l=p$1.dirname(t),s=te(t,n,i);delete s.references;const{compilerOptions:m}=s;if(m){const r=["baseUrl","outDir"];for(const b of r){const v=m[b];v&&(m[b]=B(p$1.relative(o,p$1.join(l,v)))||"./");}}return s.files&&(s.files=s.files.map(r=>B(p$1.relative(o,p$1.join(l,r))))),s.include&&(s.include=s.include.map(r=>B(p$1.relative(o,p$1.join(l,r))))),s.exclude&&(s.exclude=s.exclude.map(r=>B(p$1.relative(o,p$1.join(l,r))))),s},te=(e,o,i=new Set)=>{let n;try{n=ae(o,e);}catch{throw new Error(`Cannot resolve tsconfig at path: ${e}`)}let t=ne(n,o)||{};if(typeof t!="object")throw new SyntaxError(`Failed to parse tsconfig at: ${e}`);const l=p$1.dirname(n);if(t.compilerOptions){const{compilerOptions:s}=t;s.paths&&!s.baseUrl&&(s[M]=l);}if(t.extends){const s=Array.isArray(t.extends)?t.extends:[t.extends];delete t.extends;for(const m of s.reverse()){const r=Ae(m,l,i,o),b={...r,...t,compilerOptions:{...r.compilerOptions,...t.compilerOptions}};r.watchOptions&&(b.watchOptions={...r.watchOptions,...t.watchOptions}),t=b;}}if(t.compilerOptions){const{compilerOptions:s}=t,m=["baseUrl","rootDir"];for(const b of m){const v=s[b];if(v){const c=p$1.resolve(l,v),L=W(p$1.relative(l,c));s[b]=L;}}const{outDir:r}=s;r&&(Array.isArray(t.exclude)||(t.exclude=[]),t.exclude.includes(r)||t.exclude.push(r),s.outDir=W(r));}else t.compilerOptions={};if(t.files&&(t.files=t.files.map(W)),t.include&&(t.include=t.include.map(B)),t.watchOptions){const{watchOptions:s}=t;s.excludeDirectories&&(s.excludeDirectories=s.excludeDirectories.map(m=>B(p$1.resolve(l,m))));}return t},ie=(e,o=new Map)=>te(e,o),$e=(e=process.cwd(),o="tsconfig.json",i=new Map)=>{const n=Z(B(e),o,i);if(!n)return null;const t=ie(n,i);return {path:n,config:t}};p$1.posix;process.platform==="win32";
3801
3761
 
3802
- const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
3762
+ const __dirname$1 = url.fileURLToPath(new URL(".", import.meta.url));
3803
3763
  const newLineRegExp = /\r?\n/;
3804
3764
  const errCodeRegExp = /error TS(?<errCode>\d+)/;
3805
3765
  async function makeTscErrorInfo(errInfo) {
@@ -3847,7 +3807,7 @@ async function getTsconfig(root, config) {
3847
3807
  tmpTsConfig.compilerOptions.emitDeclarationOnly = false;
3848
3808
  tmpTsConfig.compilerOptions.incremental = true;
3849
3809
  tmpTsConfig.compilerOptions.tsBuildInfoFile = join(
3850
- process.versions.pnp ? join(nodeos__default.tmpdir(), "vitest") : __dirname,
3810
+ process.versions.pnp ? join(nodeos__default.tmpdir(), "vitest") : __dirname$1,
3851
3811
  "tsconfig.tmp.tsbuildinfo"
3852
3812
  );
3853
3813
  const tsconfigFinalContent = JSON.stringify(tmpTsConfig, null, 2);
@@ -4203,15 +4163,14 @@ class Typechecker {
4203
4163
  await this.clear();
4204
4164
  (_a = this.process) == null ? void 0 : _a.kill();
4205
4165
  }
4206
- async ensurePackageInstalled(root, checker) {
4166
+ async ensurePackageInstalled(ctx, checker) {
4207
4167
  if (checker !== "tsc" && checker !== "vue-tsc")
4208
4168
  return;
4209
4169
  const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
4210
- await ensurePackageInstalled(packageName, root);
4170
+ await ctx.packageInstaller.ensureInstalled(packageName, ctx.config.root);
4211
4171
  }
4212
4172
  async prepare() {
4213
4173
  const { root, typecheck } = this.ctx.config;
4214
- await this.ensurePackageInstalled(root, typecheck.checker);
4215
4174
  const { config, path } = await getTsconfig(root, typecheck);
4216
4175
  this.tempConfigPath = path;
4217
4176
  this.allowJs = typecheck.allowJs || config.allowJs || false;
@@ -4380,13 +4339,149 @@ function createTypecheckPool(ctx) {
4380
4339
  };
4381
4340
  }
4382
4341
 
4383
- const builtinPools = ["forks", "threads", "browser", "vmThreads", "typescript"];
4342
+ const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
4343
+ function createChildProcessChannel(project) {
4344
+ const emitter = new EventEmitter();
4345
+ const cleanup = () => emitter.removeAllListeners();
4346
+ const events = { message: "message", response: "response" };
4347
+ const channel = {
4348
+ onMessage: (callback) => emitter.on(events.message, callback),
4349
+ postMessage: (message) => emitter.emit(events.response, message)
4350
+ };
4351
+ const rpc = createBirpc(
4352
+ createMethodsRPC(project),
4353
+ {
4354
+ eventNames: ["onCancel"],
4355
+ serialize: v8.serialize,
4356
+ deserialize: (v) => v8.deserialize(Buffer.from(v)),
4357
+ post(v) {
4358
+ emitter.emit(events.message, v);
4359
+ },
4360
+ on(fn) {
4361
+ emitter.on(events.response, fn);
4362
+ }
4363
+ }
4364
+ );
4365
+ project.ctx.onCancel((reason) => rpc.onCancel(reason));
4366
+ return { channel, cleanup };
4367
+ }
4368
+ function stringifyRegex(input) {
4369
+ if (typeof input === "string")
4370
+ return input;
4371
+ return `$$vitest:${input.toString()}`;
4372
+ }
4373
+ function createVmForksPool(ctx, { execArgv, env }) {
4374
+ var _a;
4375
+ const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
4376
+ const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
4377
+ const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.vmForks) ?? {};
4378
+ const maxThreads = poolOptions.maxForks ?? ctx.config.maxWorkers ?? threadsCount;
4379
+ const minThreads = poolOptions.maxForks ?? ctx.config.minWorkers ?? threadsCount;
4380
+ const worker = resolve(ctx.distPath, "workers/vmForks.js");
4381
+ const options = {
4382
+ runtime: "child_process",
4383
+ filename: resolve(ctx.distPath, "worker.js"),
4384
+ maxThreads,
4385
+ minThreads,
4386
+ env,
4387
+ execArgv: [
4388
+ "--experimental-import-meta-resolve",
4389
+ "--experimental-vm-modules",
4390
+ "--require",
4391
+ suppressWarningsPath,
4392
+ ...poolOptions.execArgv ?? [],
4393
+ ...execArgv
4394
+ ],
4395
+ terminateTimeout: ctx.config.teardownTimeout,
4396
+ concurrentTasksPerWorker: 1,
4397
+ maxMemoryLimitBeforeRecycle: getMemoryLimit(ctx.config) || void 0
4398
+ };
4399
+ if (poolOptions.singleFork || !ctx.config.fileParallelism) {
4400
+ options.maxThreads = 1;
4401
+ options.minThreads = 1;
4402
+ }
4403
+ const pool = new Tinypool$1(options);
4404
+ const runWithFiles = (name) => {
4405
+ let id = 0;
4406
+ async function runFiles(project, config, files, environment, invalidates = []) {
4407
+ ctx.state.clearFiles(project, files);
4408
+ const { channel, cleanup } = createChildProcessChannel(project);
4409
+ const workerId = ++id;
4410
+ const data = {
4411
+ pool: "forks",
4412
+ worker,
4413
+ config,
4414
+ files,
4415
+ invalidates,
4416
+ environment,
4417
+ workerId,
4418
+ projectName: project.getName(),
4419
+ providedContext: project.getProvidedContext()
4420
+ };
4421
+ try {
4422
+ await pool.run(data, { name, channel });
4423
+ } catch (error) {
4424
+ if (error instanceof Error && /Failed to terminate worker/.test(error.message))
4425
+ ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.`);
4426
+ else if (ctx.isCancelling && error instanceof Error && /The task has been cancelled/.test(error.message))
4427
+ ctx.state.cancelFiles(files, ctx.config.root, project.config.name);
4428
+ else
4429
+ throw error;
4430
+ } finally {
4431
+ cleanup();
4432
+ }
4433
+ }
4434
+ return async (specs, invalidates) => {
4435
+ ctx.onCancel(() => pool.cancelPendingTasks());
4436
+ const configs = /* @__PURE__ */ new Map();
4437
+ const getConfig = (project) => {
4438
+ if (configs.has(project))
4439
+ return configs.get(project);
4440
+ const _config = project.getSerializableConfig();
4441
+ const config = {
4442
+ ..._config,
4443
+ // v8 serialize does not support regex
4444
+ testNamePattern: _config.testNamePattern ? stringifyRegex(_config.testNamePattern) : void 0
4445
+ };
4446
+ configs.set(project, config);
4447
+ return config;
4448
+ };
4449
+ const filesByEnv = await groupFilesByEnv(specs);
4450
+ const promises = Object.values(filesByEnv).flat();
4451
+ const results = await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates)));
4452
+ const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
4453
+ if (errors.length > 0)
4454
+ throw new AggregateErrorPonyfill(errors, "Errors occurred while running tests. For more information, see serialized error.");
4455
+ };
4456
+ };
4457
+ return {
4458
+ name: "vmForks",
4459
+ runTests: runWithFiles("run"),
4460
+ close: () => pool.destroy()
4461
+ };
4462
+ }
4463
+ function getMemoryLimit(config) {
4464
+ const memory = nodeos.totalmem();
4465
+ const limit = getWorkerMemoryLimit(config);
4466
+ if (typeof memory === "number") {
4467
+ return stringToBytes(
4468
+ limit,
4469
+ config.watch ? memory / 2 : memory
4470
+ );
4471
+ }
4472
+ if (typeof limit === "number" && limit > 1 || typeof limit === "string" && limit.at(-1) !== "%")
4473
+ return stringToBytes(limit);
4474
+ return null;
4475
+ }
4476
+
4477
+ const builtinPools = ["forks", "threads", "browser", "vmThreads", "vmForks", "typescript"];
4384
4478
  function createPool(ctx) {
4385
4479
  const pools = {
4386
4480
  forks: null,
4387
4481
  threads: null,
4388
4482
  browser: null,
4389
4483
  vmThreads: null,
4484
+ vmForks: null,
4390
4485
  typescript: null
4391
4486
  };
4392
4487
  function getDefaultPoolName(project, file) {
@@ -4409,14 +4504,19 @@ function createPool(ctx) {
4409
4504
  }
4410
4505
  return getDefaultPoolName(project, file);
4411
4506
  }
4507
+ const potentialConditions = /* @__PURE__ */ new Set(["production", "development", ...ctx.server.config.resolve.conditions]);
4508
+ const conditions = [...potentialConditions].filter((condition) => {
4509
+ if (condition === "production")
4510
+ return ctx.server.config.isProduction;
4511
+ if (condition === "development")
4512
+ return !ctx.server.config.isProduction;
4513
+ return true;
4514
+ }).flatMap((c) => ["--conditions", c]);
4515
+ const execArgv = process.execArgv.filter(
4516
+ (execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")
4517
+ );
4412
4518
  async function runTests(files, invalidate) {
4413
- var _a;
4414
- const conditions = ((_a = ctx.server.config.resolve.conditions) == null ? void 0 : _a.flatMap((c) => ["--conditions", c])) || [];
4415
- const execArgv = process.execArgv.filter(
4416
- (execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")
4417
- );
4418
4519
  const options = {
4419
- ...ctx.projectFiles,
4420
4520
  execArgv: [
4421
4521
  ...execArgv,
4422
4522
  ...conditions
@@ -4450,8 +4550,17 @@ function createPool(ctx) {
4450
4550
  threads: [],
4451
4551
  browser: [],
4452
4552
  vmThreads: [],
4553
+ vmForks: [],
4453
4554
  typescript: []
4454
4555
  };
4556
+ const factories = {
4557
+ browser: () => createBrowserPool(ctx),
4558
+ vmThreads: () => createVmThreadsPool(ctx, options),
4559
+ threads: () => createThreadsPool(ctx, options),
4560
+ forks: () => createForksPool(ctx, options),
4561
+ vmForks: () => createVmForksPool(ctx, options),
4562
+ typescript: () => createTypecheckPool(ctx)
4563
+ };
4455
4564
  for (const spec of files) {
4456
4565
  const pool = getPoolName(spec);
4457
4566
  filesByPool[pool] ?? (filesByPool[pool] = []);
@@ -4465,33 +4574,18 @@ function createPool(ctx) {
4465
4574
  return sequencer.sort(specs);
4466
4575
  }
4467
4576
  await Promise.all(Object.entries(filesByPool).map(async (entry) => {
4468
- var _a2;
4577
+ var _a;
4469
4578
  const [pool, files2] = entry;
4470
4579
  if (!files2.length)
4471
4580
  return null;
4472
4581
  const specs = await sortSpecs(files2);
4473
- if (pool === "browser") {
4474
- pools.browser ?? (pools.browser = createBrowserPool(ctx));
4475
- return pools.browser.runTests(specs, invalidate);
4476
- }
4477
- if (pool === "vmThreads") {
4478
- pools.vmThreads ?? (pools.vmThreads = createVmThreadsPool(ctx, options));
4479
- return pools.vmThreads.runTests(specs, invalidate);
4480
- }
4481
- if (pool === "threads") {
4482
- pools.threads ?? (pools.threads = createThreadsPool(ctx, options));
4483
- return pools.threads.runTests(specs, invalidate);
4484
- }
4485
- if (pool === "typescript") {
4486
- pools.typescript ?? (pools.typescript = createTypecheckPool(ctx));
4487
- return pools.typescript.runTests(specs);
4488
- }
4489
- if (pool === "forks") {
4490
- pools.forks ?? (pools.forks = createChildProcessPool(ctx, options));
4491
- return pools.forks.runTests(specs, invalidate);
4582
+ if (pool in factories) {
4583
+ const factory = factories[pool];
4584
+ pools[pool] ?? (pools[pool] = factory());
4585
+ return pools[pool].runTests(specs, invalidate);
4492
4586
  }
4493
4587
  const poolHandler = await resolveCustomPool(pool);
4494
- pools[_a2 = poolHandler.name] ?? (pools[_a2] = poolHandler);
4588
+ pools[_a = poolHandler.name] ?? (pools[_a] = poolHandler);
4495
4589
  return poolHandler.runTests(specs, invalidate);
4496
4590
  }));
4497
4591
  }
@@ -4518,11 +4612,12 @@ async function loadCustomReporterModule(path, runner) {
4518
4612
  throw new Error(`Custom reporter loaded from ${path} was not the default export`);
4519
4613
  return customReporterModule.default;
4520
4614
  }
4521
- function createReporters(reporterReferences, runner) {
4615
+ function createReporters(reporterReferences, ctx) {
4616
+ const runner = ctx.runner;
4522
4617
  const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
4523
4618
  if (typeof referenceOrInstance === "string") {
4524
4619
  if (referenceOrInstance === "html") {
4525
- await ensurePackageInstalled("@vitest/ui", runner.root);
4620
+ await ctx.packageInstaller.ensureInstalled("@vitest/ui", runner.root);
4526
4621
  const CustomReporter = await loadCustomReporterModule("@vitest/ui/reporter", runner);
4527
4622
  return new CustomReporter();
4528
4623
  } else if (referenceOrInstance in ReportersMap) {
@@ -4789,7 +4884,8 @@ const config = {
4789
4884
  include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"],
4790
4885
  exclude: defaultExclude
4791
4886
  },
4792
- slowTestThreshold: 300
4887
+ slowTestThreshold: 300,
4888
+ disableConsoleIntercept: false
4793
4889
  };
4794
4890
  const configDefaults = Object.freeze(config);
4795
4891
 
@@ -4972,14 +5068,6 @@ class RandomSequencer extends BaseSequencer {
4972
5068
  }
4973
5069
  }
4974
5070
 
4975
- const extraInlineDeps = [
4976
- /^(?!.*(?:node_modules)).*\.mjs$/,
4977
- /^(?!.*(?:node_modules)).*\.cjs\.js$/,
4978
- // Vite client
4979
- /vite\w*\/dist\/client\/env.mjs/,
4980
- // Nuxt
4981
- "@nuxt/test-utils"
4982
- ];
4983
5071
  function resolvePath(path, root) {
4984
5072
  return normalize(
4985
5073
  resolveModule(path, { paths: [root] }) ?? resolve(root, path)
@@ -5014,7 +5102,7 @@ function resolveApiServerConfig(options) {
5014
5102
  return api;
5015
5103
  }
5016
5104
  function resolveConfig(mode, options, viteConfig) {
5017
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H;
5105
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
5018
5106
  if (options.dom) {
5019
5107
  if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
5020
5108
  console.warn(
@@ -5047,6 +5135,10 @@ function resolveConfig(mode, options, viteConfig) {
5047
5135
  throw new Error("--shard <index> must be a positive number less then <count>");
5048
5136
  resolved.shard = { index, count };
5049
5137
  }
5138
+ if (resolved.maxWorkers)
5139
+ resolved.maxWorkers = Number(resolved.maxWorkers);
5140
+ if (resolved.minWorkers)
5141
+ resolved.minWorkers = Number(resolved.minWorkers);
5050
5142
  resolved.fileParallelism ?? (resolved.fileParallelism = true);
5051
5143
  if (!resolved.fileParallelism) {
5052
5144
  resolved.maxWorkers = 1;
@@ -5165,6 +5257,10 @@ function resolveConfig(mode, options, viteConfig) {
5165
5257
  forks: {
5166
5258
  ...(_w = resolved.poolOptions) == null ? void 0 : _w.forks,
5167
5259
  maxForks: Number.parseInt(process.env.VITEST_MAX_FORKS)
5260
+ },
5261
+ vmForks: {
5262
+ ...(_x = resolved.poolOptions) == null ? void 0 : _x.vmForks,
5263
+ maxForks: Number.parseInt(process.env.VITEST_MAX_FORKS)
5168
5264
  }
5169
5265
  };
5170
5266
  }
@@ -5172,7 +5268,11 @@ function resolveConfig(mode, options, viteConfig) {
5172
5268
  resolved.poolOptions = {
5173
5269
  ...resolved.poolOptions,
5174
5270
  forks: {
5175
- ...(_x = resolved.poolOptions) == null ? void 0 : _x.forks,
5271
+ ...(_y = resolved.poolOptions) == null ? void 0 : _y.forks,
5272
+ minForks: Number.parseInt(process.env.VITEST_MIN_FORKS)
5273
+ },
5274
+ vmForks: {
5275
+ ...(_z = resolved.poolOptions) == null ? void 0 : _z.vmForks,
5176
5276
  minForks: Number.parseInt(process.env.VITEST_MIN_FORKS)
5177
5277
  }
5178
5278
  };
@@ -5241,33 +5341,33 @@ function resolveConfig(mode, options, viteConfig) {
5241
5341
  resolved.passWithNoTests ?? (resolved.passWithNoTests = true);
5242
5342
  resolved.css ?? (resolved.css = {});
5243
5343
  if (typeof resolved.css === "object") {
5244
- (_y = resolved.css).modules ?? (_y.modules = {});
5245
- (_z = resolved.css.modules).classNameStrategy ?? (_z.classNameStrategy = "stable");
5344
+ (_A = resolved.css).modules ?? (_A.modules = {});
5345
+ (_B = resolved.css.modules).classNameStrategy ?? (_B.classNameStrategy = "stable");
5246
5346
  }
5247
5347
  resolved.cache ?? (resolved.cache = { dir: "" });
5248
5348
  if (resolved.cache)
5249
5349
  resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir, resolved.name);
5250
5350
  resolved.sequence ?? (resolved.sequence = {});
5251
- if (!((_A = resolved.sequence) == null ? void 0 : _A.sequencer)) {
5351
+ if (!((_C = resolved.sequence) == null ? void 0 : _C.sequencer)) {
5252
5352
  resolved.sequence.sequencer = resolved.sequence.shuffle ? RandomSequencer : BaseSequencer;
5253
5353
  }
5254
- (_B = resolved.sequence).hooks ?? (_B.hooks = "parallel");
5354
+ (_D = resolved.sequence).hooks ?? (_D.hooks = "parallel");
5255
5355
  if (resolved.sequence.sequencer === RandomSequencer)
5256
- (_C = resolved.sequence).seed ?? (_C.seed = Date.now());
5356
+ (_E = resolved.sequence).seed ?? (_E.seed = Date.now());
5257
5357
  resolved.typecheck = {
5258
5358
  ...configDefaults.typecheck,
5259
5359
  ...resolved.typecheck
5260
5360
  };
5261
5361
  resolved.environmentMatchGlobs = (resolved.environmentMatchGlobs || []).map((i) => [resolve(resolved.root, i[0]), i[1]]);
5262
5362
  resolved.typecheck ?? (resolved.typecheck = {});
5263
- (_D = resolved.typecheck).enabled ?? (_D.enabled = false);
5363
+ (_F = resolved.typecheck).enabled ?? (_F.enabled = false);
5264
5364
  if (resolved.typecheck.enabled)
5265
5365
  console.warn(c.yellow("Testing types with tsc and vue-tsc is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest's version when using it."));
5266
5366
  resolved.browser ?? (resolved.browser = {});
5267
- (_E = resolved.browser).enabled ?? (_E.enabled = false);
5268
- (_F = resolved.browser).headless ?? (_F.headless = isCI);
5269
- (_G = resolved.browser).slowHijackESM ?? (_G.slowHijackESM = false);
5270
- (_H = resolved.browser).isolate ?? (_H.isolate = true);
5367
+ (_G = resolved.browser).enabled ?? (_G.enabled = false);
5368
+ (_H = resolved.browser).headless ?? (_H.headless = isCI);
5369
+ (_I = resolved.browser).slowHijackESM ?? (_I.slowHijackESM = false);
5370
+ (_J = resolved.browser).isolate ?? (_J.isolate = true);
5271
5371
  if (resolved.browser.enabled && provider$1 === "stackblitz")
5272
5372
  resolved.browser.provider = "none";
5273
5373
  resolved.browser.api = resolveApiServerConfig(resolved.browser) || {
@@ -5281,7 +5381,7 @@ function isBrowserEnabled(config) {
5281
5381
  return Boolean((_a = config.browser) == null ? void 0 : _a.enabled);
5282
5382
  }
5283
5383
 
5284
- const ESC$1 = '\u001B[';
5384
+ const ESC$2 = '\u001B[';
5285
5385
  const OSC = '\u001B]';
5286
5386
  const BEL = '\u0007';
5287
5387
  const SEP = ';';
@@ -5295,10 +5395,10 @@ ansiEscapes.cursorTo = (x, y) => {
5295
5395
  }
5296
5396
 
5297
5397
  if (typeof y !== 'number') {
5298
- return ESC$1 + (x + 1) + 'G';
5398
+ return ESC$2 + (x + 1) + 'G';
5299
5399
  }
5300
5400
 
5301
- return ESC$1 + (y + 1) + ';' + (x + 1) + 'H';
5401
+ return ESC$2 + (y + 1) + ';' + (x + 1) + 'H';
5302
5402
  };
5303
5403
 
5304
5404
  ansiEscapes.cursorMove = (x, y) => {
@@ -5309,33 +5409,33 @@ ansiEscapes.cursorMove = (x, y) => {
5309
5409
  let returnValue = '';
5310
5410
 
5311
5411
  if (x < 0) {
5312
- returnValue += ESC$1 + (-x) + 'D';
5412
+ returnValue += ESC$2 + (-x) + 'D';
5313
5413
  } else if (x > 0) {
5314
- returnValue += ESC$1 + x + 'C';
5414
+ returnValue += ESC$2 + x + 'C';
5315
5415
  }
5316
5416
 
5317
5417
  if (y < 0) {
5318
- returnValue += ESC$1 + (-y) + 'A';
5418
+ returnValue += ESC$2 + (-y) + 'A';
5319
5419
  } else if (y > 0) {
5320
- returnValue += ESC$1 + y + 'B';
5420
+ returnValue += ESC$2 + y + 'B';
5321
5421
  }
5322
5422
 
5323
5423
  return returnValue;
5324
5424
  };
5325
5425
 
5326
- ansiEscapes.cursorUp = (count = 1) => ESC$1 + count + 'A';
5327
- ansiEscapes.cursorDown = (count = 1) => ESC$1 + count + 'B';
5328
- ansiEscapes.cursorForward = (count = 1) => ESC$1 + count + 'C';
5329
- ansiEscapes.cursorBackward = (count = 1) => ESC$1 + count + 'D';
5426
+ ansiEscapes.cursorUp = (count = 1) => ESC$2 + count + 'A';
5427
+ ansiEscapes.cursorDown = (count = 1) => ESC$2 + count + 'B';
5428
+ ansiEscapes.cursorForward = (count = 1) => ESC$2 + count + 'C';
5429
+ ansiEscapes.cursorBackward = (count = 1) => ESC$2 + count + 'D';
5330
5430
 
5331
- ansiEscapes.cursorLeft = ESC$1 + 'G';
5332
- ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC$1 + 's';
5333
- ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC$1 + 'u';
5334
- ansiEscapes.cursorGetPosition = ESC$1 + '6n';
5335
- ansiEscapes.cursorNextLine = ESC$1 + 'E';
5336
- ansiEscapes.cursorPrevLine = ESC$1 + 'F';
5337
- ansiEscapes.cursorHide = ESC$1 + '?25l';
5338
- ansiEscapes.cursorShow = ESC$1 + '?25h';
5431
+ ansiEscapes.cursorLeft = ESC$2 + 'G';
5432
+ ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC$2 + 's';
5433
+ ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC$2 + 'u';
5434
+ ansiEscapes.cursorGetPosition = ESC$2 + '6n';
5435
+ ansiEscapes.cursorNextLine = ESC$2 + 'E';
5436
+ ansiEscapes.cursorPrevLine = ESC$2 + 'F';
5437
+ ansiEscapes.cursorHide = ESC$2 + '?25l';
5438
+ ansiEscapes.cursorShow = ESC$2 + '?25h';
5339
5439
 
5340
5440
  ansiEscapes.eraseLines = count => {
5341
5441
  let clear = '';
@@ -5351,24 +5451,24 @@ ansiEscapes.eraseLines = count => {
5351
5451
  return clear;
5352
5452
  };
5353
5453
 
5354
- ansiEscapes.eraseEndLine = ESC$1 + 'K';
5355
- ansiEscapes.eraseStartLine = ESC$1 + '1K';
5356
- ansiEscapes.eraseLine = ESC$1 + '2K';
5357
- ansiEscapes.eraseDown = ESC$1 + 'J';
5358
- ansiEscapes.eraseUp = ESC$1 + '1J';
5359
- ansiEscapes.eraseScreen = ESC$1 + '2J';
5360
- ansiEscapes.scrollUp = ESC$1 + 'S';
5361
- ansiEscapes.scrollDown = ESC$1 + 'T';
5454
+ ansiEscapes.eraseEndLine = ESC$2 + 'K';
5455
+ ansiEscapes.eraseStartLine = ESC$2 + '1K';
5456
+ ansiEscapes.eraseLine = ESC$2 + '2K';
5457
+ ansiEscapes.eraseDown = ESC$2 + 'J';
5458
+ ansiEscapes.eraseUp = ESC$2 + '1J';
5459
+ ansiEscapes.eraseScreen = ESC$2 + '2J';
5460
+ ansiEscapes.scrollUp = ESC$2 + 'S';
5461
+ ansiEscapes.scrollDown = ESC$2 + 'T';
5362
5462
 
5363
5463
  ansiEscapes.clearScreen = '\u001Bc';
5364
5464
 
5365
5465
  ansiEscapes.clearTerminal = process.platform === 'win32' ?
5366
- `${ansiEscapes.eraseScreen}${ESC$1}0f` :
5466
+ `${ansiEscapes.eraseScreen}${ESC$2}0f` :
5367
5467
  // 1. Erases the screen (Only done in case `2` is not supported)
5368
5468
  // 2. Erases the whole screen including scrollback buffer
5369
5469
  // 3. Moves cursor to the top-left position
5370
5470
  // More info: https://www.real-world-systems.com/docs/ANSIcode.html
5371
- `${ansiEscapes.eraseScreen}${ESC$1}3J${ESC$1}H`;
5471
+ `${ansiEscapes.eraseScreen}${ESC$2}3J${ESC$2}H`;
5372
5472
 
5373
5473
  ansiEscapes.beep = BEL;
5374
5474
 
@@ -6480,7 +6580,23 @@ createLogUpdate(process$2.stdout);
6480
6580
 
6481
6581
  createLogUpdate(process$2.stderr);
6482
6582
 
6483
- var version = "1.1.3";
6583
+ var version = "1.2.1";
6584
+
6585
+ const HIGHLIGHT_SUPPORTED_EXTS = new Set(["js", "ts"].flatMap((lang) => [
6586
+ `.${lang}`,
6587
+ `.m${lang}`,
6588
+ `.c${lang}`,
6589
+ `.${lang}x`,
6590
+ `.m${lang}x`,
6591
+ `.c${lang}x`
6592
+ ]));
6593
+ function highlightCode(id, source, colors) {
6594
+ const ext = extname(id);
6595
+ if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
6596
+ return source;
6597
+ const isJsx = ext.endsWith("x");
6598
+ return highlight(source, { jsx: isJsx, colors: colors || c });
6599
+ }
6484
6600
 
6485
6601
  async function printError(error, project, options) {
6486
6602
  const { showCodeFrame = true, fullStack = false, type } = options;
@@ -6510,12 +6626,21 @@ async function printError(error, project, options) {
6510
6626
  parserOptions.ignoreStackEntries = [];
6511
6627
  const stacks = parseErrorStacktrace(e, parserOptions);
6512
6628
  const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
6513
- (stack) => project.getModuleById(stack.file) && existsSync(stack.file)
6629
+ (stack) => {
6630
+ try {
6631
+ return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
6632
+ } catch {
6633
+ return false;
6634
+ }
6635
+ }
6514
6636
  );
6515
6637
  const errorProperties = getErrorProperties(e);
6516
6638
  if (type)
6517
6639
  printErrorType(type, project.ctx);
6518
6640
  printErrorMessage(e, logger);
6641
+ if (e.codeFrame)
6642
+ logger.error(`${e.codeFrame}
6643
+ `);
6519
6644
  if (e.diff)
6520
6645
  displayDiff(e.diff, logger.console);
6521
6646
  if (e.frame) {
@@ -6524,7 +6649,7 @@ async function printError(error, project, options) {
6524
6649
  printStack(project, stacks, nearest, errorProperties, (s) => {
6525
6650
  if (showCodeFrame && s === nearest && nearest) {
6526
6651
  const sourceCode = readFileSync(nearest.file, "utf-8");
6527
- logger.error(generateCodeFrame(sourceCode, 4, s.line, s.column));
6652
+ logger.error(generateCodeFrame(sourceCode.length > 1e5 ? sourceCode : logger.highlight(nearest.file, sourceCode), 4, s));
6528
6653
  }
6529
6654
  });
6530
6655
  }
@@ -6536,7 +6661,7 @@ async function printError(error, project, options) {
6536
6661
  if (testName) {
6537
6662
  logger.error(c.red(`The latest test that might've caused the error is "${c.bold(testName)}". It might mean one of the following:
6538
6663
  - The error was thrown, while Vitest was running this test.
6539
- - This was the last recorded test before the error was thrown, if error originated after test finished its execution.`));
6664
+ - If the error occurred after the test had been completed, this was the last documented test before it was thrown.`));
6540
6665
  }
6541
6666
  if (afterEnvTeardown) {
6542
6667
  logger.error(c.red("This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword"));
@@ -6560,6 +6685,7 @@ const skipErrorProperties = /* @__PURE__ */ new Set([
6560
6685
  "type",
6561
6686
  "showDiff",
6562
6687
  "diff",
6688
+ "codeFrame",
6563
6689
  "actual",
6564
6690
  "expected",
6565
6691
  "diffOptions",
@@ -6657,9 +6783,9 @@ function printStack(project, stack, highlight, errorProperties, onStack) {
6657
6783
  logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
6658
6784
  }
6659
6785
  }
6660
- function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range = 2) {
6786
+ function generateCodeFrame(source, indent = 0, loc, range = 2) {
6661
6787
  var _a;
6662
- const start = positionToOffset(source, lineNumber, columnNumber);
6788
+ const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc;
6663
6789
  const end = start;
6664
6790
  const lines = source.split(lineSplitRE);
6665
6791
  const nl = /\r\n/.test(source) ? 2 : 1;
@@ -6699,20 +6825,22 @@ function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range =
6699
6825
  return res.join("\n");
6700
6826
  }
6701
6827
 
6702
- const ESC = "\x1B[";
6703
- const ERASE_DOWN = `${ESC}J`;
6704
- const ERASE_SCROLLBACK = `${ESC}3J`;
6705
- const CURSOR_TO_START = `${ESC}1;1H`;
6828
+ const ESC$1 = "\x1B[";
6829
+ const ERASE_DOWN = `${ESC$1}J`;
6830
+ const ERASE_SCROLLBACK = `${ESC$1}3J`;
6831
+ const CURSOR_TO_START = `${ESC$1}1;1H`;
6706
6832
  const CLEAR_SCREEN = "\x1Bc";
6707
6833
  class Logger {
6708
6834
  constructor(ctx, console = globalThis.console) {
6709
6835
  this.ctx = ctx;
6710
6836
  this.console = console;
6837
+ this._highlights.clear();
6711
6838
  }
6712
6839
  outputStream = process.stdout;
6713
6840
  errorStream = process.stderr;
6714
6841
  logUpdate = createLogUpdate(process.stdout);
6715
6842
  _clearScreenPending;
6843
+ _highlights = /* @__PURE__ */ new Map();
6716
6844
  log(...args) {
6717
6845
  this._clearScreen();
6718
6846
  this.console.log(...args);
@@ -6758,6 +6886,19 @@ class Logger {
6758
6886
  logger: this
6759
6887
  });
6760
6888
  }
6889
+ clearHighlightCache(filename) {
6890
+ if (filename)
6891
+ this._highlights.delete(filename);
6892
+ else
6893
+ this._highlights.clear();
6894
+ }
6895
+ highlight(filename, source) {
6896
+ if (this._highlights.has(filename))
6897
+ return this._highlights.get(filename);
6898
+ const code = highlightCode(filename, source);
6899
+ this._highlights.set(filename, code);
6900
+ return code;
6901
+ }
6761
6902
  printNoTestFound(filters) {
6762
6903
  var _a;
6763
6904
  const config = this.ctx.config;
@@ -6805,12 +6946,13 @@ No ${config.mode} files found, exiting with code 1`));
6805
6946
  if (this.ctx.config.sequence.sequencer === RandomSequencer)
6806
6947
  this.log(c.gray(` Running tests with seed "${this.ctx.config.sequence.seed}"`));
6807
6948
  this.ctx.projects.forEach((project) => {
6808
- var _a2;
6809
6949
  if (!project.browser)
6810
6950
  return;
6811
6951
  const name = project.getName();
6812
6952
  const output = project.isCore() ? "" : ` [${name}]`;
6813
- this.log(c.dim(c.green(` ${output} Browser runner started at http://${((_a2 = project.config.browser.api) == null ? void 0 : _a2.host) || "localhost"}:${c.bold(`${project.browser.config.server.port}`)}`)));
6953
+ const resolvedUrls = project.browser.resolvedUrls;
6954
+ const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
6955
+ this.log(c.dim(c.green(` ${output} Browser runner started at ${new URL("/", origin)}`)));
6814
6956
  });
6815
6957
  if (this.ctx.config.ui)
6816
6958
  this.log(c.dim(c.green(` UI started at http://${((_a = this.ctx.config.api) == null ? void 0 : _a.host) || "localhost"}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`)));
@@ -6893,13 +7035,12 @@ function getBetterEnd(code, node) {
6893
7035
  end += 1;
6894
7036
  return end;
6895
7037
  }
6896
- const regexpHoistable = /^[ \t]*\b(vi|vitest)\s*\.\s*(mock|unmock|hoisted)\(/m;
6897
- const regexpAssignedHoisted = /=[ \t]*(\bawait|)[ \t]*\b(vi|vitest)\s*\.\s*hoisted\(/;
7038
+ const regexpHoistable = /\b(vi|vitest)\s*\.\s*(mock|unmock|hoisted)\(/;
6898
7039
  const hashbangRE = /^#!.*\n/;
6899
- function hoistMocks(code, id, parse) {
7040
+ function hoistMocks(code, id, parse, colors) {
6900
7041
  var _a;
6901
- const hasMocks = regexpHoistable.test(code) || regexpAssignedHoisted.test(code);
6902
- if (!hasMocks)
7042
+ const needHoisting = regexpHoistable.test(code);
7043
+ if (!needHoisting)
6903
7044
  return;
6904
7045
  const s = new MagicString(code);
6905
7046
  let ast;
@@ -6962,6 +7103,16 @@ ${err.message}`);
6962
7103
  }
6963
7104
  const declaredConst = /* @__PURE__ */ new Set();
6964
7105
  const hoistedNodes = [];
7106
+ function createSyntaxError(node, message) {
7107
+ const _error = new SyntaxError(message);
7108
+ Error.captureStackTrace(_error, createSyntaxError);
7109
+ return {
7110
+ name: "SyntaxError",
7111
+ message: _error.message,
7112
+ stack: _error.stack,
7113
+ frame: generateCodeFrame(highlightCode(id, code, colors), 4, node.start + 1)
7114
+ };
7115
+ }
6965
7116
  esmWalker(ast, {
6966
7117
  onIdentifier(id2, info, parentStack) {
6967
7118
  const binding = idToImportMap.get(id2.name);
@@ -6984,27 +7135,74 @@ ${err.message}`);
6984
7135
  }
6985
7136
  },
6986
7137
  onCallExpression(node) {
6987
- var _a2, _b;
7138
+ var _a2, _b, _c, _d, _e;
6988
7139
  if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object) && (node.callee.object.name === "vi" || node.callee.object.name === "vitest") && isIdentifier(node.callee.property)) {
6989
7140
  const methodName = node.callee.property.name;
6990
7141
  if (methodName === "mock" || methodName === "unmock")
6991
7142
  hoistedNodes.push(node);
6992
7143
  if (methodName === "hoisted") {
6993
- const declarationNode = (_a2 = findNodeAround(ast, node.start, "VariableDeclaration")) == null ? void 0 : _a2.node;
6994
- const init = (_b = declarationNode == null ? void 0 : declarationNode.declarations[0]) == null ? void 0 : _b.init;
7144
+ const defaultExport = (_a2 = findNodeAround(ast, node.start, "ExportDefaultDeclaration")) == null ? void 0 : _a2.node;
7145
+ if ((defaultExport == null ? void 0 : defaultExport.declaration) === node || (defaultExport == null ? void 0 : defaultExport.declaration.type) === "AwaitExpression" && defaultExport.declaration.argument === node)
7146
+ throw createSyntaxError(defaultExport, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first.");
7147
+ const declarationNode = (_b = findNodeAround(ast, node.start, "VariableDeclaration")) == null ? void 0 : _b.node;
7148
+ const init = (_c = declarationNode == null ? void 0 : declarationNode.declarations[0]) == null ? void 0 : _c.init;
6995
7149
  const isViHoisted = (node2) => {
6996
7150
  return node2.callee.type === "MemberExpression" && isIdentifier(node2.callee.object) && (node2.callee.object.name === "vi" || node2.callee.object.name === "vitest") && isIdentifier(node2.callee.property) && node2.callee.property.name === "hoisted";
6997
7151
  };
6998
7152
  const canMoveDeclaration = init && init.type === "CallExpression" && isViHoisted(init) || init && init.type === "AwaitExpression" && init.argument.type === "CallExpression" && isViHoisted(init.argument);
6999
7153
  if (canMoveDeclaration) {
7154
+ const nodeExported = (_d = findNodeAround(ast, declarationNode.start, "ExportNamedDeclaration")) == null ? void 0 : _d.node;
7155
+ if ((nodeExported == null ? void 0 : nodeExported.declaration) === declarationNode)
7156
+ throw createSyntaxError(nodeExported, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first.");
7000
7157
  hoistedNodes.push(declarationNode);
7001
7158
  } else {
7002
- hoistedNodes.push(node);
7159
+ const awaitedExpression = (_e = findNodeAround(ast, node.start, "AwaitExpression")) == null ? void 0 : _e.node;
7160
+ hoistedNodes.push((awaitedExpression == null ? void 0 : awaitedExpression.argument) === node ? awaitedExpression : node);
7003
7161
  }
7004
7162
  }
7005
7163
  }
7006
7164
  }
7007
7165
  });
7166
+ function getNodeName(node) {
7167
+ const callee = node.callee || {};
7168
+ if (callee.type === "MemberExpression" && isIdentifier(callee.property) && isIdentifier(callee.object))
7169
+ return `${callee.object.name}.${callee.property.name}()`;
7170
+ return '"hoisted method"';
7171
+ }
7172
+ function getNodeCall(node) {
7173
+ if (node.type === "CallExpression")
7174
+ return node;
7175
+ if (node.type === "VariableDeclaration") {
7176
+ const { declarations } = node;
7177
+ const init = declarations[0].init;
7178
+ if (init)
7179
+ return getNodeCall(init);
7180
+ }
7181
+ if (node.type === "AwaitExpression") {
7182
+ const { argument } = node;
7183
+ if (argument.type === "CallExpression")
7184
+ return getNodeCall(argument);
7185
+ }
7186
+ return node;
7187
+ }
7188
+ function createError(outsideNode, insideNode) {
7189
+ const outsideCall = getNodeCall(outsideNode);
7190
+ const insideCall = getNodeCall(insideNode);
7191
+ throw createSyntaxError(
7192
+ insideCall,
7193
+ `Cannot call ${getNodeName(insideCall)} inside ${getNodeName(outsideCall)}: both methods are hoisted to the top of the file and not actually called inside each other.`
7194
+ );
7195
+ }
7196
+ for (let i = 0; i < hoistedNodes.length; i++) {
7197
+ const node = hoistedNodes[i];
7198
+ for (let j = i + 1; j < hoistedNodes.length; j++) {
7199
+ const otherNode = hoistedNodes[j];
7200
+ if (node.start >= otherNode.start && node.end <= otherNode.end)
7201
+ throw createError(otherNode, node);
7202
+ if (otherNode.start >= node.start && otherNode.end <= node.end)
7203
+ throw createError(node, otherNode);
7204
+ }
7205
+ }
7008
7206
  const hoistedCode = hoistedNodes.map((node) => {
7009
7207
  const end = getBetterEnd(code, node);
7010
7208
  const nodeCode = s.slice(node.start, end);
@@ -7124,10 +7322,13 @@ function resolveFsAllow(projectRoot, rootConfigFile) {
7124
7322
  }
7125
7323
 
7126
7324
  async function createBrowserServer(project, configFile) {
7325
+ var _a;
7127
7326
  const root = project.config.root;
7128
- await ensurePackageInstalled("@vitest/browser", root);
7327
+ await project.ctx.packageInstaller.ensureInstalled("@vitest/browser", root);
7129
7328
  const configPath = typeof configFile === "string" ? configFile : false;
7130
7329
  const server = await createServer({
7330
+ ...project.options,
7331
+ // spread project config inlined in root workspace config
7131
7332
  logLevel: "error",
7132
7333
  mode: project.config.mode,
7133
7334
  configFile: configPath,
@@ -7139,14 +7340,15 @@ async function createBrowserServer(project, configFile) {
7139
7340
  }
7140
7341
  },
7141
7342
  plugins: [
7343
+ ...((_a = project.options) == null ? void 0 : _a.plugins) || [],
7142
7344
  (await import('@vitest/browser')).default(project, "/"),
7143
7345
  CoverageTransform(project.ctx),
7144
7346
  {
7145
7347
  enforce: "post",
7146
7348
  name: "vitest:browser:config",
7147
7349
  async config(config) {
7148
- var _a, _b, _c;
7149
- const server2 = resolveApiServerConfig(((_a = config.test) == null ? void 0 : _a.browser) || {}) || {
7350
+ var _a2, _b, _c;
7351
+ const server2 = resolveApiServerConfig(((_a2 = config.test) == null ? void 0 : _a2.browser) || {}) || {
7150
7352
  port: defaultBrowserPort
7151
7353
  };
7152
7354
  server2.middlewareMode = false;
@@ -7176,21 +7378,21 @@ async function createBrowserServer(project, configFile) {
7176
7378
  ]
7177
7379
  });
7178
7380
  await server.listen();
7179
- (await import('../chunks/api-setup.mFKdEKxa.js')).setup(project, server);
7381
+ (await import('../chunks/api-setup.omeaEsoT.js')).setup(project, server);
7180
7382
  return server;
7181
7383
  }
7182
7384
 
7183
7385
  const builtinProviders = ["webdriverio", "playwright", "none"];
7184
- async function getBrowserProvider(options, loader) {
7386
+ async function getBrowserProvider(options, project) {
7185
7387
  if (options.provider == null || builtinProviders.includes(options.provider)) {
7186
- await ensurePackageInstalled("@vitest/browser", loader.root);
7187
- const providers = await loader.executeId("@vitest/browser/providers");
7388
+ await project.ctx.packageInstaller.ensureInstalled("@vitest/browser", project.config.root);
7389
+ const providers = await project.runner.executeId("@vitest/browser/providers");
7188
7390
  const provider = options.provider || "webdriverio";
7189
7391
  return providers[provider];
7190
7392
  }
7191
7393
  let customProviderModule;
7192
7394
  try {
7193
- customProviderModule = await loader.executeId(options.provider);
7395
+ customProviderModule = await project.runner.executeId(options.provider);
7194
7396
  } catch (error) {
7195
7397
  throw new Error(`Failed to load custom BrowserProvider from ${options.provider}`, { cause: error });
7196
7398
  }
@@ -7505,7 +7707,7 @@ async function loadGlobalSetupFile(file, runner) {
7505
7707
 
7506
7708
  async function initializeProject(workspacePath, ctx, options) {
7507
7709
  var _a;
7508
- const project = new WorkspaceProject(workspacePath, ctx);
7710
+ const project = new WorkspaceProject(workspacePath, ctx, options);
7509
7711
  const configFile = options.extends ? resolve(dirname(options.workspaceConfigPath), options.extends) : typeof workspacePath === "number" || workspacePath.endsWith("/") ? false : workspacePath;
7510
7712
  const root = options.root || (typeof workspacePath === "number" ? void 0 : workspacePath.endsWith("/") ? workspacePath : dirname(workspacePath));
7511
7713
  const config = {
@@ -7524,9 +7726,10 @@ async function initializeProject(workspacePath, ctx, options) {
7524
7726
  return project;
7525
7727
  }
7526
7728
  class WorkspaceProject {
7527
- constructor(path, ctx) {
7729
+ constructor(path, ctx, options) {
7528
7730
  this.path = path;
7529
7731
  this.ctx = ctx;
7732
+ this.options = options;
7530
7733
  }
7531
7734
  configOverride;
7532
7735
  config;
@@ -7686,10 +7889,10 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7686
7889
  filters = filters.map((f) => toNamespacedPath(f));
7687
7890
  if (filters.length) {
7688
7891
  return testFiles.filter((t) => {
7689
- const testFile = relative(dir, t);
7892
+ const testFile = relative(dir, t).toLocaleLowerCase();
7690
7893
  return filters.some((f) => {
7691
7894
  const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
7692
- return testFile.includes(f) || testFile.includes(relativePath);
7895
+ return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
7693
7896
  });
7694
7897
  });
7695
7898
  }
@@ -7732,29 +7935,39 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7732
7935
  });
7733
7936
  await this.initBrowserServer(this.server.config.configFile);
7734
7937
  }
7735
- async report(name, ...args) {
7736
- return this.ctx.report(name, ...args);
7737
- }
7738
7938
  isBrowserEnabled() {
7739
7939
  return isBrowserEnabled(this.config);
7740
7940
  }
7741
7941
  getSerializableConfig() {
7742
- var _a, _b, _c;
7942
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
7743
7943
  const optimizer = (_a = this.config.deps) == null ? void 0 : _a.optimizer;
7944
+ const poolOptions = this.config.poolOptions;
7945
+ const isolate = (_d = (_c = (_b = this.server) == null ? void 0 : _b.config) == null ? void 0 : _c.test) == null ? void 0 : _d.isolate;
7744
7946
  return deepMerge({
7745
7947
  ...this.config,
7746
7948
  coverage: this.ctx.config.coverage,
7747
- pool: this.ctx.config.pool,
7748
- poolOptions: this.ctx.config.poolOptions,
7949
+ poolOptions: {
7950
+ forks: {
7951
+ singleFork: ((_e = poolOptions == null ? void 0 : poolOptions.forks) == null ? void 0 : _e.singleFork) ?? ((_g = (_f = this.ctx.config.poolOptions) == null ? void 0 : _f.forks) == null ? void 0 : _g.singleFork) ?? false,
7952
+ isolate: ((_h = poolOptions == null ? void 0 : poolOptions.forks) == null ? void 0 : _h.isolate) ?? isolate ?? ((_j = (_i = this.ctx.config.poolOptions) == null ? void 0 : _i.forks) == null ? void 0 : _j.isolate) ?? true
7953
+ },
7954
+ threads: {
7955
+ singleThread: ((_k = poolOptions == null ? void 0 : poolOptions.threads) == null ? void 0 : _k.singleThread) ?? ((_m = (_l = this.ctx.config.poolOptions) == null ? void 0 : _l.threads) == null ? void 0 : _m.singleThread) ?? false,
7956
+ isolate: ((_n = poolOptions == null ? void 0 : poolOptions.threads) == null ? void 0 : _n.isolate) ?? isolate ?? ((_p = (_o = this.ctx.config.poolOptions) == null ? void 0 : _o.threads) == null ? void 0 : _p.isolate) ?? true
7957
+ },
7958
+ vmThreads: {
7959
+ singleThread: ((_q = poolOptions == null ? void 0 : poolOptions.vmThreads) == null ? void 0 : _q.singleThread) ?? ((_s = (_r = this.ctx.config.poolOptions) == null ? void 0 : _r.vmThreads) == null ? void 0 : _s.singleThread) ?? false
7960
+ }
7961
+ },
7749
7962
  reporters: [],
7750
7963
  deps: {
7751
7964
  ...this.config.deps,
7752
7965
  optimizer: {
7753
7966
  web: {
7754
- enabled: ((_b = optimizer == null ? void 0 : optimizer.web) == null ? void 0 : _b.enabled) ?? true
7967
+ enabled: ((_t = optimizer == null ? void 0 : optimizer.web) == null ? void 0 : _t.enabled) ?? true
7755
7968
  },
7756
7969
  ssr: {
7757
- enabled: ((_c = optimizer == null ? void 0 : optimizer.ssr) == null ? void 0 : _c.enabled) ?? true
7970
+ enabled: ((_u = optimizer == null ? void 0 : optimizer.ssr) == null ? void 0 : _u.enabled) ?? true
7758
7971
  }
7759
7972
  }
7760
7973
  },
@@ -7793,7 +8006,7 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7793
8006
  return;
7794
8007
  if (this.browserProvider)
7795
8008
  return;
7796
- const Provider = await getBrowserProvider(this.config.browser, this.runner);
8009
+ const Provider = await getBrowserProvider(this.config.browser, this);
7797
8010
  this.browserProvider = new Provider();
7798
8011
  const browser = this.config.browser.name;
7799
8012
  const supportedBrowsers = this.browserProvider.getSupportedBrowsers();
@@ -7806,11 +8019,51 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7806
8019
  }
7807
8020
  }
7808
8021
 
8022
+ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
8023
+ class VitestPackageInstaller {
8024
+ async ensureInstalled(dependency, root) {
8025
+ if (process.env.VITEST_SKIP_INSTALL_CHECKS)
8026
+ return true;
8027
+ if (process.versions.pnp) {
8028
+ const targetRequire = createRequire(__dirname);
8029
+ try {
8030
+ targetRequire.resolve(dependency, { paths: [root, __dirname] });
8031
+ return true;
8032
+ } catch (error) {
8033
+ }
8034
+ }
8035
+ if (isPackageExists(dependency, { paths: [root, __dirname] }))
8036
+ return true;
8037
+ const promptInstall = !isCI && process.stdout.isTTY;
8038
+ process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'
8039
+
8040
+ `));
8041
+ if (!promptInstall)
8042
+ return false;
8043
+ const prompts = await Promise.resolve().then(function () { return index; });
8044
+ const { install } = await prompts.prompt({
8045
+ type: "confirm",
8046
+ name: "install",
8047
+ message: c.reset(`Do you want to install ${c.green(dependency)}?`)
8048
+ });
8049
+ if (install) {
8050
+ await (await import('../chunks/install-pkg.LE8oaA1t.js')).installPackage(dependency, { dev: true });
8051
+ process.stderr.write(c.yellow(`
8052
+ Package ${dependency} installed, re-run the command to start.
8053
+ `));
8054
+ process.exit(EXIT_CODE_RESTART);
8055
+ return true;
8056
+ }
8057
+ return false;
8058
+ }
8059
+ }
8060
+
7809
8061
  const WATCHER_DEBOUNCE = 100;
7810
8062
  class Vitest {
7811
- constructor(mode) {
8063
+ constructor(mode, options = {}) {
7812
8064
  this.mode = mode;
7813
8065
  this.logger = new Logger(this);
8066
+ this.packageInstaller = options.packageInstaller || new VitestPackageInstaller();
7814
8067
  }
7815
8068
  config = void 0;
7816
8069
  configOverride = {};
@@ -7833,11 +8086,12 @@ class Vitest {
7833
8086
  isFirstRun = true;
7834
8087
  restartsCount = 0;
7835
8088
  runner = void 0;
8089
+ packageInstaller;
7836
8090
  coreWorkspaceProject;
7837
8091
  resolvedProjects = [];
7838
8092
  projects = [];
7839
8093
  projectsTestFiles = /* @__PURE__ */ new Map();
7840
- projectFiles;
8094
+ distPath;
7841
8095
  _onRestartListeners = [];
7842
8096
  _onClose = [];
7843
8097
  _onSetServer = [];
@@ -7863,11 +8117,7 @@ class Vitest {
7863
8117
  this.vitenode = new ViteNodeServer(server, this.config.server);
7864
8118
  const projectVitestPath = await this.vitenode.resolveId("vitest");
7865
8119
  const vitestDir = projectVitestPath ? resolve(projectVitestPath.id, "../..") : rootDir;
7866
- this.projectFiles = {
7867
- workerPath: join(vitestDir, "dist/worker.js"),
7868
- forksPath: join(vitestDir, "dist/child.js"),
7869
- vmPath: join(vitestDir, "dist/vm.js")
7870
- };
8120
+ this.distPath = join(vitestDir, "dist");
7871
8121
  const node = this.vitenode;
7872
8122
  this.runner = new ViteNodeRunner({
7873
8123
  root: server.config.root,
@@ -7898,7 +8148,7 @@ class Vitest {
7898
8148
  }
7899
8149
  });
7900
8150
  }
7901
- this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray((_d = resolved.benchmark) == null ? void 0 : _d.reporters), this.runner) : await createReporters(resolved.reporters, this.runner);
8151
+ this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray((_d = resolved.benchmark) == null ? void 0 : _d.reporters), this.runner) : await createReporters(resolved.reporters, this);
7902
8152
  this.cache.results.setConfig(resolved.root, resolved.cache);
7903
8153
  try {
7904
8154
  await this.cache.results.readFromCache();
@@ -8002,6 +8252,7 @@ class Vitest {
8002
8252
  "pool",
8003
8253
  "globals",
8004
8254
  "expandSnapshotDiff",
8255
+ "disableConsoleIntercept",
8005
8256
  "retry",
8006
8257
  "testNamePattern",
8007
8258
  "passWithNoTests",
@@ -8269,26 +8520,27 @@ class Vitest {
8269
8520
  await this.report("onWatcherStart", this.state.getFiles(files));
8270
8521
  }, WATCHER_DEBOUNCE);
8271
8522
  }
8272
- getModuleProjects(id) {
8523
+ getModuleProjects(filepath) {
8273
8524
  return this.projects.filter((project) => {
8274
- return project.getModulesByFilepath(id).size;
8525
+ return project.getModulesByFilepath(filepath).size;
8275
8526
  });
8276
8527
  }
8277
8528
  unregisterWatcher = noop$1;
8278
8529
  registerWatcher() {
8279
- const updateLastChanged = (id) => {
8280
- const projects = this.getModuleProjects(id);
8530
+ const updateLastChanged = (filepath) => {
8531
+ const projects = this.getModuleProjects(filepath);
8281
8532
  projects.forEach(({ server, browser }) => {
8282
- const serverMods = server.moduleGraph.getModulesByFile(id);
8533
+ const serverMods = server.moduleGraph.getModulesByFile(filepath);
8283
8534
  serverMods == null ? void 0 : serverMods.forEach((mod) => server.moduleGraph.invalidateModule(mod));
8284
8535
  if (browser) {
8285
- const browserMods = browser.moduleGraph.getModulesByFile(id);
8536
+ const browserMods = browser.moduleGraph.getModulesByFile(filepath);
8286
8537
  browserMods == null ? void 0 : browserMods.forEach((mod) => browser.moduleGraph.invalidateModule(mod));
8287
8538
  }
8288
8539
  });
8289
8540
  };
8290
8541
  const onChange = (id) => {
8291
8542
  id = slash$1(id);
8543
+ this.logger.clearHighlightCache(id);
8292
8544
  updateLastChanged(id);
8293
8545
  const needsRerun = this.handleFileChanged(id);
8294
8546
  if (needsRerun.length)
@@ -8296,6 +8548,7 @@ class Vitest {
8296
8548
  };
8297
8549
  const onUnlink = (id) => {
8298
8550
  id = slash$1(id);
8551
+ this.logger.clearHighlightCache(id);
8299
8552
  this.invalidates.add(id);
8300
8553
  if (this.state.filesMap.has(id)) {
8301
8554
  this.state.filesMap.delete(id);
@@ -8317,6 +8570,10 @@ class Vitest {
8317
8570
  this.projectsTestFiles.set(id, new Set(matchingProjects));
8318
8571
  this.changedTests.add(id);
8319
8572
  this.scheduleRerun([id]);
8573
+ } else {
8574
+ const needsRerun = this.handleFileChanged(id);
8575
+ if (needsRerun.length)
8576
+ this.scheduleRerun(needsRerun);
8320
8577
  }
8321
8578
  };
8322
8579
  const watcher = this.server.watcher;
@@ -8336,48 +8593,44 @@ class Vitest {
8336
8593
  /**
8337
8594
  * @returns A value indicating whether rerun is needed (changedTests was mutated)
8338
8595
  */
8339
- handleFileChanged(id) {
8340
- if (this.changedTests.has(id) || this.invalidates.has(id))
8596
+ handleFileChanged(filepath) {
8597
+ if (this.changedTests.has(filepath) || this.invalidates.has(filepath))
8341
8598
  return [];
8342
- if (mm.isMatch(id, this.config.forceRerunTriggers)) {
8599
+ if (mm.isMatch(filepath, this.config.forceRerunTriggers)) {
8343
8600
  this.state.getFilepaths().forEach((file) => this.changedTests.add(file));
8344
- return [id];
8601
+ return [filepath];
8345
8602
  }
8346
- const projects = this.getModuleProjects(id);
8603
+ const projects = this.getModuleProjects(filepath);
8347
8604
  if (!projects.length) {
8348
- if (this.state.filesMap.has(id) || this.projects.some((project) => project.isTestFile(id))) {
8349
- this.changedTests.add(id);
8350
- return [id];
8605
+ if (this.state.filesMap.has(filepath) || this.projects.some((project) => project.isTestFile(filepath))) {
8606
+ this.changedTests.add(filepath);
8607
+ return [filepath];
8351
8608
  }
8352
8609
  return [];
8353
8610
  }
8354
8611
  const files = [];
8355
8612
  for (const project of projects) {
8356
- const { server } = project;
8357
- const mods = project.getModulesByFilepath(id);
8613
+ const mods = project.getModulesByFilepath(filepath);
8358
8614
  if (!mods.size)
8359
8615
  continue;
8360
- id = normalizeRequestId(id, server.config.base);
8361
- this.invalidates.add(id);
8362
- if (this.state.filesMap.has(id) || project.isTestFile(id)) {
8363
- this.changedTests.add(id);
8364
- files.push(id);
8616
+ this.invalidates.add(filepath);
8617
+ if (this.state.filesMap.has(filepath) || project.isTestFile(filepath)) {
8618
+ this.changedTests.add(filepath);
8619
+ files.push(filepath);
8365
8620
  continue;
8366
8621
  }
8367
8622
  let rerun = false;
8368
8623
  for (const mod of mods) {
8369
- if (!mod.id)
8370
- continue;
8371
8624
  mod.importers.forEach((i) => {
8372
- if (!i.id)
8625
+ if (!i.file)
8373
8626
  return;
8374
- const heedsRerun = this.handleFileChanged(i.id);
8627
+ const heedsRerun = this.handleFileChanged(i.file);
8375
8628
  if (heedsRerun)
8376
8629
  rerun = true;
8377
8630
  });
8378
8631
  }
8379
8632
  if (rerun)
8380
- files.push(id);
8633
+ files.push(filepath);
8381
8634
  }
8382
8635
  return files;
8383
8636
  }
@@ -8390,7 +8643,10 @@ class Vitest {
8390
8643
  async close() {
8391
8644
  if (!this.closingPromise) {
8392
8645
  this.closingPromise = (async () => {
8393
- for await (const project of [...this.projects].reverse())
8646
+ const teardownProjects = [...this.projects];
8647
+ if (!teardownProjects.includes(this.coreWorkspaceProject))
8648
+ teardownProjects.push(this.coreWorkspaceProject);
8649
+ for await (const project of teardownProjects.reverse())
8394
8650
  await project.teardownGlobalSetup();
8395
8651
  const closePromises = this.projects.map((w) => w.close().then(() => w.server = void 0));
8396
8652
  if (!this.projects.includes(this.coreWorkspaceProject))
@@ -8485,7 +8741,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8485
8741
  return ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd();
8486
8742
  };
8487
8743
  async function UIPlugin() {
8488
- await ensurePackageInstalled("@vitest/ui", getRoot());
8744
+ await ctx.packageInstaller.ensureInstalled("@vitest/ui", getRoot());
8489
8745
  return (await import('@vitest/ui')).default(ctx);
8490
8746
  }
8491
8747
  return [
@@ -8496,7 +8752,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8496
8752
  this.meta.watchMode = false;
8497
8753
  },
8498
8754
  async config(viteConfig) {
8499
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
8755
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
8500
8756
  if (options.watch) {
8501
8757
  options = deepMerge({}, userConfig);
8502
8758
  }
@@ -8547,14 +8803,27 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8547
8803
  poolOptions: testConfig.poolOptions
8548
8804
  }
8549
8805
  };
8806
+ if (((_j = viteConfig.ssr) == null ? void 0 : _j.noExternal) !== true) {
8807
+ const inline = (_l = (_k = testConfig.server) == null ? void 0 : _k.deps) == null ? void 0 : _l.inline;
8808
+ if (inline === true) {
8809
+ config.ssr = { noExternal: true };
8810
+ } else {
8811
+ const noExternal = (_m = viteConfig.ssr) == null ? void 0 : _m.noExternal;
8812
+ const noExternalArray = typeof noExternal !== "undefined" ? toArray(noExternal) : void 0;
8813
+ const uniqueInline = inline && noExternalArray ? inline.filter((dep) => !noExternalArray.includes(dep)) : inline;
8814
+ config.ssr = {
8815
+ noExternal: uniqueInline
8816
+ };
8817
+ }
8818
+ }
8550
8819
  if (process.platform === "darwin" && process.env.VITE_TEST_WATCHER_DEBUG) {
8551
8820
  config.server.watch.useFsEvents = false;
8552
8821
  config.server.watch.usePolling = false;
8553
8822
  }
8554
- const classNameStrategy = typeof testConfig.css !== "boolean" && ((_k = (_j = testConfig.css) == null ? void 0 : _j.modules) == null ? void 0 : _k.classNameStrategy) || "stable";
8823
+ const classNameStrategy = typeof testConfig.css !== "boolean" && ((_o = (_n = testConfig.css) == null ? void 0 : _n.modules) == null ? void 0 : _o.classNameStrategy) || "stable";
8555
8824
  if (classNameStrategy !== "scoped") {
8556
8825
  config.css ?? (config.css = {});
8557
- (_l = config.css).modules ?? (_l.modules = {});
8826
+ (_p = config.css).modules ?? (_p.modules = {});
8558
8827
  if (config.css.modules) {
8559
8828
  config.css.modules.generateScopedName = (name, filename) => {
8560
8829
  const root = getRoot();
@@ -8596,7 +8865,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8596
8865
  try {
8597
8866
  await ctx.setServer(options, server, userConfig);
8598
8867
  if (options.api && options.watch)
8599
- (await import('../chunks/api-setup.mFKdEKxa.js')).setup(ctx);
8868
+ (await import('../chunks/api-setup.omeaEsoT.js')).setup(ctx);
8600
8869
  } catch (err) {
8601
8870
  await ctx.logger.printError(err, { fullStack: true });
8602
8871
  process.exit(1);
@@ -8616,9 +8885,9 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8616
8885
  ].filter(notNullish);
8617
8886
  }
8618
8887
 
8619
- async function createVitest(mode, options, viteOverrides = {}) {
8888
+ async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {}) {
8620
8889
  var _a;
8621
- const ctx = new Vitest(mode);
8890
+ const ctx = new Vitest(mode, vitestOptions);
8622
8891
  const root = resolve(options.root || process.cwd());
8623
8892
  const configPath = options.config === false ? false : options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
8624
8893
  options.config = configPath;
@@ -14909,6 +15178,140 @@ var index = /*#__PURE__*/_mergeNamespaces({
14909
15178
  default: prompt
14910
15179
  }, [prompts]);
14911
15180
 
15181
+ const MAX_RESULT_COUNT = 10;
15182
+ const SELECTION_MAX_INDEX = 7;
15183
+ const ESC = "\x1B[";
15184
+ class WatchFilter {
15185
+ filterRL;
15186
+ currentKeyword = void 0;
15187
+ message;
15188
+ results = [];
15189
+ selectionIndex = -1;
15190
+ onKeyPress;
15191
+ constructor(message) {
15192
+ this.message = message;
15193
+ this.filterRL = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });
15194
+ readline.emitKeypressEvents(process.stdin, this.filterRL);
15195
+ if (process.stdin.isTTY)
15196
+ process.stdin.setRawMode(true);
15197
+ }
15198
+ async filter(filterFunc) {
15199
+ stdout().write(this.promptLine());
15200
+ const resultPromise = createDefer();
15201
+ this.onKeyPress = this.filterHandler(filterFunc, (result) => {
15202
+ resultPromise.resolve(result);
15203
+ });
15204
+ process.stdin.on("keypress", this.onKeyPress);
15205
+ try {
15206
+ return await resultPromise;
15207
+ } finally {
15208
+ this.close();
15209
+ }
15210
+ }
15211
+ filterHandler(filterFunc, onSubmit) {
15212
+ return async (str, key) => {
15213
+ var _a, _b;
15214
+ switch (true) {
15215
+ case key.sequence === "\x7F":
15216
+ if (this.currentKeyword && ((_a = this.currentKeyword) == null ? void 0 : _a.length) > 1)
15217
+ this.currentKeyword = (_b = this.currentKeyword) == null ? void 0 : _b.slice(0, -1);
15218
+ else
15219
+ this.currentKeyword = void 0;
15220
+ break;
15221
+ case ((key == null ? void 0 : key.ctrl) && (key == null ? void 0 : key.name) === "c"):
15222
+ case (key == null ? void 0 : key.name) === "escape":
15223
+ this.cancel();
15224
+ onSubmit(void 0);
15225
+ break;
15226
+ case (key == null ? void 0 : key.name) === "enter":
15227
+ case (key == null ? void 0 : key.name) === "return":
15228
+ onSubmit(this.results[this.selectionIndex] || this.currentKeyword || "");
15229
+ this.currentKeyword = void 0;
15230
+ break;
15231
+ case (key == null ? void 0 : key.name) === "up":
15232
+ if (this.selectionIndex && this.selectionIndex > 0)
15233
+ this.selectionIndex--;
15234
+ else
15235
+ this.selectionIndex = -1;
15236
+ break;
15237
+ case (key == null ? void 0 : key.name) === "down":
15238
+ if (this.selectionIndex < this.results.length - 1)
15239
+ this.selectionIndex++;
15240
+ else if (this.selectionIndex >= this.results.length - 1)
15241
+ this.selectionIndex = this.results.length - 1;
15242
+ break;
15243
+ case (!(key == null ? void 0 : key.ctrl) && !(key == null ? void 0 : key.meta)):
15244
+ if (this.currentKeyword === void 0)
15245
+ this.currentKeyword = str;
15246
+ else
15247
+ this.currentKeyword += str || "";
15248
+ break;
15249
+ }
15250
+ if (this.currentKeyword)
15251
+ this.results = await filterFunc(this.currentKeyword);
15252
+ this.render();
15253
+ };
15254
+ }
15255
+ render() {
15256
+ let printStr = this.promptLine();
15257
+ if (!this.currentKeyword) {
15258
+ printStr += "\nPlease input filter pattern";
15259
+ } else if (this.currentKeyword && this.results.length === 0) {
15260
+ printStr += "\nPattern matches no results";
15261
+ } else {
15262
+ const resultCountLine = this.results.length === 1 ? `Pattern matches ${this.results.length} result` : `Pattern matches ${this.results.length} results`;
15263
+ let resultBody = "";
15264
+ if (this.results.length > MAX_RESULT_COUNT) {
15265
+ const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0;
15266
+ const displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset);
15267
+ const remainingResultCount = this.results.length - offset - displayResults.length;
15268
+ resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` \u203A ${result}`) : c.dim(` \u203A ${result}`)).join("\n")}`;
15269
+ if (remainingResultCount > 0)
15270
+ resultBody += `
15271
+ ${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "result" : "results"}`)}`;
15272
+ } else {
15273
+ resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` \u203A ${result}`) : c.dim(` \u203A ${result}`)).join("\n");
15274
+ }
15275
+ printStr += `
15276
+ ${resultCountLine}
15277
+ ${resultBody}`;
15278
+ }
15279
+ this.eraseAndPrint(printStr);
15280
+ this.restoreCursor();
15281
+ }
15282
+ keywordOffset() {
15283
+ return `? ${this.message} \u203A `.length + 1;
15284
+ }
15285
+ promptLine() {
15286
+ return `${c.cyan("?")} ${c.bold(this.message)} \u203A ${this.currentKeyword || ""}`;
15287
+ }
15288
+ eraseAndPrint(str) {
15289
+ let rows = 0;
15290
+ const lines = str.split(/\r?\n/);
15291
+ for (const line of lines)
15292
+ rows += 1 + Math.floor(Math.max(stripAnsi(line).length - 1, 0) / stdout().columns);
15293
+ stdout().write(`${ESC}1G`);
15294
+ stdout().write(`${ESC}J`);
15295
+ stdout().write(str);
15296
+ stdout().write(`${ESC}${rows - 1}A`);
15297
+ }
15298
+ close() {
15299
+ this.filterRL.close();
15300
+ if (this.onKeyPress)
15301
+ process.stdin.removeListener("keypress", this.onKeyPress);
15302
+ if (process.stdin.isTTY)
15303
+ process.stdin.setRawMode(false);
15304
+ }
15305
+ restoreCursor() {
15306
+ var _a;
15307
+ const cursortPos = this.keywordOffset() + (((_a = this.currentKeyword) == null ? void 0 : _a.length) || 0);
15308
+ stdout().write(`${ESC}${cursortPos}G`);
15309
+ }
15310
+ cancel() {
15311
+ stdout().write(`${ESC}J`);
15312
+ }
15313
+ }
15314
+
14912
15315
  const keys = [
14913
15316
  [["a", "return"], "rerun all tests"],
14914
15317
  ["r", "rerun current pattern tests"],
@@ -14975,16 +15378,20 @@ function registerConsoleShortcuts(ctx) {
14975
15378
  await _keypressHandler(str, key);
14976
15379
  }
14977
15380
  async function inputNamePattern() {
14978
- var _a;
14979
15381
  off();
14980
- const { filter = "" } = await prompt([{
14981
- name: "filter",
14982
- type: "text",
14983
- message: "Input test name pattern (RegExp)",
14984
- initial: ((_a = ctx.configOverride.testNamePattern) == null ? void 0 : _a.source) || ""
14985
- }]);
15382
+ const watchFilter = new WatchFilter("Input test name pattern (RegExp)");
15383
+ const filter = await watchFilter.filter((str) => {
15384
+ const files = ctx.state.getFiles();
15385
+ const tests = getTests(files);
15386
+ try {
15387
+ const reg = new RegExp(str);
15388
+ return tests.map((test) => test.name).filter((testName) => testName.match(reg));
15389
+ } catch {
15390
+ return [];
15391
+ }
15392
+ });
14986
15393
  on();
14987
- await ctx.changeNamePattern(filter.trim(), void 0, "change pattern");
15394
+ await ctx.changeNamePattern((filter == null ? void 0 : filter.trim()) || "", void 0, "change pattern");
14988
15395
  }
14989
15396
  async function inputProjectName() {
14990
15397
  off();
@@ -14999,15 +15406,16 @@ function registerConsoleShortcuts(ctx) {
14999
15406
  }
15000
15407
  async function inputFilePattern() {
15001
15408
  off();
15002
- const { filter = "" } = await prompt([{
15003
- name: "filter",
15004
- type: "text",
15005
- message: "Input filename pattern",
15006
- initial: latestFilename
15007
- }]);
15008
- latestFilename = filter.trim();
15409
+ const watchFilter = new WatchFilter("Input filename pattern");
15410
+ const filter = await watchFilter.filter(async (str) => {
15411
+ const files = await ctx.globTestFiles([str]);
15412
+ return files.map(
15413
+ (file) => relative(ctx.config.root, file[1])
15414
+ );
15415
+ });
15009
15416
  on();
15010
- await ctx.changeFilenamePattern(filter.trim());
15417
+ latestFilename = (filter == null ? void 0 : filter.trim()) || "";
15418
+ await ctx.changeFilenamePattern(latestFilename);
15011
15419
  }
15012
15420
  let rl;
15013
15421
  function on() {
@@ -15031,7 +15439,7 @@ function registerConsoleShortcuts(ctx) {
15031
15439
  };
15032
15440
  }
15033
15441
 
15034
- async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15442
+ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
15035
15443
  var _a, _b;
15036
15444
  process.env.TEST = "true";
15037
15445
  process.env.VITEST = "true";
@@ -15054,19 +15462,19 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15054
15462
  options.typecheck.only = true;
15055
15463
  options.typecheck.enabled = true;
15056
15464
  }
15057
- const ctx = await createVitest(mode, options, viteOverrides);
15465
+ const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);
15058
15466
  if (mode === "test" && ctx.config.coverage.enabled) {
15059
15467
  const provider = ctx.config.coverage.provider || "v8";
15060
15468
  const requiredPackages = CoverageProviderMap[provider];
15061
15469
  if (requiredPackages) {
15062
- if (!await ensurePackageInstalled(requiredPackages, root)) {
15470
+ if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root)) {
15063
15471
  process.exitCode = 1;
15064
15472
  return ctx;
15065
15473
  }
15066
15474
  }
15067
15475
  }
15068
15476
  const environmentPackage = getEnvPackageName(ctx.config.environment);
15069
- if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) {
15477
+ if (environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root)) {
15070
15478
  process.exitCode = 1;
15071
15479
  return ctx;
15072
15480
  }
@@ -15096,4 +15504,4 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15096
15504
  return ctx;
15097
15505
  }
15098
15506
 
15099
- export { BaseSequencer as B, VitestPlugin as V, createMethodsRPC as a, createVitest as c, registerConsoleShortcuts as r, startVitest as s, version$1 as v };
15507
+ export { BaseSequencer as B, VitestPlugin as V, WorkspaceProject as W, createMethodsRPC as a, VitestPackageInstaller as b, createVitest as c, registerConsoleShortcuts as r, startVitest as s, version$1 as v };