@optave/codegraph 3.8.0 → 3.9.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.
- package/README.md +13 -8
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +137 -86
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/metrics.d.ts +0 -3
- package/dist/ast-analysis/metrics.d.ts.map +1 -1
- package/dist/ast-analysis/metrics.js +30 -13
- package/dist/ast-analysis/metrics.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +24 -19
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +55 -39
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitor.js +91 -70
- package/dist/ast-analysis/visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +54 -58
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +81 -39
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js +57 -38
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/branch-compare.d.ts.map +1 -1
- package/dist/cli/commands/branch-compare.js +4 -0
- package/dist/cli/commands/branch-compare.js.map +1 -1
- package/dist/cli/commands/diff-impact.d.ts.map +1 -1
- package/dist/cli/commands/diff-impact.js +2 -1
- package/dist/cli/commands/diff-impact.js.map +1 -1
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +3 -2
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +16 -2
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +29 -26
- package/dist/db/connection.js.map +1 -1
- package/dist/db/query-builder.d.ts.map +1 -1
- package/dist/db/query-builder.js +16 -5
- package/dist/db/query-builder.js.map +1 -1
- package/dist/db/repository/base.d.ts +16 -0
- package/dist/db/repository/base.d.ts.map +1 -1
- package/dist/db/repository/base.js +31 -0
- package/dist/db/repository/base.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts +7 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +100 -1
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/db/repository/nodes.d.ts.map +1 -1
- package/dist/db/repository/nodes.js +8 -4
- package/dist/db/repository/nodes.js.map +1 -1
- package/dist/db/repository/sqlite-repository.d.ts +4 -0
- package/dist/db/repository/sqlite-repository.d.ts.map +1 -1
- package/dist/db/repository/sqlite-repository.js +51 -0
- package/dist/db/repository/sqlite-repository.js.map +1 -1
- package/dist/domain/analysis/brief.d.ts.map +1 -1
- package/dist/domain/analysis/brief.js +13 -17
- package/dist/domain/analysis/brief.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +14 -11
- package/dist/domain/analysis/context.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +64 -59
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +2 -7
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +33 -31
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/implementations.d.ts.map +1 -1
- package/dist/domain/analysis/implementations.js +11 -19
- package/dist/domain/analysis/implementations.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +55 -76
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/query-helpers.d.ts +7 -0
- package/dist/domain/analysis/query-helpers.d.ts.map +1 -1
- package/dist/domain/analysis/query-helpers.js +15 -1
- package/dist/domain/analysis/query-helpers.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +352 -107
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +49 -18
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +2 -2
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +2 -2
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js +32 -21
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +95 -84
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.d.ts +6 -0
- package/dist/domain/graph/cycles.d.ts.map +1 -1
- package/dist/domain/graph/cycles.js +114 -22
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/resolve.js +1 -1
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts +2 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +170 -75
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +3 -4
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +141 -89
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/generator.js +1 -1
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/domain/search/models.d.ts +4 -3
- package/dist/domain/search/models.d.ts.map +1 -1
- package/dist/domain/search/models.js +23 -8
- package/dist/domain/search/models.js.map +1 -1
- package/dist/domain/search/search/hybrid.d.ts.map +1 -1
- package/dist/domain/search/search/hybrid.js +29 -18
- package/dist/domain/search/search/hybrid.js.map +1 -1
- package/dist/extractors/go.js +36 -33
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +40 -29
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/java.js +58 -46
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.js +65 -54
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/kotlin.js +84 -78
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/python.js +29 -24
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/rust.js +41 -32
- package/dist/extractors/rust.js.map +1 -1
- package/dist/extractors/solidity.js +58 -67
- package/dist/extractors/solidity.js.map +1 -1
- package/dist/extractors/swift.js +83 -81
- package/dist/extractors/swift.js.map +1 -1
- package/dist/extractors/zig.js +58 -60
- package/dist/extractors/zig.js.map +1 -1
- package/dist/features/ast.d.ts +16 -14
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +83 -81
- package/dist/features/ast.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +8 -6
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +69 -72
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/communities.d.ts.map +1 -1
- package/dist/features/communities.js +19 -7
- package/dist/features/communities.js.map +1 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +120 -125
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +136 -137
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js +84 -79
- package/dist/features/flow.js.map +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +69 -65
- package/dist/features/structure-query.js.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.js +70 -55
- package/dist/graph/algorithms/leiden/optimiser.js.map +1 -1
- package/dist/graph/algorithms/leiden/partition.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/partition.js +288 -266
- package/dist/graph/algorithms/leiden/partition.js.map +1 -1
- package/dist/graph/model.d.ts.map +1 -1
- package/dist/graph/model.js +5 -1
- package/dist/graph/model.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +6 -4
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/suppress.d.ts +25 -0
- package/dist/infrastructure/suppress.d.ts.map +1 -0
- package/dist/infrastructure/suppress.js +43 -0
- package/dist/infrastructure/suppress.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +29 -24
- package/dist/mcp/server.js.map +1 -1
- package/dist/presentation/dataflow.d.ts.map +1 -1
- package/dist/presentation/dataflow.js +47 -38
- package/dist/presentation/dataflow.js.map +1 -1
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -1
- package/dist/presentation/diff-impact-mermaid.js +60 -51
- package/dist/presentation/diff-impact-mermaid.js.map +1 -1
- package/dist/presentation/queries-cli/exports.d.ts.map +1 -1
- package/dist/presentation/queries-cli/exports.js +20 -14
- package/dist/presentation/queries-cli/exports.js.map +1 -1
- package/dist/presentation/queries-cli/impact.d.ts.map +1 -1
- package/dist/presentation/queries-cli/impact.js +15 -13
- package/dist/presentation/queries-cli/impact.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js +101 -79
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
- package/dist/presentation/queries-cli/overview.js +25 -16
- package/dist/presentation/queries-cli/overview.js.map +1 -1
- package/dist/presentation/queries-cli/path.js +26 -20
- package/dist/presentation/queries-cli/path.js.map +1 -1
- package/dist/presentation/result-formatter.d.ts +10 -0
- package/dist/presentation/result-formatter.d.ts.map +1 -1
- package/dist/presentation/result-formatter.js +16 -1
- package/dist/presentation/result-formatter.js.map +1 -1
- package/dist/presentation/viewer.d.ts.map +1 -1
- package/dist/presentation/viewer.js +18 -12
- package/dist/presentation/viewer.js.map +1 -1
- package/dist/shared/errors.d.ts +5 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +5 -0
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/hierarchy.d.ts +8 -2
- package/dist/shared/hierarchy.d.ts.map +1 -1
- package/dist/shared/hierarchy.js +42 -1
- package/dist/shared/hierarchy.js.map +1 -1
- package/dist/shared/normalize.d.ts +6 -1
- package/dist/shared/normalize.d.ts.map +1 -1
- package/dist/shared/normalize.js +20 -12
- package/dist/shared/normalize.js.map +1 -1
- package/dist/shared/paginate.d.ts +0 -9
- package/dist/shared/paginate.d.ts.map +1 -1
- package/dist/shared/paginate.js +0 -15
- package/dist/shared/paginate.js.map +1 -1
- package/dist/types.d.ts +12 -5
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/grammars/tree-sitter-gleam.wasm +0 -0
- package/package.json +9 -9
- package/src/ast-analysis/engine.ts +176 -104
- package/src/ast-analysis/metrics.ts +33 -11
- package/src/ast-analysis/shared.ts +33 -24
- package/src/ast-analysis/visitor-utils.ts +52 -32
- package/src/ast-analysis/visitor.ts +132 -71
- package/src/ast-analysis/visitors/ast-store-visitor.ts +53 -50
- package/src/ast-analysis/visitors/complexity-visitor.ts +89 -40
- package/src/ast-analysis/visitors/dataflow-visitor.ts +87 -43
- package/src/cli/commands/branch-compare.ts +4 -0
- package/src/cli/commands/diff-impact.ts +2 -1
- package/src/cli/commands/info.ts +3 -2
- package/src/cli/commands/watch.ts +16 -2
- package/src/db/connection.ts +29 -28
- package/src/db/query-builder.ts +15 -3
- package/src/db/repository/base.ts +34 -0
- package/src/db/repository/native-repository.ts +104 -1
- package/src/db/repository/nodes.ts +13 -8
- package/src/db/repository/sqlite-repository.ts +55 -0
- package/src/domain/analysis/brief.ts +15 -25
- package/src/domain/analysis/context.ts +17 -10
- package/src/domain/analysis/dependencies.ts +77 -81
- package/src/domain/analysis/fn-impact.ts +36 -43
- package/src/domain/analysis/implementations.ts +11 -17
- package/src/domain/analysis/module-map.ts +58 -92
- package/src/domain/analysis/query-helpers.ts +18 -1
- package/src/domain/graph/builder/pipeline.ts +409 -99
- package/src/domain/graph/builder/stages/build-edges.ts +45 -19
- package/src/domain/graph/builder/stages/detect-changes.ts +2 -2
- package/src/domain/graph/builder/stages/finalize.ts +2 -2
- package/src/domain/graph/builder/stages/insert-nodes.ts +59 -34
- package/src/domain/graph/builder/stages/resolve-imports.ts +122 -100
- package/src/domain/graph/cycles.ts +110 -23
- package/src/domain/graph/resolve.ts +1 -1
- package/src/domain/graph/watcher.ts +202 -96
- package/src/domain/parser.ts +143 -89
- package/src/domain/search/generator.ts +1 -1
- package/src/domain/search/models.ts +26 -7
- package/src/domain/search/search/hybrid.ts +69 -51
- package/src/extractors/go.ts +43 -33
- package/src/extractors/helpers.ts +37 -23
- package/src/extractors/java.ts +66 -47
- package/src/extractors/javascript.ts +66 -54
- package/src/extractors/kotlin.ts +84 -77
- package/src/extractors/python.ts +31 -25
- package/src/extractors/rust.ts +37 -29
- package/src/extractors/solidity.ts +57 -61
- package/src/extractors/swift.ts +81 -80
- package/src/extractors/zig.ts +58 -61
- package/src/features/ast.ts +130 -110
- package/src/features/audit.ts +8 -6
- package/src/features/branch-compare.ts +105 -79
- package/src/features/communities.ts +25 -10
- package/src/features/complexity.ts +171 -134
- package/src/features/dataflow.ts +165 -175
- package/src/features/flow.ts +129 -92
- package/src/features/structure-query.ts +79 -64
- package/src/graph/algorithms/leiden/optimiser.ts +99 -55
- package/src/graph/algorithms/leiden/partition.ts +359 -294
- package/src/graph/model.ts +6 -1
- package/src/infrastructure/config.ts +6 -4
- package/src/infrastructure/suppress.ts +47 -0
- package/src/mcp/server.ts +53 -37
- package/src/presentation/dataflow.ts +50 -44
- package/src/presentation/diff-impact-mermaid.ts +104 -62
- package/src/presentation/queries-cli/exports.ts +21 -13
- package/src/presentation/queries-cli/impact.ts +15 -13
- package/src/presentation/queries-cli/inspect.ts +100 -81
- package/src/presentation/queries-cli/overview.ts +26 -16
- package/src/presentation/queries-cli/path.ts +33 -25
- package/src/presentation/result-formatter.ts +19 -1
- package/src/presentation/viewer.ts +42 -14
- package/src/shared/errors.ts +6 -0
- package/src/shared/hierarchy.ts +50 -2
- package/src/shared/normalize.ts +31 -12
- package/src/shared/paginate.ts +0 -17
- package/src/types.ts +26 -5
|
@@ -197,8 +197,13 @@ function buildImportEdgesNative(
|
|
|
197
197
|
};
|
|
198
198
|
const fileNodeRowCache = new Map<string, { id: number }>();
|
|
199
199
|
|
|
200
|
-
// 2. Pre-resolve all imports and
|
|
201
|
-
|
|
200
|
+
// 2. Pre-resolve all imports and build resolved imports array.
|
|
201
|
+
// Keys use forward-slash-normalized rootDir + "/" + relPath to match the Rust
|
|
202
|
+
// lookup format (format!("{}/{}", root_dir.replace('\\', "/"), file)).
|
|
203
|
+
// On Windows, rootDir has backslashes but Rust normalizes them — the JS side
|
|
204
|
+
// must do the same or every resolve key lookup misses (#750).
|
|
205
|
+
const resolvedImports: Array<{ key: string; resolvedPath: string }> = [];
|
|
206
|
+
const fwdRootDir = rootDir.replace(/\\/g, '/');
|
|
202
207
|
|
|
203
208
|
for (const [relPath, symbols] of fileSymbols) {
|
|
204
209
|
const fileNodeRow = addFileNodeId(relPath);
|
|
@@ -218,11 +223,8 @@ function buildImportEdgesNative(
|
|
|
218
223
|
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
219
224
|
addFileNodeId(resolvedPath);
|
|
220
225
|
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
if (!ctx.batchResolved?.has(resolveKey)) {
|
|
224
|
-
supplementalResolved.push({ key: resolveKey, resolvedPath });
|
|
225
|
-
}
|
|
226
|
+
// Key matches Rust's format!("{}/{}", root_dir.replace('\\', "/"), file_input.file)
|
|
227
|
+
resolvedImports.push({ key: `${fwdRootDir}/${relPath}|${imp.source}`, resolvedPath });
|
|
226
228
|
|
|
227
229
|
importInfos.push({
|
|
228
230
|
source: imp.source,
|
|
@@ -243,17 +245,6 @@ function buildImportEdgesNative(
|
|
|
243
245
|
});
|
|
244
246
|
}
|
|
245
247
|
|
|
246
|
-
// 3. Flatten batchResolved + supplemental into resolved imports array
|
|
247
|
-
const resolvedImports: Array<{ key: string; resolvedPath: string }> = [];
|
|
248
|
-
if (ctx.batchResolved) {
|
|
249
|
-
for (const [key, resolvedPath] of ctx.batchResolved) {
|
|
250
|
-
resolvedImports.push({ key, resolvedPath });
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
for (const entry of supplementalResolved) {
|
|
254
|
-
resolvedImports.push(entry);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
248
|
// 4. Flatten reexportMap
|
|
258
249
|
const fileReexports: Array<{
|
|
259
250
|
file: string;
|
|
@@ -363,7 +354,10 @@ function buildImportedNamesForNative(
|
|
|
363
354
|
rootDir: string,
|
|
364
355
|
): Array<{ name: string; file: string }> {
|
|
365
356
|
const importedNames: Array<{ name: string; file: string }> = [];
|
|
366
|
-
|
|
357
|
+
// Process dynamic imports first (lower priority), then static imports
|
|
358
|
+
// (higher priority). Rust HashMap::collect keeps the last entry per key,
|
|
359
|
+
// so static imports win when both contribute the same name.
|
|
360
|
+
const addImports = (imp: (typeof symbols.imports)[number]) => {
|
|
367
361
|
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
368
362
|
for (const name of imp.names) {
|
|
369
363
|
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
@@ -374,6 +368,12 @@ function buildImportedNamesForNative(
|
|
|
374
368
|
}
|
|
375
369
|
importedNames.push({ name: cleanName, file: targetFile });
|
|
376
370
|
}
|
|
371
|
+
};
|
|
372
|
+
for (const imp of symbols.imports) {
|
|
373
|
+
if (imp.dynamicImport) addImports(imp);
|
|
374
|
+
}
|
|
375
|
+
for (const imp of symbols.imports) {
|
|
376
|
+
if (!imp.dynamicImport) addImports(imp);
|
|
377
377
|
}
|
|
378
378
|
return importedNames;
|
|
379
379
|
}
|
|
@@ -418,12 +418,25 @@ function buildImportedNamesMap(
|
|
|
418
418
|
rootDir: string,
|
|
419
419
|
): Map<string, string> {
|
|
420
420
|
const importedNames = new Map<string, string>();
|
|
421
|
+
// Process dynamic imports first (lower priority), then static imports
|
|
422
|
+
// (higher priority). Static imports represent direct bindings while dynamic
|
|
423
|
+
// imports often use aliased destructuring (`{ foo: bar } = await import(…)`).
|
|
424
|
+
// When both contribute the same name, the static binding is authoritative.
|
|
421
425
|
for (const imp of symbols.imports) {
|
|
426
|
+
if (!imp.dynamicImport) continue;
|
|
422
427
|
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
423
428
|
for (const name of imp.names) {
|
|
424
429
|
importedNames.set(name.replace(/^\*\s+as\s+/, ''), resolvedPath);
|
|
425
430
|
}
|
|
426
431
|
}
|
|
432
|
+
for (const imp of symbols.imports) {
|
|
433
|
+
if (imp.dynamicImport) continue;
|
|
434
|
+
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
435
|
+
for (const name of imp.names) {
|
|
436
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
437
|
+
importedNames.set(cleanName, resolvedPath);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
427
440
|
return importedNames;
|
|
428
441
|
}
|
|
429
442
|
|
|
@@ -748,7 +761,20 @@ export async function buildEdges(ctx: PipelineContext): Promise<void> {
|
|
|
748
761
|
const useNativeImportEdges =
|
|
749
762
|
native?.buildImportEdges && (ctx.isFullBuild || ctx.fileSymbols.size > 3);
|
|
750
763
|
if (useNativeImportEdges) {
|
|
764
|
+
const beforeLen = allEdgeRows.length;
|
|
751
765
|
buildImportEdgesNative(ctx, getNodeIdStmt, allEdgeRows, native!);
|
|
766
|
+
// Fallback: if native produced 0 import edges but there are imports to
|
|
767
|
+
// process, the native binary may have a key-format mismatch (e.g. Windows
|
|
768
|
+
// path separators — #750). Retry with the JS implementation.
|
|
769
|
+
// NOTE: This also fires for codebases where every import targets an
|
|
770
|
+
// external package (npm deps) that the resolver intentionally skips.
|
|
771
|
+
// In that case the JS path resolves zero edges too, so the only cost
|
|
772
|
+
// is the redundant JS traversal — no correctness impact.
|
|
773
|
+
const hasImports = [...ctx.fileSymbols.values()].some((s) => s.imports.length > 0);
|
|
774
|
+
if (allEdgeRows.length === beforeLen && hasImports) {
|
|
775
|
+
debug('Native buildImportEdges produced 0 edges — falling back to JS');
|
|
776
|
+
buildImportEdges(ctx, getNodeIdStmt, allEdgeRows);
|
|
777
|
+
}
|
|
752
778
|
} else {
|
|
753
779
|
buildImportEdges(ctx, getNodeIdStmt, allEdgeRows);
|
|
754
780
|
}
|
|
@@ -349,7 +349,7 @@ function findReverseDependencies(
|
|
|
349
349
|
const changedArray = [...changedRelPaths];
|
|
350
350
|
const nativeResults = nativeDb.findReverseDependencies(changedArray);
|
|
351
351
|
for (const dep of nativeResults) {
|
|
352
|
-
const absPath = path.join(rootDir, dep);
|
|
352
|
+
const absPath = path.isAbsolute(dep) ? dep : path.join(rootDir, dep);
|
|
353
353
|
if (fs.existsSync(absPath)) {
|
|
354
354
|
reverseDeps.add(dep);
|
|
355
355
|
}
|
|
@@ -366,7 +366,7 @@ function findReverseDependencies(
|
|
|
366
366
|
for (const relPath of changedRelPaths) {
|
|
367
367
|
for (const row of findReverseDepsStmt.all(relPath) as Array<{ file: string }>) {
|
|
368
368
|
if (!changedRelPaths.has(row.file) && !reverseDeps.has(row.file)) {
|
|
369
|
-
const absPath = path.join(rootDir, row.file);
|
|
369
|
+
const absPath = path.isAbsolute(row.file) ? row.file : path.join(rootDir, row.file);
|
|
370
370
|
if (fs.existsSync(absPath)) {
|
|
371
371
|
reverseDeps.add(row.file);
|
|
372
372
|
}
|
|
@@ -86,7 +86,7 @@ function persistBuildMetadata(
|
|
|
86
86
|
ctx.nativeDb!.setBuildMeta(
|
|
87
87
|
Object.entries({
|
|
88
88
|
engine: ctx.engineName,
|
|
89
|
-
engine_version:
|
|
89
|
+
engine_version: CODEGRAPH_VERSION,
|
|
90
90
|
codegraph_version: CODEGRAPH_VERSION,
|
|
91
91
|
schema_version: String(ctx.schemaVersion),
|
|
92
92
|
built_at: buildNow.toISOString(),
|
|
@@ -97,7 +97,7 @@ function persistBuildMetadata(
|
|
|
97
97
|
} else {
|
|
98
98
|
setBuildMeta(ctx.db, {
|
|
99
99
|
engine: ctx.engineName,
|
|
100
|
-
engine_version:
|
|
100
|
+
engine_version: CODEGRAPH_VERSION,
|
|
101
101
|
codegraph_version: CODEGRAPH_VERSION,
|
|
102
102
|
schema_version: String(ctx.schemaVersion),
|
|
103
103
|
built_at: buildNow.toISOString(),
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
import path from 'node:path';
|
|
12
12
|
import { performance } from 'node:perf_hooks';
|
|
13
13
|
import { bulkNodeIdsByFile } from '../../../../db/index.js';
|
|
14
|
+
import { debug } from '../../../../infrastructure/logger.js';
|
|
15
|
+
import { toErrorMessage } from '../../../../shared/errors.js';
|
|
14
16
|
import type {
|
|
15
17
|
BetterSqlite3Database,
|
|
16
18
|
ExtractorOutput,
|
|
@@ -36,35 +38,31 @@ interface PrecomputedFileData {
|
|
|
36
38
|
_reverseDepOnly?: boolean;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
// ── Native fast-path
|
|
41
|
+
// ── Native fast-path helpers ─────────────────────────────────────────
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
definitions: Array<{
|
|
43
|
+
/** Shape of a marshaled batch for native bulk insert. */
|
|
44
|
+
interface InsertNodesBatch {
|
|
45
|
+
file: string;
|
|
46
|
+
definitions: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
kind: string;
|
|
49
|
+
line: number;
|
|
50
|
+
endLine?: number;
|
|
51
|
+
visibility?: string;
|
|
52
|
+
children: Array<{
|
|
52
53
|
name: string;
|
|
53
54
|
kind: string;
|
|
54
55
|
line: number;
|
|
55
56
|
endLine?: number;
|
|
56
57
|
visibility?: string;
|
|
57
|
-
children: Array<{
|
|
58
|
-
name: string;
|
|
59
|
-
kind: string;
|
|
60
|
-
line: number;
|
|
61
|
-
endLine?: number;
|
|
62
|
-
visibility?: string;
|
|
63
|
-
}>;
|
|
64
58
|
}>;
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
}>;
|
|
60
|
+
exports: Array<{ name: string; kind: string; line: number }>;
|
|
61
|
+
}
|
|
67
62
|
|
|
63
|
+
/** Marshal allSymbols into the batch format expected by native bulkInsertNodes. */
|
|
64
|
+
function marshalSymbolBatches(allSymbols: Map<string, ExtractorOutput>): InsertNodesBatch[] {
|
|
65
|
+
const batches: InsertNodesBatch[] = [];
|
|
68
66
|
for (const [relPath, symbols] of allSymbols) {
|
|
69
67
|
batches.push({
|
|
70
68
|
file: relPath,
|
|
@@ -89,14 +87,18 @@ function tryNativeInsert(ctx: PipelineContext): boolean {
|
|
|
89
87
|
})),
|
|
90
88
|
});
|
|
91
89
|
}
|
|
90
|
+
return batches;
|
|
91
|
+
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
/** Build file hash entries from parsed symbols and precomputed/metadata sources. */
|
|
94
|
+
function buildFileHashes(
|
|
95
|
+
allSymbols: Map<string, ExtractorOutput>,
|
|
96
|
+
precomputedData: Map<string, PrecomputedFileData>,
|
|
97
|
+
metadataUpdates: MetadataUpdate[],
|
|
98
|
+
rootDir: string,
|
|
99
|
+
): Array<{ file: string; hash: string; mtime: number; size: number }> {
|
|
99
100
|
const fileHashes: Array<{ file: string; hash: string; mtime: number; size: number }> = [];
|
|
101
|
+
|
|
100
102
|
for (const [relPath] of allSymbols) {
|
|
101
103
|
const precomputed = precomputedData.get(relPath);
|
|
102
104
|
if (precomputed?._reverseDepOnly) {
|
|
@@ -119,7 +121,8 @@ function tryNativeInsert(ctx: PipelineContext): boolean {
|
|
|
119
121
|
let code: string | null;
|
|
120
122
|
try {
|
|
121
123
|
code = readFileSafe(absPath);
|
|
122
|
-
} catch {
|
|
124
|
+
} catch (e) {
|
|
125
|
+
debug(`buildFileHashes: readFileSafe failed for ${relPath}: ${toErrorMessage(e)}`);
|
|
123
126
|
code = null;
|
|
124
127
|
}
|
|
125
128
|
if (code !== null) {
|
|
@@ -138,6 +141,24 @@ function tryNativeInsert(ctx: PipelineContext): boolean {
|
|
|
138
141
|
fileHashes.push({ file: item.relPath, hash: item.hash, mtime, size });
|
|
139
142
|
}
|
|
140
143
|
|
|
144
|
+
return fileHashes;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── Native fast-path ─────────────────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
function tryNativeInsert(ctx: PipelineContext): boolean {
|
|
150
|
+
if (!ctx.nativeDb?.bulkInsertNodes) return false;
|
|
151
|
+
|
|
152
|
+
const { allSymbols, filesToParse, metadataUpdates, rootDir, removed } = ctx;
|
|
153
|
+
|
|
154
|
+
const batches = marshalSymbolBatches(allSymbols);
|
|
155
|
+
|
|
156
|
+
const precomputedData = new Map<string, PrecomputedFileData>();
|
|
157
|
+
for (const item of filesToParse) {
|
|
158
|
+
if (item.relPath) precomputedData.set(item.relPath, item as PrecomputedFileData);
|
|
159
|
+
}
|
|
160
|
+
const fileHashes = buildFileHashes(allSymbols, precomputedData, metadataUpdates, rootDir);
|
|
161
|
+
|
|
141
162
|
// WAL guard: same suspendJsDb/resumeJsDb pattern used by feature modules
|
|
142
163
|
// (ast, cfg, complexity, dataflow). Checkpoint JS side before native write,
|
|
143
164
|
// then checkpoint native side after, so neither library reads WAL frames
|
|
@@ -151,8 +172,10 @@ function tryNativeInsert(ctx: PipelineContext): boolean {
|
|
|
151
172
|
} finally {
|
|
152
173
|
try {
|
|
153
174
|
ctx.nativeDb?.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
154
|
-
} catch {
|
|
155
|
-
|
|
175
|
+
} catch (e) {
|
|
176
|
+
debug(
|
|
177
|
+
`tryNativeInsert: WAL checkpoint failed (nativeDb may already be closed): ${toErrorMessage(e)}`,
|
|
178
|
+
);
|
|
156
179
|
}
|
|
157
180
|
}
|
|
158
181
|
return result;
|
|
@@ -324,7 +347,8 @@ function updateFileHashes(
|
|
|
324
347
|
let code: string | null;
|
|
325
348
|
try {
|
|
326
349
|
code = readFileSafe(absPath);
|
|
327
|
-
} catch {
|
|
350
|
+
} catch (e) {
|
|
351
|
+
debug(`updateFileHashes: readFileSafe failed for ${relPath}: ${toErrorMessage(e)}`);
|
|
328
352
|
code = null;
|
|
329
353
|
}
|
|
330
354
|
if (code !== null) {
|
|
@@ -364,8 +388,8 @@ export async function insertNodes(ctx: PipelineContext): Promise<void> {
|
|
|
364
388
|
// Removed-file hash cleanup is handled inside the native call
|
|
365
389
|
return;
|
|
366
390
|
}
|
|
367
|
-
} catch {
|
|
368
|
-
|
|
391
|
+
} catch (e) {
|
|
392
|
+
debug(`insertNodes: native insert failed, falling back to JS: ${toErrorMessage(e)}`);
|
|
369
393
|
}
|
|
370
394
|
}
|
|
371
395
|
|
|
@@ -380,7 +404,8 @@ export async function insertNodes(ctx: PipelineContext): Promise<void> {
|
|
|
380
404
|
upsertHash = ctx.db.prepare(
|
|
381
405
|
'INSERT OR REPLACE INTO file_hashes (file, hash, mtime, size) VALUES (?, ?, ?, ?)',
|
|
382
406
|
);
|
|
383
|
-
} catch {
|
|
407
|
+
} catch (e) {
|
|
408
|
+
debug(`insertNodes: file_hashes prepare failed (table may not exist): ${toErrorMessage(e)}`);
|
|
384
409
|
upsertHash = null;
|
|
385
410
|
}
|
|
386
411
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { performance } from 'node:perf_hooks';
|
|
3
3
|
import { debug } from '../../../../infrastructure/logger.js';
|
|
4
|
+
import { normalizePath } from '../../../../shared/constants.js';
|
|
4
5
|
import type { Import } from '../../../../types.js';
|
|
5
6
|
import { parseFilesAuto } from '../../../parser.js';
|
|
6
7
|
import { resolveImportPath, resolveImportsBatch } from '../../resolve.js';
|
|
@@ -12,20 +13,10 @@ interface ReexportEntry {
|
|
|
12
13
|
wildcardReexport: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const t0 = performance.now();
|
|
18
|
-
const batchInputs: Array<{ fromFile: string; importSource: string }> = [];
|
|
19
|
-
for (const [relPath, symbols] of fileSymbols) {
|
|
20
|
-
const absFile = path.join(rootDir, relPath);
|
|
21
|
-
for (const imp of symbols.imports) {
|
|
22
|
-
batchInputs.push({ fromFile: absFile, importSource: imp.source });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
ctx.batchResolved = resolveImportsBatch(batchInputs, rootDir, aliases, allFiles);
|
|
26
|
-
ctx.timing.resolveMs = performance.now() - t0;
|
|
27
|
-
|
|
16
|
+
/** Collect reexport entries from fileSymbols into the reexportMap. */
|
|
17
|
+
function buildReexportMap(ctx: PipelineContext): void {
|
|
28
18
|
ctx.reexportMap = new Map<string, ReexportEntry[]>();
|
|
19
|
+
const { fileSymbols, rootDir } = ctx;
|
|
29
20
|
for (const [relPath, symbols] of fileSymbols) {
|
|
30
21
|
const reexports = symbols.imports.filter((imp) => imp.reexport);
|
|
31
22
|
if (reexports.length > 0) {
|
|
@@ -39,110 +30,141 @@ export async function resolveImports(ctx: PipelineContext): Promise<void> {
|
|
|
39
30
|
);
|
|
40
31
|
}
|
|
41
32
|
}
|
|
33
|
+
}
|
|
42
34
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
let barrelCandidates: Array<{ file: string }>;
|
|
52
|
-
if (changedRelPaths.size <= 5) {
|
|
53
|
-
// All known barrel files (has at least one reexport edge)
|
|
54
|
-
const allBarrelFiles = new Set(
|
|
55
|
-
(
|
|
56
|
-
db
|
|
57
|
-
.prepare(
|
|
58
|
-
`SELECT DISTINCT n1.file FROM edges e
|
|
59
|
-
JOIN nodes n1 ON e.source_id = n1.id
|
|
60
|
-
WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
|
|
61
|
-
)
|
|
62
|
-
.all() as Array<{ file: string }>
|
|
63
|
-
).map((r) => r.file),
|
|
64
|
-
);
|
|
35
|
+
/**
|
|
36
|
+
* Find barrel files related to changed files for scoped re-parsing.
|
|
37
|
+
* For small incremental builds (<=5 files), only barrels that re-export from
|
|
38
|
+
* or are imported by the changed files. For larger changes, all barrels.
|
|
39
|
+
*/
|
|
40
|
+
function findBarrelCandidates(ctx: PipelineContext): Array<{ file: string }> {
|
|
41
|
+
const { db, fileSymbols, rootDir, aliases } = ctx;
|
|
42
|
+
const changedRelPaths = new Set<string>(fileSymbols.keys());
|
|
65
43
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
}
|
|
44
|
+
const SMALL_CHANGE_THRESHOLD = 5;
|
|
45
|
+
if (changedRelPaths.size <= SMALL_CHANGE_THRESHOLD) {
|
|
46
|
+
const allBarrelFiles = new Set(
|
|
47
|
+
(
|
|
48
|
+
db
|
|
49
|
+
.prepare(
|
|
50
|
+
`SELECT DISTINCT n1.file FROM edges e
|
|
51
|
+
JOIN nodes n1 ON e.source_id = n1.id
|
|
52
|
+
WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
|
|
53
|
+
)
|
|
54
|
+
.all() as Array<{ file: string }>
|
|
55
|
+
).map((r) => r.file),
|
|
56
|
+
);
|
|
81
57
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
89
|
-
for (const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
58
|
+
const barrels = new Set<string>();
|
|
59
|
+
|
|
60
|
+
// Find barrels imported by changed files using parsed import data
|
|
61
|
+
// (can't query DB edges -- they were purged for the changed files).
|
|
62
|
+
for (const relPath of changedRelPaths) {
|
|
63
|
+
const symbols = fileSymbols.get(relPath);
|
|
64
|
+
if (!symbols) continue;
|
|
65
|
+
for (const imp of symbols.imports) {
|
|
66
|
+
const resolved = ctx.batchResolved?.get(
|
|
67
|
+
`${normalizePath(path.join(rootDir, relPath))}|${imp.source}`,
|
|
68
|
+
);
|
|
69
|
+
const target =
|
|
70
|
+
resolved ?? resolveImportPath(path.join(rootDir, relPath), imp.source, rootDir, aliases);
|
|
71
|
+
if (allBarrelFiles.has(target)) barrels.add(target);
|
|
93
72
|
}
|
|
94
|
-
barrelCandidates = [...barrels].map((file) => ({ file }));
|
|
95
|
-
} else {
|
|
96
|
-
barrelCandidates = db
|
|
97
|
-
.prepare(
|
|
98
|
-
`SELECT DISTINCT n1.file FROM edges e
|
|
99
|
-
JOIN nodes n1 ON e.source_id = n1.id
|
|
100
|
-
WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
|
|
101
|
-
)
|
|
102
|
-
.all() as Array<{ file: string }>;
|
|
103
73
|
}
|
|
104
74
|
|
|
105
|
-
//
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
75
|
+
// Also find barrels that re-export from the changed files
|
|
76
|
+
const reexportSourceStmt = db.prepare(
|
|
77
|
+
`SELECT DISTINCT n1.file FROM edges e
|
|
78
|
+
JOIN nodes n1 ON e.source_id = n1.id
|
|
79
|
+
JOIN nodes n2 ON e.target_id = n2.id
|
|
80
|
+
WHERE e.kind = 'reexports' AND n1.kind = 'file' AND n2.file = ?`,
|
|
81
|
+
);
|
|
82
|
+
for (const relPath of changedRelPaths) {
|
|
83
|
+
for (const row of reexportSourceStmt.all(relPath) as Array<{ file: string }>) {
|
|
84
|
+
barrels.add(row.file);
|
|
110
85
|
}
|
|
111
86
|
}
|
|
87
|
+
return [...barrels].map((file) => ({ file }));
|
|
88
|
+
}
|
|
112
89
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
90
|
+
return db
|
|
91
|
+
.prepare(
|
|
92
|
+
`SELECT DISTINCT n1.file FROM edges e
|
|
93
|
+
JOIN nodes n1 ON e.source_id = n1.id
|
|
94
|
+
WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
|
|
95
|
+
)
|
|
96
|
+
.all() as Array<{ file: string }>;
|
|
97
|
+
}
|
|
117
98
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
99
|
+
/** Re-parse barrel files and update fileSymbols/reexportMap with fresh data. */
|
|
100
|
+
async function reparseBarrelFiles(
|
|
101
|
+
ctx: PipelineContext,
|
|
102
|
+
barrelCandidates: Array<{ file: string }>,
|
|
103
|
+
): Promise<void> {
|
|
104
|
+
const { db, fileSymbols, rootDir, engineOpts } = ctx;
|
|
105
|
+
|
|
106
|
+
const barrelPaths: string[] = [];
|
|
107
|
+
for (const { file: relPath } of barrelCandidates) {
|
|
108
|
+
if (!fileSymbols.has(relPath)) {
|
|
109
|
+
barrelPaths.push(path.join(rootDir, relPath));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (barrelPaths.length === 0) return;
|
|
114
|
+
|
|
115
|
+
const deleteOutgoingEdges = db.prepare(
|
|
116
|
+
'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
const barrelSymbols = await parseFilesAuto(barrelPaths, rootDir, engineOpts);
|
|
121
|
+
for (const [relPath, fileSym] of barrelSymbols) {
|
|
122
|
+
deleteOutgoingEdges.run(relPath);
|
|
123
|
+
fileSymbols.set(relPath, fileSym);
|
|
124
|
+
ctx.barrelOnlyFiles.add(relPath);
|
|
125
|
+
const reexports = fileSym.imports.filter((imp: Import) => imp.reexport);
|
|
126
|
+
if (reexports.length > 0) {
|
|
127
|
+
ctx.reexportMap.set(
|
|
128
|
+
relPath,
|
|
129
|
+
reexports.map((imp: Import) => ({
|
|
130
|
+
source: getResolved(ctx, path.join(rootDir, relPath), imp.source),
|
|
131
|
+
names: imp.names,
|
|
132
|
+
wildcardReexport: imp.wildcardReexport || false,
|
|
133
|
+
})),
|
|
134
|
+
);
|
|
138
135
|
}
|
|
139
136
|
}
|
|
137
|
+
} catch (e: unknown) {
|
|
138
|
+
debug(`Barrel re-parse failed (non-fatal): ${(e as Error).message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export async function resolveImports(ctx: PipelineContext): Promise<void> {
|
|
143
|
+
const { fileSymbols, rootDir, aliases, allFiles, isFullBuild } = ctx;
|
|
144
|
+
const t0 = performance.now();
|
|
145
|
+
|
|
146
|
+
const batchInputs: Array<{ fromFile: string; importSource: string }> = [];
|
|
147
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
148
|
+
const absFile = path.join(rootDir, relPath);
|
|
149
|
+
for (const imp of symbols.imports) {
|
|
150
|
+
batchInputs.push({ fromFile: absFile, importSource: imp.source });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
ctx.batchResolved = resolveImportsBatch(batchInputs, rootDir, aliases, allFiles);
|
|
154
|
+
ctx.timing.resolveMs = performance.now() - t0;
|
|
155
|
+
|
|
156
|
+
buildReexportMap(ctx);
|
|
157
|
+
|
|
158
|
+
ctx.barrelOnlyFiles = new Set<string>();
|
|
159
|
+
if (!isFullBuild) {
|
|
160
|
+
const barrelCandidates = findBarrelCandidates(ctx);
|
|
161
|
+
await reparseBarrelFiles(ctx, barrelCandidates);
|
|
140
162
|
}
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
export function getResolved(ctx: PipelineContext, absFile: string, importSource: string): string {
|
|
144
166
|
if (ctx.batchResolved) {
|
|
145
|
-
const key = `${absFile}|${importSource}`;
|
|
167
|
+
const key = `${normalizePath(absFile)}|${importSource}`;
|
|
146
168
|
const hit = ctx.batchResolved.get(key);
|
|
147
169
|
if (hit !== undefined) return hit;
|
|
148
170
|
}
|