vitest 4.0.14 → 4.0.15

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 (48) hide show
  1. package/dist/browser.d.ts +1 -1
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{base.BEv8sRbK.js → base.CTp-EStD.js} +6 -6
  4. package/dist/chunks/browser.d.DBzUq_Na.d.ts +57 -0
  5. package/dist/chunks/{cac.DnEx6DOX.js → cac.BNNpZQl7.js} +10 -25
  6. package/dist/chunks/{cli-api.CbjxIXjQ.js → cli-api.C7sYjHmQ.js} +423 -98
  7. package/dist/chunks/{config.d.g6OOauRt.d.ts → config.d.CzIjkicf.d.ts} +1 -0
  8. package/dist/chunks/evaluatedModules.d.BxJ5omdx.d.ts +7 -0
  9. package/dist/chunks/{globals.C0izxiX3.js → globals.DOayXfHP.js} +3 -3
  10. package/dist/chunks/{index.D6PC4Dpu.js → index.456_DGfR.js} +128 -18
  11. package/dist/chunks/{index.B88tjlE5.js → index.Drsj_6e7.js} +1 -1
  12. package/dist/chunks/{index.DBx1AtPJ.js → index.Z5E_ObnR.js} +1 -1
  13. package/dist/chunks/{index.CQwQ_SLL.js → index.bFLgAE-Z.js} +2 -2
  14. package/dist/chunks/{init-forks.DmvIFK4U.js → init-forks.CKEYp90N.js} +11 -2
  15. package/dist/chunks/{init-threads.De6b3S3g.js → init-threads.D8Ok07M7.js} +1 -1
  16. package/dist/chunks/{init.a5SCIJ0x.js → init.B04saIIg.js} +1 -1
  17. package/dist/chunks/modules.DJPjQW6m.js +35 -0
  18. package/dist/chunks/{plugin.d.B6hlg3fN.d.ts → plugin.d.CY7CUjf-.d.ts} +1 -1
  19. package/dist/chunks/{reporters.d.DeFcIuza.d.ts → reporters.d.OXEK7y4s.d.ts} +27 -4
  20. package/dist/chunks/{setup-common.DGHc_BUK.js → setup-common.Cm-kSBVi.js} +1 -1
  21. package/dist/chunks/{startModuleRunner.W28wBIgJ.js → startModuleRunner.Iz2V0ESw.js} +8 -9
  22. package/dist/chunks/{test.DqQZzsWf.js → test.BT8LKgU9.js} +8 -3
  23. package/dist/chunks/{vi.BiaV1qII.js → vi.2VT5v0um.js} +40 -30
  24. package/dist/chunks/{vm.BbVD4fJ5.js → vm.BwmD1Rql.js} +2 -2
  25. package/dist/chunks/{worker.d.DhEa3KzY.d.ts → worker.d.B4A26qg6.d.ts} +1 -1
  26. package/dist/cli.js +2 -2
  27. package/dist/config.d.ts +7 -7
  28. package/dist/coverage.d.ts +8 -8
  29. package/dist/index.d.ts +22 -14
  30. package/dist/index.js +3 -3
  31. package/dist/module-evaluator.d.ts +5 -0
  32. package/dist/module-evaluator.js +21 -6
  33. package/dist/module-runner.js +2 -1
  34. package/dist/node.d.ts +7 -7
  35. package/dist/node.js +6 -5
  36. package/dist/reporters.d.ts +7 -7
  37. package/dist/reporters.js +2 -2
  38. package/dist/runners.d.ts +2 -1
  39. package/dist/runners.js +2 -2
  40. package/dist/worker.d.ts +2 -2
  41. package/dist/worker.js +9 -8
  42. package/dist/workers/forks.js +10 -9
  43. package/dist/workers/runVmTests.js +5 -5
  44. package/dist/workers/threads.js +10 -9
  45. package/dist/workers/vmForks.js +5 -4
  46. package/dist/workers/vmThreads.js +5 -4
  47. package/package.json +14 -14
  48. package/dist/chunks/browser.d.F6jMf15V.d.ts +0 -18
@@ -6,16 +6,16 @@ import { noop, createDefer, slash, isExternalUrl, unwrapId, withTrailingSlash, c
6
6
  import { a as any, p as prompt } from './index.D4KonVSU.js';
7
7
  import { h as hash, R as RandomSequencer, i as isPackageExists, c as isBrowserEnabled, r as resolveConfig, g as getCoverageProvider, a as resolveApiServerConfig, d as resolveModule } from './coverage.CtyeYmKM.js';
8
8
  import * as vite from 'vite';
9
- import { parseAst, searchForWorkspaceRoot, fetchModule, version, mergeConfig, createServer } from 'vite';
9
+ import { isFileServingAllowed, parseAst, searchForWorkspaceRoot, fetchModule, version, mergeConfig, createServer } from 'vite';
10
10
  import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.D_Q9UYh-.js';
11
11
  import * as nodeos from 'node:os';
12
12
  import nodeos__default, { tmpdir } from 'node:os';
13
13
  import { generateHash as generateHash$1, createTaskName, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, hasFailed, generateFileHash, limitConcurrency, createFileTask as createFileTask$1, getTasks, isTestCase } from '@vitest/runner/utils';
14
14
  import { SnapshotManager } from '@vitest/snapshot/manager';
15
- import { v as version$1 } from './cac.DnEx6DOX.js';
15
+ import { v as version$1 } from './cac.BNNpZQl7.js';
16
16
  import { performance as performance$1 } from 'node:perf_hooks';
17
17
  import { c as createBirpc } from './index.0kCJoeWi.js';
18
- import { p as parse, d as stringify, e as TraceMap, o as originalPositionFor, h as ancestor, i as printError, f as formatProjectName, w as withLabel, j as errorBanner, k as divider, l as Typechecker, m as generateCodeFrame, n as createDefinesScript, R as ReportersMap, B as BlobReporter, r as readBlobs, q as convertTasksToEvents, H as HangingProcessReporter } from './index.D6PC4Dpu.js';
18
+ import { p as parse, d as stringify, e as createIndexLocationsMap, h as TraceMap, o as originalPositionFor, i as ancestor, j as printError, f as formatProjectName, w as withLabel, k as errorBanner, l as divider, m as Typechecker, n as generateCodeFrame, q as escapeRegExp, r as createDefinesScript, R as ReportersMap, u as groupBy, B as BlobReporter, v as readBlobs, x as convertTasksToEvents, H as HangingProcessReporter, y as wildcardPatternToRegExp, z as stdout } from './index.456_DGfR.js';
19
19
  import require$$0$3 from 'events';
20
20
  import require$$1$1 from 'https';
21
21
  import require$$2 from 'http';
@@ -37,11 +37,12 @@ import { VitestModuleEvaluator } from '#module-evaluator';
37
37
  import { ModuleRunner } from 'vite/module-runner';
38
38
  import { Console } from 'node:console';
39
39
  import { highlight } from '@vitest/utils/highlight';
40
- import { createRequire, isBuiltin, builtinModules } from 'node:module';
40
+ import { createRequire, builtinModules, isBuiltin as isBuiltin$1 } from 'node:module';
41
41
  import url, { fileURLToPath, pathToFileURL } from 'node:url';
42
42
  import { i as isTTY, a as isWindows } from './env.D4Lgay0q.js';
43
43
  import { isatty } from 'node:tty';
44
44
  import EventEmitter$1, { EventEmitter } from 'node:events';
45
+ import { t as toBuiltin, i as isBuiltin } from './modules.DJPjQW6m.js';
45
46
  import { fork } from 'node:child_process';
46
47
  import { Worker } from 'node:worker_threads';
47
48
  import pm from 'picomatch';
@@ -52,7 +53,7 @@ import { c as configDefaults } from './defaults.BOqNVLsY.js';
52
53
  import { KNOWN_ASSET_RE } from '@vitest/utils/constants';
53
54
  import { findNearestPackageData } from '@vitest/utils/resolver';
54
55
  import * as esModuleLexer from 'es-module-lexer';
55
- import { a as BenchmarkReportsMap } from './index.B88tjlE5.js';
56
+ import { a as BenchmarkReportsMap } from './index.Drsj_6e7.js';
56
57
  import assert$1 from 'node:assert';
57
58
  import { serializeValue } from '@vitest/utils/serialize';
58
59
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
@@ -5025,30 +5026,55 @@ function requireWebsocketServer () {
5025
5026
  var websocketServerExports = requireWebsocketServer();
5026
5027
  var WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServerExports);
5027
5028
 
5028
- async function getModuleGraph(ctx, projectName, id, browser = false) {
5029
+ function getTestFileEnvironment(project, testFile, browser = false) {
5030
+ let environment;
5031
+ if (browser) environment = project.browser?.vite.environments.client;
5032
+ else for (const name in project.vite.environments) {
5033
+ const env = project.vite.environments[name];
5034
+ if (env.moduleGraph.getModuleById(testFile)) {
5035
+ environment = env;
5036
+ break;
5037
+ }
5038
+ }
5039
+ return environment;
5040
+ }
5041
+
5042
+ async function getModuleGraph(ctx, projectName, testFilePath, browser = false) {
5029
5043
  const graph = {};
5030
5044
  const externalized = /* @__PURE__ */ new Set();
5031
5045
  const inlined = /* @__PURE__ */ new Set();
5032
5046
  const project = ctx.getProjectByName(projectName);
5033
- async function get(mod, seen = /* @__PURE__ */ new Map()) {
5047
+ const environment = getTestFileEnvironment(project, testFilePath, browser);
5048
+ if (!environment) throw new Error(`Cannot find environment for ${testFilePath}`);
5049
+ const seen = /* @__PURE__ */ new Map();
5050
+ function get(mod) {
5034
5051
  if (!mod || !mod.id) return;
5035
- if (mod.id === "\0vitest/browser") return;
5052
+ if (mod.id === "\0vitest/browser" || mod.id.includes("plugin-vue:export-helper")) return;
5036
5053
  if (seen.has(mod)) return seen.get(mod);
5037
- let id = clearId(mod.id);
5054
+ const id = clearId(mod.id);
5038
5055
  seen.set(mod, id);
5039
- // TODO: how to know if it was rewritten(?) - what is rewritten?
5040
- const rewrote = browser ? mod.file?.includes(project.browser.vite.config.cacheDir) ? mod.id : false : false;
5041
- if (rewrote) {
5042
- id = rewrote;
5043
- externalized.add(id);
5044
- seen.set(mod, id);
5045
- } else inlined.add(id);
5046
- const mods = Array.from(mod.importedModules).filter((i) => i.id && !i.id.includes("/vitest/dist/"));
5047
- graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean);
5056
+ if (id.startsWith("__vite-browser-external:")) {
5057
+ const external = id.slice(24);
5058
+ externalized.add(external);
5059
+ return external;
5060
+ }
5061
+ const external = project._resolver.wasExternalized(id);
5062
+ if (typeof external === "string") {
5063
+ externalized.add(external);
5064
+ return external;
5065
+ }
5066
+ if (browser && mod.file?.includes(project.browser.vite.config.cacheDir)) {
5067
+ externalized.add(mod.id);
5068
+ return id;
5069
+ }
5070
+ inlined.add(id);
5071
+ graph[id] = Array.from(mod.importedModules).filter((i) => i.id && !i.id.includes("/vitest/dist/")).map((m) => get(m)).filter(Boolean);
5048
5072
  return id;
5049
5073
  }
5050
- if (browser && project.browser) await get(project.browser.vite.moduleGraph.getModuleById(id));
5051
- else await get(project.vite.moduleGraph.getModuleById(id));
5074
+ get(environment.moduleGraph.getModuleById(testFilePath));
5075
+ project.config.setupFiles.forEach((setupFile) => {
5076
+ get(environment.moduleGraph.getModuleById(setupFile));
5077
+ });
5052
5078
  return {
5053
5079
  graph,
5054
5080
  externalized: Array.from(externalized),
@@ -5146,15 +5172,36 @@ function setup(ctx, _server) {
5146
5172
  color: p.color
5147
5173
  }));
5148
5174
  },
5149
- async getTransformResult(projectName, id, browser = false) {
5175
+ async getExternalResult(moduleId, testFileTaskId) {
5176
+ const testModule = ctx.state.getReportedEntityById(testFileTaskId);
5177
+ if (!testModule) return;
5178
+ if (!isFileServingAllowed(testModule.project.vite.config, moduleId)) return;
5179
+ const result = {};
5180
+ try {
5181
+ result.source = await promises.readFile(moduleId, "utf-8");
5182
+ } catch {}
5183
+ return result;
5184
+ },
5185
+ async getTransformResult(projectName, moduleId, testFileTaskId, browser = false) {
5150
5186
  const project = ctx.getProjectByName(projectName);
5151
- const result = browser ? await project.browser.vite.transformRequest(id) : await project.vite.transformRequest(id);
5152
- if (result) {
5153
- try {
5154
- result.source = result.source || await promises.readFile(id, "utf-8");
5155
- } catch {}
5156
- return result;
5157
- }
5187
+ const testModule = ctx.state.getReportedEntityById(testFileTaskId);
5188
+ if (!testModule || !isFileServingAllowed(project.vite.config, moduleId)) return;
5189
+ const environment = getTestFileEnvironment(project, testModule.moduleId, browser);
5190
+ const moduleNode = environment?.moduleGraph.getModuleById(moduleId);
5191
+ if (!environment || !moduleNode?.transformResult) return;
5192
+ const result = moduleNode.transformResult;
5193
+ try {
5194
+ result.source = result.source || (moduleNode.file ? await promises.readFile(moduleNode.file, "utf-8") : void 0);
5195
+ } catch {}
5196
+ // TODO: store this in HTML reporter separetly
5197
+ const transformDuration = ctx.state.metadata[projectName]?.duration[moduleNode.url]?.[0];
5198
+ if (transformDuration != null) result.transformTime = transformDuration;
5199
+ try {
5200
+ const diagnostic = await ctx.experimental_getSourceModuleDiagnostic(moduleId, testModule);
5201
+ result.modules = diagnostic.modules;
5202
+ result.untrackedModules = diagnostic.untrackedModules;
5203
+ } catch {}
5204
+ return result;
5158
5205
  },
5159
5206
  async getModuleGraph(project, id, browser) {
5160
5207
  return getModuleGraph(ctx, project, id, browser);
@@ -5273,31 +5320,6 @@ var setup$1 = /*#__PURE__*/Object.freeze({
5273
5320
  setup: setup
5274
5321
  });
5275
5322
 
5276
- function groupBy(collection, iteratee) {
5277
- return collection.reduce((acc, item) => {
5278
- const key = iteratee(item);
5279
- acc[key] ||= [];
5280
- acc[key].push(item);
5281
- return acc;
5282
- }, {});
5283
- }
5284
- function stdout() {
5285
- // @ts-expect-error Node.js maps process.stdout to console._stdout
5286
- // eslint-disable-next-line no-console
5287
- return console._stdout || process.stdout;
5288
- }
5289
- function escapeRegExp(s) {
5290
- // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
5291
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5292
- }
5293
- function wildcardPatternToRegExp(pattern) {
5294
- const negated = pattern[0] === "!";
5295
- if (negated) pattern = pattern.slice(1);
5296
- let regexp = `${pattern.split("*").map(escapeRegExp).join(".*")}$`;
5297
- if (negated) regexp = `(?!${regexp})`;
5298
- return new RegExp(`^${regexp}`, "i");
5299
- }
5300
-
5301
5323
  function createDebugger(namespace) {
5302
5324
  const debug = createDebug(namespace);
5303
5325
  if (debug.enabled) return debug;
@@ -5450,7 +5472,7 @@ function createFileTask(testFilepath, code, requestMap, options) {
5450
5472
  file: null
5451
5473
  };
5452
5474
  file.file = file;
5453
- const indexMap = createIndexMap(code);
5475
+ const indexMap = createIndexLocationsMap(code);
5454
5476
  const map = requestMap && new TraceMap(requestMap);
5455
5477
  let lastSuite = file;
5456
5478
  const updateLatestSuite = (index) => {
@@ -5552,23 +5574,6 @@ async function transformSSR(project, filepath) {
5552
5574
  if (!request) return null;
5553
5575
  return await project.vite.ssrTransform(request.code, request.map, filepath);
5554
5576
  }
5555
- function createIndexMap(source) {
5556
- const map = /* @__PURE__ */ new Map();
5557
- let index = 0;
5558
- let line = 1;
5559
- let column = 1;
5560
- for (const char of source) {
5561
- map.set(index++, {
5562
- line,
5563
- column
5564
- });
5565
- if (char === "\n" || char === "\r\n") {
5566
- line++;
5567
- column = 0;
5568
- } else column++;
5569
- }
5570
- return map;
5571
- }
5572
5577
  function markDynamicTests(tasks) {
5573
5578
  for (const task of tasks) {
5574
5579
  if (task.dynamic) task.id += "-dynamic";
@@ -5766,7 +5771,7 @@ class FileSystemModuleCache {
5766
5771
  */
5767
5772
  rootCache;
5768
5773
  metadataFilePath;
5769
- version = "1.0.0-beta.2";
5774
+ version = "1.0.0-beta.3";
5770
5775
  fsCacheRoots = /* @__PURE__ */ new WeakMap();
5771
5776
  fsEnvironmentHashMap = /* @__PURE__ */ new WeakMap();
5772
5777
  fsCacheKeyGenerators = /* @__PURE__ */ new Set();
@@ -5811,7 +5816,7 @@ class FileSystemModuleCache {
5811
5816
  }
5812
5817
  async getCachedModule(cachedFilePath) {
5813
5818
  if (!existsSync(cachedFilePath)) {
5814
- debugFs?.(`${c.red("[empty]")} ${cachedFilePath} doesn't exist, transforming by vite instead`);
5819
+ debugFs?.(`${c.red("[empty]")} ${cachedFilePath} doesn't exist, transforming by vite first`);
5815
5820
  return;
5816
5821
  }
5817
5822
  const fileResult = await this.readCachedFileConcurrently(cachedFilePath);
@@ -5824,16 +5829,18 @@ class FileSystemModuleCache {
5824
5829
  file: meta.file,
5825
5830
  code,
5826
5831
  importers: meta.importers,
5832
+ importedUrls: meta.importedUrls,
5827
5833
  mappings: meta.mappings
5828
5834
  };
5829
5835
  }
5830
- async saveCachedModule(cachedFilePath, fetchResult, importers = [], mappings = false) {
5836
+ async saveCachedModule(cachedFilePath, fetchResult, importers = [], importedUrls = [], mappings = false) {
5831
5837
  if ("code" in fetchResult) {
5832
5838
  const result = {
5833
5839
  file: fetchResult.file,
5834
5840
  id: fetchResult.id,
5835
5841
  url: fetchResult.url,
5836
5842
  importers,
5843
+ importedUrls,
5837
5844
  mappings
5838
5845
  };
5839
5846
  debugFs?.(`${c.yellow("[write]")} ${fetchResult.id} is cached in ${cachedFilePath}`);
@@ -5861,12 +5868,12 @@ class FileSystemModuleCache {
5861
5868
  else if (result === null) debugMemory?.(`${c.green("[read]")} ${id} was bailed out`);
5862
5869
  return result;
5863
5870
  }
5864
- generateCachePath(vitestConfig, environment, resolver, id, fileContent) {
5871
+ generateCachePath(vitestConfig, environment, id, fileContent) {
5865
5872
  // bail out if file has import.meta.glob because it depends on other files
5866
5873
  // TODO: figure out a way to still support it
5867
5874
  if (fileContent.includes("import.meta.glob(")) {
5868
5875
  this.saveMemoryCache(environment, id, null);
5869
- debugMemory?.(`${c.yellow("[write]")} ${id} was bailed out`);
5876
+ debugMemory?.(`${c.yellow("[write]")} ${id} was bailed out because it has "import.meta.glob"`);
5870
5877
  return null;
5871
5878
  }
5872
5879
  let hashString = "";
@@ -5895,7 +5902,7 @@ class FileSystemModuleCache {
5895
5902
  mode: config.mode,
5896
5903
  consumer: config.consumer,
5897
5904
  resolve: config.resolve,
5898
- plugins: config.plugins.map((p) => p.name),
5905
+ plugins: config.plugins.filter((p) => p.api?.vitest?.experimental?.ignoreFsModuleCache !== true).map((p) => p.name),
5899
5906
  configFileDependencies: config.configFileDependencies.map((file) => tryReadFileSync(file)),
5900
5907
  environment: environment.name,
5901
5908
  css: vitestConfig.css
@@ -5910,6 +5917,7 @@ class FileSystemModuleCache {
5910
5917
  let cacheRoot = this.fsCacheRoots.get(vitestConfig);
5911
5918
  if (cacheRoot == null) {
5912
5919
  cacheRoot = vitestConfig.experimental.fsModuleCachePath || this.rootCache;
5920
+ this.fsCacheRoots.set(vitestConfig, cacheRoot);
5913
5921
  if (!existsSync(cacheRoot)) mkdirSync(cacheRoot, { recursive: true });
5914
5922
  }
5915
5923
  const fsResultPath = join(cacheRoot, cacheKey);
@@ -6079,11 +6087,10 @@ const readFilePromises = /* @__PURE__ */ new Map();
6079
6087
  class ModuleFetcher {
6080
6088
  tmpDirectories = /* @__PURE__ */ new Set();
6081
6089
  fsCacheEnabled;
6082
- constructor(resolver, config, fsCache, traces, tmpProjectDir) {
6090
+ constructor(resolver, config, fsCache, tmpProjectDir) {
6083
6091
  this.resolver = resolver;
6084
6092
  this.config = config;
6085
6093
  this.fsCache = fsCache;
6086
- this.traces = traces;
6087
6094
  this.tmpProjectDir = tmpProjectDir;
6088
6095
  this.fsCacheEnabled = config.experimental?.fsModuleCache === true;
6089
6096
  }
@@ -6151,10 +6158,20 @@ class ModuleFetcher {
6151
6158
  }
6152
6159
  const result = await this.fetchAndProcess(environment, url, importer, moduleGraphModule, options);
6153
6160
  const importers = this.getSerializedDependencies(moduleGraphModule);
6161
+ const importedUrls = this.getSerializedImports(moduleGraphModule);
6154
6162
  const map = moduleGraphModule.transformResult?.map;
6155
6163
  const mappings = map && !("version" in map) && map.mappings === "";
6156
- return this.cacheResult(result, cachePath, importers, !!mappings);
6164
+ return this.cacheResult(result, cachePath, importers, importedUrls, !!mappings);
6165
+ }
6166
+ // we need this for UI to be able to show a module graph
6167
+ getSerializedImports(node) {
6168
+ const imports = [];
6169
+ node.importedModules.forEach((importer) => {
6170
+ imports.push(importer.url);
6171
+ });
6172
+ return imports;
6157
6173
  }
6174
+ // we need this for the watcher to be able to find the related test file
6158
6175
  getSerializedDependencies(node) {
6159
6176
  const dependencies = [];
6160
6177
  node.importers.forEach((importer) => {
@@ -6186,7 +6203,7 @@ class ModuleFetcher {
6186
6203
  // null means the file should not be cached
6187
6204
  if (memoryCacheKey !== void 0) return memoryCacheKey;
6188
6205
  const fileContent = await this.readFileContentToCache(environment, moduleGraphModule);
6189
- return this.fsCache.generateCachePath(this.config, environment, this.resolver, moduleGraphModule.id, fileContent);
6206
+ return this.fsCache.generateCachePath(this.config, environment, moduleGraphModule.id, fileContent);
6190
6207
  }
6191
6208
  async readFileContentToCache(environment, moduleGraphModule) {
6192
6209
  if (moduleGraphModule.file && !moduleGraphModule.file.startsWith("\0") && !moduleGraphModule.file.startsWith("virtual:")) {
@@ -6225,6 +6242,10 @@ class ModuleFetcher {
6225
6242
  const environmentNode = environment.moduleGraph.getModuleById(importer);
6226
6243
  if (environmentNode) moduleGraphModule.importers.add(environmentNode);
6227
6244
  });
6245
+ await Promise.all(cachedModule.importedUrls.map(async (url) => {
6246
+ const moduleNode = await environment.moduleGraph.ensureEntryFromUrl(url).catch(() => null);
6247
+ if (moduleNode) moduleGraphModule.importedModules.add(moduleNode);
6248
+ }));
6228
6249
  return {
6229
6250
  cached: true,
6230
6251
  file: cachedModule.file,
@@ -6240,13 +6261,13 @@ class ModuleFetcher {
6240
6261
  inlineSourceMap: false
6241
6262
  }).catch(handleRollupError));
6242
6263
  }
6243
- async cacheResult(result, cachePath, importers = [], mappings = false) {
6264
+ async cacheResult(result, cachePath, importers = [], importedUrls = [], mappings = false) {
6244
6265
  const returnResult = "code" in result ? getCachedResult(result, cachePath) : result;
6245
6266
  if (saveCachePromises.has(cachePath)) {
6246
6267
  await saveCachePromises.get(cachePath);
6247
6268
  return returnResult;
6248
6269
  }
6249
- const savePromise = this.fsCache.saveCachedModule(cachePath, result, importers, mappings).then(() => result).finally(() => {
6270
+ const savePromise = this.fsCache.saveCachedModule(cachePath, result, importers, importedUrls, mappings).then(() => result).finally(() => {
6250
6271
  saveCachePromises.delete(cachePath);
6251
6272
  });
6252
6273
  saveCachePromises.set(cachePath, savePromise);
@@ -6265,7 +6286,7 @@ class ModuleFetcher {
6265
6286
  }
6266
6287
  }
6267
6288
  function createFetchModuleFunction(resolver, config, fsCache, traces, tmpProjectDir) {
6268
- const fetcher = new ModuleFetcher(resolver, config, fsCache, traces, tmpProjectDir);
6289
+ const fetcher = new ModuleFetcher(resolver, config, fsCache, tmpProjectDir);
6269
6290
  return async (url, importer, environment, cacheFs, options, otelCarrier) => {
6270
6291
  await traces.waitInit();
6271
6292
  const context = otelCarrier ? traces.getContextFromCarrier(otelCarrier) : void 0;
@@ -6664,6 +6685,238 @@ This might cause false positive tests. Resolve unhandled errors to make sure you
6664
6685
  }
6665
6686
  }
6666
6687
 
6688
+ // this function recieves the module diagnostic with the location of imports
6689
+ // and populates it with collected import durations; the duration is injected
6690
+ // only if the current module is the one that imported the module
6691
+ // if testModule is not defined, then Vitest aggregates durations of ALL collected test modules
6692
+ function collectModuleDurationsDiagnostic(moduleId, state, moduleDiagnostic, testModule) {
6693
+ if (!moduleDiagnostic) return {
6694
+ modules: [],
6695
+ untrackedModules: []
6696
+ };
6697
+ const modules = [];
6698
+ const modulesById = {};
6699
+ const allModules = [...moduleDiagnostic.modules, ...moduleDiagnostic.untracked];
6700
+ const visitedByFiles = {};
6701
+ // this aggregates the times for _ALL_ tests if testModule is not passed
6702
+ // so if the module was imported in separate tests, the time will be accumulated
6703
+ for (const files of testModule ? [[testModule.task]] : state.filesMap.values()) for (const file of files) {
6704
+ const importDurations = file.importDurations;
6705
+ if (!importDurations) continue;
6706
+ const currentModule = state.getReportedEntity(file);
6707
+ if (!currentModule) continue;
6708
+ const visitedKey = currentModule.project.config.isolate === false ? "non-isolate" : file.id;
6709
+ if (!visitedByFiles[visitedKey]) visitedByFiles[visitedKey] = /* @__PURE__ */ new Set();
6710
+ const visited = visitedByFiles[visitedKey];
6711
+ allModules.forEach(({ resolvedId, resolvedUrl }) => {
6712
+ const durations = importDurations[resolvedId];
6713
+ // do not accumulate if module was already visited by suite (or suites in non-isolate mode)
6714
+ if (!durations || visited.has(resolvedId)) return;
6715
+ const importer = getModuleImporter(moduleId, durations, currentModule);
6716
+ modulesById[resolvedId] ??= {
6717
+ selfTime: 0,
6718
+ totalTime: 0,
6719
+ transformTime: 0,
6720
+ external: durations.external,
6721
+ importer
6722
+ };
6723
+ // only track if the current module imported this module,
6724
+ // otherwise it was imported instantly because it's cached
6725
+ if (importer === moduleId) {
6726
+ visited.add(resolvedId);
6727
+ modulesById[resolvedId].selfTime += durations.selfTime;
6728
+ modulesById[resolvedId].totalTime += durations.totalTime;
6729
+ // don't aggregate
6730
+ modulesById[resolvedId].transformTime = state.metadata[currentModule.project.name]?.duration[resolvedUrl]?.[0];
6731
+ }
6732
+ });
6733
+ }
6734
+ // if module was imported twice in the same file,
6735
+ // show only one time - the second should be shown as 0
6736
+ const visitedInFile = /* @__PURE__ */ new Set();
6737
+ moduleDiagnostic.modules.forEach((diagnostic) => {
6738
+ const durations = modulesById[diagnostic.resolvedId];
6739
+ if (!durations) return;
6740
+ if (visitedInFile.has(diagnostic.resolvedId)) modules.push({
6741
+ ...diagnostic,
6742
+ selfTime: 0,
6743
+ totalTime: 0,
6744
+ transformTime: 0,
6745
+ external: durations.external,
6746
+ importer: durations.importer
6747
+ });
6748
+ else {
6749
+ visitedInFile.add(diagnostic.resolvedId);
6750
+ modules.push({
6751
+ ...diagnostic,
6752
+ ...durations
6753
+ });
6754
+ }
6755
+ });
6756
+ const untracked = [];
6757
+ moduleDiagnostic.untracked.forEach((diagnostic) => {
6758
+ const durations = modulesById[diagnostic.resolvedId];
6759
+ if (!durations) return;
6760
+ if (visitedInFile.has(diagnostic.resolvedId)) untracked.push({
6761
+ selfTime: 0,
6762
+ totalTime: 0,
6763
+ transformTime: 0,
6764
+ external: durations.external,
6765
+ importer: durations.importer,
6766
+ resolvedId: diagnostic.resolvedId,
6767
+ resolvedUrl: diagnostic.resolvedUrl,
6768
+ url: diagnostic.rawUrl
6769
+ });
6770
+ else {
6771
+ visitedInFile.add(diagnostic.resolvedId);
6772
+ untracked.push({
6773
+ ...durations,
6774
+ resolvedId: diagnostic.resolvedId,
6775
+ resolvedUrl: diagnostic.resolvedUrl,
6776
+ url: diagnostic.rawUrl
6777
+ });
6778
+ }
6779
+ });
6780
+ return {
6781
+ modules,
6782
+ untrackedModules: untracked
6783
+ };
6784
+ }
6785
+ function getModuleImporter(moduleId, durations, testModule) {
6786
+ if (durations.importer === moduleId) return moduleId;
6787
+ if (!durations.importer) {
6788
+ if (moduleId === testModule.moduleId) return testModule.moduleId;
6789
+ return testModule.project.config.setupFiles.includes(moduleId) ? moduleId : durations.importer;
6790
+ }
6791
+ return durations.importer;
6792
+ }
6793
+ // the idea of this is very simple
6794
+ // it parses the source code to extract import/export statements
6795
+ // it parses SSR transformed file to extract __vite_ssr_import__ and __vite_ssr_dynamic_import__
6796
+ // it combines the two by looking at the original positions of SSR primitives
6797
+ // in the end, we are able to return a list of modules that were imported by this module
6798
+ // mapped to their IDs in Vite's module graph
6799
+ async function collectSourceModulesLocations(moduleId, moduleGraph) {
6800
+ const transformResult = moduleGraph.getModuleById(moduleId)?.transformResult;
6801
+ if (!transformResult || !transformResult.ssr) return;
6802
+ const map = transformResult.map;
6803
+ if (!map || !("version" in map) || !map.sources.length) return;
6804
+ const sourceImports = map.sources.reduce((acc, sourceId, index) => {
6805
+ const source = map.sourcesContent?.[index];
6806
+ if (source != null) acc[sourceId] = parseSourceImportsAndExports(source);
6807
+ return acc;
6808
+ }, {});
6809
+ const transformImports = await parseTransformResult(moduleGraph, transformResult);
6810
+ const traceMap = map && "version" in map && new TraceMap(map);
6811
+ const modules = {};
6812
+ const untracked = [];
6813
+ transformImports.forEach((row) => {
6814
+ const original = traceMap && originalPositionFor(traceMap, row.start);
6815
+ if (original && original.source != null) {
6816
+ // if there are several at the same position, this is a bug
6817
+ // probably caused by import.meta.glob imports returning incorrect positions
6818
+ // all the new import.meta.glob imports come first, so only the last module on this line is correct
6819
+ const sourceImport = sourceImports[original.source].get(`${original.line}:${original.column}`);
6820
+ if (sourceImport) {
6821
+ if (modules[sourceImport.rawUrl]) {
6822
+ // remove imports with a different resolvedId
6823
+ const differentImports = modules[sourceImport.rawUrl].filter((d) => d.resolvedId !== row.resolvedId);
6824
+ untracked.push(...differentImports);
6825
+ modules[sourceImport.rawUrl] = modules[sourceImport.rawUrl].filter((d) => d.resolvedId === row.resolvedId);
6826
+ }
6827
+ modules[sourceImport.rawUrl] ??= [];
6828
+ modules[sourceImport.rawUrl].push({
6829
+ start: sourceImport.start,
6830
+ end: sourceImport.end,
6831
+ startIndex: sourceImport.startIndex,
6832
+ endIndex: sourceImport.endIndex,
6833
+ rawUrl: sourceImport.rawUrl,
6834
+ resolvedId: row.resolvedId,
6835
+ resolvedUrl: row.resolvedUrl
6836
+ });
6837
+ }
6838
+ }
6839
+ });
6840
+ return {
6841
+ modules: Object.values(modules).flat(),
6842
+ untracked
6843
+ };
6844
+ }
6845
+ function fillSourcesMap(syntax, sourcesMap, source, indexMap) {
6846
+ const splitSeparator = `${syntax} `;
6847
+ const splitSources = source.split(splitSeparator);
6848
+ const chunks = [];
6849
+ let index = 0;
6850
+ for (const chunk of splitSources) {
6851
+ chunks.push({
6852
+ chunk,
6853
+ startIndex: index
6854
+ });
6855
+ index += chunk.length + splitSeparator.length;
6856
+ }
6857
+ chunks.forEach(({ chunk, startIndex }) => {
6858
+ const normalized = chunk.replace(/'/g, "\"");
6859
+ const startQuoteIdx = normalized.indexOf("\"");
6860
+ if (startQuoteIdx === -1) return;
6861
+ const endQuoteIdx = normalized.indexOf("\"", startQuoteIdx + 1);
6862
+ if (endQuoteIdx === -1) return;
6863
+ const staticSyntax = {
6864
+ startIndex: startIndex + startQuoteIdx,
6865
+ endIndex: startIndex + endQuoteIdx + 1,
6866
+ start: indexMap.get(startIndex + startQuoteIdx),
6867
+ end: indexMap.get(startIndex + endQuoteIdx + 1),
6868
+ rawUrl: normalized.slice(startQuoteIdx + 1, endQuoteIdx)
6869
+ };
6870
+ // -7 to include "import "
6871
+ for (let i = startIndex - 7; i < staticSyntax.endIndex; i++) {
6872
+ const location = indexMap.get(i);
6873
+ if (location) sourcesMap.set(`${location.line}:${location.column}`, staticSyntax);
6874
+ }
6875
+ });
6876
+ }
6877
+ // this function tries to parse ESM static import and export statements from
6878
+ // the source. if the source is not JS/TS, but supports static ESM syntax,
6879
+ // then this will also find them because it' only checks the strings, it doesn't parse the AST
6880
+ function parseSourceImportsAndExports(source) {
6881
+ if (!source.includes("import ") && !source.includes("export ")) return /* @__PURE__ */ new Map();
6882
+ const sourcesMap = /* @__PURE__ */ new Map();
6883
+ const indexMap = createIndexLocationsMap(source);
6884
+ fillSourcesMap("import", sourcesMap, source, indexMap);
6885
+ fillSourcesMap("export", sourcesMap, source, indexMap);
6886
+ return sourcesMap;
6887
+ }
6888
+ async function parseTransformResult(moduleGraph, transformResult) {
6889
+ const code = transformResult.code;
6890
+ const regexp = /(?:__vite_ssr_import__|__vite_ssr_dynamic_import__)\("([^"]+)"/g;
6891
+ const lineColumnMap = createIndexLocationsMap(code);
6892
+ const importPositions = [];
6893
+ let match;
6894
+ // eslint-disable-next-line no-cond-assign
6895
+ while (match = regexp.exec(code)) {
6896
+ const startIndex = match.index;
6897
+ const endIndex = match.index + match[0].length - 1;
6898
+ importPositions.push({
6899
+ raw: match[1],
6900
+ startIndex,
6901
+ endIndex
6902
+ });
6903
+ }
6904
+ return (await Promise.all(importPositions.map(async ({ startIndex, endIndex, raw }) => {
6905
+ const position = lineColumnMap.get(startIndex);
6906
+ const endPosition = lineColumnMap.get(endIndex);
6907
+ const moduleNode = await moduleGraph.getModuleByUrl(raw);
6908
+ if (!position || !endPosition || !moduleNode || !moduleNode.id) return;
6909
+ return {
6910
+ resolvedId: moduleNode.id,
6911
+ resolvedUrl: moduleNode.url,
6912
+ start: position,
6913
+ end: endPosition,
6914
+ startIndex,
6915
+ endIndex
6916
+ };
6917
+ }))).filter((n) => n != null);
6918
+ }
6919
+
6667
6920
  const __dirname$1 = url.fileURLToPath(new URL(".", import.meta.url));
6668
6921
  class VitestPackageInstaller {
6669
6922
  isPackageExists(name, options) {
@@ -7042,7 +7295,7 @@ function createMethodsRPC(project, methodsOptions = {}) {
7042
7295
  const file = cleanUrl(resolved.id);
7043
7296
  if (resolved.external) return {
7044
7297
  file,
7045
- url: !resolved.id.startsWith("node:") && isBuiltin(resolved.id) ? `node:${resolved.id}` : resolved.id,
7298
+ url: isBuiltin(resolved.id) ? toBuiltin(resolved.id) : resolved.id,
7046
7299
  id: resolved.id
7047
7300
  };
7048
7301
  return {
@@ -7246,7 +7499,7 @@ class PoolRunner {
7246
7499
  this._operationLock = null;
7247
7500
  }
7248
7501
  }
7249
- async stop() {
7502
+ async stop(options) {
7250
7503
  // Wait for any ongoing operation to complete
7251
7504
  if (this._operationLock) await this._operationLock;
7252
7505
  if (this._state === RunnerState.STOPPED || this._state === RunnerState.STOPPING) return;
@@ -7274,6 +7527,11 @@ class PoolRunner {
7274
7527
  this.off("message", onStop);
7275
7528
  }
7276
7529
  };
7530
+ // Don't wait for graceful exit's response when force exiting
7531
+ if (options?.force) return onStop({
7532
+ type: "stopped",
7533
+ __vitest_worker_response__: true
7534
+ });
7277
7535
  this.on("message", onStop);
7278
7536
  this.postMessage({
7279
7537
  type: "stop",
@@ -7733,7 +7991,8 @@ class Pool {
7733
7991
  };
7734
7992
  this.activeTasks.push(activeTask);
7735
7993
  // active tasks receive cancel signal and shut down gracefully
7736
- async function cancelTask() {
7994
+ async function cancelTask(options) {
7995
+ if (options?.force) await runner.stop({ force: true });
7737
7996
  await runner.waitForTerminated();
7738
7997
  resolver.reject(/* @__PURE__ */ new Error("Cancelled"));
7739
7998
  }
@@ -7783,6 +8042,9 @@ catch (error) {
7783
8042
  return this.schedule();
7784
8043
  }
7785
8044
  async cancel() {
8045
+ // Force exit if previous cancel is still on-going
8046
+ // for example when user does 'CTRL+c' twice in row
8047
+ const force = this._isCancelling;
7786
8048
  // Set flag to prevent new tasks from being queued
7787
8049
  this._isCancelling = true;
7788
8050
  const pendingTasks = this.queue.splice(0);
@@ -7790,11 +8052,12 @@ catch (error) {
7790
8052
  const error = /* @__PURE__ */ new Error("Cancelled");
7791
8053
  pendingTasks.forEach((task) => task.resolver.reject(error));
7792
8054
  }
7793
- const activeTasks = this.activeTasks.splice(0);
7794
- await Promise.all(activeTasks.map((task) => task.cancelTask()));
7795
- const sharedRunners = this.sharedRunners.splice(0);
7796
- await Promise.all(sharedRunners.map((runner) => runner.stop()));
7797
- await Promise.all(this.exitPromises.splice(0));
8055
+ await Promise.all(this.activeTasks.map((task) => task.cancelTask({ force })));
8056
+ this.activeTasks = [];
8057
+ await Promise.all(this.sharedRunners.map((runner) => runner.stop()));
8058
+ this.sharedRunners = [];
8059
+ await Promise.all(this.exitPromises);
8060
+ this.exitPromises = [];
7798
8061
  this.workerIds.forEach((_, id) => this.freeWorkerId(id));
7799
8062
  // Reset flag after cancellation completes
7800
8063
  this._isCancelling = false;
@@ -8198,7 +8461,10 @@ function serializeConfig(project) {
8198
8461
  printConsoleTrace: config.printConsoleTrace ?? globalConfig.printConsoleTrace,
8199
8462
  benchmark: config.benchmark && { includeSamples: config.benchmark.includeSamples },
8200
8463
  serializedDefines: config.browser.enabled ? "" : project._serializedDefines || "",
8201
- experimental: { fsModuleCache: config.experimental.fsModuleCache ?? false }
8464
+ experimental: {
8465
+ fsModuleCache: config.experimental.fsModuleCache ?? false,
8466
+ printImportBreakdown: config.experimental.printImportBreakdown
8467
+ }
8202
8468
  };
8203
8469
  }
8204
8470
 
@@ -9118,7 +9384,10 @@ function ModuleRunnerTransform() {
9118
9384
  environment.resolve.noExternal = true;
9119
9385
  // Workaround `noExternal` merging bug on Vite 6
9120
9386
  // https://github.com/vitejs/vite/pull/20502
9121
- if (name === "ssr") delete config.ssr?.noExternal;
9387
+ if (name === "ssr") {
9388
+ delete config.ssr?.noExternal;
9389
+ delete config.ssr?.external;
9390
+ }
9122
9391
  if (name === "__vitest_vm__" || name === "__vitest__") continue;
9123
9392
  const currentOptimizeDeps = environment.optimizeDeps || (name === "client" ? config.optimizeDeps : name === "ssr" ? config.ssr?.optimizeDeps : void 0);
9124
9393
  const optimizeDeps = resolveOptimizerConfig(testConfig.deps?.optimizer?.[name], currentOptimizeDeps);
@@ -9348,6 +9617,7 @@ function WorkspaceVitestPlugin(project, options) {
9348
9617
 
9349
9618
  class VitestResolver {
9350
9619
  options;
9620
+ externalizeConcurrentCache = /* @__PURE__ */ new Map();
9351
9621
  externalizeCache = /* @__PURE__ */ new Map();
9352
9622
  constructor(cacheDir, config) {
9353
9623
  // sorting to make cache consistent
@@ -9367,8 +9637,20 @@ class VitestResolver {
9367
9637
  external
9368
9638
  };
9369
9639
  }
9370
- shouldExternalize(file) {
9371
- return shouldExternalize(normalizeId(file), this.options, this.externalizeCache);
9640
+ wasExternalized(file) {
9641
+ const normalizedFile = normalizeId(file);
9642
+ if (!this.externalizeCache.has(normalizedFile)) return false;
9643
+ return this.externalizeCache.get(normalizedFile) ?? false;
9644
+ }
9645
+ async shouldExternalize(file) {
9646
+ const normalizedFile = normalizeId(file);
9647
+ if (this.externalizeCache.has(normalizedFile)) return this.externalizeCache.get(normalizedFile);
9648
+ return shouldExternalize(normalizeId(file), this.options, this.externalizeConcurrentCache).then((result) => {
9649
+ this.externalizeCache.set(normalizedFile, result);
9650
+ return result;
9651
+ }).finally(() => {
9652
+ this.externalizeConcurrentCache.delete(normalizedFile);
9653
+ });
9372
9654
  }
9373
9655
  }
9374
9656
  function normalizeId(id) {
@@ -9413,6 +9695,9 @@ function guessCJSversion(id) {
9413
9695
  }
9414
9696
  // The code from https://github.com/unjs/mlly/blob/c5bcca0cda175921344fd6de1bc0c499e73e5dac/src/syntax.ts#L51-L98
9415
9697
  async function isValidNodeImport(id) {
9698
+ // clean url to strip off `?v=...` query etc.
9699
+ // node can natively import files with query params, so externalizing them is safe.
9700
+ id = cleanUrl(id);
9416
9701
  const extension = extname(id);
9417
9702
  if (BUILTIN_EXTENSIONS.has(extension)) return true;
9418
9703
  if (extension !== ".js") return false;
@@ -9433,7 +9718,7 @@ async function shouldExternalize(id, options, cache) {
9433
9718
  return cache.get(id);
9434
9719
  }
9435
9720
  async function _shouldExternalize(id, options) {
9436
- if (isBuiltin(id)) return id;
9721
+ if (isBuiltin$1(id)) return id;
9437
9722
  // data: should be processed by native import,
9438
9723
  // since it is a feature of ESM.
9439
9724
  // also externalize network imports since nodejs allows it when --experimental-network-imports
@@ -9450,7 +9735,6 @@ async function _shouldExternalize(id, options) {
9450
9735
  if (matchPattern(id, moduleDirectories, defaultInline)) return false;
9451
9736
  if (matchPattern(id, moduleDirectories, depsExternal)) return id;
9452
9737
  if (isLibraryModule && await isValidNodeImport(id)) return id;
9453
- return false;
9454
9738
  }
9455
9739
  function matchPattern(id, moduleDirectories, patterns) {
9456
9740
  if (patterns == null) return false;
@@ -10681,6 +10965,12 @@ class TestSuite extends SuiteImplementation {
10681
10965
  class TestModule extends SuiteImplementation {
10682
10966
  type = "module";
10683
10967
  /**
10968
+ * The Vite environment that processes files on the server.
10969
+ *
10970
+ * Can be empty if test module did not run yet.
10971
+ */
10972
+ viteEnvironment;
10973
+ /**
10684
10974
  * This is usually an absolute UNIX file path.
10685
10975
  * It can be a virtual ID if the file is not on the disk.
10686
10976
  * This value corresponds to the ID in the Vite's module graph.
@@ -10695,6 +10985,8 @@ class TestModule extends SuiteImplementation {
10695
10985
  super(task, project);
10696
10986
  this.moduleId = task.filepath;
10697
10987
  this.relativeModuleId = task.name;
10988
+ if (task.viteEnvironment === "__browser__") this.viteEnvironment = project.browser?.vite.environments.client;
10989
+ else if (typeof task.viteEnvironment === "string") this.viteEnvironment = project.vite.environments[task.viteEnvironment];
10698
10990
  }
10699
10991
  /**
10700
10992
  * Checks the running state of the test file.
@@ -12247,6 +12539,39 @@ class Vitest {
12247
12539
  return await this.runningPromise;
12248
12540
  });
12249
12541
  }
12542
+ /**
12543
+ * Returns module's diagnostic. If `testModule` is not provided, `selfTime` and `totalTime` will be aggregated across all tests.
12544
+ *
12545
+ * If the module was not transformed or executed, the diagnostic will be empty.
12546
+ * @experimental
12547
+ * @see {@link https://vitest.dev/api/advanced/vitest#getsourcemodulediagnostic}
12548
+ */
12549
+ async experimental_getSourceModuleDiagnostic(moduleId, testModule) {
12550
+ if (testModule) {
12551
+ const viteEnvironment = testModule.viteEnvironment;
12552
+ // if there is no viteEnvironment, it means the file did not run yet
12553
+ if (!viteEnvironment) return {
12554
+ modules: [],
12555
+ untrackedModules: []
12556
+ };
12557
+ const moduleLocations = await collectSourceModulesLocations(moduleId, viteEnvironment.moduleGraph);
12558
+ return collectModuleDurationsDiagnostic(moduleId, this.state, moduleLocations, testModule);
12559
+ }
12560
+ const environments = this.projects.flatMap((p) => {
12561
+ return Object.values(p.vite.environments);
12562
+ });
12563
+ const aggregatedLocationsResult = await Promise.all(environments.map((environment) => collectSourceModulesLocations(moduleId, environment.moduleGraph)));
12564
+ return collectModuleDurationsDiagnostic(moduleId, this.state, aggregatedLocationsResult.reduce((acc, locations) => {
12565
+ if (locations) {
12566
+ acc.modules.push(...locations.modules);
12567
+ acc.untracked.push(...locations.untracked);
12568
+ }
12569
+ return acc;
12570
+ }, {
12571
+ modules: [],
12572
+ untracked: []
12573
+ }));
12574
+ }
12250
12575
  async experimental_parseSpecifications(specifications, options) {
12251
12576
  if (this.mode !== "test") throw new Error(`The \`experimental_parseSpecifications\` does not support "${this.mode}" mode.`);
12252
12577
  const limit = limitConcurrency(options?.concurrency ?? (typeof nodeos__default.availableParallelism === "function" ? nodeos__default.availableParallelism() : nodeos__default.cpus().length));