deslop-js 0.0.16 → 0.0.17-dev.7acf549

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.
package/dist/index.cjs CHANGED
@@ -35,6 +35,10 @@ let node_fs_promises = require("node:fs/promises");
35
35
  let oxc_parser = require("oxc-parser");
36
36
  let typescript = require("typescript");
37
37
  typescript = __toESM(typescript, 1);
38
+ let node_worker_threads = require("node:worker_threads");
39
+ let node_url = require("node:url");
40
+ let node_os = require("node:os");
41
+ node_os = __toESM(node_os, 1);
38
42
  let oxc_resolver = require("oxc-resolver");
39
43
  let minimatch = require("minimatch");
40
44
 
@@ -6141,6 +6145,148 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
6141
6145
  };
6142
6146
  };
6143
6147
 
6148
+ //#endregion
6149
+ //#region src/utils/resolve-available-concurrency.ts
6150
+ const resolveAvailableConcurrency = () => {
6151
+ const available = node_os.default.availableParallelism();
6152
+ if (!Number.isFinite(available) || available < 1) return 1;
6153
+ return Math.max(1, Math.min(Math.floor(available), 16));
6154
+ };
6155
+
6156
+ //#endregion
6157
+ //#region src/collect/parallel-parse.ts
6158
+ const deserializeErrors = (serializedErrors) => serializedErrors.map((errorJson) => new DeslopError({
6159
+ code: errorJson.code,
6160
+ module: errorJson.module,
6161
+ severity: errorJson.severity,
6162
+ message: errorJson.message,
6163
+ path: errorJson.path,
6164
+ detail: errorJson.detail
6165
+ }));
6166
+ const deserializeParsedSource = (serialized) => ({
6167
+ imports: serialized.imports,
6168
+ exports: serialized.exports,
6169
+ memberAccesses: serialized.memberAccesses,
6170
+ wholeObjectUses: serialized.wholeObjectUses,
6171
+ localIdentifierReferences: serialized.localIdentifierReferences,
6172
+ referencedFilenames: serialized.referencedFilenames,
6173
+ redundantTypePatterns: serialized.redundantTypePatterns,
6174
+ identityWrappers: serialized.identityWrappers,
6175
+ typeDefinitionHashes: serialized.typeDefinitionHashes,
6176
+ inlineTypeLiterals: serialized.inlineTypeLiterals,
6177
+ simplifiableFunctions: serialized.simplifiableFunctions,
6178
+ simplifiableExpressions: serialized.simplifiableExpressions,
6179
+ duplicateConstantCandidates: serialized.duplicateConstantCandidates,
6180
+ errors: deserializeErrors(serialized.errors)
6181
+ });
6182
+ const resolveWorkerPath = () => {
6183
+ const currentUrl = require("url").pathToFileURL(__filename).href;
6184
+ if (currentUrl.endsWith(".ts")) return (0, node_url.fileURLToPath)(new URL("./parse-worker.ts", currentUrl));
6185
+ return (0, node_url.fileURLToPath)(new URL("./parse-worker.mjs", currentUrl));
6186
+ };
6187
+ const createWorker = (workerPath) => {
6188
+ return new node_worker_threads.Worker(workerPath, { ...workerPath.endsWith(".ts") ? { execArgv: ["--import", "tsx"] } : {} });
6189
+ };
6190
+ const waitForReady = (worker) => new Promise((resolve, reject) => {
6191
+ const onMessage = (message) => {
6192
+ if (message.type === "ready") {
6193
+ worker.off("message", onMessage);
6194
+ worker.off("error", onError);
6195
+ resolve();
6196
+ }
6197
+ };
6198
+ const onError = (error) => {
6199
+ worker.off("message", onMessage);
6200
+ worker.off("error", onError);
6201
+ reject(error);
6202
+ };
6203
+ worker.on("message", onMessage);
6204
+ worker.on("error", onError);
6205
+ });
6206
+ const parseFilesWithWorkerPool = async (files, workerCount) => {
6207
+ const workerPath = resolveWorkerPath();
6208
+ const results = new Array(files.length);
6209
+ const workers = [];
6210
+ try {
6211
+ for (let workerIndex = 0; workerIndex < workerCount; workerIndex++) workers.push(createWorker(workerPath));
6212
+ await Promise.all(workers.map(waitForReady));
6213
+ } catch {
6214
+ for (const worker of workers) worker.terminate();
6215
+ return files.map((file) => parseSourceFile(file.path));
6216
+ }
6217
+ let nextFileIndex = 0;
6218
+ let completedCount = 0;
6219
+ return new Promise((resolve, reject) => {
6220
+ const dispatchNext = (worker) => {
6221
+ if (nextFileIndex >= files.length) return;
6222
+ const fileIndex = nextFileIndex;
6223
+ nextFileIndex += 1;
6224
+ worker.postMessage({
6225
+ type: "parse",
6226
+ filePath: files[fileIndex].path,
6227
+ fileIndex
6228
+ });
6229
+ };
6230
+ const onWorkerMessage = (worker) => (message) => {
6231
+ if (message.type === "result") {
6232
+ results[message.fileIndex] = deserializeParsedSource(message.parsed);
6233
+ completedCount += 1;
6234
+ if (completedCount === files.length) {
6235
+ cleanup();
6236
+ resolve(results);
6237
+ } else dispatchNext(worker);
6238
+ } else if (message.type === "error") {
6239
+ results[message.fileIndex] = {
6240
+ imports: [],
6241
+ exports: [],
6242
+ memberAccesses: [],
6243
+ wholeObjectUses: [],
6244
+ localIdentifierReferences: [],
6245
+ referencedFilenames: [],
6246
+ redundantTypePatterns: [],
6247
+ identityWrappers: [],
6248
+ typeDefinitionHashes: [],
6249
+ inlineTypeLiterals: [],
6250
+ simplifiableFunctions: [],
6251
+ simplifiableExpressions: [],
6252
+ duplicateConstantCandidates: [],
6253
+ errors: [new ParseError({
6254
+ code: "parse-failed",
6255
+ message: `Worker parse failed: ${message.errorMessage}`,
6256
+ path: message.filePath
6257
+ })]
6258
+ };
6259
+ completedCount += 1;
6260
+ if (completedCount === files.length) {
6261
+ cleanup();
6262
+ resolve(results);
6263
+ } else dispatchNext(worker);
6264
+ }
6265
+ };
6266
+ const cleanup = () => {
6267
+ for (const worker of workers) worker.terminate();
6268
+ };
6269
+ for (const worker of workers) {
6270
+ worker.on("message", onWorkerMessage(worker));
6271
+ worker.on("error", (error) => {
6272
+ cleanup();
6273
+ reject(error);
6274
+ });
6275
+ }
6276
+ for (const worker of workers) dispatchNext(worker);
6277
+ });
6278
+ };
6279
+ const parseFilesInParallel = async (files) => {
6280
+ if (files.length <= 50) return files.map((file) => parseSourceFile(file.path));
6281
+ const concurrency = resolveAvailableConcurrency();
6282
+ if (concurrency <= 1) return files.map((file) => parseSourceFile(file.path));
6283
+ try {
6284
+ return await parseFilesWithWorkerPool(files, concurrency);
6285
+ } catch {
6286
+ return files.map((file) => parseSourceFile(file.path));
6287
+ }
6288
+ };
6289
+
6144
6290
  //#endregion
6145
6291
  //#region src/utils/is-platform-builtin-or-virtual.ts
6146
6292
  const BUILTIN_SUBPATH_NODE_MODULES = new Set([
@@ -7650,8 +7796,11 @@ const collectPnpmWorkspaceOverrideMappings = (rootDir) => {
7650
7796
  };
7651
7797
 
7652
7798
  //#endregion
7653
- //#region src/utils/matches-package-import-reference.ts
7799
+ //#region src/utils/escape-reg-exp.ts
7654
7800
  const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7801
+
7802
+ //#endregion
7803
+ //#region src/utils/matches-package-import-reference.ts
7655
7804
  const matchesPackageImportReference = (content, packageName) => {
7656
7805
  const escapedPackageName = escapeRegExp(packageName);
7657
7806
  const subpathPattern = `(?:/[^'"]*)?`;
@@ -7664,6 +7813,13 @@ const matchesPackageImportReference = (content, packageName) => {
7664
7813
  ].some((pattern) => pattern.test(content));
7665
7814
  };
7666
7815
 
7816
+ //#endregion
7817
+ //#region src/utils/matches-package-token-reference.ts
7818
+ const matchesPackageTokenReference = (command, packageName) => {
7819
+ const escapedPackageName = escapeRegExp(packageName);
7820
+ return new RegExp(`(?:^|[\\s='"\`(,;:|&])${escapedPackageName}(?:/[^\\s'"\`]*)?(?=$|[\\s='"\`),;:|&])`).test(command);
7821
+ };
7822
+
7667
7823
  //#endregion
7668
7824
  //#region src/report/packages.ts
7669
7825
  const discoverAllPackageJsonPaths = (rootDir) => {
@@ -7953,6 +8109,10 @@ const collectScriptReferencedPackages = (packageJsonPath, declaredNames, binToPa
7953
8109
  if (typeof scriptCommand !== "string") continue;
7954
8110
  const commandReferenced = collectCommandReferencedPackages(scriptCommand, declaredNames, binToPackage);
7955
8111
  for (const packageName of commandReferenced) referenced.add(packageName);
8112
+ for (const declaredName of declaredNames) {
8113
+ if (referenced.has(declaredName)) continue;
8114
+ if (matchesPackageTokenReference(scriptCommand, declaredName)) referenced.add(declaredName);
8115
+ }
7956
8116
  }
7957
8117
  } catch {
7958
8118
  return referenced;
@@ -12576,8 +12736,23 @@ const analyze = async (config) => {
12576
12736
  ignorePatterns: [...config.ignorePatterns, ...allExclusionPatterns]
12577
12737
  } : config;
12578
12738
  let files;
12739
+ let discoveredEntries;
12579
12740
  try {
12580
- files = await collectSourceFiles(configWithExclusions);
12741
+ const [collectedFiles, resolvedEntries] = await Promise.all([collectSourceFiles(configWithExclusions), resolveEntries(configWithExclusions).catch((entriesError) => {
12742
+ setupErrors.push(new WorkspaceError({
12743
+ code: "workspace-discovery-failed",
12744
+ message: "resolveEntries failed — defaulting to empty entry set",
12745
+ path: config.rootDir,
12746
+ detail: describeUnknownError(entriesError)
12747
+ }));
12748
+ return {
12749
+ productionEntries: [],
12750
+ testEntries: [],
12751
+ alwaysUsedFiles: []
12752
+ };
12753
+ })]);
12754
+ files = collectedFiles;
12755
+ discoveredEntries = resolvedEntries;
12581
12756
  } catch (collectError) {
12582
12757
  setupErrors.push(new WorkspaceError({
12583
12758
  code: "workspace-discovery-failed",
@@ -12588,22 +12763,6 @@ const analyze = async (config) => {
12588
12763
  }));
12589
12764
  return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
12590
12765
  }
12591
- let discoveredEntries;
12592
- try {
12593
- discoveredEntries = await resolveEntries(configWithExclusions);
12594
- } catch (entriesError) {
12595
- setupErrors.push(new WorkspaceError({
12596
- code: "workspace-discovery-failed",
12597
- message: "resolveEntries failed — defaulting to empty entry set",
12598
- path: config.rootDir,
12599
- detail: describeUnknownError(entriesError)
12600
- }));
12601
- discoveredEntries = {
12602
- productionEntries: [],
12603
- testEntries: [],
12604
- alwaysUsedFiles: []
12605
- };
12606
- }
12607
12766
  const productionEntrySet = new Set(discoveredEntries.productionEntries);
12608
12767
  const testEntrySet = new Set(discoveredEntries.testEntries);
12609
12768
  const alwaysUsedFileSet = new Set(discoveredEntries.alwaysUsedFiles);
@@ -12630,9 +12789,11 @@ const analyze = async (config) => {
12630
12789
  }));
12631
12790
  return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
12632
12791
  }
12792
+ const parsedModules = await parseFilesInParallel(files);
12633
12793
  const graphInputs = [];
12634
- for (const file of files) {
12635
- const parsedModule = parseSourceFile(file.path);
12794
+ for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
12795
+ const file = files[fileIndex];
12796
+ const parsedModule = parsedModules[fileIndex];
12636
12797
  const resolvedImportMap = /* @__PURE__ */ new Map();
12637
12798
  const safeResolveImport = (specifier) => {
12638
12799
  try {
package/dist/index.mjs CHANGED
@@ -4,6 +4,9 @@ import fg from "fast-glob";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { parseSync } from "oxc-parser";
6
6
  import ts from "typescript";
7
+ import { Worker } from "node:worker_threads";
8
+ import { fileURLToPath } from "node:url";
9
+ import os from "node:os";
7
10
  import { ResolverFactory } from "oxc-resolver";
8
11
  import { minimatch } from "minimatch";
9
12
 
@@ -6110,6 +6113,148 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
6110
6113
  };
6111
6114
  };
6112
6115
 
6116
+ //#endregion
6117
+ //#region src/utils/resolve-available-concurrency.ts
6118
+ const resolveAvailableConcurrency = () => {
6119
+ const available = os.availableParallelism();
6120
+ if (!Number.isFinite(available) || available < 1) return 1;
6121
+ return Math.max(1, Math.min(Math.floor(available), 16));
6122
+ };
6123
+
6124
+ //#endregion
6125
+ //#region src/collect/parallel-parse.ts
6126
+ const deserializeErrors = (serializedErrors) => serializedErrors.map((errorJson) => new DeslopError({
6127
+ code: errorJson.code,
6128
+ module: errorJson.module,
6129
+ severity: errorJson.severity,
6130
+ message: errorJson.message,
6131
+ path: errorJson.path,
6132
+ detail: errorJson.detail
6133
+ }));
6134
+ const deserializeParsedSource = (serialized) => ({
6135
+ imports: serialized.imports,
6136
+ exports: serialized.exports,
6137
+ memberAccesses: serialized.memberAccesses,
6138
+ wholeObjectUses: serialized.wholeObjectUses,
6139
+ localIdentifierReferences: serialized.localIdentifierReferences,
6140
+ referencedFilenames: serialized.referencedFilenames,
6141
+ redundantTypePatterns: serialized.redundantTypePatterns,
6142
+ identityWrappers: serialized.identityWrappers,
6143
+ typeDefinitionHashes: serialized.typeDefinitionHashes,
6144
+ inlineTypeLiterals: serialized.inlineTypeLiterals,
6145
+ simplifiableFunctions: serialized.simplifiableFunctions,
6146
+ simplifiableExpressions: serialized.simplifiableExpressions,
6147
+ duplicateConstantCandidates: serialized.duplicateConstantCandidates,
6148
+ errors: deserializeErrors(serialized.errors)
6149
+ });
6150
+ const resolveWorkerPath = () => {
6151
+ const currentUrl = import.meta.url;
6152
+ if (currentUrl.endsWith(".ts")) return fileURLToPath(new URL("./parse-worker.ts", currentUrl));
6153
+ return fileURLToPath(new URL("./parse-worker.mjs", currentUrl));
6154
+ };
6155
+ const createWorker = (workerPath) => {
6156
+ return new Worker(workerPath, { ...workerPath.endsWith(".ts") ? { execArgv: ["--import", "tsx"] } : {} });
6157
+ };
6158
+ const waitForReady = (worker) => new Promise((resolve, reject) => {
6159
+ const onMessage = (message) => {
6160
+ if (message.type === "ready") {
6161
+ worker.off("message", onMessage);
6162
+ worker.off("error", onError);
6163
+ resolve();
6164
+ }
6165
+ };
6166
+ const onError = (error) => {
6167
+ worker.off("message", onMessage);
6168
+ worker.off("error", onError);
6169
+ reject(error);
6170
+ };
6171
+ worker.on("message", onMessage);
6172
+ worker.on("error", onError);
6173
+ });
6174
+ const parseFilesWithWorkerPool = async (files, workerCount) => {
6175
+ const workerPath = resolveWorkerPath();
6176
+ const results = new Array(files.length);
6177
+ const workers = [];
6178
+ try {
6179
+ for (let workerIndex = 0; workerIndex < workerCount; workerIndex++) workers.push(createWorker(workerPath));
6180
+ await Promise.all(workers.map(waitForReady));
6181
+ } catch {
6182
+ for (const worker of workers) worker.terminate();
6183
+ return files.map((file) => parseSourceFile(file.path));
6184
+ }
6185
+ let nextFileIndex = 0;
6186
+ let completedCount = 0;
6187
+ return new Promise((resolve, reject) => {
6188
+ const dispatchNext = (worker) => {
6189
+ if (nextFileIndex >= files.length) return;
6190
+ const fileIndex = nextFileIndex;
6191
+ nextFileIndex += 1;
6192
+ worker.postMessage({
6193
+ type: "parse",
6194
+ filePath: files[fileIndex].path,
6195
+ fileIndex
6196
+ });
6197
+ };
6198
+ const onWorkerMessage = (worker) => (message) => {
6199
+ if (message.type === "result") {
6200
+ results[message.fileIndex] = deserializeParsedSource(message.parsed);
6201
+ completedCount += 1;
6202
+ if (completedCount === files.length) {
6203
+ cleanup();
6204
+ resolve(results);
6205
+ } else dispatchNext(worker);
6206
+ } else if (message.type === "error") {
6207
+ results[message.fileIndex] = {
6208
+ imports: [],
6209
+ exports: [],
6210
+ memberAccesses: [],
6211
+ wholeObjectUses: [],
6212
+ localIdentifierReferences: [],
6213
+ referencedFilenames: [],
6214
+ redundantTypePatterns: [],
6215
+ identityWrappers: [],
6216
+ typeDefinitionHashes: [],
6217
+ inlineTypeLiterals: [],
6218
+ simplifiableFunctions: [],
6219
+ simplifiableExpressions: [],
6220
+ duplicateConstantCandidates: [],
6221
+ errors: [new ParseError({
6222
+ code: "parse-failed",
6223
+ message: `Worker parse failed: ${message.errorMessage}`,
6224
+ path: message.filePath
6225
+ })]
6226
+ };
6227
+ completedCount += 1;
6228
+ if (completedCount === files.length) {
6229
+ cleanup();
6230
+ resolve(results);
6231
+ } else dispatchNext(worker);
6232
+ }
6233
+ };
6234
+ const cleanup = () => {
6235
+ for (const worker of workers) worker.terminate();
6236
+ };
6237
+ for (const worker of workers) {
6238
+ worker.on("message", onWorkerMessage(worker));
6239
+ worker.on("error", (error) => {
6240
+ cleanup();
6241
+ reject(error);
6242
+ });
6243
+ }
6244
+ for (const worker of workers) dispatchNext(worker);
6245
+ });
6246
+ };
6247
+ const parseFilesInParallel = async (files) => {
6248
+ if (files.length <= 50) return files.map((file) => parseSourceFile(file.path));
6249
+ const concurrency = resolveAvailableConcurrency();
6250
+ if (concurrency <= 1) return files.map((file) => parseSourceFile(file.path));
6251
+ try {
6252
+ return await parseFilesWithWorkerPool(files, concurrency);
6253
+ } catch {
6254
+ return files.map((file) => parseSourceFile(file.path));
6255
+ }
6256
+ };
6257
+
6113
6258
  //#endregion
6114
6259
  //#region src/utils/is-platform-builtin-or-virtual.ts
6115
6260
  const BUILTIN_SUBPATH_NODE_MODULES = new Set([
@@ -7619,8 +7764,11 @@ const collectPnpmWorkspaceOverrideMappings = (rootDir) => {
7619
7764
  };
7620
7765
 
7621
7766
  //#endregion
7622
- //#region src/utils/matches-package-import-reference.ts
7767
+ //#region src/utils/escape-reg-exp.ts
7623
7768
  const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7769
+
7770
+ //#endregion
7771
+ //#region src/utils/matches-package-import-reference.ts
7624
7772
  const matchesPackageImportReference = (content, packageName) => {
7625
7773
  const escapedPackageName = escapeRegExp(packageName);
7626
7774
  const subpathPattern = `(?:/[^'"]*)?`;
@@ -7633,6 +7781,13 @@ const matchesPackageImportReference = (content, packageName) => {
7633
7781
  ].some((pattern) => pattern.test(content));
7634
7782
  };
7635
7783
 
7784
+ //#endregion
7785
+ //#region src/utils/matches-package-token-reference.ts
7786
+ const matchesPackageTokenReference = (command, packageName) => {
7787
+ const escapedPackageName = escapeRegExp(packageName);
7788
+ return new RegExp(`(?:^|[\\s='"\`(,;:|&])${escapedPackageName}(?:/[^\\s'"\`]*)?(?=$|[\\s='"\`),;:|&])`).test(command);
7789
+ };
7790
+
7636
7791
  //#endregion
7637
7792
  //#region src/report/packages.ts
7638
7793
  const discoverAllPackageJsonPaths = (rootDir) => {
@@ -7922,6 +8077,10 @@ const collectScriptReferencedPackages = (packageJsonPath, declaredNames, binToPa
7922
8077
  if (typeof scriptCommand !== "string") continue;
7923
8078
  const commandReferenced = collectCommandReferencedPackages(scriptCommand, declaredNames, binToPackage);
7924
8079
  for (const packageName of commandReferenced) referenced.add(packageName);
8080
+ for (const declaredName of declaredNames) {
8081
+ if (referenced.has(declaredName)) continue;
8082
+ if (matchesPackageTokenReference(scriptCommand, declaredName)) referenced.add(declaredName);
8083
+ }
7925
8084
  }
7926
8085
  } catch {
7927
8086
  return referenced;
@@ -12545,8 +12704,23 @@ const analyze = async (config) => {
12545
12704
  ignorePatterns: [...config.ignorePatterns, ...allExclusionPatterns]
12546
12705
  } : config;
12547
12706
  let files;
12707
+ let discoveredEntries;
12548
12708
  try {
12549
- files = await collectSourceFiles(configWithExclusions);
12709
+ const [collectedFiles, resolvedEntries] = await Promise.all([collectSourceFiles(configWithExclusions), resolveEntries(configWithExclusions).catch((entriesError) => {
12710
+ setupErrors.push(new WorkspaceError({
12711
+ code: "workspace-discovery-failed",
12712
+ message: "resolveEntries failed — defaulting to empty entry set",
12713
+ path: config.rootDir,
12714
+ detail: describeUnknownError(entriesError)
12715
+ }));
12716
+ return {
12717
+ productionEntries: [],
12718
+ testEntries: [],
12719
+ alwaysUsedFiles: []
12720
+ };
12721
+ })]);
12722
+ files = collectedFiles;
12723
+ discoveredEntries = resolvedEntries;
12550
12724
  } catch (collectError) {
12551
12725
  setupErrors.push(new WorkspaceError({
12552
12726
  code: "workspace-discovery-failed",
@@ -12557,22 +12731,6 @@ const analyze = async (config) => {
12557
12731
  }));
12558
12732
  return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
12559
12733
  }
12560
- let discoveredEntries;
12561
- try {
12562
- discoveredEntries = await resolveEntries(configWithExclusions);
12563
- } catch (entriesError) {
12564
- setupErrors.push(new WorkspaceError({
12565
- code: "workspace-discovery-failed",
12566
- message: "resolveEntries failed — defaulting to empty entry set",
12567
- path: config.rootDir,
12568
- detail: describeUnknownError(entriesError)
12569
- }));
12570
- discoveredEntries = {
12571
- productionEntries: [],
12572
- testEntries: [],
12573
- alwaysUsedFiles: []
12574
- };
12575
- }
12576
12734
  const productionEntrySet = new Set(discoveredEntries.productionEntries);
12577
12735
  const testEntrySet = new Set(discoveredEntries.testEntries);
12578
12736
  const alwaysUsedFileSet = new Set(discoveredEntries.alwaysUsedFiles);
@@ -12599,9 +12757,11 @@ const analyze = async (config) => {
12599
12757
  }));
12600
12758
  return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
12601
12759
  }
12760
+ const parsedModules = await parseFilesInParallel(files);
12602
12761
  const graphInputs = [];
12603
- for (const file of files) {
12604
- const parsedModule = parseSourceFile(file.path);
12762
+ for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
12763
+ const file = files[fileIndex];
12764
+ const parsedModule = parsedModules[fileIndex];
12605
12765
  const resolvedImportMap = /* @__PURE__ */ new Map();
12606
12766
  const safeResolveImport = (specifier) => {
12607
12767
  try {