vitest 1.1.3 → 1.2.0

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 (62) 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.MAoRkVWJ.js} +60 -6
  4. package/dist/chunks/{integrations-globals.tnKXwyh5.js → integrations-globals.VbxbZ7hn.js} +9 -8
  5. package/dist/{entry.js → chunks/runtime-runBaseTests.LWFmrzDk.js} +20 -18
  6. package/dist/cli-wrapper.js +1 -1
  7. package/dist/cli.js +14 -14
  8. package/dist/config.cjs +12 -1
  9. package/dist/config.d.ts +5 -2
  10. package/dist/config.js +12 -2
  11. package/dist/coverage.d.ts +1 -1
  12. package/dist/environments.d.ts +1 -1
  13. package/dist/environments.js +1 -1
  14. package/dist/execute.d.ts +8 -6
  15. package/dist/execute.js +4 -7
  16. package/dist/index.d.ts +4 -3
  17. package/dist/index.js +8 -7
  18. package/dist/node.d.ts +3 -3
  19. package/dist/node.js +12 -12
  20. package/dist/{reporters-qc5Smpt5.d.ts → reporters-trlZlObr.d.ts} +111 -27
  21. package/dist/reporters.d.ts +1 -1
  22. package/dist/reporters.js +4 -4
  23. package/dist/runners.d.ts +1 -1
  24. package/dist/runners.js +7 -5
  25. package/dist/{suite-WwpgKT7k.d.ts → suite-6Pt_ep5V.d.ts} +1 -1
  26. package/dist/suite.d.ts +2 -2
  27. package/dist/suite.js +3 -3
  28. package/dist/vendor/base.8wUUWReP.js +38 -0
  29. package/dist/vendor/{base._79unx2z.js → base.dzu0Y6Hj.js} +10 -1
  30. package/dist/vendor/{benchmark.WVm6DARl.js → benchmark.IlKmJkUU.js} +1 -1
  31. package/dist/vendor/{constants.WSvnD_fn.js → constants.i1PoEnhr.js} +9 -1
  32. package/dist/vendor/{coverage.v6aD8iAh.js → coverage.E7sG1b3r.js} +1 -1
  33. package/dist/vendor/{environments.QJtma9XQ.js → environments.sU0TD7wX.js} +19 -7
  34. package/dist/vendor/execute.3_hyGknJ.js +589 -0
  35. package/dist/vendor/{global.L7JRz1qU.js → global.CkGT_TMy.js} +10 -1
  36. package/dist/vendor/{index.IhksUGLR.js → index.3iX2R_Z5.js} +6 -6
  37. package/dist/vendor/{index.h0j9y5vy.js → index.D-jOsMas.js} +5 -5
  38. package/dist/vendor/{index.XU72Rmy8.js → index.rJjbcrrp.js} +1 -1
  39. package/dist/vendor/{node.wTZytysZ.js → node.xyYo9ZvH.js} +650 -274
  40. package/dist/vendor/{reporters.7Y4WN6gc.js → reporters.2PaQ2peU.js} +7 -4
  41. package/dist/vendor/{rpc.Bl-ysZIr.js → rpc.w4v8oCkK.js} +23 -2
  42. package/dist/vendor/{run-once.X3E7xx3F.js → run-once.Olz_Zkd8.js} +2 -2
  43. package/dist/vendor/setup-common.j9IXYrbN.js +29 -0
  44. package/dist/vendor/utils.GbToHGHI.js +41 -0
  45. package/dist/vendor/{vi.DTC--YO5.js → vi.smj1Ggd4.js} +9 -5
  46. package/dist/vendor/vm.vFKXXdo0.js +696 -0
  47. package/dist/worker.js +109 -82
  48. package/dist/workers/forks.js +33 -0
  49. package/dist/{entry-vm.js → workers/runVmTests.js} +20 -16
  50. package/dist/workers/threads.js +26 -0
  51. package/dist/workers/vmForks.js +43 -0
  52. package/dist/workers/vmThreads.js +36 -0
  53. package/dist/workers.d.ts +36 -0
  54. package/dist/workers.js +30 -0
  55. package/package.json +11 -7
  56. package/workers.d.ts +1 -0
  57. package/dist/child.js +0 -125
  58. package/dist/vendor/execute.cedv4NLQ.js +0 -1235
  59. package/dist/vendor/inspector.lFAeuaAt.js +0 -26
  60. package/dist/vendor/loader.L9CYwKn1.js +0 -39
  61. package/dist/vm.js +0 -126
  62. /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.dzu0Y6Hj.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, inspect, positionToOffset, lineSplitRE, highlight, 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.2PaQ2peU.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.0";
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
 
@@ -3668,7 +3629,7 @@ function stringToBytes(input, percentageReference) {
3668
3629
  return null;
3669
3630
  }
3670
3631
 
3671
- const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
3632
+ const suppressWarningsPath$1 = resolve(rootDir, "./suppress-warnings.cjs");
3672
3633
  function createWorkerChannel(project) {
3673
3634
  const channel = new MessageChannel();
3674
3635
  const port = channel.port2;
@@ -3688,15 +3649,16 @@ function createWorkerChannel(project) {
3688
3649
  project.ctx.onCancel((reason) => rpc.onCancel(reason));
3689
3650
  return { workerPort, port };
3690
3651
  }
3691
- function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3652
+ function createVmThreadsPool(ctx, { execArgv, env }) {
3692
3653
  var _a;
3693
3654
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
3694
3655
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
3695
3656
  const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.vmThreads) ?? {};
3696
3657
  const maxThreads = poolOptions.maxThreads ?? ctx.config.maxWorkers ?? threadsCount;
3697
3658
  const minThreads = poolOptions.minThreads ?? ctx.config.minWorkers ?? threadsCount;
3659
+ const worker = resolve(ctx.distPath, "workers/vmThreads.js");
3698
3660
  const options = {
3699
- filename: vmPath,
3661
+ filename: resolve(ctx.distPath, "worker.js"),
3700
3662
  // TODO: investigate further
3701
3663
  // It seems atomics introduced V8 Fatal Error https://github.com/vitest-dev/vitest/issues/1191
3702
3664
  useAtomics: poolOptions.useAtomics ?? false,
@@ -3707,13 +3669,13 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3707
3669
  "--experimental-import-meta-resolve",
3708
3670
  "--experimental-vm-modules",
3709
3671
  "--require",
3710
- suppressWarningsPath,
3672
+ suppressWarningsPath$1,
3711
3673
  ...poolOptions.execArgv ?? [],
3712
3674
  ...execArgv
3713
3675
  ],
3714
3676
  terminateTimeout: ctx.config.teardownTimeout,
3715
3677
  concurrentTasksPerWorker: 1,
3716
- maxMemoryLimitBeforeRecycle: getMemoryLimit(ctx.config) || void 0
3678
+ maxMemoryLimitBeforeRecycle: getMemoryLimit$1(ctx.config) || void 0
3717
3679
  };
3718
3680
  if (poolOptions.singleThread || !ctx.config.fileParallelism) {
3719
3681
  options.maxThreads = 1;
@@ -3727,6 +3689,8 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3727
3689
  const { workerPort, port } = createWorkerChannel(project);
3728
3690
  const workerId = ++id;
3729
3691
  const data = {
3692
+ pool: "vmThreads",
3693
+ worker,
3730
3694
  port: workerPort,
3731
3695
  config,
3732
3696
  files,
@@ -3771,15 +3735,10 @@ function createVmThreadsPool(ctx, { execArgv, env, vmPath }) {
3771
3735
  return {
3772
3736
  name: "vmThreads",
3773
3737
  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
- }
3738
+ close: () => pool.destroy()
3780
3739
  };
3781
3740
  }
3782
- function getMemoryLimit(config) {
3741
+ function getMemoryLimit$1(config) {
3783
3742
  const memory = nodeos.totalmem();
3784
3743
  const limit = getWorkerMemoryLimit(config);
3785
3744
  if (typeof memory === "number") {
@@ -3799,7 +3758,7 @@ function B(e){return e.startsWith("\\\\?\\")?e:e.replace(/\\/g,"/")}const x=e=>{
3799
3758
  `;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
3759
  `),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
3760
 
3802
- const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
3761
+ const __dirname$1 = url.fileURLToPath(new URL(".", import.meta.url));
3803
3762
  const newLineRegExp = /\r?\n/;
3804
3763
  const errCodeRegExp = /error TS(?<errCode>\d+)/;
3805
3764
  async function makeTscErrorInfo(errInfo) {
@@ -3847,7 +3806,7 @@ async function getTsconfig(root, config) {
3847
3806
  tmpTsConfig.compilerOptions.emitDeclarationOnly = false;
3848
3807
  tmpTsConfig.compilerOptions.incremental = true;
3849
3808
  tmpTsConfig.compilerOptions.tsBuildInfoFile = join(
3850
- process.versions.pnp ? join(nodeos__default.tmpdir(), "vitest") : __dirname,
3809
+ process.versions.pnp ? join(nodeos__default.tmpdir(), "vitest") : __dirname$1,
3851
3810
  "tsconfig.tmp.tsbuildinfo"
3852
3811
  );
3853
3812
  const tsconfigFinalContent = JSON.stringify(tmpTsConfig, null, 2);
@@ -4203,15 +4162,14 @@ class Typechecker {
4203
4162
  await this.clear();
4204
4163
  (_a = this.process) == null ? void 0 : _a.kill();
4205
4164
  }
4206
- async ensurePackageInstalled(root, checker) {
4165
+ async ensurePackageInstalled(ctx, checker) {
4207
4166
  if (checker !== "tsc" && checker !== "vue-tsc")
4208
4167
  return;
4209
4168
  const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
4210
- await ensurePackageInstalled(packageName, root);
4169
+ await ctx.packageInstaller.ensureInstalled(packageName, ctx.config.root);
4211
4170
  }
4212
4171
  async prepare() {
4213
4172
  const { root, typecheck } = this.ctx.config;
4214
- await this.ensurePackageInstalled(root, typecheck.checker);
4215
4173
  const { config, path } = await getTsconfig(root, typecheck);
4216
4174
  this.tempConfigPath = path;
4217
4175
  this.allowJs = typecheck.allowJs || config.allowJs || false;
@@ -4380,13 +4338,150 @@ function createTypecheckPool(ctx) {
4380
4338
  };
4381
4339
  }
4382
4340
 
4383
- const builtinPools = ["forks", "threads", "browser", "vmThreads", "typescript"];
4341
+ const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
4342
+ function createChildProcessChannel(project) {
4343
+ const emitter = new EventEmitter();
4344
+ const cleanup = () => emitter.removeAllListeners();
4345
+ const events = { message: "message", response: "response" };
4346
+ const channel = {
4347
+ onMessage: (callback) => emitter.on(events.message, callback),
4348
+ postMessage: (message) => emitter.emit(events.response, message)
4349
+ };
4350
+ const rpc = createBirpc(
4351
+ createMethodsRPC(project),
4352
+ {
4353
+ eventNames: ["onCancel"],
4354
+ serialize: v8.serialize,
4355
+ deserialize: (v) => v8.deserialize(Buffer.from(v)),
4356
+ post(v) {
4357
+ emitter.emit(events.message, v);
4358
+ },
4359
+ on(fn) {
4360
+ emitter.on(events.response, fn);
4361
+ }
4362
+ }
4363
+ );
4364
+ project.ctx.onCancel((reason) => rpc.onCancel(reason));
4365
+ return { channel, cleanup };
4366
+ }
4367
+ function stringifyRegex(input) {
4368
+ if (typeof input === "string")
4369
+ return input;
4370
+ return `$$vitest:${input.toString()}`;
4371
+ }
4372
+ function createVmForksPool(ctx, { execArgv, env }) {
4373
+ var _a;
4374
+ const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length;
4375
+ const threadsCount = ctx.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
4376
+ const poolOptions = ((_a = ctx.config.poolOptions) == null ? void 0 : _a.vmForks) ?? {};
4377
+ const maxThreads = poolOptions.maxForks ?? ctx.config.maxWorkers ?? threadsCount;
4378
+ const minThreads = poolOptions.maxForks ?? ctx.config.minWorkers ?? threadsCount;
4379
+ const worker = resolve(ctx.distPath, "workers/vmForks.js");
4380
+ const options = {
4381
+ runtime: "child_process",
4382
+ filename: resolve(ctx.distPath, "worker.js"),
4383
+ maxThreads,
4384
+ minThreads,
4385
+ env,
4386
+ execArgv: [
4387
+ "--experimental-import-meta-resolve",
4388
+ "--experimental-vm-modules",
4389
+ "--require",
4390
+ suppressWarningsPath,
4391
+ ...poolOptions.execArgv ?? [],
4392
+ ...execArgv
4393
+ ],
4394
+ terminateTimeout: ctx.config.teardownTimeout,
4395
+ concurrentTasksPerWorker: 1,
4396
+ maxMemoryLimitBeforeRecycle: getMemoryLimit(ctx.config) || void 0
4397
+ };
4398
+ if (poolOptions.singleFork || !ctx.config.fileParallelism) {
4399
+ options.maxThreads = 1;
4400
+ options.minThreads = 1;
4401
+ }
4402
+ const pool = new Tinypool$1(options);
4403
+ const runWithFiles = (name) => {
4404
+ let id = 0;
4405
+ async function runFiles(project, config, files, environment, invalidates = []) {
4406
+ ctx.state.clearFiles(project, files);
4407
+ const { channel, cleanup } = createChildProcessChannel(project);
4408
+ const workerId = ++id;
4409
+ const data = {
4410
+ pool: "forks",
4411
+ worker,
4412
+ config,
4413
+ files,
4414
+ invalidates,
4415
+ environment,
4416
+ workerId,
4417
+ projectName: project.getName(),
4418
+ providedContext: project.getProvidedContext()
4419
+ };
4420
+ try {
4421
+ await pool.run(data, { name, channel });
4422
+ } catch (error) {
4423
+ if (error instanceof Error && /Failed to terminate worker/.test(error.message))
4424
+ ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.`);
4425
+ else if (ctx.isCancelling && error instanceof Error && /The task has been cancelled/.test(error.message))
4426
+ ctx.state.cancelFiles(files, ctx.config.root, project.config.name);
4427
+ else
4428
+ throw error;
4429
+ } finally {
4430
+ cleanup();
4431
+ }
4432
+ }
4433
+ return async (specs, invalidates) => {
4434
+ ctx.onCancel(() => pool.cancelPendingTasks());
4435
+ const configs = /* @__PURE__ */ new Map();
4436
+ const getConfig = (project) => {
4437
+ if (configs.has(project))
4438
+ return configs.get(project);
4439
+ const _config = project.getSerializableConfig();
4440
+ const config = {
4441
+ ..._config,
4442
+ // v8 serialize does not support regex
4443
+ testNamePattern: _config.testNamePattern ? stringifyRegex(_config.testNamePattern) : void 0
4444
+ };
4445
+ configs.set(project, config);
4446
+ return config;
4447
+ };
4448
+ const filesByEnv = await groupFilesByEnv(specs);
4449
+ const promises = Object.values(filesByEnv).flat();
4450
+ const results = await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates)));
4451
+ const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
4452
+ if (errors.length > 0)
4453
+ throw new AggregateErrorPonyfill(errors, "Errors occurred while running tests. For more information, see serialized error.");
4454
+ };
4455
+ };
4456
+ return {
4457
+ name: "vmForks",
4458
+ runTests: runWithFiles("run"),
4459
+ close: () => pool.destroy()
4460
+ };
4461
+ }
4462
+ function getMemoryLimit(config) {
4463
+ const memory = nodeos.totalmem();
4464
+ const limit = getWorkerMemoryLimit(config);
4465
+ if (typeof memory === "number") {
4466
+ return stringToBytes(
4467
+ limit,
4468
+ config.watch ? memory / 2 : memory
4469
+ );
4470
+ }
4471
+ if (typeof limit === "number" && limit > 1 || typeof limit === "string" && limit.at(-1) !== "%")
4472
+ return stringToBytes(limit);
4473
+ return null;
4474
+ }
4475
+
4476
+ const builtinPools = ["forks", "threads", "browser", "vmThreads", "vmForks", "typescript"];
4384
4477
  function createPool(ctx) {
4478
+ var _a;
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,12 @@ function createPool(ctx) {
4409
4504
  }
4410
4505
  return getDefaultPoolName(project, file);
4411
4506
  }
4507
+ const conditions = ((_a = ctx.server.config.resolve.conditions) == null ? void 0 : _a.flatMap((c) => ["--conditions", c])) || [];
4508
+ const execArgv = process.execArgv.filter(
4509
+ (execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")
4510
+ );
4412
4511
  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
4512
  const options = {
4419
- ...ctx.projectFiles,
4420
4513
  execArgv: [
4421
4514
  ...execArgv,
4422
4515
  ...conditions
@@ -4450,8 +4543,17 @@ function createPool(ctx) {
4450
4543
  threads: [],
4451
4544
  browser: [],
4452
4545
  vmThreads: [],
4546
+ vmForks: [],
4453
4547
  typescript: []
4454
4548
  };
4549
+ const factories = {
4550
+ browser: () => createBrowserPool(ctx),
4551
+ vmThreads: () => createVmThreadsPool(ctx, options),
4552
+ threads: () => createThreadsPool(ctx, options),
4553
+ forks: () => createForksPool(ctx, options),
4554
+ vmForks: () => createVmForksPool(ctx, options),
4555
+ typescript: () => createTypecheckPool(ctx)
4556
+ };
4455
4557
  for (const spec of files) {
4456
4558
  const pool = getPoolName(spec);
4457
4559
  filesByPool[pool] ?? (filesByPool[pool] = []);
@@ -4470,25 +4572,10 @@ function createPool(ctx) {
4470
4572
  if (!files2.length)
4471
4573
  return null;
4472
4574
  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);
4575
+ if (pool in factories) {
4576
+ const factory = factories[pool];
4577
+ pools[pool] ?? (pools[pool] = factory());
4578
+ return pools[pool].runTests(specs, invalidate);
4492
4579
  }
4493
4580
  const poolHandler = await resolveCustomPool(pool);
4494
4581
  pools[_a2 = poolHandler.name] ?? (pools[_a2] = poolHandler);
@@ -4500,8 +4587,8 @@ function createPool(ctx) {
4500
4587
  runTests,
4501
4588
  async close() {
4502
4589
  await Promise.all(Object.values(pools).map((p) => {
4503
- var _a;
4504
- return (_a = p == null ? void 0 : p.close) == null ? void 0 : _a.call(p);
4590
+ var _a2;
4591
+ return (_a2 = p == null ? void 0 : p.close) == null ? void 0 : _a2.call(p);
4505
4592
  }));
4506
4593
  }
4507
4594
  };
@@ -4518,11 +4605,12 @@ async function loadCustomReporterModule(path, runner) {
4518
4605
  throw new Error(`Custom reporter loaded from ${path} was not the default export`);
4519
4606
  return customReporterModule.default;
4520
4607
  }
4521
- function createReporters(reporterReferences, runner) {
4608
+ function createReporters(reporterReferences, ctx) {
4609
+ const runner = ctx.runner;
4522
4610
  const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
4523
4611
  if (typeof referenceOrInstance === "string") {
4524
4612
  if (referenceOrInstance === "html") {
4525
- await ensurePackageInstalled("@vitest/ui", runner.root);
4613
+ await ctx.packageInstaller.ensureInstalled("@vitest/ui", runner.root);
4526
4614
  const CustomReporter = await loadCustomReporterModule("@vitest/ui/reporter", runner);
4527
4615
  return new CustomReporter();
4528
4616
  } else if (referenceOrInstance in ReportersMap) {
@@ -4789,7 +4877,8 @@ const config = {
4789
4877
  include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"],
4790
4878
  exclude: defaultExclude
4791
4879
  },
4792
- slowTestThreshold: 300
4880
+ slowTestThreshold: 300,
4881
+ disableConsoleIntercept: false
4793
4882
  };
4794
4883
  const configDefaults = Object.freeze(config);
4795
4884
 
@@ -4972,14 +5061,6 @@ class RandomSequencer extends BaseSequencer {
4972
5061
  }
4973
5062
  }
4974
5063
 
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
5064
  function resolvePath(path, root) {
4984
5065
  return normalize(
4985
5066
  resolveModule(path, { paths: [root] }) ?? resolve(root, path)
@@ -5014,7 +5095,7 @@ function resolveApiServerConfig(options) {
5014
5095
  return api;
5015
5096
  }
5016
5097
  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;
5098
+ 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
5099
  if (options.dom) {
5019
5100
  if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
5020
5101
  console.warn(
@@ -5047,6 +5128,10 @@ function resolveConfig(mode, options, viteConfig) {
5047
5128
  throw new Error("--shard <index> must be a positive number less then <count>");
5048
5129
  resolved.shard = { index, count };
5049
5130
  }
5131
+ if (resolved.maxWorkers)
5132
+ resolved.maxWorkers = Number(resolved.maxWorkers);
5133
+ if (resolved.minWorkers)
5134
+ resolved.minWorkers = Number(resolved.minWorkers);
5050
5135
  resolved.fileParallelism ?? (resolved.fileParallelism = true);
5051
5136
  if (!resolved.fileParallelism) {
5052
5137
  resolved.maxWorkers = 1;
@@ -5165,6 +5250,10 @@ function resolveConfig(mode, options, viteConfig) {
5165
5250
  forks: {
5166
5251
  ...(_w = resolved.poolOptions) == null ? void 0 : _w.forks,
5167
5252
  maxForks: Number.parseInt(process.env.VITEST_MAX_FORKS)
5253
+ },
5254
+ vmForks: {
5255
+ ...(_x = resolved.poolOptions) == null ? void 0 : _x.vmForks,
5256
+ maxForks: Number.parseInt(process.env.VITEST_MAX_FORKS)
5168
5257
  }
5169
5258
  };
5170
5259
  }
@@ -5172,7 +5261,11 @@ function resolveConfig(mode, options, viteConfig) {
5172
5261
  resolved.poolOptions = {
5173
5262
  ...resolved.poolOptions,
5174
5263
  forks: {
5175
- ...(_x = resolved.poolOptions) == null ? void 0 : _x.forks,
5264
+ ...(_y = resolved.poolOptions) == null ? void 0 : _y.forks,
5265
+ minForks: Number.parseInt(process.env.VITEST_MIN_FORKS)
5266
+ },
5267
+ vmForks: {
5268
+ ...(_z = resolved.poolOptions) == null ? void 0 : _z.vmForks,
5176
5269
  minForks: Number.parseInt(process.env.VITEST_MIN_FORKS)
5177
5270
  }
5178
5271
  };
@@ -5241,33 +5334,33 @@ function resolveConfig(mode, options, viteConfig) {
5241
5334
  resolved.passWithNoTests ?? (resolved.passWithNoTests = true);
5242
5335
  resolved.css ?? (resolved.css = {});
5243
5336
  if (typeof resolved.css === "object") {
5244
- (_y = resolved.css).modules ?? (_y.modules = {});
5245
- (_z = resolved.css.modules).classNameStrategy ?? (_z.classNameStrategy = "stable");
5337
+ (_A = resolved.css).modules ?? (_A.modules = {});
5338
+ (_B = resolved.css.modules).classNameStrategy ?? (_B.classNameStrategy = "stable");
5246
5339
  }
5247
5340
  resolved.cache ?? (resolved.cache = { dir: "" });
5248
5341
  if (resolved.cache)
5249
5342
  resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir, resolved.name);
5250
5343
  resolved.sequence ?? (resolved.sequence = {});
5251
- if (!((_A = resolved.sequence) == null ? void 0 : _A.sequencer)) {
5344
+ if (!((_C = resolved.sequence) == null ? void 0 : _C.sequencer)) {
5252
5345
  resolved.sequence.sequencer = resolved.sequence.shuffle ? RandomSequencer : BaseSequencer;
5253
5346
  }
5254
- (_B = resolved.sequence).hooks ?? (_B.hooks = "parallel");
5347
+ (_D = resolved.sequence).hooks ?? (_D.hooks = "parallel");
5255
5348
  if (resolved.sequence.sequencer === RandomSequencer)
5256
- (_C = resolved.sequence).seed ?? (_C.seed = Date.now());
5349
+ (_E = resolved.sequence).seed ?? (_E.seed = Date.now());
5257
5350
  resolved.typecheck = {
5258
5351
  ...configDefaults.typecheck,
5259
5352
  ...resolved.typecheck
5260
5353
  };
5261
5354
  resolved.environmentMatchGlobs = (resolved.environmentMatchGlobs || []).map((i) => [resolve(resolved.root, i[0]), i[1]]);
5262
5355
  resolved.typecheck ?? (resolved.typecheck = {});
5263
- (_D = resolved.typecheck).enabled ?? (_D.enabled = false);
5356
+ (_F = resolved.typecheck).enabled ?? (_F.enabled = false);
5264
5357
  if (resolved.typecheck.enabled)
5265
5358
  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
5359
  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);
5360
+ (_G = resolved.browser).enabled ?? (_G.enabled = false);
5361
+ (_H = resolved.browser).headless ?? (_H.headless = isCI);
5362
+ (_I = resolved.browser).slowHijackESM ?? (_I.slowHijackESM = false);
5363
+ (_J = resolved.browser).isolate ?? (_J.isolate = true);
5271
5364
  if (resolved.browser.enabled && provider$1 === "stackblitz")
5272
5365
  resolved.browser.provider = "none";
5273
5366
  resolved.browser.api = resolveApiServerConfig(resolved.browser) || {
@@ -5281,7 +5374,7 @@ function isBrowserEnabled(config) {
5281
5374
  return Boolean((_a = config.browser) == null ? void 0 : _a.enabled);
5282
5375
  }
5283
5376
 
5284
- const ESC$1 = '\u001B[';
5377
+ const ESC$2 = '\u001B[';
5285
5378
  const OSC = '\u001B]';
5286
5379
  const BEL = '\u0007';
5287
5380
  const SEP = ';';
@@ -5295,10 +5388,10 @@ ansiEscapes.cursorTo = (x, y) => {
5295
5388
  }
5296
5389
 
5297
5390
  if (typeof y !== 'number') {
5298
- return ESC$1 + (x + 1) + 'G';
5391
+ return ESC$2 + (x + 1) + 'G';
5299
5392
  }
5300
5393
 
5301
- return ESC$1 + (y + 1) + ';' + (x + 1) + 'H';
5394
+ return ESC$2 + (y + 1) + ';' + (x + 1) + 'H';
5302
5395
  };
5303
5396
 
5304
5397
  ansiEscapes.cursorMove = (x, y) => {
@@ -5309,33 +5402,33 @@ ansiEscapes.cursorMove = (x, y) => {
5309
5402
  let returnValue = '';
5310
5403
 
5311
5404
  if (x < 0) {
5312
- returnValue += ESC$1 + (-x) + 'D';
5405
+ returnValue += ESC$2 + (-x) + 'D';
5313
5406
  } else if (x > 0) {
5314
- returnValue += ESC$1 + x + 'C';
5407
+ returnValue += ESC$2 + x + 'C';
5315
5408
  }
5316
5409
 
5317
5410
  if (y < 0) {
5318
- returnValue += ESC$1 + (-y) + 'A';
5411
+ returnValue += ESC$2 + (-y) + 'A';
5319
5412
  } else if (y > 0) {
5320
- returnValue += ESC$1 + y + 'B';
5413
+ returnValue += ESC$2 + y + 'B';
5321
5414
  }
5322
5415
 
5323
5416
  return returnValue;
5324
5417
  };
5325
5418
 
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';
5419
+ ansiEscapes.cursorUp = (count = 1) => ESC$2 + count + 'A';
5420
+ ansiEscapes.cursorDown = (count = 1) => ESC$2 + count + 'B';
5421
+ ansiEscapes.cursorForward = (count = 1) => ESC$2 + count + 'C';
5422
+ ansiEscapes.cursorBackward = (count = 1) => ESC$2 + count + 'D';
5330
5423
 
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';
5424
+ ansiEscapes.cursorLeft = ESC$2 + 'G';
5425
+ ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC$2 + 's';
5426
+ ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC$2 + 'u';
5427
+ ansiEscapes.cursorGetPosition = ESC$2 + '6n';
5428
+ ansiEscapes.cursorNextLine = ESC$2 + 'E';
5429
+ ansiEscapes.cursorPrevLine = ESC$2 + 'F';
5430
+ ansiEscapes.cursorHide = ESC$2 + '?25l';
5431
+ ansiEscapes.cursorShow = ESC$2 + '?25h';
5339
5432
 
5340
5433
  ansiEscapes.eraseLines = count => {
5341
5434
  let clear = '';
@@ -5351,24 +5444,24 @@ ansiEscapes.eraseLines = count => {
5351
5444
  return clear;
5352
5445
  };
5353
5446
 
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';
5447
+ ansiEscapes.eraseEndLine = ESC$2 + 'K';
5448
+ ansiEscapes.eraseStartLine = ESC$2 + '1K';
5449
+ ansiEscapes.eraseLine = ESC$2 + '2K';
5450
+ ansiEscapes.eraseDown = ESC$2 + 'J';
5451
+ ansiEscapes.eraseUp = ESC$2 + '1J';
5452
+ ansiEscapes.eraseScreen = ESC$2 + '2J';
5453
+ ansiEscapes.scrollUp = ESC$2 + 'S';
5454
+ ansiEscapes.scrollDown = ESC$2 + 'T';
5362
5455
 
5363
5456
  ansiEscapes.clearScreen = '\u001Bc';
5364
5457
 
5365
5458
  ansiEscapes.clearTerminal = process.platform === 'win32' ?
5366
- `${ansiEscapes.eraseScreen}${ESC$1}0f` :
5459
+ `${ansiEscapes.eraseScreen}${ESC$2}0f` :
5367
5460
  // 1. Erases the screen (Only done in case `2` is not supported)
5368
5461
  // 2. Erases the whole screen including scrollback buffer
5369
5462
  // 3. Moves cursor to the top-left position
5370
5463
  // More info: https://www.real-world-systems.com/docs/ANSIcode.html
5371
- `${ansiEscapes.eraseScreen}${ESC$1}3J${ESC$1}H`;
5464
+ `${ansiEscapes.eraseScreen}${ESC$2}3J${ESC$2}H`;
5372
5465
 
5373
5466
  ansiEscapes.beep = BEL;
5374
5467
 
@@ -6480,7 +6573,7 @@ createLogUpdate(process$2.stdout);
6480
6573
 
6481
6574
  createLogUpdate(process$2.stderr);
6482
6575
 
6483
- var version = "1.1.3";
6576
+ var version = "1.2.0";
6484
6577
 
6485
6578
  async function printError(error, project, options) {
6486
6579
  const { showCodeFrame = true, fullStack = false, type } = options;
@@ -6510,12 +6603,21 @@ async function printError(error, project, options) {
6510
6603
  parserOptions.ignoreStackEntries = [];
6511
6604
  const stacks = parseErrorStacktrace(e, parserOptions);
6512
6605
  const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
6513
- (stack) => project.getModuleById(stack.file) && existsSync(stack.file)
6606
+ (stack) => {
6607
+ try {
6608
+ return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
6609
+ } catch {
6610
+ return false;
6611
+ }
6612
+ }
6514
6613
  );
6515
6614
  const errorProperties = getErrorProperties(e);
6516
6615
  if (type)
6517
6616
  printErrorType(type, project.ctx);
6518
6617
  printErrorMessage(e, logger);
6618
+ if (e.codeFrame)
6619
+ logger.error(`${e.codeFrame}
6620
+ `);
6519
6621
  if (e.diff)
6520
6622
  displayDiff(e.diff, logger.console);
6521
6623
  if (e.frame) {
@@ -6524,7 +6626,7 @@ async function printError(error, project, options) {
6524
6626
  printStack(project, stacks, nearest, errorProperties, (s) => {
6525
6627
  if (showCodeFrame && s === nearest && nearest) {
6526
6628
  const sourceCode = readFileSync(nearest.file, "utf-8");
6527
- logger.error(generateCodeFrame(sourceCode, 4, s.line, s.column));
6629
+ logger.error(generateCodeFrame(sourceCode.length > 1e5 ? sourceCode : logger.highlight(nearest.file, sourceCode), 4, s));
6528
6630
  }
6529
6631
  });
6530
6632
  }
@@ -6536,7 +6638,7 @@ async function printError(error, project, options) {
6536
6638
  if (testName) {
6537
6639
  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
6640
  - 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.`));
6641
+ - If the error occurred after the test had been completed, this was the last documented test before it was thrown.`));
6540
6642
  }
6541
6643
  if (afterEnvTeardown) {
6542
6644
  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 +6662,7 @@ const skipErrorProperties = /* @__PURE__ */ new Set([
6560
6662
  "type",
6561
6663
  "showDiff",
6562
6664
  "diff",
6665
+ "codeFrame",
6563
6666
  "actual",
6564
6667
  "expected",
6565
6668
  "diffOptions",
@@ -6657,9 +6760,9 @@ function printStack(project, stack, highlight, errorProperties, onStack) {
6657
6760
  logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
6658
6761
  }
6659
6762
  }
6660
- function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range = 2) {
6763
+ function generateCodeFrame(source, indent = 0, loc, range = 2) {
6661
6764
  var _a;
6662
- const start = positionToOffset(source, lineNumber, columnNumber);
6765
+ const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc;
6663
6766
  const end = start;
6664
6767
  const lines = source.split(lineSplitRE);
6665
6768
  const nl = /\r\n/.test(source) ? 2 : 1;
@@ -6699,20 +6802,30 @@ function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range =
6699
6802
  return res.join("\n");
6700
6803
  }
6701
6804
 
6702
- const ESC = "\x1B[";
6703
- const ERASE_DOWN = `${ESC}J`;
6704
- const ERASE_SCROLLBACK = `${ESC}3J`;
6705
- const CURSOR_TO_START = `${ESC}1;1H`;
6805
+ const ESC$1 = "\x1B[";
6806
+ const ERASE_DOWN = `${ESC$1}J`;
6807
+ const ERASE_SCROLLBACK = `${ESC$1}3J`;
6808
+ const CURSOR_TO_START = `${ESC$1}1;1H`;
6706
6809
  const CLEAR_SCREEN = "\x1Bc";
6810
+ const HIGHLIGHT_SUPPORTED_EXTS = new Set(["js", "ts"].flatMap((lang) => [
6811
+ `.${lang}`,
6812
+ `.m${lang}`,
6813
+ `.c${lang}`,
6814
+ `.${lang}x`,
6815
+ `.m${lang}x`,
6816
+ `.c${lang}x`
6817
+ ]));
6707
6818
  class Logger {
6708
6819
  constructor(ctx, console = globalThis.console) {
6709
6820
  this.ctx = ctx;
6710
6821
  this.console = console;
6822
+ this._highlights.clear();
6711
6823
  }
6712
6824
  outputStream = process.stdout;
6713
6825
  errorStream = process.stderr;
6714
6826
  logUpdate = createLogUpdate(process.stdout);
6715
6827
  _clearScreenPending;
6828
+ _highlights = /* @__PURE__ */ new Map();
6716
6829
  log(...args) {
6717
6830
  this._clearScreen();
6718
6831
  this.console.log(...args);
@@ -6758,6 +6871,23 @@ class Logger {
6758
6871
  logger: this
6759
6872
  });
6760
6873
  }
6874
+ clearHighlightCache(filename) {
6875
+ if (filename)
6876
+ this._highlights.delete(filename);
6877
+ else
6878
+ this._highlights.clear();
6879
+ }
6880
+ highlight(filename, source) {
6881
+ if (this._highlights.has(filename))
6882
+ return this._highlights.get(filename);
6883
+ const ext = extname(filename);
6884
+ if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
6885
+ return source;
6886
+ const isJsx = ext.endsWith("x");
6887
+ const code = highlight(source, { jsx: isJsx, colors: c });
6888
+ this._highlights.set(filename, code);
6889
+ return code;
6890
+ }
6761
6891
  printNoTestFound(filters) {
6762
6892
  var _a;
6763
6893
  const config = this.ctx.config;
@@ -6898,8 +7028,8 @@ const regexpAssignedHoisted = /=[ \t]*(\bawait|)[ \t]*\b(vi|vitest)\s*\.\s*hoist
6898
7028
  const hashbangRE = /^#!.*\n/;
6899
7029
  function hoistMocks(code, id, parse) {
6900
7030
  var _a;
6901
- const hasMocks = regexpHoistable.test(code) || regexpAssignedHoisted.test(code);
6902
- if (!hasMocks)
7031
+ const needHoisting = regexpHoistable.test(code) || regexpAssignedHoisted.test(code);
7032
+ if (!needHoisting)
6903
7033
  return;
6904
7034
  const s = new MagicString(code);
6905
7035
  let ast;
@@ -6984,7 +7114,7 @@ ${err.message}`);
6984
7114
  }
6985
7115
  },
6986
7116
  onCallExpression(node) {
6987
- var _a2, _b;
7117
+ var _a2, _b, _c;
6988
7118
  if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object) && (node.callee.object.name === "vi" || node.callee.object.name === "vitest") && isIdentifier(node.callee.property)) {
6989
7119
  const methodName = node.callee.property.name;
6990
7120
  if (methodName === "mock" || methodName === "unmock")
@@ -6999,12 +7129,57 @@ ${err.message}`);
6999
7129
  if (canMoveDeclaration) {
7000
7130
  hoistedNodes.push(declarationNode);
7001
7131
  } else {
7002
- hoistedNodes.push(node);
7132
+ const awaitedExpression = (_c = findNodeAround(ast, node.start, "AwaitExpression")) == null ? void 0 : _c.node;
7133
+ hoistedNodes.push((awaitedExpression == null ? void 0 : awaitedExpression.argument) === node ? awaitedExpression : node);
7003
7134
  }
7004
7135
  }
7005
7136
  }
7006
7137
  }
7007
7138
  });
7139
+ function getNodeName(node) {
7140
+ const callee = node.callee || {};
7141
+ if (callee.type === "MemberExpression" && isIdentifier(callee.property) && isIdentifier(callee.object))
7142
+ return `${callee.object.name}.${callee.property.name}()`;
7143
+ return '"hoisted method"';
7144
+ }
7145
+ function getNodeCall(node) {
7146
+ if (node.type === "CallExpression")
7147
+ return node;
7148
+ if (node.type === "VariableDeclaration") {
7149
+ const { declarations } = node;
7150
+ const init = declarations[0].init;
7151
+ if (init)
7152
+ return getNodeCall(init);
7153
+ }
7154
+ if (node.type === "AwaitExpression") {
7155
+ const { argument } = node;
7156
+ if (argument.type === "CallExpression")
7157
+ return getNodeCall(argument);
7158
+ }
7159
+ return node;
7160
+ }
7161
+ function createError(outsideNode, insideNode) {
7162
+ const outsideCall = getNodeCall(outsideNode);
7163
+ const insideCall = getNodeCall(insideNode);
7164
+ const _error = new SyntaxError(`Cannot call ${getNodeName(insideCall)} inside ${getNodeName(outsideCall)}: both methods are hoisted to the top of the file and not actually called inside each other.`);
7165
+ const error = {
7166
+ name: "SyntaxError",
7167
+ message: _error.message,
7168
+ stack: _error.stack,
7169
+ frame: generateCodeFrame(highlight(code), 4, insideCall.start + 1)
7170
+ };
7171
+ throw error;
7172
+ }
7173
+ for (let i = 0; i < hoistedNodes.length; i++) {
7174
+ const node = hoistedNodes[i];
7175
+ for (let j = i + 1; j < hoistedNodes.length; j++) {
7176
+ const otherNode = hoistedNodes[j];
7177
+ if (node.start >= otherNode.start && node.end <= otherNode.end)
7178
+ throw createError(otherNode, node);
7179
+ if (otherNode.start >= node.start && otherNode.end <= node.end)
7180
+ throw createError(node, otherNode);
7181
+ }
7182
+ }
7008
7183
  const hoistedCode = hoistedNodes.map((node) => {
7009
7184
  const end = getBetterEnd(code, node);
7010
7185
  const nodeCode = s.slice(node.start, end);
@@ -7125,7 +7300,7 @@ function resolveFsAllow(projectRoot, rootConfigFile) {
7125
7300
 
7126
7301
  async function createBrowserServer(project, configFile) {
7127
7302
  const root = project.config.root;
7128
- await ensurePackageInstalled("@vitest/browser", root);
7303
+ await project.ctx.packageInstaller.ensureInstalled("@vitest/browser", root);
7129
7304
  const configPath = typeof configFile === "string" ? configFile : false;
7130
7305
  const server = await createServer({
7131
7306
  logLevel: "error",
@@ -7176,21 +7351,21 @@ async function createBrowserServer(project, configFile) {
7176
7351
  ]
7177
7352
  });
7178
7353
  await server.listen();
7179
- (await import('../chunks/api-setup.mFKdEKxa.js')).setup(project, server);
7354
+ (await import('../chunks/api-setup.MAoRkVWJ.js')).setup(project, server);
7180
7355
  return server;
7181
7356
  }
7182
7357
 
7183
7358
  const builtinProviders = ["webdriverio", "playwright", "none"];
7184
- async function getBrowserProvider(options, loader) {
7359
+ async function getBrowserProvider(options, project) {
7185
7360
  if (options.provider == null || builtinProviders.includes(options.provider)) {
7186
- await ensurePackageInstalled("@vitest/browser", loader.root);
7187
- const providers = await loader.executeId("@vitest/browser/providers");
7361
+ await project.ctx.packageInstaller.ensureInstalled("@vitest/browser", project.config.root);
7362
+ const providers = await project.runner.executeId("@vitest/browser/providers");
7188
7363
  const provider = options.provider || "webdriverio";
7189
7364
  return providers[provider];
7190
7365
  }
7191
7366
  let customProviderModule;
7192
7367
  try {
7193
- customProviderModule = await loader.executeId(options.provider);
7368
+ customProviderModule = await project.runner.executeId(options.provider);
7194
7369
  } catch (error) {
7195
7370
  throw new Error(`Failed to load custom BrowserProvider from ${options.provider}`, { cause: error });
7196
7371
  }
@@ -7686,10 +7861,10 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7686
7861
  filters = filters.map((f) => toNamespacedPath(f));
7687
7862
  if (filters.length) {
7688
7863
  return testFiles.filter((t) => {
7689
- const testFile = relative(dir, t);
7864
+ const testFile = relative(dir, t).toLocaleLowerCase();
7690
7865
  return filters.some((f) => {
7691
7866
  const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
7692
- return testFile.includes(f) || testFile.includes(relativePath);
7867
+ return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
7693
7868
  });
7694
7869
  });
7695
7870
  }
@@ -7732,29 +7907,39 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7732
7907
  });
7733
7908
  await this.initBrowserServer(this.server.config.configFile);
7734
7909
  }
7735
- async report(name, ...args) {
7736
- return this.ctx.report(name, ...args);
7737
- }
7738
7910
  isBrowserEnabled() {
7739
7911
  return isBrowserEnabled(this.config);
7740
7912
  }
7741
7913
  getSerializableConfig() {
7742
- var _a, _b, _c;
7914
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
7743
7915
  const optimizer = (_a = this.config.deps) == null ? void 0 : _a.optimizer;
7916
+ const poolOptions = this.config.poolOptions;
7917
+ const isolate = (_d = (_c = (_b = this.server) == null ? void 0 : _b.config) == null ? void 0 : _c.test) == null ? void 0 : _d.isolate;
7744
7918
  return deepMerge({
7745
7919
  ...this.config,
7746
7920
  coverage: this.ctx.config.coverage,
7747
- pool: this.ctx.config.pool,
7748
- poolOptions: this.ctx.config.poolOptions,
7921
+ poolOptions: {
7922
+ forks: {
7923
+ 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,
7924
+ 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
7925
+ },
7926
+ threads: {
7927
+ 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,
7928
+ 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
7929
+ },
7930
+ vmThreads: {
7931
+ 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
7932
+ }
7933
+ },
7749
7934
  reporters: [],
7750
7935
  deps: {
7751
7936
  ...this.config.deps,
7752
7937
  optimizer: {
7753
7938
  web: {
7754
- enabled: ((_b = optimizer == null ? void 0 : optimizer.web) == null ? void 0 : _b.enabled) ?? true
7939
+ enabled: ((_t = optimizer == null ? void 0 : optimizer.web) == null ? void 0 : _t.enabled) ?? true
7755
7940
  },
7756
7941
  ssr: {
7757
- enabled: ((_c = optimizer == null ? void 0 : optimizer.ssr) == null ? void 0 : _c.enabled) ?? true
7942
+ enabled: ((_u = optimizer == null ? void 0 : optimizer.ssr) == null ? void 0 : _u.enabled) ?? true
7758
7943
  }
7759
7944
  }
7760
7945
  },
@@ -7793,7 +7978,7 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7793
7978
  return;
7794
7979
  if (this.browserProvider)
7795
7980
  return;
7796
- const Provider = await getBrowserProvider(this.config.browser, this.runner);
7981
+ const Provider = await getBrowserProvider(this.config.browser, this);
7797
7982
  this.browserProvider = new Provider();
7798
7983
  const browser = this.config.browser.name;
7799
7984
  const supportedBrowsers = this.browserProvider.getSupportedBrowsers();
@@ -7806,11 +7991,51 @@ ${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
7806
7991
  }
7807
7992
  }
7808
7993
 
7994
+ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
7995
+ class VitestPackageInstaller {
7996
+ async ensureInstalled(dependency, root) {
7997
+ if (process.env.VITEST_SKIP_INSTALL_CHECKS)
7998
+ return true;
7999
+ if (process.versions.pnp) {
8000
+ const targetRequire = createRequire(__dirname);
8001
+ try {
8002
+ targetRequire.resolve(dependency, { paths: [root, __dirname] });
8003
+ return true;
8004
+ } catch (error) {
8005
+ }
8006
+ }
8007
+ if (isPackageExists(dependency, { paths: [root, __dirname] }))
8008
+ return true;
8009
+ const promptInstall = !isCI && process.stdout.isTTY;
8010
+ process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'
8011
+
8012
+ `));
8013
+ if (!promptInstall)
8014
+ return false;
8015
+ const prompts = await Promise.resolve().then(function () { return index; });
8016
+ const { install } = await prompts.prompt({
8017
+ type: "confirm",
8018
+ name: "install",
8019
+ message: c.reset(`Do you want to install ${c.green(dependency)}?`)
8020
+ });
8021
+ if (install) {
8022
+ await (await import('../chunks/install-pkg.LE8oaA1t.js')).installPackage(dependency, { dev: true });
8023
+ process.stderr.write(c.yellow(`
8024
+ Package ${dependency} installed, re-run the command to start.
8025
+ `));
8026
+ process.exit(EXIT_CODE_RESTART);
8027
+ return true;
8028
+ }
8029
+ return false;
8030
+ }
8031
+ }
8032
+
7809
8033
  const WATCHER_DEBOUNCE = 100;
7810
8034
  class Vitest {
7811
- constructor(mode) {
8035
+ constructor(mode, options = {}) {
7812
8036
  this.mode = mode;
7813
8037
  this.logger = new Logger(this);
8038
+ this.packageInstaller = options.packageInstaller || new VitestPackageInstaller();
7814
8039
  }
7815
8040
  config = void 0;
7816
8041
  configOverride = {};
@@ -7833,11 +8058,12 @@ class Vitest {
7833
8058
  isFirstRun = true;
7834
8059
  restartsCount = 0;
7835
8060
  runner = void 0;
8061
+ packageInstaller;
7836
8062
  coreWorkspaceProject;
7837
8063
  resolvedProjects = [];
7838
8064
  projects = [];
7839
8065
  projectsTestFiles = /* @__PURE__ */ new Map();
7840
- projectFiles;
8066
+ distPath;
7841
8067
  _onRestartListeners = [];
7842
8068
  _onClose = [];
7843
8069
  _onSetServer = [];
@@ -7863,11 +8089,7 @@ class Vitest {
7863
8089
  this.vitenode = new ViteNodeServer(server, this.config.server);
7864
8090
  const projectVitestPath = await this.vitenode.resolveId("vitest");
7865
8091
  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
- };
8092
+ this.distPath = join(vitestDir, "dist");
7871
8093
  const node = this.vitenode;
7872
8094
  this.runner = new ViteNodeRunner({
7873
8095
  root: server.config.root,
@@ -7898,7 +8120,7 @@ class Vitest {
7898
8120
  }
7899
8121
  });
7900
8122
  }
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);
8123
+ this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray((_d = resolved.benchmark) == null ? void 0 : _d.reporters), this.runner) : await createReporters(resolved.reporters, this);
7902
8124
  this.cache.results.setConfig(resolved.root, resolved.cache);
7903
8125
  try {
7904
8126
  await this.cache.results.readFromCache();
@@ -8002,6 +8224,7 @@ class Vitest {
8002
8224
  "pool",
8003
8225
  "globals",
8004
8226
  "expandSnapshotDiff",
8227
+ "disableConsoleIntercept",
8005
8228
  "retry",
8006
8229
  "testNamePattern",
8007
8230
  "passWithNoTests",
@@ -8269,26 +8492,27 @@ class Vitest {
8269
8492
  await this.report("onWatcherStart", this.state.getFiles(files));
8270
8493
  }, WATCHER_DEBOUNCE);
8271
8494
  }
8272
- getModuleProjects(id) {
8495
+ getModuleProjects(filepath) {
8273
8496
  return this.projects.filter((project) => {
8274
- return project.getModulesByFilepath(id).size;
8497
+ return project.getModulesByFilepath(filepath).size;
8275
8498
  });
8276
8499
  }
8277
8500
  unregisterWatcher = noop$1;
8278
8501
  registerWatcher() {
8279
- const updateLastChanged = (id) => {
8280
- const projects = this.getModuleProjects(id);
8502
+ const updateLastChanged = (filepath) => {
8503
+ const projects = this.getModuleProjects(filepath);
8281
8504
  projects.forEach(({ server, browser }) => {
8282
- const serverMods = server.moduleGraph.getModulesByFile(id);
8505
+ const serverMods = server.moduleGraph.getModulesByFile(filepath);
8283
8506
  serverMods == null ? void 0 : serverMods.forEach((mod) => server.moduleGraph.invalidateModule(mod));
8284
8507
  if (browser) {
8285
- const browserMods = browser.moduleGraph.getModulesByFile(id);
8508
+ const browserMods = browser.moduleGraph.getModulesByFile(filepath);
8286
8509
  browserMods == null ? void 0 : browserMods.forEach((mod) => browser.moduleGraph.invalidateModule(mod));
8287
8510
  }
8288
8511
  });
8289
8512
  };
8290
8513
  const onChange = (id) => {
8291
8514
  id = slash$1(id);
8515
+ this.logger.clearHighlightCache(id);
8292
8516
  updateLastChanged(id);
8293
8517
  const needsRerun = this.handleFileChanged(id);
8294
8518
  if (needsRerun.length)
@@ -8296,6 +8520,7 @@ class Vitest {
8296
8520
  };
8297
8521
  const onUnlink = (id) => {
8298
8522
  id = slash$1(id);
8523
+ this.logger.clearHighlightCache(id);
8299
8524
  this.invalidates.add(id);
8300
8525
  if (this.state.filesMap.has(id)) {
8301
8526
  this.state.filesMap.delete(id);
@@ -8336,48 +8561,44 @@ class Vitest {
8336
8561
  /**
8337
8562
  * @returns A value indicating whether rerun is needed (changedTests was mutated)
8338
8563
  */
8339
- handleFileChanged(id) {
8340
- if (this.changedTests.has(id) || this.invalidates.has(id))
8564
+ handleFileChanged(filepath) {
8565
+ if (this.changedTests.has(filepath) || this.invalidates.has(filepath))
8341
8566
  return [];
8342
- if (mm.isMatch(id, this.config.forceRerunTriggers)) {
8567
+ if (mm.isMatch(filepath, this.config.forceRerunTriggers)) {
8343
8568
  this.state.getFilepaths().forEach((file) => this.changedTests.add(file));
8344
- return [id];
8569
+ return [filepath];
8345
8570
  }
8346
- const projects = this.getModuleProjects(id);
8571
+ const projects = this.getModuleProjects(filepath);
8347
8572
  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];
8573
+ if (this.state.filesMap.has(filepath) || this.projects.some((project) => project.isTestFile(filepath))) {
8574
+ this.changedTests.add(filepath);
8575
+ return [filepath];
8351
8576
  }
8352
8577
  return [];
8353
8578
  }
8354
8579
  const files = [];
8355
8580
  for (const project of projects) {
8356
- const { server } = project;
8357
- const mods = project.getModulesByFilepath(id);
8581
+ const mods = project.getModulesByFilepath(filepath);
8358
8582
  if (!mods.size)
8359
8583
  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);
8584
+ this.invalidates.add(filepath);
8585
+ if (this.state.filesMap.has(filepath) || project.isTestFile(filepath)) {
8586
+ this.changedTests.add(filepath);
8587
+ files.push(filepath);
8365
8588
  continue;
8366
8589
  }
8367
8590
  let rerun = false;
8368
8591
  for (const mod of mods) {
8369
- if (!mod.id)
8370
- continue;
8371
8592
  mod.importers.forEach((i) => {
8372
- if (!i.id)
8593
+ if (!i.file)
8373
8594
  return;
8374
- const heedsRerun = this.handleFileChanged(i.id);
8595
+ const heedsRerun = this.handleFileChanged(i.file);
8375
8596
  if (heedsRerun)
8376
8597
  rerun = true;
8377
8598
  });
8378
8599
  }
8379
8600
  if (rerun)
8380
- files.push(id);
8601
+ files.push(filepath);
8381
8602
  }
8382
8603
  return files;
8383
8604
  }
@@ -8390,7 +8611,10 @@ class Vitest {
8390
8611
  async close() {
8391
8612
  if (!this.closingPromise) {
8392
8613
  this.closingPromise = (async () => {
8393
- for await (const project of [...this.projects].reverse())
8614
+ const teardownProjects = [...this.projects];
8615
+ if (!teardownProjects.includes(this.coreWorkspaceProject))
8616
+ teardownProjects.push(this.coreWorkspaceProject);
8617
+ for await (const project of teardownProjects.reverse())
8394
8618
  await project.teardownGlobalSetup();
8395
8619
  const closePromises = this.projects.map((w) => w.close().then(() => w.server = void 0));
8396
8620
  if (!this.projects.includes(this.coreWorkspaceProject))
@@ -8485,7 +8709,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8485
8709
  return ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd();
8486
8710
  };
8487
8711
  async function UIPlugin() {
8488
- await ensurePackageInstalled("@vitest/ui", getRoot());
8712
+ await ctx.packageInstaller.ensureInstalled("@vitest/ui", getRoot());
8489
8713
  return (await import('@vitest/ui')).default(ctx);
8490
8714
  }
8491
8715
  return [
@@ -8496,7 +8720,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8496
8720
  this.meta.watchMode = false;
8497
8721
  },
8498
8722
  async config(viteConfig) {
8499
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
8723
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
8500
8724
  if (options.watch) {
8501
8725
  options = deepMerge({}, userConfig);
8502
8726
  }
@@ -8547,14 +8771,27 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8547
8771
  poolOptions: testConfig.poolOptions
8548
8772
  }
8549
8773
  };
8774
+ if (((_j = viteConfig.ssr) == null ? void 0 : _j.noExternal) !== true) {
8775
+ const inline = (_l = (_k = testConfig.server) == null ? void 0 : _k.deps) == null ? void 0 : _l.inline;
8776
+ if (inline === true) {
8777
+ config.ssr = { noExternal: true };
8778
+ } else {
8779
+ const noExternal = (_m = viteConfig.ssr) == null ? void 0 : _m.noExternal;
8780
+ const noExternalArray = typeof noExternal !== "undefined" ? toArray(noExternal) : void 0;
8781
+ const uniqueInline = inline && noExternalArray ? inline.filter((dep) => !noExternalArray.includes(dep)) : inline;
8782
+ config.ssr = {
8783
+ noExternal: uniqueInline
8784
+ };
8785
+ }
8786
+ }
8550
8787
  if (process.platform === "darwin" && process.env.VITE_TEST_WATCHER_DEBUG) {
8551
8788
  config.server.watch.useFsEvents = false;
8552
8789
  config.server.watch.usePolling = false;
8553
8790
  }
8554
- const classNameStrategy = typeof testConfig.css !== "boolean" && ((_k = (_j = testConfig.css) == null ? void 0 : _j.modules) == null ? void 0 : _k.classNameStrategy) || "stable";
8791
+ const classNameStrategy = typeof testConfig.css !== "boolean" && ((_o = (_n = testConfig.css) == null ? void 0 : _n.modules) == null ? void 0 : _o.classNameStrategy) || "stable";
8555
8792
  if (classNameStrategy !== "scoped") {
8556
8793
  config.css ?? (config.css = {});
8557
- (_l = config.css).modules ?? (_l.modules = {});
8794
+ (_p = config.css).modules ?? (_p.modules = {});
8558
8795
  if (config.css.modules) {
8559
8796
  config.css.modules.generateScopedName = (name, filename) => {
8560
8797
  const root = getRoot();
@@ -8596,7 +8833,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8596
8833
  try {
8597
8834
  await ctx.setServer(options, server, userConfig);
8598
8835
  if (options.api && options.watch)
8599
- (await import('../chunks/api-setup.mFKdEKxa.js')).setup(ctx);
8836
+ (await import('../chunks/api-setup.MAoRkVWJ.js')).setup(ctx);
8600
8837
  } catch (err) {
8601
8838
  await ctx.logger.printError(err, { fullStack: true });
8602
8839
  process.exit(1);
@@ -8616,9 +8853,9 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8616
8853
  ].filter(notNullish);
8617
8854
  }
8618
8855
 
8619
- async function createVitest(mode, options, viteOverrides = {}) {
8856
+ async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {}) {
8620
8857
  var _a;
8621
- const ctx = new Vitest(mode);
8858
+ const ctx = new Vitest(mode, vitestOptions);
8622
8859
  const root = resolve(options.root || process.cwd());
8623
8860
  const configPath = options.config === false ? false : options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
8624
8861
  options.config = configPath;
@@ -14909,6 +15146,140 @@ var index = /*#__PURE__*/_mergeNamespaces({
14909
15146
  default: prompt
14910
15147
  }, [prompts]);
14911
15148
 
15149
+ const MAX_RESULT_COUNT = 10;
15150
+ const SELECTION_MAX_INDEX = 7;
15151
+ const ESC = "\x1B[";
15152
+ class WatchFilter {
15153
+ filterRL;
15154
+ currentKeyword = void 0;
15155
+ message;
15156
+ results = [];
15157
+ selectionIndex = -1;
15158
+ onKeyPress;
15159
+ constructor(message) {
15160
+ this.message = message;
15161
+ this.filterRL = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });
15162
+ readline.emitKeypressEvents(process.stdin, this.filterRL);
15163
+ if (process.stdin.isTTY)
15164
+ process.stdin.setRawMode(true);
15165
+ }
15166
+ async filter(filterFunc) {
15167
+ stdout().write(this.promptLine());
15168
+ const resultPromise = createDefer();
15169
+ this.onKeyPress = this.filterHandler(filterFunc, (result) => {
15170
+ resultPromise.resolve(result);
15171
+ });
15172
+ process.stdin.on("keypress", this.onKeyPress);
15173
+ try {
15174
+ return await resultPromise;
15175
+ } finally {
15176
+ this.close();
15177
+ }
15178
+ }
15179
+ filterHandler(filterFunc, onSubmit) {
15180
+ return async (str, key) => {
15181
+ var _a, _b;
15182
+ switch (true) {
15183
+ case key.sequence === "\x7F":
15184
+ if (this.currentKeyword && ((_a = this.currentKeyword) == null ? void 0 : _a.length) > 1)
15185
+ this.currentKeyword = (_b = this.currentKeyword) == null ? void 0 : _b.slice(0, -1);
15186
+ else
15187
+ this.currentKeyword = void 0;
15188
+ break;
15189
+ case ((key == null ? void 0 : key.ctrl) && (key == null ? void 0 : key.name) === "c"):
15190
+ case (key == null ? void 0 : key.name) === "escape":
15191
+ this.cancel();
15192
+ onSubmit(void 0);
15193
+ break;
15194
+ case (key == null ? void 0 : key.name) === "enter":
15195
+ case (key == null ? void 0 : key.name) === "return":
15196
+ onSubmit(this.results[this.selectionIndex] || this.currentKeyword || "");
15197
+ this.currentKeyword = void 0;
15198
+ break;
15199
+ case (key == null ? void 0 : key.name) === "up":
15200
+ if (this.selectionIndex && this.selectionIndex > 0)
15201
+ this.selectionIndex--;
15202
+ else
15203
+ this.selectionIndex = -1;
15204
+ break;
15205
+ case (key == null ? void 0 : key.name) === "down":
15206
+ if (this.selectionIndex < this.results.length - 1)
15207
+ this.selectionIndex++;
15208
+ else if (this.selectionIndex >= this.results.length - 1)
15209
+ this.selectionIndex = this.results.length - 1;
15210
+ break;
15211
+ case (!(key == null ? void 0 : key.ctrl) && !(key == null ? void 0 : key.meta)):
15212
+ if (this.currentKeyword === void 0)
15213
+ this.currentKeyword = str;
15214
+ else
15215
+ this.currentKeyword += str || "";
15216
+ break;
15217
+ }
15218
+ if (this.currentKeyword)
15219
+ this.results = await filterFunc(this.currentKeyword);
15220
+ this.render();
15221
+ };
15222
+ }
15223
+ render() {
15224
+ let printStr = this.promptLine();
15225
+ if (!this.currentKeyword) {
15226
+ printStr += "\nPlease input filter pattern";
15227
+ } else if (this.currentKeyword && this.results.length === 0) {
15228
+ printStr += "\nPattern matches no results";
15229
+ } else {
15230
+ const resultCountLine = this.results.length === 1 ? `Pattern matches ${this.results.length} result` : `Pattern matches ${this.results.length} results`;
15231
+ let resultBody = "";
15232
+ if (this.results.length > MAX_RESULT_COUNT) {
15233
+ const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0;
15234
+ const displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset);
15235
+ const remainingResultCount = this.results.length - offset - displayResults.length;
15236
+ resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` \u203A ${result}`) : c.dim(` \u203A ${result}`)).join("\n")}`;
15237
+ if (remainingResultCount > 0)
15238
+ resultBody += `
15239
+ ${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "result" : "results"}`)}`;
15240
+ } else {
15241
+ resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` \u203A ${result}`) : c.dim(` \u203A ${result}`)).join("\n");
15242
+ }
15243
+ printStr += `
15244
+ ${resultCountLine}
15245
+ ${resultBody}`;
15246
+ }
15247
+ this.eraseAndPrint(printStr);
15248
+ this.restoreCursor();
15249
+ }
15250
+ keywordOffset() {
15251
+ return `? ${this.message} \u203A `.length + 1;
15252
+ }
15253
+ promptLine() {
15254
+ return `${c.cyan("?")} ${c.bold(this.message)} \u203A ${this.currentKeyword || ""}`;
15255
+ }
15256
+ eraseAndPrint(str) {
15257
+ let rows = 0;
15258
+ const lines = str.split(/\r?\n/);
15259
+ for (const line of lines)
15260
+ rows += 1 + Math.floor(Math.max(stripAnsi(line).length - 1, 0) / stdout().columns);
15261
+ stdout().write(`${ESC}1G`);
15262
+ stdout().write(`${ESC}J`);
15263
+ stdout().write(str);
15264
+ stdout().write(`${ESC}${rows - 1}A`);
15265
+ }
15266
+ close() {
15267
+ this.filterRL.close();
15268
+ if (this.onKeyPress)
15269
+ process.stdin.removeListener("keypress", this.onKeyPress);
15270
+ if (process.stdin.isTTY)
15271
+ process.stdin.setRawMode(false);
15272
+ }
15273
+ restoreCursor() {
15274
+ var _a;
15275
+ const cursortPos = this.keywordOffset() + (((_a = this.currentKeyword) == null ? void 0 : _a.length) || 0);
15276
+ stdout().write(`${ESC}${cursortPos}G`);
15277
+ }
15278
+ cancel() {
15279
+ stdout().write(`${ESC}J`);
15280
+ }
15281
+ }
15282
+
14912
15283
  const keys = [
14913
15284
  [["a", "return"], "rerun all tests"],
14914
15285
  ["r", "rerun current pattern tests"],
@@ -14975,16 +15346,20 @@ function registerConsoleShortcuts(ctx) {
14975
15346
  await _keypressHandler(str, key);
14976
15347
  }
14977
15348
  async function inputNamePattern() {
14978
- var _a;
14979
15349
  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
- }]);
15350
+ const watchFilter = new WatchFilter("Input test name pattern (RegExp)");
15351
+ const filter = await watchFilter.filter((str) => {
15352
+ const files = ctx.state.getFiles();
15353
+ const tests = getTests(files);
15354
+ try {
15355
+ const reg = new RegExp(str);
15356
+ return tests.map((test) => test.name).filter((testName) => testName.match(reg));
15357
+ } catch {
15358
+ return [];
15359
+ }
15360
+ });
14986
15361
  on();
14987
- await ctx.changeNamePattern(filter.trim(), void 0, "change pattern");
15362
+ await ctx.changeNamePattern((filter == null ? void 0 : filter.trim()) || "", void 0, "change pattern");
14988
15363
  }
14989
15364
  async function inputProjectName() {
14990
15365
  off();
@@ -14999,15 +15374,16 @@ function registerConsoleShortcuts(ctx) {
14999
15374
  }
15000
15375
  async function inputFilePattern() {
15001
15376
  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();
15377
+ const watchFilter = new WatchFilter("Input filename pattern");
15378
+ const filter = await watchFilter.filter(async (str) => {
15379
+ const files = await ctx.globTestFiles([str]);
15380
+ return files.map(
15381
+ (file) => relative(ctx.config.root, file[1])
15382
+ );
15383
+ });
15009
15384
  on();
15010
- await ctx.changeFilenamePattern(filter.trim());
15385
+ latestFilename = (filter == null ? void 0 : filter.trim()) || "";
15386
+ await ctx.changeFilenamePattern(latestFilename);
15011
15387
  }
15012
15388
  let rl;
15013
15389
  function on() {
@@ -15031,7 +15407,7 @@ function registerConsoleShortcuts(ctx) {
15031
15407
  };
15032
15408
  }
15033
15409
 
15034
- async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15410
+ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
15035
15411
  var _a, _b;
15036
15412
  process.env.TEST = "true";
15037
15413
  process.env.VITEST = "true";
@@ -15054,19 +15430,19 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15054
15430
  options.typecheck.only = true;
15055
15431
  options.typecheck.enabled = true;
15056
15432
  }
15057
- const ctx = await createVitest(mode, options, viteOverrides);
15433
+ const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);
15058
15434
  if (mode === "test" && ctx.config.coverage.enabled) {
15059
15435
  const provider = ctx.config.coverage.provider || "v8";
15060
15436
  const requiredPackages = CoverageProviderMap[provider];
15061
15437
  if (requiredPackages) {
15062
- if (!await ensurePackageInstalled(requiredPackages, root)) {
15438
+ if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root)) {
15063
15439
  process.exitCode = 1;
15064
15440
  return ctx;
15065
15441
  }
15066
15442
  }
15067
15443
  }
15068
15444
  const environmentPackage = getEnvPackageName(ctx.config.environment);
15069
- if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) {
15445
+ if (environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root)) {
15070
15446
  process.exitCode = 1;
15071
15447
  return ctx;
15072
15448
  }
@@ -15096,4 +15472,4 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides) {
15096
15472
  return ctx;
15097
15473
  }
15098
15474
 
15099
- export { BaseSequencer as B, VitestPlugin as V, createMethodsRPC as a, createVitest as c, registerConsoleShortcuts as r, startVitest as s, version$1 as v };
15475
+ 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 };