@optave/codegraph 3.5.0 → 3.6.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 +35 -14
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +119 -127
- package/dist/ast-analysis/engine.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 +14 -1
- 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 +11 -13
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/db/connection.d.ts +12 -2
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +81 -53
- package/dist/db/connection.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +38 -32
- package/dist/db/migrations.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +51 -66
- 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 +62 -70
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/diff-impact.d.ts +9 -7
- package/dist/domain/analysis/diff-impact.d.ts.map +1 -1
- package/dist/domain/analysis/exports.d.ts.map +1 -1
- package/dist/domain/analysis/exports.js +29 -33
- package/dist/domain/analysis/exports.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +15 -17
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +35 -65
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +91 -6
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/query-helpers.d.ts +20 -0
- package/dist/domain/analysis/query-helpers.d.ts.map +1 -0
- package/dist/domain/analysis/query-helpers.js +27 -0
- package/dist/domain/analysis/query-helpers.js.map +1 -0
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +15 -9
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js +3 -2
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +69 -3
- 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 +7 -51
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.js +7 -5
- package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.js +2 -2
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.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.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +124 -105
- 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 +28 -15
- 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 +3 -2
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/resolve.d.ts +0 -4
- package/dist/domain/graph/resolve.d.ts.map +1 -1
- package/dist/domain/graph/resolve.js +32 -48
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +12 -12
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +1 -1
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +164 -101
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/search/cli-formatter.d.ts.map +1 -1
- package/dist/domain/search/search/cli-formatter.js +88 -83
- package/dist/domain/search/search/cli-formatter.js.map +1 -1
- package/dist/extractors/bash.d.ts +6 -0
- package/dist/extractors/bash.d.ts.map +1 -0
- package/dist/extractors/bash.js +91 -0
- package/dist/extractors/bash.js.map +1 -0
- package/dist/extractors/c.d.ts +6 -0
- package/dist/extractors/c.d.ts.map +1 -0
- package/dist/extractors/c.js +204 -0
- package/dist/extractors/c.js.map +1 -0
- package/dist/extractors/cpp.d.ts +6 -0
- package/dist/extractors/cpp.d.ts.map +1 -0
- package/dist/extractors/cpp.js +283 -0
- package/dist/extractors/cpp.js.map +1 -0
- package/dist/extractors/csharp.d.ts.map +1 -1
- package/dist/extractors/csharp.js +42 -54
- package/dist/extractors/csharp.js.map +1 -1
- package/dist/extractors/go.d.ts.map +1 -1
- package/dist/extractors/go.js +126 -130
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/hcl.js +6 -6
- package/dist/extractors/hcl.js.map +1 -1
- package/dist/extractors/helpers.d.ts +32 -1
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +74 -0
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/index.d.ts +6 -0
- package/dist/extractors/index.d.ts.map +1 -1
- package/dist/extractors/index.js +6 -0
- package/dist/extractors/index.js.map +1 -1
- package/dist/extractors/java.d.ts.map +1 -1
- package/dist/extractors/java.js +32 -47
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.d.ts.map +1 -1
- package/dist/extractors/javascript.js +306 -292
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/kotlin.d.ts +6 -0
- package/dist/extractors/kotlin.d.ts.map +1 -0
- package/dist/extractors/kotlin.js +275 -0
- package/dist/extractors/kotlin.js.map +1 -0
- package/dist/extractors/php.d.ts.map +1 -1
- package/dist/extractors/php.js +39 -44
- package/dist/extractors/php.js.map +1 -1
- package/dist/extractors/python.d.ts.map +1 -1
- package/dist/extractors/python.js +75 -93
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/ruby.js +6 -13
- package/dist/extractors/ruby.js.map +1 -1
- package/dist/extractors/rust.d.ts.map +1 -1
- package/dist/extractors/rust.js +58 -83
- package/dist/extractors/rust.js.map +1 -1
- package/dist/extractors/scala.d.ts +6 -0
- package/dist/extractors/scala.d.ts.map +1 -0
- package/dist/extractors/scala.js +269 -0
- package/dist/extractors/scala.js.map +1 -0
- package/dist/extractors/swift.d.ts +6 -0
- package/dist/extractors/swift.d.ts.map +1 -0
- package/dist/extractors/swift.js +275 -0
- package/dist/extractors/swift.js.map +1 -0
- package/dist/features/ast.d.ts +2 -0
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +9 -24
- package/dist/features/ast.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +17 -21
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +47 -3
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/cfg.d.ts +7 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +118 -62
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/check.d.ts.map +1 -1
- package/dist/features/check.js +79 -62
- package/dist/features/check.js.map +1 -1
- package/dist/features/complexity-query.d.ts.map +1 -1
- package/dist/features/complexity-query.js +142 -137
- package/dist/features/complexity-query.js.map +1 -1
- package/dist/features/complexity.d.ts +7 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +62 -1
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts +7 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +356 -188
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/graph-enrichment.d.ts.map +1 -1
- package/dist/features/graph-enrichment.js +117 -104
- package/dist/features/graph-enrichment.js.map +1 -1
- package/dist/features/sequence.d.ts.map +1 -1
- package/dist/features/sequence.js +25 -4
- package/dist/features/sequence.js.map +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +29 -4
- package/dist/features/structure-query.js.map +1 -1
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +35 -15
- package/dist/features/structure.js.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.js +88 -73
- package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
- package/dist/graph/algorithms/leiden/index.js +43 -28
- package/dist/graph/algorithms/leiden/index.js.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.js +90 -104
- 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 +89 -106
- package/dist/graph/algorithms/leiden/partition.js.map +1 -1
- package/dist/graph/model.d.ts +2 -0
- package/dist/graph/model.d.ts.map +1 -1
- package/dist/graph/model.js +20 -8
- package/dist/graph/model.js.map +1 -1
- package/dist/infrastructure/config.d.ts +0 -8
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +73 -62
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/registry.d.ts +0 -8
- package/dist/infrastructure/registry.d.ts.map +1 -1
- package/dist/infrastructure/registry.js +12 -14
- package/dist/infrastructure/registry.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +45 -36
- package/dist/mcp/server.js.map +1 -1
- package/dist/presentation/audit.d.ts.map +1 -1
- package/dist/presentation/audit.js +61 -57
- package/dist/presentation/audit.js.map +1 -1
- package/dist/presentation/branch-compare.d.ts.map +1 -1
- package/dist/presentation/branch-compare.js +56 -38
- package/dist/presentation/branch-compare.js.map +1 -1
- package/dist/presentation/check.d.ts.map +1 -1
- package/dist/presentation/check.js +30 -32
- package/dist/presentation/check.js.map +1 -1
- package/dist/presentation/colors.d.ts.map +1 -1
- package/dist/presentation/colors.js +2 -0
- package/dist/presentation/colors.js.map +1 -1
- package/dist/presentation/complexity.d.ts.map +1 -1
- package/dist/presentation/complexity.js +25 -19
- package/dist/presentation/complexity.js.map +1 -1
- package/dist/presentation/queries-cli/exports.d.ts.map +1 -1
- package/dist/presentation/queries-cli/exports.js +15 -15
- 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 +29 -19
- package/dist/presentation/queries-cli/impact.js.map +1 -1
- package/dist/types.d.ts +182 -7
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-bash.wasm +0 -0
- package/grammars/tree-sitter-c.wasm +0 -0
- package/grammars/tree-sitter-cpp.wasm +0 -0
- package/grammars/tree-sitter-kotlin.wasm +0 -0
- package/grammars/tree-sitter-scala.wasm +0 -0
- package/grammars/tree-sitter-swift.wasm +0 -0
- package/package.json +13 -7
- package/src/ast-analysis/engine.ts +147 -138
- package/src/ast-analysis/visitors/ast-store-visitor.ts +15 -2
- package/src/ast-analysis/visitors/complexity-visitor.ts +11 -11
- package/src/db/connection.ts +90 -59
- package/src/db/index.ts +1 -0
- package/src/db/migrations.ts +36 -32
- package/src/domain/analysis/context.ts +73 -75
- package/src/domain/analysis/dependencies.ts +78 -68
- package/src/domain/analysis/exports.ts +45 -34
- package/src/domain/analysis/fn-impact.ts +67 -64
- package/src/domain/analysis/module-map.ts +103 -8
- package/src/domain/analysis/query-helpers.ts +35 -0
- package/src/domain/graph/builder/helpers.ts +12 -6
- package/src/domain/graph/builder/incremental.ts +3 -2
- package/src/domain/graph/builder/pipeline.ts +71 -3
- package/src/domain/graph/builder/stages/build-edges.ts +10 -75
- package/src/domain/graph/builder/stages/build-structure.ts +9 -7
- package/src/domain/graph/builder/stages/collect-files.ts +2 -2
- package/src/domain/graph/builder/stages/detect-changes.ts +7 -2
- package/src/domain/graph/builder/stages/finalize.ts +159 -125
- package/src/domain/graph/builder/stages/insert-nodes.ts +32 -21
- package/src/domain/graph/builder/stages/resolve-imports.ts +3 -2
- package/src/domain/graph/resolve.ts +34 -46
- package/src/domain/graph/watcher.ts +12 -14
- package/src/domain/parser.ts +168 -97
- package/src/domain/search/search/cli-formatter.ts +121 -94
- package/src/extractors/bash.ts +97 -0
- package/src/extractors/c.ts +212 -0
- package/src/extractors/cpp.ts +298 -0
- package/src/extractors/csharp.ts +53 -56
- package/src/extractors/go.ts +152 -134
- package/src/extractors/hcl.ts +6 -6
- package/src/extractors/helpers.ts +93 -1
- package/src/extractors/index.ts +6 -0
- package/src/extractors/java.ts +43 -48
- package/src/extractors/javascript.ts +328 -281
- package/src/extractors/kotlin.ts +293 -0
- package/src/extractors/php.ts +46 -40
- package/src/extractors/python.ts +81 -104
- package/src/extractors/ruby.ts +6 -13
- package/src/extractors/rust.ts +65 -85
- package/src/extractors/scala.ts +285 -0
- package/src/extractors/swift.ts +293 -0
- package/src/features/ast.ts +10 -25
- package/src/features/audit.ts +24 -20
- package/src/features/branch-compare.ts +51 -4
- package/src/features/cfg.ts +158 -65
- package/src/features/check.ts +90 -74
- package/src/features/complexity-query.ts +181 -163
- package/src/features/complexity.ts +64 -1
- package/src/features/dataflow.ts +462 -217
- package/src/features/graph-enrichment.ts +161 -117
- package/src/features/sequence.ts +27 -4
- package/src/features/structure-query.ts +43 -4
- package/src/features/structure.ts +50 -22
- package/src/graph/algorithms/leiden/adapter.ts +126 -71
- package/src/graph/algorithms/leiden/index.ts +67 -28
- package/src/graph/algorithms/leiden/optimiser.ts +114 -105
- package/src/graph/algorithms/leiden/partition.ts +131 -98
- package/src/graph/model.ts +19 -7
- package/src/infrastructure/config.ts +60 -58
- package/src/infrastructure/registry.ts +17 -14
- package/src/mcp/server.ts +46 -37
- package/src/presentation/audit.ts +72 -67
- package/src/presentation/branch-compare.ts +54 -50
- package/src/presentation/check.ts +34 -34
- package/src/presentation/colors.ts +2 -0
- package/src/presentation/complexity.ts +39 -33
- package/src/presentation/queries-cli/exports.ts +17 -17
- package/src/presentation/queries-cli/impact.ts +30 -22
- package/src/types.ts +189 -7
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import { performance } from 'node:perf_hooks';
|
|
9
|
-
import { getNodeId } from '
|
|
10
|
-
import { debug } from '
|
|
11
|
-
import { loadNative } from '
|
|
9
|
+
import { getNodeId } from '../../../../db/index.js';
|
|
10
|
+
import { debug } from '../../../../infrastructure/logger.js';
|
|
11
|
+
import { loadNative } from '../../../../infrastructure/native.js';
|
|
12
12
|
import type {
|
|
13
13
|
BetterSqlite3Database,
|
|
14
14
|
Call,
|
|
@@ -18,10 +18,11 @@ import type {
|
|
|
18
18
|
NativeAddon,
|
|
19
19
|
NodeRow,
|
|
20
20
|
TypeMapEntry,
|
|
21
|
-
} from '
|
|
21
|
+
} from '../../../../types.js';
|
|
22
22
|
import { computeConfidence } from '../../resolve.js';
|
|
23
23
|
import type { PipelineContext } from '../context.js';
|
|
24
24
|
import { BUILTIN_RECEIVERS, batchInsertEdges } from '../helpers.js';
|
|
25
|
+
|
|
25
26
|
import { getResolved, isBarrelFile, resolveBarrelExport } from './resolve-imports.js';
|
|
26
27
|
|
|
27
28
|
// ── Local types ──────────────────────────────────────────────────────────
|
|
@@ -61,12 +62,6 @@ interface NativeEdge {
|
|
|
61
62
|
dynamic: number;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
/** TypeMap entry used in receiver supplement (normalized from native format). */
|
|
65
|
-
interface NormalizedTypeEntry {
|
|
66
|
-
type: string;
|
|
67
|
-
confidence: number;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
65
|
// ── Node lookup setup ───────────────────────────────────────────────────
|
|
71
66
|
|
|
72
67
|
function makeGetNodeIdStmt(db: BetterSqlite3Database): NodeIdStmt {
|
|
@@ -210,14 +205,6 @@ function buildCallEdgesNative(
|
|
|
210
205
|
for (const e of nativeEdges) {
|
|
211
206
|
allEdgeRows.push([e.sourceId, e.targetId, e.kind, e.confidence, e.dynamic]);
|
|
212
207
|
}
|
|
213
|
-
|
|
214
|
-
// Older native binaries (< 3.2.0) don't emit receiver or type-resolved method-call
|
|
215
|
-
// edges. Supplement them on the JS side if the native binary missed them.
|
|
216
|
-
// TODO: Remove once all published native binaries handle receivers (>= 3.2.0)
|
|
217
|
-
const hasReceiver = nativeEdges.some((e) => e.kind === 'receiver');
|
|
218
|
-
if (!hasReceiver) {
|
|
219
|
-
supplementReceiverEdges(ctx, nativeFiles, getNodeIdStmt, allEdgeRows);
|
|
220
|
-
}
|
|
221
208
|
}
|
|
222
209
|
|
|
223
210
|
function buildImportedNamesForNative(
|
|
@@ -242,58 +229,6 @@ function buildImportedNamesForNative(
|
|
|
242
229
|
return importedNames;
|
|
243
230
|
}
|
|
244
231
|
|
|
245
|
-
// ── Receiver edge supplement for older native binaries ──────────────────
|
|
246
|
-
|
|
247
|
-
function supplementReceiverEdges(
|
|
248
|
-
ctx: PipelineContext,
|
|
249
|
-
nativeFiles: NativeFileEntry[],
|
|
250
|
-
getNodeIdStmt: NodeIdStmt,
|
|
251
|
-
allEdgeRows: EdgeRowTuple[],
|
|
252
|
-
): void {
|
|
253
|
-
const seenCallEdges = new Set<string>();
|
|
254
|
-
// Collect existing edges to avoid duplicates
|
|
255
|
-
for (const row of allEdgeRows) {
|
|
256
|
-
seenCallEdges.add(`${row[0]}|${row[1]}|${row[2]}`);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
for (const nf of nativeFiles) {
|
|
260
|
-
const relPath = nf.file;
|
|
261
|
-
const typeMap = new Map<string, NormalizedTypeEntry>(
|
|
262
|
-
nf.typeMap.map((t) => [t.name, { type: t.typeName, confidence: t.confidence ?? 0.9 }]),
|
|
263
|
-
);
|
|
264
|
-
const fileNodeRow = { id: nf.fileNodeId };
|
|
265
|
-
|
|
266
|
-
for (const call of nf.calls) {
|
|
267
|
-
if (!call.receiver || BUILTIN_RECEIVERS.has(call.receiver)) continue;
|
|
268
|
-
if (call.receiver === 'this' || call.receiver === 'self' || call.receiver === 'super')
|
|
269
|
-
continue;
|
|
270
|
-
|
|
271
|
-
const caller = findCaller(call, nf.definitions, relPath, getNodeIdStmt, fileNodeRow);
|
|
272
|
-
|
|
273
|
-
// Receiver edge: caller → receiver type node
|
|
274
|
-
buildReceiverEdge(ctx, call, caller, relPath, seenCallEdges, allEdgeRows, typeMap);
|
|
275
|
-
|
|
276
|
-
// Type-resolved method call: caller → Type.method
|
|
277
|
-
const typeEntry = typeMap.get(call.receiver);
|
|
278
|
-
const typeName = typeEntry ? typeEntry.type : null;
|
|
279
|
-
if (typeName) {
|
|
280
|
-
const qualifiedName = `${typeName}.${call.name}`;
|
|
281
|
-
const targets = (ctx.nodesByName.get(qualifiedName) || []).filter(
|
|
282
|
-
(n) => n.kind === 'method',
|
|
283
|
-
);
|
|
284
|
-
for (const t of targets) {
|
|
285
|
-
const key = `${caller.id}|${t.id}|calls`;
|
|
286
|
-
if (t.id !== caller.id && !seenCallEdges.has(key)) {
|
|
287
|
-
seenCallEdges.add(key);
|
|
288
|
-
const confidence = computeConfidence(relPath, t.file, null);
|
|
289
|
-
allEdgeRows.push([caller.id, t.id, 'calls', confidence, call.dynamic ? 1 : 0]);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
232
|
// ── Call edges (JS fallback) ────────────────────────────────────────────
|
|
298
233
|
|
|
299
234
|
function buildCallEdgesJS(
|
|
@@ -495,7 +430,7 @@ function buildReceiverEdge(
|
|
|
495
430
|
relPath: string,
|
|
496
431
|
seenCallEdges: Set<string>,
|
|
497
432
|
allEdgeRows: EdgeRowTuple[],
|
|
498
|
-
typeMap: Map<string, TypeMapEntry |
|
|
433
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
499
434
|
): void {
|
|
500
435
|
const receiverKinds = new Set(['class', 'struct', 'interface', 'type', 'module']);
|
|
501
436
|
const typeEntry = typeMap?.get(call.receiver!);
|
|
@@ -608,7 +543,7 @@ function loadNodes(ctx: PipelineContext): { rows: QueryNodeRow[]; scoped: boolea
|
|
|
608
543
|
|
|
609
544
|
/**
|
|
610
545
|
* For scoped node loading, patch nodesByName.get with a lazy SQL fallback
|
|
611
|
-
* so global name-only lookups (resolveByMethodOrGlobal
|
|
546
|
+
* so global name-only lookups (resolveByMethodOrGlobal)
|
|
612
547
|
* can still find nodes outside the scoped set.
|
|
613
548
|
*/
|
|
614
549
|
function addLazyFallback(ctx: PipelineContext, scopedLoad: boolean): void {
|
|
@@ -673,7 +608,7 @@ export async function buildEdges(ctx: PipelineContext): Promise<void> {
|
|
|
673
608
|
|
|
674
609
|
// When using native edge insert, skip JS insert here — do it after tx commits.
|
|
675
610
|
// Otherwise insert edges within this transaction for atomicity.
|
|
676
|
-
const useNativeEdgeInsert = !!ctx.nativeDb?.bulkInsertEdges;
|
|
611
|
+
const useNativeEdgeInsert = ctx.engineName === 'native' && !!ctx.nativeDb?.bulkInsertEdges;
|
|
677
612
|
if (!useNativeEdgeInsert) {
|
|
678
613
|
batchInsertEdges(db, allEdgeRows);
|
|
679
614
|
}
|
|
@@ -683,7 +618,7 @@ export async function buildEdges(ctx: PipelineContext): Promise<void> {
|
|
|
683
618
|
// Phase 2: Native rusqlite bulk insert (outside better-sqlite3 transaction
|
|
684
619
|
// to avoid SQLITE_BUSY contention). Uses NativeDatabase persistent connection.
|
|
685
620
|
// Standalone napi functions were removed in 6.17.
|
|
686
|
-
if (ctx.nativeDb?.bulkInsertEdges && allEdgeRows.length > 0) {
|
|
621
|
+
if (ctx.engineName === 'native' && ctx.nativeDb?.bulkInsertEdges && allEdgeRows.length > 0) {
|
|
687
622
|
const nativeEdges = allEdgeRows.map((r) => ({
|
|
688
623
|
sourceId: r[0],
|
|
689
624
|
targetId: r[1],
|
|
@@ -694,7 +629,7 @@ export async function buildEdges(ctx: PipelineContext): Promise<void> {
|
|
|
694
629
|
const ok = ctx.nativeDb.bulkInsertEdges(nativeEdges);
|
|
695
630
|
if (!ok) {
|
|
696
631
|
debug('Native bulkInsertEdges failed — falling back to JS batchInsertEdges');
|
|
697
|
-
batchInsertEdges(db, allEdgeRows);
|
|
632
|
+
batchInsertEdges(ctx.db, allEdgeRows);
|
|
698
633
|
}
|
|
699
634
|
}
|
|
700
635
|
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import { performance } from 'node:perf_hooks';
|
|
8
|
-
import { debug } from '
|
|
9
|
-
import { normalizePath } from '
|
|
10
|
-
import type { ExtractorOutput } from '
|
|
8
|
+
import { debug } from '../../../../infrastructure/logger.js';
|
|
9
|
+
import { normalizePath } from '../../../../shared/constants.js';
|
|
10
|
+
import type { ExtractorOutput } from '../../../../types.js';
|
|
11
11
|
import type { PipelineContext } from '../context.js';
|
|
12
12
|
import { readFileSafe } from '../helpers.js';
|
|
13
13
|
|
|
@@ -39,10 +39,11 @@ export async function buildStructure(ctx: PipelineContext): Promise<void> {
|
|
|
39
39
|
// loading ALL definitions from DB (~8ms) and recomputing ALL metrics (~15ms).
|
|
40
40
|
// Gate: ≤5 changed files AND significantly more existing files (>20) to
|
|
41
41
|
// avoid triggering on small test fixtures where directory metrics matter.
|
|
42
|
+
const useNativeReads = ctx.engineName === 'native' && !!ctx.nativeDb;
|
|
42
43
|
const existingFileCount = !isFullBuild
|
|
43
44
|
? (
|
|
44
|
-
(
|
|
45
|
-
? ctx.nativeDb
|
|
45
|
+
(useNativeReads
|
|
46
|
+
? ctx.nativeDb!.queryGet("SELECT COUNT(*) as c FROM nodes WHERE kind = 'file'", [])
|
|
46
47
|
: db.prepare("SELECT COUNT(*) as c FROM nodes WHERE kind = 'file'").get()) as {
|
|
47
48
|
c: number;
|
|
48
49
|
}
|
|
@@ -96,7 +97,8 @@ export async function buildStructure(ctx: PipelineContext): Promise<void> {
|
|
|
96
97
|
|
|
97
98
|
// Use NativeDatabase persistent connection (Phase 6.15+).
|
|
98
99
|
// Standalone napi functions were removed in 6.17 — falls through to JS if nativeDb unavailable.
|
|
99
|
-
|
|
100
|
+
// Note: classifyRoles* both read (fan-in/fan-out) and write (UPDATE nodes SET role).
|
|
101
|
+
if (useNativeReads && ctx.nativeDb?.classifyRolesFull) {
|
|
100
102
|
const nativeResult =
|
|
101
103
|
changedFileList && changedFileList.length > 0
|
|
102
104
|
? ctx.nativeDb.classifyRolesIncremental(changedFileList)
|
|
@@ -126,7 +128,7 @@ export async function buildStructure(ctx: PipelineContext): Promise<void> {
|
|
|
126
128
|
changedFiles?: string[] | null,
|
|
127
129
|
) => Record<string, number>;
|
|
128
130
|
};
|
|
129
|
-
roleSummary = classifyNodeRoles(db, changedFileList);
|
|
131
|
+
roleSummary = classifyNodeRoles(ctx.db, changedFileList);
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
debug(
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import fs from 'node:fs';
|
|
9
9
|
import path from 'node:path';
|
|
10
|
-
import { debug, info } from '
|
|
11
|
-
import { normalizePath } from '
|
|
10
|
+
import { debug, info } from '../../../../infrastructure/logger.js';
|
|
11
|
+
import { normalizePath } from '../../../../shared/constants.js';
|
|
12
12
|
import { readJournal } from '../../journal.js';
|
|
13
13
|
import type { PipelineContext } from '../context.js';
|
|
14
14
|
import { collectFiles as collectFilesUtil } from '../helpers.js';
|
|
@@ -338,7 +338,7 @@ function purgeAndAddReverseDeps(
|
|
|
338
338
|
if (hasPurge || hasReverseDeps) {
|
|
339
339
|
const filesToPurge = hasPurge ? [...ctx.removed, ...changePaths] : [];
|
|
340
340
|
// Prefer NativeDatabase: purge + reverse-dep edge deletion in one transaction (#670)
|
|
341
|
-
if (ctx.nativeDb?.purgeFilesData) {
|
|
341
|
+
if (ctx.engineName === 'native' && ctx.nativeDb?.purgeFilesData) {
|
|
342
342
|
ctx.nativeDb.purgeFilesData(filesToPurge, false, hasReverseDeps ? reverseDepList : undefined);
|
|
343
343
|
} else {
|
|
344
344
|
if (hasPurge) {
|
|
@@ -433,7 +433,12 @@ export async function detectChanges(ctx: PipelineContext): Promise<void> {
|
|
|
433
433
|
}
|
|
434
434
|
const increResult =
|
|
435
435
|
incremental && !forceFullRebuild
|
|
436
|
-
? getChangedFiles(
|
|
436
|
+
? getChangedFiles(
|
|
437
|
+
db,
|
|
438
|
+
allFiles,
|
|
439
|
+
rootDir,
|
|
440
|
+
ctx.engineName === 'native' ? ctx.nativeDb : undefined,
|
|
441
|
+
)
|
|
437
442
|
: {
|
|
438
443
|
changed: allFiles.map((f): ChangedFile => ({ file: f })),
|
|
439
444
|
removed: [] as string[],
|
|
@@ -17,12 +17,8 @@ import { CODEGRAPH_VERSION } from '../../../../shared/version.js';
|
|
|
17
17
|
import { writeJournalHeader } from '../../journal.js';
|
|
18
18
|
import type { PipelineContext } from '../context.js';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const t0 = performance.now();
|
|
24
|
-
|
|
25
|
-
// Release cached WASM trees
|
|
20
|
+
/** Release cached WASM parse trees to free memory. */
|
|
21
|
+
function releaseWasmTrees(allSymbols: PipelineContext['allSymbols']): void {
|
|
26
22
|
for (const [, symbols] of allSymbols) {
|
|
27
23
|
const tree = symbols._tree as { delete?: () => void } | undefined;
|
|
28
24
|
if (tree && typeof tree.delete === 'function') {
|
|
@@ -35,133 +31,141 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
|
|
|
35
31
|
symbols._tree = undefined;
|
|
36
32
|
symbols._langId = undefined;
|
|
37
33
|
}
|
|
34
|
+
}
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Detect significant drift between current and previous node/edge counts.
|
|
38
|
+
* Skipped for small incremental changes where count fluctuation is expected.
|
|
39
|
+
*/
|
|
40
|
+
function detectIncrementalDrift(
|
|
41
|
+
ctx: PipelineContext,
|
|
42
|
+
nodeCount: number,
|
|
43
|
+
actualEdgeCount: number,
|
|
44
|
+
): void {
|
|
45
|
+
const { db, allSymbols, config } = ctx;
|
|
46
|
+
const useNativeDb = ctx.engineName === 'native' && !!ctx.nativeDb;
|
|
47
|
+
if (ctx.isFullBuild || allSymbols.size <= 3) return;
|
|
42
48
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
const prevNodes = useNativeDb
|
|
50
|
+
? ctx.nativeDb!.getBuildMeta('node_count')
|
|
51
|
+
: getBuildMeta(db, 'node_count');
|
|
52
|
+
const prevEdges = useNativeDb
|
|
53
|
+
? ctx.nativeDb!.getBuildMeta('edge_count')
|
|
54
|
+
: getBuildMeta(db, 'edge_count');
|
|
55
|
+
if (!prevNodes || !prevEdges) return;
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (prevN > 0) {
|
|
61
|
-
const nodeDrift = Math.abs(nodeCount - prevN) / prevN;
|
|
62
|
-
const edgeDrift = prevE > 0 ? Math.abs(actualEdgeCount - prevE) / prevE : 0;
|
|
63
|
-
const driftThreshold =
|
|
64
|
-
(config as { build?: { driftThreshold?: number } }).build?.driftThreshold ?? 0.2;
|
|
65
|
-
if (nodeDrift > driftThreshold || edgeDrift > driftThreshold) {
|
|
66
|
-
warn(
|
|
67
|
-
`Incremental build diverged significantly from previous counts (nodes: ${prevN}\u2192${nodeCount} [${(nodeDrift * 100).toFixed(1)}%], edges: ${prevE}\u2192${actualEdgeCount} [${(edgeDrift * 100).toFixed(1)}%], threshold: ${(driftThreshold * 100).toFixed(0)}%). Consider rebuilding with --no-incremental.`,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
57
|
+
const prevN = Number(prevNodes);
|
|
58
|
+
const prevE = Number(prevEdges);
|
|
59
|
+
if (prevN <= 0) return;
|
|
60
|
+
|
|
61
|
+
const nodeDrift = Math.abs(nodeCount - prevN) / prevN;
|
|
62
|
+
const edgeDrift = prevE > 0 ? Math.abs(actualEdgeCount - prevE) / prevE : 0;
|
|
63
|
+
const driftThreshold =
|
|
64
|
+
(config as { build?: { driftThreshold?: number } }).build?.driftThreshold ?? 0.2;
|
|
65
|
+
if (nodeDrift > driftThreshold || edgeDrift > driftThreshold) {
|
|
66
|
+
warn(
|
|
67
|
+
`Incremental build diverged significantly from previous counts (nodes: ${prevN}\u2192${nodeCount} [${(nodeDrift * 100).toFixed(1)}%], edges: ${prevE}\u2192${actualEdgeCount} [${(edgeDrift * 100).toFixed(1)}%], threshold: ${(driftThreshold * 100).toFixed(0)}%). Consider rebuilding with --no-incremental.`,
|
|
68
|
+
);
|
|
72
69
|
}
|
|
70
|
+
}
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
built_at: buildNow.toISOString(),
|
|
91
|
-
node_count: String(nodeCount),
|
|
92
|
-
edge_count: String(actualEdgeCount),
|
|
93
|
-
}).map(([key, value]) => ({ key, value: String(value) })),
|
|
94
|
-
);
|
|
95
|
-
} else {
|
|
96
|
-
setBuildMeta(db, {
|
|
72
|
+
/**
|
|
73
|
+
* Persist build metadata (engine, version, counts, timestamp).
|
|
74
|
+
* Skipped for small incremental builds to avoid WAL fsync cost.
|
|
75
|
+
*/
|
|
76
|
+
function persistBuildMetadata(
|
|
77
|
+
ctx: PipelineContext,
|
|
78
|
+
nodeCount: number,
|
|
79
|
+
actualEdgeCount: number,
|
|
80
|
+
buildNow: Date,
|
|
81
|
+
): void {
|
|
82
|
+
const useNativeDb = ctx.engineName === 'native' && !!ctx.nativeDb;
|
|
83
|
+
if (!ctx.isFullBuild && ctx.allSymbols.size <= 3) return;
|
|
84
|
+
try {
|
|
85
|
+
if (useNativeDb) {
|
|
86
|
+
ctx.nativeDb!.setBuildMeta(
|
|
87
|
+
Object.entries({
|
|
97
88
|
engine: ctx.engineName,
|
|
98
89
|
engine_version: ctx.engineVersion || '',
|
|
99
90
|
codegraph_version: CODEGRAPH_VERSION,
|
|
100
|
-
schema_version: String(schemaVersion),
|
|
91
|
+
schema_version: String(ctx.schemaVersion),
|
|
101
92
|
built_at: buildNow.toISOString(),
|
|
102
|
-
node_count: nodeCount,
|
|
103
|
-
edge_count: actualEdgeCount,
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
93
|
+
node_count: String(nodeCount),
|
|
94
|
+
edge_count: String(actualEdgeCount),
|
|
95
|
+
}).map(([key, value]) => ({ key, value: String(value) })),
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
setBuildMeta(ctx.db, {
|
|
99
|
+
engine: ctx.engineName,
|
|
100
|
+
engine_version: ctx.engineVersion || '',
|
|
101
|
+
codegraph_version: CODEGRAPH_VERSION,
|
|
102
|
+
schema_version: String(ctx.schemaVersion),
|
|
103
|
+
built_at: buildNow.toISOString(),
|
|
104
|
+
node_count: nodeCount,
|
|
105
|
+
edge_count: actualEdgeCount,
|
|
106
|
+
});
|
|
108
107
|
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
warn(`Failed to write build metadata: ${(err as Error).message}`);
|
|
109
110
|
}
|
|
111
|
+
}
|
|
110
112
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/* ignore - embeddings table may have been dropped */
|
|
113
|
+
/**
|
|
114
|
+
* Run advisory checks on full builds: orphaned embeddings, stale embeddings,
|
|
115
|
+
* and unused exports. Informational only — does not affect correctness.
|
|
116
|
+
*/
|
|
117
|
+
function runAdvisoryChecks(
|
|
118
|
+
db: PipelineContext['db'],
|
|
119
|
+
hasEmbeddings: boolean,
|
|
120
|
+
buildNow: Date,
|
|
121
|
+
): void {
|
|
122
|
+
// Orphaned embeddings warning
|
|
123
|
+
if (hasEmbeddings) {
|
|
124
|
+
try {
|
|
125
|
+
const orphaned = (
|
|
126
|
+
db
|
|
127
|
+
.prepare(
|
|
128
|
+
'SELECT COUNT(*) as c FROM embeddings WHERE node_id NOT IN (SELECT id FROM nodes)',
|
|
129
|
+
)
|
|
130
|
+
.get() as { c: number }
|
|
131
|
+
).c;
|
|
132
|
+
if (orphaned > 0) {
|
|
133
|
+
warn(
|
|
134
|
+
`${orphaned} embeddings are orphaned (nodes changed). Run "codegraph embed" to refresh.`,
|
|
135
|
+
);
|
|
135
136
|
}
|
|
137
|
+
} catch {
|
|
138
|
+
/* ignore - embeddings table may have been dropped */
|
|
136
139
|
}
|
|
140
|
+
}
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
142
|
+
// Stale embeddings warning (built before current graph rebuild)
|
|
143
|
+
if (hasEmbeddings) {
|
|
144
|
+
try {
|
|
145
|
+
const embedBuiltAt = (
|
|
146
|
+
db.prepare("SELECT value FROM embedding_meta WHERE key = 'built_at'").get() as
|
|
147
|
+
| { value: string }
|
|
148
|
+
| undefined
|
|
149
|
+
)?.value;
|
|
150
|
+
if (embedBuiltAt) {
|
|
151
|
+
const embedTime = new Date(embedBuiltAt).getTime();
|
|
152
|
+
if (!Number.isNaN(embedTime) && embedTime < buildNow.getTime()) {
|
|
153
|
+
warn(
|
|
154
|
+
'Embeddings were built before the last graph rebuild. Run "codegraph embed" to update.',
|
|
155
|
+
);
|
|
153
156
|
}
|
|
154
|
-
} catch {
|
|
155
|
-
/* ignore - embedding_meta table may not exist */
|
|
156
157
|
}
|
|
158
|
+
} catch {
|
|
159
|
+
/* ignore - embedding_meta table may not exist */
|
|
157
160
|
}
|
|
161
|
+
}
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
// Unused exports warning
|
|
164
|
+
try {
|
|
165
|
+
const unusedCount = (
|
|
166
|
+
db
|
|
167
|
+
.prepare(
|
|
168
|
+
`SELECT COUNT(*) as c FROM nodes
|
|
165
169
|
WHERE exported = 1 AND kind != 'file'
|
|
166
170
|
AND id NOT IN (
|
|
167
171
|
SELECT DISTINCT e.target_id FROM edges e
|
|
@@ -169,17 +173,47 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
|
|
|
169
173
|
JOIN nodes target ON e.target_id = target.id
|
|
170
174
|
WHERE e.kind = 'calls' AND caller.file != target.file
|
|
171
175
|
)`,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
} catch {
|
|
181
|
-
/* exported column may not exist on older DBs */
|
|
176
|
+
)
|
|
177
|
+
.get() as { c: number }
|
|
178
|
+
).c;
|
|
179
|
+
if (unusedCount > 0) {
|
|
180
|
+
warn(
|
|
181
|
+
`${unusedCount} exported symbol${unusedCount > 1 ? 's have' : ' has'} zero cross-file consumers. Run "codegraph exports <file> --unused" to inspect.`,
|
|
182
|
+
);
|
|
182
183
|
}
|
|
184
|
+
} catch {
|
|
185
|
+
/* exported column may not exist on older DBs */
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function finalize(ctx: PipelineContext): Promise<void> {
|
|
190
|
+
const { allSymbols, rootDir, isFullBuild, hasEmbeddings, opts } = ctx;
|
|
191
|
+
|
|
192
|
+
const t0 = performance.now();
|
|
193
|
+
|
|
194
|
+
releaseWasmTrees(allSymbols);
|
|
195
|
+
|
|
196
|
+
// Capture a single wall-clock timestamp for the current build — used for
|
|
197
|
+
// both the stale-embeddings comparison and the persisted built_at metadata.
|
|
198
|
+
const buildNow = new Date();
|
|
199
|
+
|
|
200
|
+
const nodeCount = (ctx.db.prepare('SELECT COUNT(*) as c FROM nodes').get() as { c: number }).c;
|
|
201
|
+
const actualEdgeCount = (ctx.db.prepare('SELECT COUNT(*) as c FROM edges').get() as { c: number })
|
|
202
|
+
.c;
|
|
203
|
+
info(`Graph built: ${nodeCount} nodes, ${actualEdgeCount} edges`);
|
|
204
|
+
info(`Stored in ${ctx.dbPath}`);
|
|
205
|
+
|
|
206
|
+
detectIncrementalDrift(ctx, nodeCount, actualEdgeCount);
|
|
207
|
+
persistBuildMetadata(ctx, nodeCount, actualEdgeCount, buildNow);
|
|
208
|
+
|
|
209
|
+
// Skip expensive advisory queries for incremental builds — these are
|
|
210
|
+
// informational warnings that don't affect correctness and cost ~40-60ms.
|
|
211
|
+
if (!isFullBuild) {
|
|
212
|
+
debug(
|
|
213
|
+
'Finalize: skipping advisory queries (orphaned/stale embeddings, unused exports) for incremental build',
|
|
214
|
+
);
|
|
215
|
+
} else {
|
|
216
|
+
runAdvisoryChecks(ctx.db, hasEmbeddings, buildNow);
|
|
183
217
|
}
|
|
184
218
|
|
|
185
219
|
// Intentionally measured before closeDb / writeJournalHeader / auto-registration:
|
|
@@ -192,7 +226,7 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
|
|
|
192
226
|
// For small incremental builds, defer the expensive WAL checkpoint to the
|
|
193
227
|
// next event loop tick. Skip for temp directories (tests) — they rmSync
|
|
194
228
|
// immediately after build.
|
|
195
|
-
const pair = { db, nativeDb: ctx.nativeDb };
|
|
229
|
+
const pair = { db: ctx.db, nativeDb: ctx.nativeDb };
|
|
196
230
|
const isTempDir = path.resolve(rootDir).startsWith(path.resolve(tmpdir()));
|
|
197
231
|
if (!isFullBuild && allSymbols.size <= 5 && !isTempDir) {
|
|
198
232
|
closeDbPairDeferred(pair);
|