homegraph 1.4.1 → 1.5.1
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/LICENSE +21 -21
- package/README.md +305 -268
- package/dist/bin/command-supervision.d.ts.map +1 -1
- package/dist/bin/command-supervision.js +7 -4
- package/dist/bin/command-supervision.js.map +1 -1
- package/dist/bin/homegraph.js +304 -81
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +32 -11
- package/dist/context/index.js.map +1 -1
- package/dist/db/index.d.ts +143 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +305 -28
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.js +37 -37
- package/dist/db/queries.d.ts +43 -4
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +294 -170
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +203 -203
- package/dist/db/sqlite-adapter.d.ts +24 -17
- package/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.js +292 -36
- package/dist/db/sqlite-adapter.js.map +1 -1
- package/dist/db/wal-valve.d.ts +15 -2
- package/dist/db/wal-valve.d.ts.map +1 -1
- package/dist/db/wal-valve.js +88 -6
- package/dist/db/wal-valve.js.map +1 -1
- package/dist/directory.js +5 -5
- package/dist/extraction/arkts-batch-worker.js +3 -2
- package/dist/extraction/arkts-batch-worker.js.map +1 -1
- package/dist/extraction/default-ignore.d.ts +39 -0
- package/dist/extraction/default-ignore.d.ts.map +1 -0
- package/dist/extraction/default-ignore.js +221 -0
- package/dist/extraction/default-ignore.js.map +1 -0
- package/dist/extraction/index.d.ts +9 -10
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +227 -323
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.d.ts +2 -4
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.js +6 -21
- package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +100 -6
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1777 -173
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/store-worker.d.ts +20 -0
- package/dist/extraction/store-worker.d.ts.map +1 -0
- package/dist/extraction/store-worker.js +102 -0
- package/dist/extraction/store-worker.js.map +1 -0
- package/dist/extraction/store-writer.d.ts +48 -0
- package/dist/extraction/store-writer.d.ts.map +1 -0
- package/dist/extraction/store-writer.js +167 -0
- package/dist/extraction/store-writer.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +47 -0
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +14 -4
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
- package/dist/extraction/wasm-runtime-flags.js +55 -7
- package/dist/extraction/wasm-runtime-flags.js.map +1 -1
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +135 -97
- package/dist/index.js.map +1 -1
- package/dist/installer/instructions-template.js +9 -9
- package/dist/mcp/liveness-watchdog.d.ts +18 -0
- package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/dist/mcp/liveness-watchdog.js +185 -73
- package/dist/mcp/liveness-watchdog.js.map +1 -1
- package/dist/mcp/query-worker.d.ts +2 -2
- package/dist/mcp/query-worker.js +2 -2
- package/dist/mcp/server-instructions.js +47 -47
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +42 -26
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reasoning/reasoner.js +32 -32
- package/dist/resolution/callback-synthesizer.d.ts +52 -16
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +234 -180
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +10 -2
- package/dist/resolution/cooperative-yield.d.ts.map +1 -1
- package/dist/resolution/cooperative-yield.js +6 -4
- package/dist/resolution/cooperative-yield.js.map +1 -1
- package/dist/resolution/frameworks/go.d.ts.map +1 -1
- package/dist/resolution/frameworks/go.js +29 -6
- package/dist/resolution/frameworks/go.js.map +1 -1
- package/dist/resolution/import-resolver.d.ts +2 -3
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +166 -7
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +87 -2
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +739 -131
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/memory-budget.d.ts +48 -0
- package/dist/resolution/memory-budget.d.ts.map +1 -0
- package/dist/resolution/memory-budget.js +162 -0
- package/dist/resolution/memory-budget.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +12 -1
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +439 -97
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/resolver-pool.d.ts +106 -0
- package/dist/resolution/resolver-pool.d.ts.map +1 -0
- package/dist/resolution/resolver-pool.js +344 -0
- package/dist/resolution/resolver-pool.js.map +1 -0
- package/dist/resolution/resolver-worker.d.ts +17 -0
- package/dist/resolution/resolver-worker.d.ts.map +1 -0
- package/dist/resolution/resolver-worker.js +141 -0
- package/dist/resolution/resolver-worker.js.map +1 -0
- package/dist/resolution/types.d.ts +3 -0
- package/dist/resolution/types.d.ts.map +1 -1
- package/dist/spec/build/diff-parser.d.ts +55 -0
- package/dist/spec/build/diff-parser.d.ts.map +1 -0
- package/dist/spec/build/diff-parser.js +205 -0
- package/dist/spec/build/diff-parser.js.map +1 -0
- package/dist/spec/build/pipeline.d.ts +54 -0
- package/dist/spec/build/pipeline.d.ts.map +1 -0
- package/dist/spec/build/pipeline.js +170 -0
- package/dist/spec/build/pipeline.js.map +1 -0
- package/dist/spec/build/scan.d.ts +48 -0
- package/dist/spec/build/scan.d.ts.map +1 -0
- package/dist/spec/build/scan.js +89 -0
- package/dist/spec/build/scan.js.map +1 -0
- package/dist/spec/build/scope-resolver.d.ts +50 -0
- package/dist/spec/build/scope-resolver.d.ts.map +1 -0
- package/dist/spec/build/scope-resolver.js +105 -0
- package/dist/spec/build/scope-resolver.js.map +1 -0
- package/dist/spec/build/spec-extractor.d.ts +74 -0
- package/dist/spec/build/spec-extractor.d.ts.map +1 -0
- package/dist/spec/build/spec-extractor.js +344 -0
- package/dist/spec/build/spec-extractor.js.map +1 -0
- package/dist/spec/config.d.ts +35 -1
- package/dist/spec/config.d.ts.map +1 -1
- package/dist/spec/config.js +30 -5
- package/dist/spec/config.js.map +1 -1
- package/dist/spec/db/commit-node.js +4 -4
- package/dist/spec/db/fragment-node.js +10 -10
- package/dist/spec/db/fts.d.ts.map +1 -1
- package/dist/spec/db/fts.js +27 -58
- package/dist/spec/db/fts.js.map +1 -1
- package/dist/spec/db/index.d.ts +5 -3
- package/dist/spec/db/index.d.ts.map +1 -1
- package/dist/spec/db/index.js +16 -1
- package/dist/spec/db/index.js.map +1 -1
- package/dist/spec/db/persist.d.ts +45 -0
- package/dist/spec/db/persist.d.ts.map +1 -0
- package/dist/spec/db/persist.js +66 -0
- package/dist/spec/db/persist.js.map +1 -0
- package/dist/spec/db/relations.d.ts +80 -1
- package/dist/spec/db/relations.d.ts.map +1 -1
- package/dist/spec/db/relations.js +218 -47
- package/dist/spec/db/relations.js.map +1 -1
- package/dist/spec/db/schema.d.ts +4 -0
- package/dist/spec/db/schema.d.ts.map +1 -1
- package/dist/spec/db/schema.js +10 -6
- package/dist/spec/db/schema.js.map +1 -1
- package/dist/spec/db/schema.sql +121 -117
- package/dist/spec/db/spec-node.d.ts +5 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -1
- package/dist/spec/db/spec-node.js +15 -9
- package/dist/spec/db/spec-node.js.map +1 -1
- package/dist/spec/db/sql-utils.d.ts +11 -0
- package/dist/spec/db/sql-utils.d.ts.map +1 -0
- package/dist/spec/db/sql-utils.js +19 -0
- package/dist/spec/db/sql-utils.js.map +1 -0
- package/dist/spec/evolve/cluster-context.d.ts +30 -0
- package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
- package/dist/spec/evolve/cluster-context.js +78 -0
- package/dist/spec/evolve/cluster-context.js.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
- package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.js +93 -0
- package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +23 -7
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
- package/dist/spec/evolve/impact-locator.js +58 -14
- package/dist/spec/evolve/impact-locator.js.map +1 -1
- package/dist/spec/evolve/pipeline.d.ts +62 -25
- package/dist/spec/evolve/pipeline.d.ts.map +1 -1
- package/dist/spec/evolve/pipeline.js +436 -457
- package/dist/spec/evolve/pipeline.js.map +1 -1
- package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
- package/dist/spec/evolve/spec-rewriter.js +45 -45
- package/dist/spec/evolve/spec-rewriter.js.map +1 -1
- package/dist/spec/git/commits.d.ts +85 -0
- package/dist/spec/git/commits.d.ts.map +1 -0
- package/dist/spec/git/commits.js +218 -0
- package/dist/spec/git/commits.js.map +1 -0
- package/dist/spec/git/exec.d.ts +13 -0
- package/dist/spec/git/exec.d.ts.map +1 -0
- package/dist/spec/git/exec.js +19 -0
- package/dist/spec/git/exec.js.map +1 -0
- package/dist/spec/git/index.d.ts +9 -0
- package/dist/spec/git/index.d.ts.map +1 -0
- package/dist/spec/git/index.js +22 -0
- package/dist/spec/git/index.js.map +1 -0
- package/dist/spec/graph/index.d.ts +8 -0
- package/dist/spec/graph/index.d.ts.map +1 -0
- package/dist/spec/graph/index.js +17 -0
- package/dist/spec/graph/index.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +6 -35
- package/dist/spec/graph/queries.d.ts.map +1 -1
- package/dist/spec/graph/queries.js +71 -248
- package/dist/spec/graph/queries.js.map +1 -1
- package/dist/spec/llm/agent-client.d.ts +59 -0
- package/dist/spec/llm/agent-client.d.ts.map +1 -0
- package/dist/spec/llm/agent-client.js +213 -0
- package/dist/spec/llm/agent-client.js.map +1 -0
- package/dist/spec/llm/agents/claude-code.d.ts +32 -0
- package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/claude-code.js +125 -0
- package/dist/spec/llm/agents/claude-code.js.map +1 -0
- package/dist/spec/llm/agents/codex.d.ts +32 -0
- package/dist/spec/llm/agents/codex.d.ts.map +1 -0
- package/dist/spec/llm/agents/codex.js +145 -0
- package/dist/spec/llm/agents/codex.js.map +1 -0
- package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
- package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
- package/dist/spec/llm/agents/detect-utils.js +91 -0
- package/dist/spec/llm/agents/detect-utils.js.map +1 -0
- package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
- package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/deveco-code.js +165 -0
- package/dist/spec/llm/agents/deveco-code.js.map +1 -0
- package/dist/spec/llm/agents/index.d.ts +31 -0
- package/dist/spec/llm/agents/index.d.ts.map +1 -0
- package/dist/spec/llm/agents/index.js +65 -0
- package/dist/spec/llm/agents/index.js.map +1 -0
- package/dist/spec/llm/agents/types.d.ts +76 -0
- package/dist/spec/llm/agents/types.d.ts.map +1 -0
- package/dist/spec/llm/agents/types.js +15 -0
- package/dist/spec/llm/agents/types.js.map +1 -0
- package/dist/spec/llm/client.d.ts +31 -11
- package/dist/spec/llm/client.d.ts.map +1 -1
- package/dist/spec/llm/client.js +143 -81
- package/dist/spec/llm/client.js.map +1 -1
- package/dist/spec/llm/factory.d.ts +41 -0
- package/dist/spec/llm/factory.d.ts.map +1 -0
- package/dist/spec/llm/factory.js +80 -0
- package/dist/spec/llm/factory.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +24 -8
- package/dist/spec/llm/prompts.d.ts.map +1 -1
- package/dist/spec/llm/prompts.js +112 -62
- package/dist/spec/llm/prompts.js.map +1 -1
- package/dist/spec/llm/retry.d.ts +53 -0
- package/dist/spec/llm/retry.d.ts.map +1 -0
- package/dist/spec/llm/retry.js +153 -0
- package/dist/spec/llm/retry.js.map +1 -0
- package/dist/spec/mine/clustering/features.d.ts +38 -0
- package/dist/spec/mine/clustering/features.d.ts.map +1 -0
- package/dist/spec/mine/clustering/features.js +108 -0
- package/dist/spec/mine/clustering/features.js.map +1 -0
- package/dist/spec/mine/clustering/index.d.ts +62 -0
- package/dist/spec/mine/clustering/index.d.ts.map +1 -0
- package/dist/spec/mine/clustering/index.js +259 -0
- package/dist/spec/mine/clustering/index.js.map +1 -0
- package/dist/spec/mine/clustering/leiden.d.ts +61 -0
- package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
- package/dist/spec/mine/clustering/leiden.js +489 -0
- package/dist/spec/mine/clustering/leiden.js.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.js +98 -0
- package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
- package/dist/spec/mine/generator.d.ts +54 -0
- package/dist/spec/mine/generator.d.ts.map +1 -0
- package/dist/spec/mine/generator.js +267 -0
- package/dist/spec/mine/generator.js.map +1 -0
- package/dist/spec/mine/persist.d.ts +37 -0
- package/dist/spec/mine/persist.d.ts.map +1 -0
- package/dist/spec/mine/persist.js +170 -0
- package/dist/spec/mine/persist.js.map +1 -0
- package/dist/spec/mine/pipeline.d.ts +41 -0
- package/dist/spec/mine/pipeline.d.ts.map +1 -0
- package/dist/spec/mine/pipeline.js +236 -0
- package/dist/spec/mine/pipeline.js.map +1 -0
- package/dist/spec/mine/scanner.d.ts +59 -0
- package/dist/spec/mine/scanner.d.ts.map +1 -0
- package/dist/spec/mine/scanner.js +383 -0
- package/dist/spec/mine/scanner.js.map +1 -0
- package/dist/spec/types.d.ts +32 -0
- package/dist/spec/types.d.ts.map +1 -1
- package/dist/spec/ui/index.d.ts +9 -0
- package/dist/spec/ui/index.d.ts.map +1 -0
- package/dist/spec/ui/index.js +16 -0
- package/dist/spec/ui/index.js.map +1 -0
- package/dist/spec/ui/progress-handler.d.ts +33 -0
- package/dist/spec/ui/progress-handler.d.ts.map +1 -0
- package/dist/spec/ui/progress-handler.js +132 -0
- package/dist/spec/ui/progress-handler.js.map +1 -0
- package/dist/spec/ui/progress.d.ts +24 -0
- package/dist/spec/ui/progress.d.ts.map +1 -0
- package/dist/spec/ui/progress.js +13 -0
- package/dist/spec/ui/progress.js.map +1 -0
- package/dist/spec/utils/fs.d.ts +45 -0
- package/dist/spec/utils/fs.d.ts.map +1 -0
- package/dist/spec/utils/fs.js +163 -0
- package/dist/spec/utils/fs.js.map +1 -0
- package/dist/spec/utils/index.d.ts +12 -0
- package/dist/spec/utils/index.d.ts.map +1 -0
- package/dist/spec/utils/index.js +26 -0
- package/dist/spec/utils/index.js.map +1 -0
- package/dist/spec/utils/meta.d.ts +32 -0
- package/dist/spec/utils/meta.d.ts.map +1 -0
- package/dist/spec/utils/meta.js +122 -0
- package/dist/spec/utils/meta.js.map +1 -0
- package/dist/spec/utils/truncate.d.ts +86 -0
- package/dist/spec/utils/truncate.d.ts.map +1 -0
- package/dist/spec/utils/truncate.js +172 -0
- package/dist/spec/utils/truncate.js.map +1 -0
- package/dist/sync/watcher.d.ts +25 -1
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +76 -3
- package/dist/sync/watcher.js.map +1 -1
- package/dist/telemetry/index.js +3 -3
- package/dist/telemetry/index.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +62 -58
- package/scripts/_tmp-cfwk-resolve.log +0 -0
- package/scripts/_tmp-cfwk-sig.log +0 -0
- package/scripts/_tmp-cfwk-vt.log +0 -0
- package/scripts/add-lang/bench.sh +60 -60
- package/scripts/add-lang/check-grammar.mjs +75 -75
- package/scripts/add-lang/dump-ast.mjs +103 -103
- package/scripts/add-lang/verify-extraction.mjs +70 -70
- package/scripts/agent-eval/ab-adoption.sh +91 -91
- package/scripts/agent-eval/ab-hook.sh +86 -86
- package/scripts/agent-eval/ab-impl.sh +78 -78
- package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
- package/scripts/agent-eval/ab-sufficiency.sh +78 -78
- package/scripts/agent-eval/arms-F.sh +21 -21
- package/scripts/agent-eval/arms-matrix.sh +37 -37
- package/scripts/agent-eval/audit.sh +68 -68
- package/scripts/agent-eval/bench-readme.sh +28 -28
- package/scripts/agent-eval/bench-why-repo.sh +22 -22
- package/scripts/agent-eval/block-read-hook.sh +19 -19
- package/scripts/agent-eval/hook-settings.json +15 -15
- package/scripts/agent-eval/itrun.sh +120 -120
- package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
- package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
- package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
- package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
- package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
- package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
- package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
- package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
- package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
- package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
- package/scripts/agent-eval/offload-eval-setup.sh +24 -24
- package/scripts/agent-eval/offload-eval-styles.sh +71 -71
- package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
- package/scripts/agent-eval/offload-eval.md +76 -76
- package/scripts/agent-eval/parse-arms.mjs +116 -116
- package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
- package/scripts/agent-eval/parse-run.mjs +45 -45
- package/scripts/agent-eval/parse-session.mjs +93 -93
- package/scripts/agent-eval/probe-context.mjs +21 -21
- package/scripts/agent-eval/probe-explore.mjs +40 -40
- package/scripts/agent-eval/probe-node.mjs +20 -20
- package/scripts/agent-eval/probe-sweep.mjs +119 -119
- package/scripts/agent-eval/probe-trace.mjs +20 -20
- package/scripts/agent-eval/redirect-read-hook.sh +38 -38
- package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -119
- package/scripts/agent-eval/repro-daemon-clients.mjs +125 -125
- package/scripts/agent-eval/run-agent.sh +34 -34
- package/scripts/agent-eval/run-all.sh +75 -75
- package/scripts/agent-eval/run-arms.sh +56 -56
- package/scripts/agent-eval/seq-matrix.mjs +137 -137
- package/scripts/bench-arkts-init-rss.log +0 -0
- package/scripts/build-bundle.sh +123 -123
- package/scripts/exp_boundary_eval/README.md +247 -247
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -78
- package/scripts/exp_boundary_eval/_test_stdin.py +8 -8
- package/scripts/exp_boundary_eval/_utils.py +1116 -1116
- package/scripts/exp_boundary_eval/analyze.py +1313 -1313
- package/scripts/exp_boundary_eval/deveco_arm.py +519 -519
- package/scripts/exp_boundary_eval/run_all.py +378 -378
- package/scripts/exp_boundary_eval/run_one.py +165 -165
- package/scripts/exp_boundary_eval/run_session.py +158 -158
- package/scripts/exp_boundary_eval/setup.py +120 -120
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -73
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -36
- package/scripts/exp_boundary_eval/win_node_launcher.py +24 -24
- package/scripts/extract-release-notes.mjs +130 -130
- package/scripts/local-install.sh +41 -41
- package/scripts/npm-sdk.js +75 -75
- package/scripts/npm-shim.js +275 -275
- package/scripts/ohos-sdk-publish.mjs +133 -133
- package/scripts/pack-npm.sh +119 -119
- package/scripts/prepare-release.mjs +270 -270
- package/scripts/probe-arkts-mem-why-run.log +0 -0
- package/scripts/probe-banner-livecard-ir.log +0 -0
- package/scripts/probe-cfwk-ast.stderr.log +0 -0
- package/scripts/probe-cfwk-ast.stdout.log +0 -0
- package/scripts/probe-cfwk-attr-shape.log +0 -0
- package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
- package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
- package/scripts/probe-cfwk-cvc.stderr.log +0 -0
- package/scripts/probe-cfwk-cvc.stdout.log +0 -0
- package/scripts/probe-cfwk-diag2.log +0 -0
- package/scripts/probe-cfwk-diag3.log +0 -0
- package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
- package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
- package/scripts/probe-cfwk-fileresult.log +0 -0
- package/scripts/probe-cfwk-fix.stderr.log +0 -0
- package/scripts/probe-cfwk-fix.stdout.log +0 -0
- package/scripts/probe-cfwk-fix2.stderr.log +0 -0
- package/scripts/probe-cfwk-fix2.stdout.log +0 -0
- package/scripts/probe-cfwk-fix3.stderr.log +0 -0
- package/scripts/probe-cfwk-fix3.stdout.log +0 -0
- package/scripts/probe-cfwk-foreach.log +0 -0
- package/scripts/probe-cfwk-getmethod-throw.log +0 -0
- package/scripts/probe-cfwk-hg-extract.log +0 -0
- package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
- package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
- package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
- package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
- package/scripts/probe-cfwk-resolve-sim.log +0 -0
- package/scripts/probe-cfwk-tree-shape.log +0 -0
- package/scripts/probe-cfwk-walk-abort.log +0 -0
- package/scripts/probe-cfwk.log +0 -0
- package/scripts/probe-force-index.log +0 -0
- package/scripts/probe-no-force-index.log +0 -0
- package/scripts/probe-samefile-ir.stderr.log +0 -0
- package/scripts/probe-samefile-ir.stdout.log +224 -0
- package/scripts/probe-sdk-vs-project.log +0 -0
- package/scripts/probe-viewtree-downgrade.log +0 -0
- package/dist/arkts/ohos-api-index.d.ts +0 -15
- package/dist/arkts/ohos-api-index.d.ts.map +0 -1
- package/dist/arkts/ohos-api-index.js +0 -190
- package/dist/arkts/ohos-api-index.js.map +0 -1
- package/dist/arkts/ohos-sdk-input.d.ts +0 -36
- package/dist/arkts/ohos-sdk-input.d.ts.map +0 -1
- package/dist/arkts/ohos-sdk-input.js +0 -214
- package/dist/arkts/ohos-sdk-input.js.map +0 -1
- package/dist/extraction/languages/arkts-state-decorators.d.ts +0 -13
- package/dist/extraction/languages/arkts-state-decorators.d.ts.map +0 -1
- package/dist/extraction/languages/arkts-state-decorators.js +0 -26
- package/dist/extraction/languages/arkts-state-decorators.js.map +0 -1
- package/dist/extraction/languages/ohos-api-consumer.d.ts +0 -34
- package/dist/extraction/languages/ohos-api-consumer.d.ts.map +0 -1
- package/dist/extraction/languages/ohos-api-consumer.js +0 -283
- package/dist/extraction/languages/ohos-api-consumer.js.map +0 -1
package/dist/db/queries.js
CHANGED
|
@@ -154,9 +154,54 @@ class QueryBuilder {
|
|
|
154
154
|
ohosApiDbPath = null;
|
|
155
155
|
// Prepared statements (lazily initialized)
|
|
156
156
|
stmts = {};
|
|
157
|
+
// Multi-row INSERT statements, cached per (statement kind × row count).
|
|
158
|
+
batchStmts = new Map();
|
|
159
|
+
static BATCH_SIZES = [128, 32, 8, 1];
|
|
160
|
+
/**
|
|
161
|
+
* Run `rows` through a multi-row `INSERT` built as `head + (tuple,)*n`,
|
|
162
|
+
* decomposed greedily into the cached batch sizes. Preserves row order.
|
|
163
|
+
*/
|
|
164
|
+
runBatched(kind, head, tuple, rows) {
|
|
165
|
+
if (rows.length === 0)
|
|
166
|
+
return;
|
|
167
|
+
let i = 0;
|
|
168
|
+
for (const size of QueryBuilder.BATCH_SIZES) {
|
|
169
|
+
while (rows.length - i >= size) {
|
|
170
|
+
const key = `${kind}:${size}`;
|
|
171
|
+
let stmt = this.batchStmts.get(key);
|
|
172
|
+
if (!stmt) {
|
|
173
|
+
stmt = this.db.prepare(head + new Array(size).fill(tuple).join(','));
|
|
174
|
+
this.batchStmts.set(key, stmt);
|
|
175
|
+
}
|
|
176
|
+
if (size === 1) {
|
|
177
|
+
stmt.run(...rows[i]);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const params = [];
|
|
181
|
+
for (let r = 0; r < size; r++) {
|
|
182
|
+
const row = rows[i + r];
|
|
183
|
+
for (let c = 0; c < row.length; c++)
|
|
184
|
+
params.push(row[c]);
|
|
185
|
+
}
|
|
186
|
+
stmt.run(...params);
|
|
187
|
+
}
|
|
188
|
+
i += size;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
157
192
|
constructor(db) {
|
|
158
193
|
this.db = db;
|
|
159
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Swap the underlying connection in place. Used by pool workers'
|
|
197
|
+
* connection recycling: a long-lived read connection pins WAL checkpoint
|
|
198
|
+
* progress; workers close and reopen at the pool-idle boundary.
|
|
199
|
+
*/
|
|
200
|
+
rebind(db) {
|
|
201
|
+
this.db = db;
|
|
202
|
+
this.stmts = {};
|
|
203
|
+
this.batchStmts.clear();
|
|
204
|
+
}
|
|
160
205
|
/** Attach a versioned OHOS API db for federated symbol lookup. */
|
|
161
206
|
attachOhosApiDb(dbPath) {
|
|
162
207
|
if (dbPath === this.ohosApiDbPath)
|
|
@@ -210,20 +255,20 @@ class QueryBuilder {
|
|
|
210
255
|
*/
|
|
211
256
|
insertNode(node) {
|
|
212
257
|
if (!this.stmts.insertNode) {
|
|
213
|
-
this.stmts.insertNode = this.db.prepare(`
|
|
214
|
-
INSERT OR REPLACE INTO nodes (
|
|
215
|
-
id, kind, name, qualified_name, file_path, language,
|
|
216
|
-
start_line, end_line, start_column, end_column,
|
|
217
|
-
docstring, signature, visibility,
|
|
218
|
-
is_exported, is_async, is_static, is_abstract,
|
|
219
|
-
decorators, type_parameters, return_type, updated_at
|
|
220
|
-
) VALUES (
|
|
221
|
-
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
222
|
-
@startLine, @endLine, @startColumn, @endColumn,
|
|
223
|
-
@docstring, @signature, @visibility,
|
|
224
|
-
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
225
|
-
@decorators, @typeParameters, @returnType, @updatedAt
|
|
226
|
-
)
|
|
258
|
+
this.stmts.insertNode = this.db.prepare(`
|
|
259
|
+
INSERT OR REPLACE INTO nodes (
|
|
260
|
+
id, kind, name, qualified_name, file_path, language,
|
|
261
|
+
start_line, end_line, start_column, end_column,
|
|
262
|
+
docstring, signature, visibility,
|
|
263
|
+
is_exported, is_async, is_static, is_abstract,
|
|
264
|
+
decorators, type_parameters, return_type, updated_at
|
|
265
|
+
) VALUES (
|
|
266
|
+
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
267
|
+
@startLine, @endLine, @startColumn, @endColumn,
|
|
268
|
+
@docstring, @signature, @visibility,
|
|
269
|
+
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
270
|
+
@decorators, @typeParameters, @returnType, @updatedAt
|
|
271
|
+
)
|
|
227
272
|
`);
|
|
228
273
|
}
|
|
229
274
|
// Validate required fields to prevent SQLite bind errors
|
|
@@ -280,34 +325,68 @@ class QueryBuilder {
|
|
|
280
325
|
}
|
|
281
326
|
})();
|
|
282
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Store one file's whole extraction bundle — nodes, edges, unresolved refs,
|
|
330
|
+
* and the file record — in a SINGLE transaction. The bulk-index path calls
|
|
331
|
+
* this once per file instead of opening one transaction per table (#1015
|
|
332
|
+
* file-order commit discipline is unchanged: callers still invoke it in file
|
|
333
|
+
* order, and row order within is input order).
|
|
334
|
+
*
|
|
335
|
+
* Edges MUST already be endpoint-filtered by the caller (the store path
|
|
336
|
+
* filters to the file's own inserted node ids), so the per-file existence
|
|
337
|
+
* SELECT that insertEdges() pays is skipped here.
|
|
338
|
+
*/
|
|
339
|
+
storeFileBundle(bundle) {
|
|
340
|
+
this.db.transaction(() => {
|
|
341
|
+
this.insertNodes(bundle.nodes);
|
|
342
|
+
if (bundle.edges.length > 0) {
|
|
343
|
+
const rows = [];
|
|
344
|
+
for (const edge of bundle.edges) {
|
|
345
|
+
rows.push([
|
|
346
|
+
edge.source,
|
|
347
|
+
edge.target,
|
|
348
|
+
edge.kind,
|
|
349
|
+
edge.metadata ? JSON.stringify(edge.metadata) : null,
|
|
350
|
+
edge.line ?? null,
|
|
351
|
+
edge.column ?? null,
|
|
352
|
+
edge.provenance ?? null,
|
|
353
|
+
]);
|
|
354
|
+
}
|
|
355
|
+
this.runBatched('insertEdges', 'INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance) VALUES ', '(?,?,?,?,?,?,?)', rows);
|
|
356
|
+
}
|
|
357
|
+
if (bundle.refs.length > 0)
|
|
358
|
+
this.insertUnresolvedRefsBatch(bundle.refs);
|
|
359
|
+
this.upsertFile(bundle.file);
|
|
360
|
+
})();
|
|
361
|
+
}
|
|
283
362
|
/**
|
|
284
363
|
* Update an existing node
|
|
285
364
|
*/
|
|
286
365
|
updateNode(node) {
|
|
287
366
|
if (!this.stmts.updateNode) {
|
|
288
|
-
this.stmts.updateNode = this.db.prepare(`
|
|
289
|
-
UPDATE nodes SET
|
|
290
|
-
kind = @kind,
|
|
291
|
-
name = @name,
|
|
292
|
-
qualified_name = @qualifiedName,
|
|
293
|
-
file_path = @filePath,
|
|
294
|
-
language = @language,
|
|
295
|
-
start_line = @startLine,
|
|
296
|
-
end_line = @endLine,
|
|
297
|
-
start_column = @startColumn,
|
|
298
|
-
end_column = @endColumn,
|
|
299
|
-
docstring = @docstring,
|
|
300
|
-
signature = @signature,
|
|
301
|
-
visibility = @visibility,
|
|
302
|
-
is_exported = @isExported,
|
|
303
|
-
is_async = @isAsync,
|
|
304
|
-
is_static = @isStatic,
|
|
305
|
-
is_abstract = @isAbstract,
|
|
306
|
-
decorators = @decorators,
|
|
307
|
-
type_parameters = @typeParameters,
|
|
308
|
-
return_type = @returnType,
|
|
309
|
-
updated_at = @updatedAt
|
|
310
|
-
WHERE id = @id
|
|
367
|
+
this.stmts.updateNode = this.db.prepare(`
|
|
368
|
+
UPDATE nodes SET
|
|
369
|
+
kind = @kind,
|
|
370
|
+
name = @name,
|
|
371
|
+
qualified_name = @qualifiedName,
|
|
372
|
+
file_path = @filePath,
|
|
373
|
+
language = @language,
|
|
374
|
+
start_line = @startLine,
|
|
375
|
+
end_line = @endLine,
|
|
376
|
+
start_column = @startColumn,
|
|
377
|
+
end_column = @endColumn,
|
|
378
|
+
docstring = @docstring,
|
|
379
|
+
signature = @signature,
|
|
380
|
+
visibility = @visibility,
|
|
381
|
+
is_exported = @isExported,
|
|
382
|
+
is_async = @isAsync,
|
|
383
|
+
is_static = @isStatic,
|
|
384
|
+
is_abstract = @isAbstract,
|
|
385
|
+
decorators = @decorators,
|
|
386
|
+
type_parameters = @typeParameters,
|
|
387
|
+
return_type = @returnType,
|
|
388
|
+
updated_at = @updatedAt
|
|
389
|
+
WHERE id = @id
|
|
311
390
|
`);
|
|
312
391
|
}
|
|
313
392
|
// Invalidate cache before update
|
|
@@ -439,12 +518,12 @@ class QueryBuilder {
|
|
|
439
518
|
const placeholders = variants.map(() => '?').join(', ');
|
|
440
519
|
const whens = variants.map(() => 'WHEN ? THEN ?').join(' ');
|
|
441
520
|
const rows = this.db
|
|
442
|
-
.prepare(`SELECT name, COUNT(DISTINCT CASE segment ${whens} END) AS matches
|
|
443
|
-
FROM name_segment_vocab
|
|
444
|
-
WHERE segment IN (${placeholders})
|
|
445
|
-
GROUP BY name
|
|
446
|
-
HAVING matches >= ?
|
|
447
|
-
ORDER BY matches DESC, length(name) ASC
|
|
521
|
+
.prepare(`SELECT name, COUNT(DISTINCT CASE segment ${whens} END) AS matches
|
|
522
|
+
FROM name_segment_vocab
|
|
523
|
+
WHERE segment IN (${placeholders})
|
|
524
|
+
GROUP BY name
|
|
525
|
+
HAVING matches >= ?
|
|
526
|
+
ORDER BY matches DESC, length(name) ASC
|
|
448
527
|
LIMIT ?`)
|
|
449
528
|
.all(...variants.flatMap((v) => [v.segment, v.word]), ...variants.map((v) => v.segment), minWords, limit);
|
|
450
529
|
return rows;
|
|
@@ -456,7 +535,7 @@ class QueryBuilder {
|
|
|
456
535
|
return new Map();
|
|
457
536
|
const placeholders = segments.map(() => '?').join(', ');
|
|
458
537
|
const rows = this.db
|
|
459
|
-
.prepare(`SELECT segment, COUNT(*) AS n FROM name_segment_vocab
|
|
538
|
+
.prepare(`SELECT segment, COUNT(*) AS n FROM name_segment_vocab
|
|
460
539
|
WHERE segment IN (${placeholders}) GROUP BY segment`)
|
|
461
540
|
.all(...segments);
|
|
462
541
|
return new Map(rows.map((r) => [r.segment, r.n]));
|
|
@@ -616,15 +695,15 @@ class QueryBuilder {
|
|
|
616
695
|
// protobuf stub) outranks the real `server/etcdserver/server.go`
|
|
617
696
|
// (470 edges) by 4×, and the boost would push the agent toward
|
|
618
697
|
// generated code.
|
|
619
|
-
this.stmts.getDominantFile = this.db.prepare(`
|
|
620
|
-
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
621
|
-
FROM edges e
|
|
622
|
-
JOIN nodes n ON e.source = n.id
|
|
623
|
-
JOIN nodes m ON e.target = m.id
|
|
624
|
-
WHERE n.file_path = m.file_path
|
|
625
|
-
GROUP BY n.file_path
|
|
626
|
-
ORDER BY edge_count DESC
|
|
627
|
-
LIMIT 20
|
|
698
|
+
this.stmts.getDominantFile = this.db.prepare(`
|
|
699
|
+
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
700
|
+
FROM edges e
|
|
701
|
+
JOIN nodes n ON e.source = n.id
|
|
702
|
+
JOIN nodes m ON e.target = m.id
|
|
703
|
+
WHERE n.file_path = m.file_path
|
|
704
|
+
GROUP BY n.file_path
|
|
705
|
+
ORDER BY edge_count DESC
|
|
706
|
+
LIMIT 20
|
|
628
707
|
`);
|
|
629
708
|
}
|
|
630
709
|
const rows = this.stmts.getDominantFile.all();
|
|
@@ -651,13 +730,13 @@ class QueryBuilder {
|
|
|
651
730
|
*/
|
|
652
731
|
getTopRouteFile() {
|
|
653
732
|
if (!this.stmts.getTopRouteFile) {
|
|
654
|
-
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
655
|
-
SELECT file_path, COUNT(*) AS cnt
|
|
656
|
-
FROM nodes
|
|
657
|
-
WHERE kind = 'route'
|
|
658
|
-
GROUP BY file_path
|
|
659
|
-
ORDER BY cnt DESC
|
|
660
|
-
LIMIT 20
|
|
733
|
+
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
734
|
+
SELECT file_path, COUNT(*) AS cnt
|
|
735
|
+
FROM nodes
|
|
736
|
+
WHERE kind = 'route'
|
|
737
|
+
GROUP BY file_path
|
|
738
|
+
ORDER BY cnt DESC
|
|
739
|
+
LIMIT 20
|
|
661
740
|
`);
|
|
662
741
|
}
|
|
663
742
|
const rows = this.stmts.getTopRouteFile.all();
|
|
@@ -688,21 +767,21 @@ class QueryBuilder {
|
|
|
688
767
|
// Edge kind varies across framework resolvers: Spring/Rails/
|
|
689
768
|
// Laravel/Drupal emit `references`, Express emits `calls`. Accept
|
|
690
769
|
// both — the semantic is the same (route → its handler).
|
|
691
|
-
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
692
|
-
SELECT
|
|
693
|
-
r.name AS url,
|
|
694
|
-
h.name AS handler,
|
|
695
|
-
h.file_path AS handler_file,
|
|
696
|
-
h.start_line AS handler_line,
|
|
697
|
-
h.kind AS handler_kind
|
|
698
|
-
FROM nodes r
|
|
699
|
-
JOIN edges e ON e.source = r.id
|
|
700
|
-
JOIN nodes h ON e.target = h.id
|
|
701
|
-
WHERE r.kind = 'route'
|
|
702
|
-
AND e.kind IN ('references', 'calls')
|
|
703
|
-
AND h.kind IN ('function', 'method', 'class')
|
|
704
|
-
ORDER BY r.file_path, r.start_line
|
|
705
|
-
LIMIT ?
|
|
770
|
+
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
771
|
+
SELECT
|
|
772
|
+
r.name AS url,
|
|
773
|
+
h.name AS handler,
|
|
774
|
+
h.file_path AS handler_file,
|
|
775
|
+
h.start_line AS handler_line,
|
|
776
|
+
h.kind AS handler_kind
|
|
777
|
+
FROM nodes r
|
|
778
|
+
JOIN edges e ON e.source = r.id
|
|
779
|
+
JOIN nodes h ON e.target = h.id
|
|
780
|
+
WHERE r.kind = 'route'
|
|
781
|
+
AND e.kind IN ('references', 'calls')
|
|
782
|
+
AND h.kind IN ('function', 'method', 'class')
|
|
783
|
+
ORDER BY r.file_path, r.start_line
|
|
784
|
+
LIMIT ?
|
|
706
785
|
`);
|
|
707
786
|
}
|
|
708
787
|
const rows = this.stmts.getRoutingManifest.all(limit);
|
|
@@ -957,10 +1036,10 @@ class QueryBuilder {
|
|
|
957
1036
|
const seen = new Set(existing.map((r) => r.node.id));
|
|
958
1037
|
const merged = [...existing];
|
|
959
1038
|
const apiLimit = Math.min(20, Math.max(5, Math.floor(limit / 4)));
|
|
960
|
-
let sql = `
|
|
961
|
-
SELECT nodes.*, 0.9 as score
|
|
962
|
-
FROM ohos_api.nodes
|
|
963
|
-
WHERE (name LIKE ? OR qualified_name LIKE ?)
|
|
1039
|
+
let sql = `
|
|
1040
|
+
SELECT nodes.*, 0.9 as score
|
|
1041
|
+
FROM ohos_api.nodes
|
|
1042
|
+
WHERE (name LIKE ? OR qualified_name LIKE ?)
|
|
964
1043
|
`;
|
|
965
1044
|
const pattern = `%${text}%`;
|
|
966
1045
|
const params = [pattern, pattern];
|
|
@@ -1099,11 +1178,11 @@ class QueryBuilder {
|
|
|
1099
1178
|
// Fetch 5x requested limit so post-hoc rescoring (kindBonus, pathRelevance,
|
|
1100
1179
|
// nameMatchBonus) can promote results that BM25 alone undervalues.
|
|
1101
1180
|
const ftsLimit = Math.max(limit * 5, 100);
|
|
1102
|
-
let sql = `
|
|
1103
|
-
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
1104
|
-
FROM nodes_fts
|
|
1105
|
-
JOIN nodes ON nodes_fts.id = nodes.id
|
|
1106
|
-
WHERE nodes_fts MATCH ?
|
|
1181
|
+
let sql = `
|
|
1182
|
+
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
1183
|
+
FROM nodes_fts
|
|
1184
|
+
JOIN nodes ON nodes_fts.id = nodes.id
|
|
1185
|
+
WHERE nodes_fts MATCH ?
|
|
1107
1186
|
`;
|
|
1108
1187
|
const params = [ftsQuery];
|
|
1109
1188
|
if (kinds && kinds.length > 0) {
|
|
@@ -1134,21 +1213,21 @@ class QueryBuilder {
|
|
|
1134
1213
|
*/
|
|
1135
1214
|
searchNodesLike(query, options) {
|
|
1136
1215
|
const { kinds, languages, limit = 100, offset = 0 } = options;
|
|
1137
|
-
let sql = `
|
|
1138
|
-
SELECT nodes.*,
|
|
1139
|
-
CASE
|
|
1140
|
-
WHEN name = ? THEN 1.0
|
|
1141
|
-
WHEN name LIKE ? THEN 0.9
|
|
1142
|
-
WHEN name LIKE ? THEN 0.8
|
|
1143
|
-
WHEN qualified_name LIKE ? THEN 0.7
|
|
1144
|
-
ELSE 0.5
|
|
1145
|
-
END as score
|
|
1146
|
-
FROM nodes
|
|
1147
|
-
WHERE (
|
|
1148
|
-
name LIKE ? OR
|
|
1149
|
-
qualified_name LIKE ? OR
|
|
1150
|
-
name LIKE ?
|
|
1151
|
-
)
|
|
1216
|
+
let sql = `
|
|
1217
|
+
SELECT nodes.*,
|
|
1218
|
+
CASE
|
|
1219
|
+
WHEN name = ? THEN 1.0
|
|
1220
|
+
WHEN name LIKE ? THEN 0.9
|
|
1221
|
+
WHEN name LIKE ? THEN 0.8
|
|
1222
|
+
WHEN qualified_name LIKE ? THEN 0.7
|
|
1223
|
+
ELSE 0.5
|
|
1224
|
+
END as score
|
|
1225
|
+
FROM nodes
|
|
1226
|
+
WHERE (
|
|
1227
|
+
name LIKE ? OR
|
|
1228
|
+
qualified_name LIKE ? OR
|
|
1229
|
+
name LIKE ?
|
|
1230
|
+
)
|
|
1152
1231
|
`;
|
|
1153
1232
|
// Pattern variants for better matching
|
|
1154
1233
|
const exactMatch = query;
|
|
@@ -1222,10 +1301,10 @@ class QueryBuilder {
|
|
|
1222
1301
|
const allResults = [];
|
|
1223
1302
|
const seenIds = new Set();
|
|
1224
1303
|
for (const name of names) {
|
|
1225
|
-
let sql = `
|
|
1226
|
-
SELECT nodes.*, 1.0 as score
|
|
1227
|
-
FROM nodes
|
|
1228
|
-
WHERE name COLLATE NOCASE = ?
|
|
1304
|
+
let sql = `
|
|
1305
|
+
SELECT nodes.*, 1.0 as score
|
|
1306
|
+
FROM nodes
|
|
1307
|
+
WHERE name COLLATE NOCASE = ?
|
|
1229
1308
|
`;
|
|
1230
1309
|
const params = [name];
|
|
1231
1310
|
if (kinds && kinds.length > 0) {
|
|
@@ -1256,10 +1335,10 @@ class QueryBuilder {
|
|
|
1256
1335
|
allResults.push(r);
|
|
1257
1336
|
}
|
|
1258
1337
|
if (this.hasOhosApiAttached()) {
|
|
1259
|
-
let apiSql = `
|
|
1260
|
-
SELECT nodes.*, 0.95 as score
|
|
1261
|
-
FROM ohos_api.nodes
|
|
1262
|
-
WHERE name COLLATE NOCASE = ?
|
|
1338
|
+
let apiSql = `
|
|
1339
|
+
SELECT nodes.*, 0.95 as score
|
|
1340
|
+
FROM ohos_api.nodes
|
|
1341
|
+
WHERE name COLLATE NOCASE = ?
|
|
1263
1342
|
`;
|
|
1264
1343
|
const apiParams = [name];
|
|
1265
1344
|
if (kinds && kinds.length > 0) {
|
|
@@ -1295,10 +1374,10 @@ class QueryBuilder {
|
|
|
1295
1374
|
*/
|
|
1296
1375
|
findNodesByNameSubstring(substring, options = {}) {
|
|
1297
1376
|
const { kinds, languages, limit = 30, excludePrefix } = options;
|
|
1298
|
-
let sql = `
|
|
1299
|
-
SELECT nodes.*, 1.0 as score
|
|
1300
|
-
FROM nodes
|
|
1301
|
-
WHERE name LIKE ?
|
|
1377
|
+
let sql = `
|
|
1378
|
+
SELECT nodes.*, 1.0 as score
|
|
1379
|
+
FROM nodes
|
|
1380
|
+
WHERE name LIKE ?
|
|
1302
1381
|
`;
|
|
1303
1382
|
const params = [`%${substring}%`];
|
|
1304
1383
|
// Exclude prefix matches (handled by FTS-based prefix search in Step 2b)
|
|
@@ -1330,9 +1409,9 @@ class QueryBuilder {
|
|
|
1330
1409
|
*/
|
|
1331
1410
|
insertEdge(edge) {
|
|
1332
1411
|
if (!this.stmts.insertEdge) {
|
|
1333
|
-
this.stmts.insertEdge = this.db.prepare(`
|
|
1334
|
-
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1335
|
-
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1412
|
+
this.stmts.insertEdge = this.db.prepare(`
|
|
1413
|
+
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1414
|
+
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1336
1415
|
`);
|
|
1337
1416
|
}
|
|
1338
1417
|
this.stmts.insertEdge.run({
|
|
@@ -1459,12 +1538,12 @@ class QueryBuilder {
|
|
|
1459
1538
|
* it. One indexed query (idx_nodes_file_path + idx_edges_target_kind).
|
|
1460
1539
|
*/
|
|
1461
1540
|
getDependentFilePaths(filePath) {
|
|
1462
|
-
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1463
|
-
FROM edges e
|
|
1464
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1465
|
-
JOIN nodes src ON src.id = e.source
|
|
1466
|
-
WHERE tgt.file_path = ?
|
|
1467
|
-
AND e.kind != 'contains'
|
|
1541
|
+
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1542
|
+
FROM edges e
|
|
1543
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1544
|
+
JOIN nodes src ON src.id = e.source
|
|
1545
|
+
WHERE tgt.file_path = ?
|
|
1546
|
+
AND e.kind != 'contains'
|
|
1468
1547
|
AND src.file_path != ?`;
|
|
1469
1548
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1470
1549
|
return rows.map((r) => r.fp);
|
|
@@ -1476,12 +1555,12 @@ class QueryBuilder {
|
|
|
1476
1555
|
* (all kinds except `contains`); same reason imports-only is insufficient.
|
|
1477
1556
|
*/
|
|
1478
1557
|
getDependencyFilePaths(filePath) {
|
|
1479
|
-
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1480
|
-
FROM edges e
|
|
1481
|
-
JOIN nodes src ON src.id = e.source
|
|
1482
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1483
|
-
WHERE src.file_path = ?
|
|
1484
|
-
AND e.kind != 'contains'
|
|
1558
|
+
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1559
|
+
FROM edges e
|
|
1560
|
+
JOIN nodes src ON src.id = e.source
|
|
1561
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1562
|
+
WHERE src.file_path = ?
|
|
1563
|
+
AND e.kind != 'contains'
|
|
1485
1564
|
AND tgt.file_path != ?`;
|
|
1486
1565
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1487
1566
|
return rows.map((r) => r.fp);
|
|
@@ -1497,13 +1576,13 @@ class QueryBuilder {
|
|
|
1497
1576
|
* {@link getDependentFilePaths}: all kinds except `contains`.
|
|
1498
1577
|
*/
|
|
1499
1578
|
getCrossFileIncomingEdgesWithTarget(filePath) {
|
|
1500
|
-
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind,
|
|
1501
|
-
src.file_path AS source_file_path, src.language AS source_language
|
|
1502
|
-
FROM edges e
|
|
1503
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1504
|
-
JOIN nodes src ON src.id = e.source
|
|
1505
|
-
WHERE tgt.file_path = ?
|
|
1506
|
-
AND e.kind != 'contains'
|
|
1579
|
+
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind,
|
|
1580
|
+
src.file_path AS source_file_path, src.language AS source_language
|
|
1581
|
+
FROM edges e
|
|
1582
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1583
|
+
JOIN nodes src ON src.id = e.source
|
|
1584
|
+
WHERE tgt.file_path = ?
|
|
1585
|
+
AND e.kind != 'contains'
|
|
1507
1586
|
AND src.file_path != ?`;
|
|
1508
1587
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1509
1588
|
return rows.map(row => ({
|
|
@@ -1520,10 +1599,10 @@ class QueryBuilder {
|
|
|
1520
1599
|
*/
|
|
1521
1600
|
deleteArkTSCrossFileCallEdges() {
|
|
1522
1601
|
const result = this.db
|
|
1523
|
-
.prepare(`DELETE FROM edges
|
|
1524
|
-
WHERE kind = 'calls'
|
|
1525
|
-
AND provenance = 'heuristic'
|
|
1526
|
-
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1602
|
+
.prepare(`DELETE FROM edges
|
|
1603
|
+
WHERE kind = 'calls'
|
|
1604
|
+
AND provenance = 'heuristic'
|
|
1605
|
+
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1527
1606
|
AND metadata LIKE '%"sourceFile"%'`)
|
|
1528
1607
|
.run();
|
|
1529
1608
|
return result.changes;
|
|
@@ -1536,17 +1615,17 @@ class QueryBuilder {
|
|
|
1536
1615
|
*/
|
|
1537
1616
|
upsertFile(file) {
|
|
1538
1617
|
if (!this.stmts.upsertFile) {
|
|
1539
|
-
this.stmts.upsertFile = this.db.prepare(`
|
|
1540
|
-
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1541
|
-
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1542
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
1543
|
-
content_hash = @contentHash,
|
|
1544
|
-
language = @language,
|
|
1545
|
-
size = @size,
|
|
1546
|
-
modified_at = @modifiedAt,
|
|
1547
|
-
indexed_at = @indexedAt,
|
|
1548
|
-
node_count = @nodeCount,
|
|
1549
|
-
errors = @errors
|
|
1618
|
+
this.stmts.upsertFile = this.db.prepare(`
|
|
1619
|
+
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1620
|
+
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1621
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
1622
|
+
content_hash = @contentHash,
|
|
1623
|
+
language = @language,
|
|
1624
|
+
size = @size,
|
|
1625
|
+
modified_at = @modifiedAt,
|
|
1626
|
+
indexed_at = @indexedAt,
|
|
1627
|
+
node_count = @nodeCount,
|
|
1628
|
+
errors = @errors
|
|
1550
1629
|
`);
|
|
1551
1630
|
}
|
|
1552
1631
|
this.stmts.upsertFile.run({
|
|
@@ -1620,9 +1699,9 @@ class QueryBuilder {
|
|
|
1620
1699
|
*/
|
|
1621
1700
|
insertUnresolvedRef(ref) {
|
|
1622
1701
|
if (!this.stmts.insertUnresolved) {
|
|
1623
|
-
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1624
|
-
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1625
|
-
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1702
|
+
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1703
|
+
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1704
|
+
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1626
1705
|
`);
|
|
1627
1706
|
}
|
|
1628
1707
|
this.stmts.insertUnresolved.run({
|
|
@@ -1709,7 +1788,7 @@ class QueryBuilder {
|
|
|
1709
1788
|
*/
|
|
1710
1789
|
getUnresolvedReferencesBatch(offset, limit) {
|
|
1711
1790
|
if (!this.stmts.getUnresolvedBatch) {
|
|
1712
|
-
this.stmts.getUnresolvedBatch = this.db.prepare("SELECT * FROM unresolved_refs WHERE status = 'pending' LIMIT ? OFFSET ?");
|
|
1791
|
+
this.stmts.getUnresolvedBatch = this.db.prepare("SELECT * FROM unresolved_refs WHERE status = 'pending' ORDER BY rowid LIMIT ? OFFSET ?");
|
|
1713
1792
|
}
|
|
1714
1793
|
const rows = this.stmts.getUnresolvedBatch.all(limit, offset);
|
|
1715
1794
|
return rows.map((row) => ({
|
|
@@ -1721,6 +1800,32 @@ class QueryBuilder {
|
|
|
1721
1800
|
candidates: row.candidates ? (0, utils_1.safeJsonParse)(row.candidates, undefined) : undefined,
|
|
1722
1801
|
filePath: row.file_path,
|
|
1723
1802
|
language: row.language,
|
|
1803
|
+
rowId: row.id,
|
|
1804
|
+
}));
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
* Keyset variant of {@link getUnresolvedReferencesBatch} for the batched
|
|
1808
|
+
* resolution loop: seek past the last-seen row id instead of OFFSET-walking.
|
|
1809
|
+
* OFFSET reads re-scan the accumulated failed-row prefix on every batch —
|
|
1810
|
+
* O(failed rows) per read, measured at 54.6s of the kernel-scale batch loop
|
|
1811
|
+
* (§7a.2) — while the seek is O(batch) forever. `id` is the rowid alias, so
|
|
1812
|
+
* the enumeration order is identical to the OFFSET reader's.
|
|
1813
|
+
*/
|
|
1814
|
+
getUnresolvedReferencesBatchAfter(afterRowId, limit) {
|
|
1815
|
+
if (!this.stmts.getUnresolvedBatchAfter) {
|
|
1816
|
+
this.stmts.getUnresolvedBatchAfter = this.db.prepare("SELECT * FROM unresolved_refs WHERE status = 'pending' AND id > ? ORDER BY id LIMIT ?");
|
|
1817
|
+
}
|
|
1818
|
+
const rows = this.stmts.getUnresolvedBatchAfter.all(afterRowId, limit);
|
|
1819
|
+
return rows.map((row) => ({
|
|
1820
|
+
fromNodeId: row.from_node_id,
|
|
1821
|
+
referenceName: row.reference_name,
|
|
1822
|
+
referenceKind: row.reference_kind,
|
|
1823
|
+
line: row.line,
|
|
1824
|
+
column: row.col,
|
|
1825
|
+
candidates: row.candidates ? (0, utils_1.safeJsonParse)(row.candidates, undefined) : undefined,
|
|
1826
|
+
filePath: row.file_path,
|
|
1827
|
+
language: row.language,
|
|
1828
|
+
rowId: row.id,
|
|
1724
1829
|
}));
|
|
1725
1830
|
}
|
|
1726
1831
|
/**
|
|
@@ -1759,14 +1864,16 @@ class QueryBuilder {
|
|
|
1759
1864
|
*/
|
|
1760
1865
|
markReferencesFailed(refs) {
|
|
1761
1866
|
if (refs.length === 0)
|
|
1762
|
-
return;
|
|
1867
|
+
return 0;
|
|
1763
1868
|
const stmt = this.db.prepare("UPDATE unresolved_refs SET status = 'failed', name_tail = ? WHERE from_node_id = ? AND reference_name = ? AND reference_kind = ?");
|
|
1869
|
+
let changed = 0;
|
|
1764
1870
|
const markMany = this.db.transaction((items) => {
|
|
1765
1871
|
for (const ref of items) {
|
|
1766
|
-
stmt.run(referenceNameTail(ref.referenceName), ref.fromNodeId, ref.referenceName, ref.referenceKind);
|
|
1872
|
+
changed += stmt.run(referenceNameTail(ref.referenceName), ref.fromNodeId, ref.referenceName, ref.referenceKind).changes;
|
|
1767
1873
|
}
|
|
1768
1874
|
});
|
|
1769
1875
|
markMany(refs);
|
|
1876
|
+
return changed;
|
|
1770
1877
|
}
|
|
1771
1878
|
/**
|
|
1772
1879
|
* Delete unresolved-ref rows by row id — the precise cleanup for refs a
|
|
@@ -1778,12 +1885,25 @@ class QueryBuilder {
|
|
|
1778
1885
|
*/
|
|
1779
1886
|
deleteReferencesByRowIds(rowIds) {
|
|
1780
1887
|
if (rowIds.length === 0)
|
|
1781
|
-
return;
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1888
|
+
return 0;
|
|
1889
|
+
let changed = 0;
|
|
1890
|
+
this.db.transaction(() => {
|
|
1891
|
+
for (let i = 0; i < rowIds.length; i += SQLITE_PARAM_CHUNK_SIZE) {
|
|
1892
|
+
const chunk = rowIds.slice(i, i + SQLITE_PARAM_CHUNK_SIZE);
|
|
1893
|
+
if (chunk.length === SQLITE_PARAM_CHUNK_SIZE) {
|
|
1894
|
+
if (!this.stmts.deleteRefsByRowIdsFull) {
|
|
1895
|
+
const placeholders = new Array(SQLITE_PARAM_CHUNK_SIZE).fill('?').join(',');
|
|
1896
|
+
this.stmts.deleteRefsByRowIdsFull = this.db.prepare(`DELETE FROM unresolved_refs WHERE id IN (${placeholders})`);
|
|
1897
|
+
}
|
|
1898
|
+
changed += this.stmts.deleteRefsByRowIdsFull.run(...chunk).changes;
|
|
1899
|
+
}
|
|
1900
|
+
else {
|
|
1901
|
+
const placeholders = chunk.map(() => '?').join(',');
|
|
1902
|
+
changed += this.db.prepare(`DELETE FROM unresolved_refs WHERE id IN (${placeholders})`).run(...chunk).changes;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
})();
|
|
1906
|
+
return changed;
|
|
1787
1907
|
}
|
|
1788
1908
|
/**
|
|
1789
1909
|
* Park refs as status='failed' by row id — the precise counterpart of
|
|
@@ -1795,14 +1915,16 @@ class QueryBuilder {
|
|
|
1795
1915
|
*/
|
|
1796
1916
|
markReferencesFailedByRowIds(refs) {
|
|
1797
1917
|
if (refs.length === 0)
|
|
1798
|
-
return;
|
|
1918
|
+
return 0;
|
|
1799
1919
|
const stmt = this.db.prepare("UPDATE unresolved_refs SET status = 'failed', name_tail = ? WHERE id = ?");
|
|
1920
|
+
let changed = 0;
|
|
1800
1921
|
const markMany = this.db.transaction((items) => {
|
|
1801
1922
|
for (const ref of items) {
|
|
1802
|
-
stmt.run(referenceNameTail(ref.referenceName), ref.rowId);
|
|
1923
|
+
changed += stmt.run(referenceNameTail(ref.referenceName), ref.rowId).changes;
|
|
1803
1924
|
}
|
|
1804
1925
|
});
|
|
1805
1926
|
markMany(refs);
|
|
1927
|
+
return changed;
|
|
1806
1928
|
}
|
|
1807
1929
|
/**
|
|
1808
1930
|
* Failed refs whose name tail matches one of the given symbol names — the
|
|
@@ -1919,7 +2041,7 @@ class QueryBuilder {
|
|
|
1919
2041
|
// this file. The internal resolution path uses deleteSpecificResolvedReferences
|
|
1920
2042
|
// instead, but QueryBuilder is part of the public API, so a library consumer
|
|
1921
2043
|
// passing more ids than SQLITE_MAX_VARIABLE_NUMBER (32766 on the bundled
|
|
1922
|
-
//
|
|
2044
|
+
// SQLite would otherwise hit "too many SQL variables". (#540, #1001)
|
|
1923
2045
|
for (let i = 0; i < fromNodeIds.length; i += SQLITE_PARAM_CHUNK_SIZE) {
|
|
1924
2046
|
const chunk = fromNodeIds.slice(i, i + SQLITE_PARAM_CHUNK_SIZE);
|
|
1925
2047
|
const placeholders = chunk.map(() => '?').join(',');
|
|
@@ -1932,14 +2054,16 @@ class QueryBuilder {
|
|
|
1932
2054
|
*/
|
|
1933
2055
|
deleteSpecificResolvedReferences(refs) {
|
|
1934
2056
|
if (refs.length === 0)
|
|
1935
|
-
return;
|
|
2057
|
+
return 0;
|
|
1936
2058
|
const stmt = this.db.prepare('DELETE FROM unresolved_refs WHERE from_node_id = ? AND reference_name = ? AND reference_kind = ?');
|
|
2059
|
+
let changed = 0;
|
|
1937
2060
|
const deleteMany = this.db.transaction((items) => {
|
|
1938
2061
|
for (const ref of items) {
|
|
1939
|
-
stmt.run(ref.fromNodeId, ref.referenceName, ref.referenceKind);
|
|
2062
|
+
changed += stmt.run(ref.fromNodeId, ref.referenceName, ref.referenceKind).changes;
|
|
1940
2063
|
}
|
|
1941
2064
|
});
|
|
1942
2065
|
deleteMany(refs);
|
|
2066
|
+
return changed;
|
|
1943
2067
|
}
|
|
1944
2068
|
// ===========================================================================
|
|
1945
2069
|
// Statistics
|
|
@@ -1961,11 +2085,11 @@ class QueryBuilder {
|
|
|
1961
2085
|
*/
|
|
1962
2086
|
getStats() {
|
|
1963
2087
|
// Single query for all three aggregate counts
|
|
1964
|
-
const counts = this.db.prepare(`
|
|
1965
|
-
SELECT
|
|
1966
|
-
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
1967
|
-
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
1968
|
-
(SELECT COUNT(*) FROM files) AS file_count
|
|
2088
|
+
const counts = this.db.prepare(`
|
|
2089
|
+
SELECT
|
|
2090
|
+
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
2091
|
+
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
2092
|
+
(SELECT COUNT(*) FROM files) AS file_count
|
|
1969
2093
|
`).get();
|
|
1970
2094
|
const nodesByKind = {};
|
|
1971
2095
|
const nodeKindRows = this.db
|