gitnexus 1.6.8-rc.8 → 1.6.8
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 +3 -3
- package/dist/_shared/graph/types.d.ts +31 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +11 -1
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +6 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +6 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +31 -1
- package/dist/cli/ai-context.js +18 -16
- package/dist/cli/analyze-config.js +11 -0
- package/dist/cli/analyze.d.ts +14 -0
- package/dist/cli/analyze.js +98 -0
- package/dist/cli/embedding-dims.d.ts +33 -0
- package/dist/cli/embedding-dims.js +39 -0
- package/dist/cli/eval-server.d.ts +8 -0
- package/dist/cli/eval-server.js +242 -2
- package/dist/cli/help-i18n.js +19 -0
- package/dist/cli/i18n/en.d.ts +15 -1
- package/dist/cli/i18n/en.js +15 -1
- package/dist/cli/i18n/resources.d.ts +29 -1
- package/dist/cli/i18n/zh-CN.d.ts +14 -0
- package/dist/cli/i18n/zh-CN.js +15 -1
- package/dist/cli/index.js +89 -1
- package/dist/cli/mcp.d.ts +6 -1
- package/dist/cli/mcp.js +26 -1
- package/dist/cli/optional-grammars.d.ts +6 -8
- package/dist/cli/optional-grammars.js +8 -11
- package/dist/cli/setup.d.ts +3 -1
- package/dist/cli/setup.js +67 -17
- package/dist/cli/skill-gen.js +2 -1
- package/dist/cli/tool.d.ts +19 -1
- package/dist/cli/tool.js +96 -3
- package/dist/core/embeddings/hf-env.d.ts +0 -66
- package/dist/core/embeddings/http-client.d.ts +7 -0
- package/dist/core/embeddings/http-client.js +5 -3
- package/dist/core/embeddings/server-mapping.d.ts +1 -1
- package/dist/core/embeddings/server-mapping.js +7 -3
- package/dist/core/graph/import-cycles.d.ts +10 -0
- package/dist/core/graph/import-cycles.js +103 -0
- package/dist/core/group/cross-impact.d.ts +2 -1
- package/dist/core/group/cross-impact.js +5 -1
- package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
- package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
- package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
- package/dist/core/group/extractors/http-route-extractor.js +22 -4
- package/dist/core/group/extractors/include-extractor.js +22 -13
- package/dist/core/group/sync.d.ts +27 -1
- package/dist/core/group/sync.js +0 -0
- package/dist/core/incremental/subgraph-extract.js +18 -1
- package/dist/core/ingestion/cfg/cfg-builder.d.ts +114 -0
- package/dist/core/ingestion/cfg/cfg-builder.js +196 -0
- package/dist/core/ingestion/cfg/collect.d.ts +51 -0
- package/dist/core/ingestion/cfg/collect.js +77 -0
- package/dist/core/ingestion/cfg/control-dependence.d.ts +58 -0
- package/dist/core/ingestion/cfg/control-dependence.js +182 -0
- package/dist/core/ingestion/cfg/control-flow-context.d.ts +106 -0
- package/dist/core/ingestion/cfg/control-flow-context.js +124 -0
- package/dist/core/ingestion/cfg/emit.d.ts +293 -0
- package/dist/core/ingestion/cfg/emit.js +646 -0
- package/dist/core/ingestion/cfg/post-dominators.d.ts +79 -0
- package/dist/core/ingestion/cfg/post-dominators.js +176 -0
- package/dist/core/ingestion/cfg/reaching-def-reason-codec.d.ts +106 -0
- package/dist/core/ingestion/cfg/reaching-def-reason-codec.js +133 -0
- package/dist/core/ingestion/cfg/reaching-defs-graph.d.ts +18 -0
- package/dist/core/ingestion/cfg/reaching-defs-graph.js +312 -0
- package/dist/core/ingestion/cfg/reaching-defs.d.ts +162 -0
- package/dist/core/ingestion/cfg/reaching-defs.js +785 -0
- package/dist/core/ingestion/cfg/synthetic-escape.d.ts +124 -0
- package/dist/core/ingestion/cfg/synthetic-escape.js +300 -0
- package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
- package/dist/core/ingestion/cfg/traversal-result.js +2 -0
- package/dist/core/ingestion/cfg/types.d.ts +274 -0
- package/dist/core/ingestion/cfg/types.js +13 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.d.ts +111 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.js +541 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp.d.ts +74 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp.js +584 -0
- package/dist/core/ingestion/cfg/visitors/call-site-harvest.d.ts +195 -0
- package/dist/core/ingestion/cfg/visitors/call-site-harvest.js +350 -0
- package/dist/core/ingestion/cfg/visitors/csharp-harvest.d.ts +124 -0
- package/dist/core/ingestion/cfg/visitors/csharp-harvest.js +589 -0
- package/dist/core/ingestion/cfg/visitors/csharp.d.ts +87 -0
- package/dist/core/ingestion/cfg/visitors/csharp.js +867 -0
- package/dist/core/ingestion/cfg/visitors/dart-harvest.d.ts +278 -0
- package/dist/core/ingestion/cfg/visitors/dart-harvest.js +870 -0
- package/dist/core/ingestion/cfg/visitors/dart.d.ts +119 -0
- package/dist/core/ingestion/cfg/visitors/dart.js +836 -0
- package/dist/core/ingestion/cfg/visitors/go-harvest.d.ts +160 -0
- package/dist/core/ingestion/cfg/visitors/go-harvest.js +621 -0
- package/dist/core/ingestion/cfg/visitors/go.d.ts +108 -0
- package/dist/core/ingestion/cfg/visitors/go.js +638 -0
- package/dist/core/ingestion/cfg/visitors/java-harvest.d.ts +108 -0
- package/dist/core/ingestion/cfg/visitors/java-harvest.js +513 -0
- package/dist/core/ingestion/cfg/visitors/java.d.ts +101 -0
- package/dist/core/ingestion/cfg/visitors/java.js +812 -0
- package/dist/core/ingestion/cfg/visitors/kotlin-harvest.d.ts +253 -0
- package/dist/core/ingestion/cfg/visitors/kotlin-harvest.js +719 -0
- package/dist/core/ingestion/cfg/visitors/kotlin.d.ts +121 -0
- package/dist/core/ingestion/cfg/visitors/kotlin.js +809 -0
- package/dist/core/ingestion/cfg/visitors/php-harvest.d.ts +172 -0
- package/dist/core/ingestion/cfg/visitors/php-harvest.js +626 -0
- package/dist/core/ingestion/cfg/visitors/php.d.ts +96 -0
- package/dist/core/ingestion/cfg/visitors/php.js +721 -0
- package/dist/core/ingestion/cfg/visitors/python-harvest.d.ts +212 -0
- package/dist/core/ingestion/cfg/visitors/python-harvest.js +739 -0
- package/dist/core/ingestion/cfg/visitors/python.d.ts +103 -0
- package/dist/core/ingestion/cfg/visitors/python.js +558 -0
- package/dist/core/ingestion/cfg/visitors/ruby-harvest.d.ts +223 -0
- package/dist/core/ingestion/cfg/visitors/ruby-harvest.js +587 -0
- package/dist/core/ingestion/cfg/visitors/ruby.d.ts +112 -0
- package/dist/core/ingestion/cfg/visitors/ruby.js +756 -0
- package/dist/core/ingestion/cfg/visitors/rust-harvest.d.ts +324 -0
- package/dist/core/ingestion/cfg/visitors/rust-harvest.js +873 -0
- package/dist/core/ingestion/cfg/visitors/rust.d.ts +95 -0
- package/dist/core/ingestion/cfg/visitors/rust.js +558 -0
- package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.d.ts +87 -0
- package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.js +116 -0
- package/dist/core/ingestion/cfg/visitors/swift-harvest.d.ts +255 -0
- package/dist/core/ingestion/cfg/visitors/swift-harvest.js +679 -0
- package/dist/core/ingestion/cfg/visitors/swift.d.ts +116 -0
- package/dist/core/ingestion/cfg/visitors/swift.js +787 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +149 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1056 -0
- package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
- package/dist/core/ingestion/cfg/visitors/typescript.js +583 -0
- package/dist/core/ingestion/import-resolvers/utils.js +2 -0
- package/dist/core/ingestion/language-provider.d.ts +23 -2
- package/dist/core/ingestion/languages/c-cpp.js +17 -5
- package/dist/core/ingestion/languages/cobol.js +4 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +41 -2
- package/dist/core/ingestion/languages/cpp/captures.js +50 -1
- package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.js +89 -0
- package/dist/core/ingestion/languages/cpp/header-scan.d.ts +1 -1
- package/dist/core/ingestion/languages/cpp/header-scan.js +2 -2
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +7 -2
- package/dist/core/ingestion/languages/cpp/member-lookup.js +2 -1
- package/dist/core/ingestion/languages/cpp/query.js +23 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +2 -1
- package/dist/core/ingestion/languages/csharp.js +2 -0
- package/dist/core/ingestion/languages/dart.js +2 -0
- package/dist/core/ingestion/languages/go.js +2 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/kotlin/query.js +3 -2
- package/dist/core/ingestion/languages/kotlin.js +8 -1
- package/dist/core/ingestion/languages/php.js +2 -0
- package/dist/core/ingestion/languages/python.js +2 -0
- package/dist/core/ingestion/languages/ruby.js +2 -0
- package/dist/core/ingestion/languages/rust.js +2 -0
- package/dist/core/ingestion/languages/swift.js +2 -0
- package/dist/core/ingestion/languages/typescript.js +5 -0
- package/dist/core/ingestion/languages/vue.js +6 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
- package/dist/core/ingestion/method-extractors/generic.js +1 -0
- package/dist/core/ingestion/method-types.d.ts +2 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
- package/dist/core/ingestion/model/symbol-table.js +1 -0
- package/dist/core/ingestion/mro-processor.js +109 -0
- package/dist/core/ingestion/parsing-processor.js +44 -0
- package/dist/core/ingestion/pipeline-phases/call-summaries.d.ts +26 -0
- package/dist/core/ingestion/pipeline-phases/call-summaries.js +46 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +0 -21
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
- package/dist/core/ingestion/pipeline-phases/routes.d.ts +10 -0
- package/dist/core/ingestion/pipeline-phases/routes.js +30 -1
- package/dist/core/ingestion/pipeline-phases/taint-summaries.d.ts +30 -0
- package/dist/core/ingestion/pipeline-phases/taint-summaries.js +81 -0
- package/dist/core/ingestion/pipeline.d.ts +92 -10
- package/dist/core/ingestion/pipeline.js +11 -2
- package/dist/core/ingestion/scope-extractor.js +12 -2
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +9 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +75 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +67 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +14 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +6 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +13 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +9 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +28 -2
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +4 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +9 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +6 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +174 -40
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +24 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +276 -190
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +75 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +349 -1
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/taint/call-summary-codec.d.ts +75 -0
- package/dist/core/ingestion/taint/call-summary-codec.js +128 -0
- package/dist/core/ingestion/taint/call-summary-emit.d.ts +43 -0
- package/dist/core/ingestion/taint/call-summary-emit.js +70 -0
- package/dist/core/ingestion/taint/call-summary-harvest.d.ts +77 -0
- package/dist/core/ingestion/taint/call-summary-harvest.js +179 -0
- package/dist/core/ingestion/taint/call-summary-model.d.ts +47 -0
- package/dist/core/ingestion/taint/call-summary-model.js +25 -0
- package/dist/core/ingestion/taint/emit.d.ts +125 -0
- package/dist/core/ingestion/taint/emit.js +208 -0
- package/dist/core/ingestion/taint/interproc-emit.d.ts +50 -0
- package/dist/core/ingestion/taint/interproc-emit.js +88 -0
- package/dist/core/ingestion/taint/interproc-solver.d.ts +110 -0
- package/dist/core/ingestion/taint/interproc-solver.js +312 -0
- package/dist/core/ingestion/taint/match.d.ts +153 -0
- package/dist/core/ingestion/taint/match.js +278 -0
- package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
- package/dist/core/ingestion/taint/path-codec.js +190 -0
- package/dist/core/ingestion/taint/propagate.d.ts +216 -0
- package/dist/core/ingestion/taint/propagate.js +659 -0
- package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
- package/dist/core/ingestion/taint/site-safety.js +98 -0
- package/dist/core/ingestion/taint/source-sink-config.d.ts +107 -23
- package/dist/core/ingestion/taint/source-sink-config.js +35 -12
- package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
- package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
- package/dist/core/ingestion/taint/summary-harvest-driver.d.ts +80 -0
- package/dist/core/ingestion/taint/summary-harvest-driver.js +179 -0
- package/dist/core/ingestion/taint/summary-harvest.d.ts +89 -0
- package/dist/core/ingestion/taint/summary-harvest.js +537 -0
- package/dist/core/ingestion/taint/summary-model.d.ts +200 -0
- package/dist/core/ingestion/taint/summary-model.js +86 -0
- package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
- package/dist/core/ingestion/taint/typescript-model.js +102 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +21 -0
- package/dist/core/ingestion/utils/env.d.ts +7 -0
- package/dist/core/ingestion/utils/env.js +12 -0
- package/dist/core/ingestion/utils/method-props.js +1 -0
- package/dist/core/ingestion/workers/clone-safety.d.ts +109 -0
- package/dist/core/ingestion/workers/clone-safety.js +465 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +23 -0
- package/dist/core/ingestion/workers/parse-worker.js +81 -53
- package/dist/core/ingestion/workers/post-result.d.ts +22 -0
- package/dist/core/ingestion/workers/post-result.js +87 -0
- package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
- package/dist/core/ingestion/workers/result-merge.js +43 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +15 -40
- package/dist/core/ingestion/workers/worker-pool.js +43 -16
- package/dist/core/lbug/csv-generator.d.ts +51 -3
- package/dist/core/lbug/csv-generator.js +369 -255
- package/dist/core/lbug/lbug-adapter.d.ts +58 -18
- package/dist/core/lbug/lbug-adapter.js +346 -84
- package/dist/core/lbug/lbug-config.d.ts +19 -0
- package/dist/core/lbug/lbug-config.js +29 -0
- package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
- package/dist/core/lbug/pdg-emit-sink.js +358 -0
- package/dist/core/lbug/pool-adapter.d.ts +35 -0
- package/dist/core/lbug/pool-adapter.js +90 -1
- package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
- package/dist/core/lbug/rel-pair-routing.js +140 -0
- package/dist/core/lbug/schema.d.ts +2 -2
- package/dist/core/lbug/schema.js +3 -0
- package/dist/core/logger.d.ts +0 -5
- package/dist/core/run-analyze.d.ts +96 -0
- package/dist/core/run-analyze.js +207 -3
- package/dist/core/tree-sitter/parser-loader.js +5 -4
- package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
- package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
- package/dist/core/tree-sitter/vendored-grammars.js +57 -0
- package/dist/core/wiki/generator.js +3 -1
- package/dist/core/wiki/graph-queries.d.ts +6 -0
- package/dist/core/wiki/graph-queries.js +9 -1
- package/dist/mcp/http-transport.d.ts +134 -0
- package/dist/mcp/http-transport.js +503 -0
- package/dist/mcp/local/local-backend.d.ts +110 -24
- package/dist/mcp/local/local-backend.js +1225 -19
- package/dist/mcp/local/pdg-impact.d.ts +384 -0
- package/dist/mcp/local/pdg-impact.js +1972 -0
- package/dist/mcp/resources.js +13 -1
- package/dist/mcp/tools.d.ts +12 -0
- package/dist/mcp/tools.js +214 -7
- package/dist/server/analyze-launch.d.ts +29 -0
- package/dist/server/analyze-launch.js +137 -0
- package/dist/server/analyze-upload.d.ts +33 -0
- package/dist/server/analyze-upload.js +123 -0
- package/dist/server/analyze-worker-ipc.d.ts +58 -0
- package/dist/server/analyze-worker-ipc.js +16 -0
- package/dist/server/analyze-worker.d.ts +17 -1
- package/dist/server/analyze-worker.js +7 -1
- package/dist/server/api.d.ts +17 -0
- package/dist/server/api.js +132 -168
- package/dist/server/git-clone.d.ts +43 -2
- package/dist/server/git-clone.js +211 -16
- package/dist/server/mcp-http.d.ts +5 -6
- package/dist/server/mcp-http.js +9 -82
- package/dist/server/middleware.d.ts +40 -0
- package/dist/server/middleware.js +92 -0
- package/dist/server/private-ip.d.ts +1 -0
- package/dist/server/private-ip.js +15 -0
- package/dist/server/upload-ingest.d.ts +56 -0
- package/dist/server/upload-ingest.js +276 -0
- package/dist/server/upload-paths.d.ts +37 -0
- package/dist/server/upload-paths.js +57 -0
- package/dist/server/upload-sweep.d.ts +20 -0
- package/dist/server/upload-sweep.js +57 -0
- package/dist/storage/git.js +5 -8
- package/dist/storage/parse-cache.d.ts +22 -1
- package/dist/storage/parse-cache.js +44 -10
- package/dist/storage/repo-manager.d.ts +121 -10
- package/dist/storage/repo-manager.js +43 -5
- package/dist/types/pipeline.d.ts +9 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
- package/hooks/claude/gitnexus-hook.cjs +110 -13
- package/hooks/claude/hook-db-lock-probe.cjs +513 -26
- package/package.json +8 -2
- package/scripts/assert-publish-grammar-coverage.cjs +31 -0
- package/scripts/build-tree-sitter-grammars.cjs +16 -10
- package/scripts/cross-platform-tests.ts +1 -0
- package/skills/gitnexus-debugging.md +16 -4
- package/skills/gitnexus-exploring.md +3 -3
- package/skills/gitnexus-guide.md +33 -0
- package/skills/gitnexus-pdg-query.md +89 -0
- package/skills/gitnexus-refactoring.md +1 -1
- package/skills/gitnexus-taint-analysis.md +178 -0
- package/vendor/tree-sitter-c/package.json +1 -1
- package/vendor/tree-sitter-dart/package.json +1 -1
- package/vendor/tree-sitter-kotlin/package.json +1 -1
- package/vendor/tree-sitter-proto/package.json +1 -1
- package/vendor/tree-sitter-swift/package.json +1 -1
- package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
- package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
- package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
- package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
- package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
- package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
- package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
- package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
- package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
- package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
- package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
- package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
- package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
- package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
- package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
- package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
- package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
- package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
- package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
- package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
- package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
- package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
- package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
- package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
- package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
- package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
- package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
- package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
- package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
- package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
- package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
- package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
- package/web/assets/index-BvYev1UJ.js +635 -0
- package/web/assets/index-_lgn7hs5.css +2 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
- package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
- package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
- package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
- package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
- package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
- package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
- package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
- package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
- package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
- package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
- package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
- package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
- package/web/index.html +13 -15
- package/scripts/materialize-vendor-grammars.cjs +0 -97
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
- package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
- package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
- package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
- package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
- package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
- package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
- package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
- package/web/assets/chunk-CilyBKbf.js +0 -1
- package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
- package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
- package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
- package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
- package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
- package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
- package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
- package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
- package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
- package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
- package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
- package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
- package/web/assets/index-BKWA-m7o.css +0 -2
- package/web/assets/index-CG6q8eTs.js +0 -626
- package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
- package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
- package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
- /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import fs from 'fs/promises';
|
|
15
15
|
import { createWriteStream } from 'fs';
|
|
16
16
|
import path from 'path';
|
|
17
|
+
import { NODE_TABLES } from './schema.js';
|
|
18
|
+
import { RelPairRouter } from './rel-pair-routing.js';
|
|
17
19
|
import { parseTruthyEnv } from '../ingestion/utils/env.js';
|
|
18
20
|
/**
|
|
19
21
|
* Deterministic output ordering — optional (out-of-core / windowed-resolve
|
|
@@ -31,6 +33,14 @@ const orderedNodes = (graph, sorted) => sorted ? [...graph.iterNodes()].sort(byG
|
|
|
31
33
|
const orderedRelationships = (graph, sorted) => sorted ? [...graph.iterRelationships()].sort(byGraphId) : graph.iterRelationships();
|
|
32
34
|
/** Flush buffered rows to disk every N rows */
|
|
33
35
|
const FLUSH_EVERY = 500;
|
|
36
|
+
/**
|
|
37
|
+
* Yield the event loop every N relationship rows during the emit pass (#2226 F4)
|
|
38
|
+
* so a concurrent node COPY (the overlap in loadGraphToLbug) and write-stream
|
|
39
|
+
* drain callbacks get scheduling time during long synchronous emit stretches.
|
|
40
|
+
* Scheduling-only — never changes row content or order (byte-identical). Tuning
|
|
41
|
+
* constant, not load-bearing.
|
|
42
|
+
*/
|
|
43
|
+
const REL_YIELD_EVERY = 5000;
|
|
34
44
|
// ============================================================================
|
|
35
45
|
// CSV ESCAPE UTILITIES
|
|
36
46
|
// ============================================================================
|
|
@@ -158,13 +168,20 @@ class BufferedCSVWriter {
|
|
|
158
168
|
this.ws.setMaxListeners(50);
|
|
159
169
|
this.buffer.push(header);
|
|
160
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Buffer a row. Returns a promise ONLY when the buffer crossed FLUSH_EVERY
|
|
173
|
+
* and a disk write was issued; otherwise returns `undefined` so the caller
|
|
174
|
+
* can skip awaiting (#2203 U3) — avoiding a microtask tick on every buffered
|
|
175
|
+
* row (millions at scale). The flush promise still resolves on drain, so
|
|
176
|
+
* backpressure is preserved on the rows that actually write.
|
|
177
|
+
*/
|
|
161
178
|
addRow(row) {
|
|
162
179
|
this.buffer.push(row);
|
|
163
180
|
this.rows++;
|
|
164
181
|
if (this.buffer.length >= FLUSH_EVERY) {
|
|
165
182
|
return this.flush();
|
|
166
183
|
}
|
|
167
|
-
return
|
|
184
|
+
return undefined;
|
|
168
185
|
}
|
|
169
186
|
flush() {
|
|
170
187
|
if (this.buffer.length === 0)
|
|
@@ -194,12 +211,65 @@ class BufferedCSVWriter {
|
|
|
194
211
|
});
|
|
195
212
|
}
|
|
196
213
|
}
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// STREAMING CSV GENERATION — SINGLE PASS
|
|
216
|
+
// ============================================================================
|
|
217
|
+
/** Canonical relationship CSV header — shared by the emit pass and the
|
|
218
|
+
* `splitRelCsvByLabelPair` differential oracle. */
|
|
219
|
+
export const REL_CSV_HEADER = 'from,to,type,confidence,reason,step';
|
|
220
|
+
/** Build the escaped CSV row (no trailing newline) for one relationship.
|
|
221
|
+
* Single source of the relationship row bytes — used by the emit pass and by
|
|
222
|
+
* the byte-identity differential test that feeds the legacy split oracle. */
|
|
223
|
+
export const buildRelRow = (rel) => [
|
|
224
|
+
escapeCSVField(rel.sourceId),
|
|
225
|
+
escapeCSVField(rel.targetId),
|
|
226
|
+
escapeCSVField(rel.type),
|
|
227
|
+
escapeCSVNumber(rel.confidence, 1.0),
|
|
228
|
+
escapeCSVField(rel.reason),
|
|
229
|
+
escapeCSVNumber(rel.step, 0),
|
|
230
|
+
].join(',');
|
|
231
|
+
/** Canonical BasicBlock node CSV header — taint/PDG substrate (issue #2080).
|
|
232
|
+
* No `name` column; blocks are identified by id + source span. Shared by the
|
|
233
|
+
* whole-graph emit pass and the streaming PDG emit sink (issue #2202) so the
|
|
234
|
+
* two paths produce byte-identical BasicBlock rows by construction. */
|
|
235
|
+
export const BASICBLOCK_CSV_HEADER = 'id,filePath,startLine,endLine,text,callees,calleeIds';
|
|
236
|
+
/** Build the escaped CSV row (no trailing newline) for one BasicBlock node.
|
|
237
|
+
* Single source of the BasicBlock row bytes — used by `streamAllCSVsToDisk`
|
|
238
|
+
* and by the streaming `PdgEmitSink` (issue #2202). `callees` is a comma-free
|
|
239
|
+
* (space-joined) list of the leaf callee names invoked in the block — the
|
|
240
|
+
* statement-precise inter-procedural reach substrate (the field is itself a CSV
|
|
241
|
+
* cell, so the inner separator must NOT be a comma). `calleeIds` is the SOUND
|
|
242
|
+
* parallel to `callees`: the space-joined RESOLVED callee symbol ids for the
|
|
243
|
+
* block (#2227 follow-up), likewise a comma-free cell. */
|
|
244
|
+
export const buildBasicBlockRow = (node) => [
|
|
245
|
+
escapeCSVField(node.id),
|
|
246
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
247
|
+
escapeCSVNumber(node.properties.startLine, -1),
|
|
248
|
+
escapeCSVNumber(node.properties.endLine, -1),
|
|
249
|
+
escapeCSVField(node.properties.text || ''),
|
|
250
|
+
escapeCSVField(String(node.properties.callees ?? '')),
|
|
251
|
+
escapeCSVField(String(node.properties.calleeIds ?? '')),
|
|
252
|
+
].join(',');
|
|
197
253
|
/**
|
|
198
254
|
* Stream all CSV data directly to disk files.
|
|
199
255
|
* Iterates graph nodes exactly ONCE — routes each node to the right writer.
|
|
200
256
|
* File contents are lazy-read from disk with a generous LRU cache.
|
|
257
|
+
*
|
|
258
|
+
* `onNodePhaseComplete` (optional, #2203 parallelism leg): fired exactly once,
|
|
259
|
+
* right after every node CSV is fully flushed to disk and BEFORE the
|
|
260
|
+
* relationship pass starts writing any `rel_*.csv`. It receives the finished
|
|
261
|
+
* node-file manifest so the caller can begin `COPY`-ing nodes while this
|
|
262
|
+
* function keeps generating relationship CSVs (the only single-writer-safe
|
|
263
|
+
* overlap — node `COPY` ‖ relationship emit). It is intentionally NOT awaited:
|
|
264
|
+
* the relationship pass proceeds concurrently with whatever the caller
|
|
265
|
+
* schedules. A synchronous throw from the callback is allowed and propagates out
|
|
266
|
+
* of this function (rejecting the returned promise) — it is raised before the
|
|
267
|
+
* relationship pass begins, so no `rel_*.csv` is written; `loadGraphToLbug` uses
|
|
268
|
+
* this to surface its PDG-manifest collision guard. The callback must NOT, however,
|
|
269
|
+
* schedule un-awaited async work that can reject unobserved. Absent ⇒ today's
|
|
270
|
+
* behavior, byte-for-byte.
|
|
201
271
|
*/
|
|
202
|
-
export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
272
|
+
export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, onNodePhaseComplete) => {
|
|
203
273
|
// Deterministic (id-sorted) node/relationship row order when enabled;
|
|
204
274
|
// default off = today's graph-insertion order (byte-identical).
|
|
205
275
|
const sortOutput = parseTruthyEnv(process.env.GITNEXUS_SORT_GRAPH_OUTPUT);
|
|
@@ -213,191 +283,131 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
213
283
|
// MaxListenersExceededWarning (restored after all streams finish).
|
|
214
284
|
const prevMax = process.getMaxListeners();
|
|
215
285
|
process.setMaxListeners(prevMax + 40);
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
'
|
|
243
|
-
|
|
244
|
-
'
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
seenNodeIds
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
escapeCSVField(node.properties.description || ''),
|
|
340
|
-
escapeCSVNumber(node.properties.parameterCount, 0),
|
|
341
|
-
escapeCSVField(node.properties.returnType || ''),
|
|
342
|
-
].join(','));
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
case 'Section': {
|
|
346
|
-
const content = await extractContent(node, contentCache);
|
|
347
|
-
await sectionWriter.addRow([
|
|
348
|
-
escapeCSVField(node.id),
|
|
349
|
-
escapeCSVField(node.properties.name || ''),
|
|
350
|
-
escapeCSVField(node.properties.filePath || ''),
|
|
351
|
-
escapeCSVNumber(node.properties.startLine, -1),
|
|
352
|
-
escapeCSVNumber(node.properties.endLine, -1),
|
|
353
|
-
escapeCSVNumber(node.properties.level, 1),
|
|
354
|
-
escapeCSVField(content),
|
|
355
|
-
escapeCSVField(node.properties.description || ''),
|
|
356
|
-
].join(','));
|
|
357
|
-
break;
|
|
358
|
-
}
|
|
359
|
-
case 'Route': {
|
|
360
|
-
const responseKeys = node.properties.responseKeys || [];
|
|
361
|
-
// LadybugDB array literal inside a quoted CSV field: escapeCSVField wraps in "..."
|
|
362
|
-
// and the array uses single-quoted elements
|
|
363
|
-
const keysStr = `[${responseKeys.map((k) => `'${k.replace(/'/g, "''")}'`).join(',')}]`;
|
|
364
|
-
const errorKeys = node.properties.errorKeys || [];
|
|
365
|
-
const errorKeysStr = `[${errorKeys.map((k) => `'${k.replace(/'/g, "''")}'`).join(',')}]`;
|
|
366
|
-
const middleware = node.properties.middleware || [];
|
|
367
|
-
const middlewareStr = `[${middleware.map((m) => `'${m.replace(/'/g, "''")}'`).join(',')}]`;
|
|
368
|
-
await routeWriter.addRow([
|
|
369
|
-
escapeCSVField(node.id),
|
|
370
|
-
escapeCSVField(node.properties.name || ''),
|
|
371
|
-
escapeCSVField(node.properties.filePath || ''),
|
|
372
|
-
escapeCSVField(keysStr),
|
|
373
|
-
escapeCSVField(errorKeysStr),
|
|
374
|
-
escapeCSVField(middlewareStr),
|
|
375
|
-
].join(','));
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
case 'Tool':
|
|
379
|
-
await toolWriter.addRow([
|
|
380
|
-
escapeCSVField(node.id),
|
|
381
|
-
escapeCSVField(node.properties.name || ''),
|
|
382
|
-
escapeCSVField(node.properties.filePath || ''),
|
|
383
|
-
escapeCSVField(node.properties.description || ''),
|
|
384
|
-
].join(','));
|
|
385
|
-
break;
|
|
386
|
-
case 'BasicBlock':
|
|
387
|
-
await basicBlockWriter.addRow([
|
|
388
|
-
escapeCSVField(node.id),
|
|
389
|
-
escapeCSVField(node.properties.filePath || ''),
|
|
390
|
-
escapeCSVNumber(node.properties.startLine, -1),
|
|
391
|
-
escapeCSVNumber(node.properties.endLine, -1),
|
|
392
|
-
escapeCSVField(node.properties.text || ''),
|
|
393
|
-
].join(','));
|
|
394
|
-
break;
|
|
395
|
-
default: {
|
|
396
|
-
// Code element nodes (Function, Class, Interface, CodeElement)
|
|
397
|
-
const writer = codeWriterMap[node.label];
|
|
398
|
-
if (writer) {
|
|
286
|
+
// try/finally so the listener bump is ALWAYS restored — including the
|
|
287
|
+
// rel-routing throw path (#2203 U2) and any node-writer finish() rejection,
|
|
288
|
+
// not just the success path (avoids leaking +40 listeners across failed runs
|
|
289
|
+
// in long-lived hosts / the test suite).
|
|
290
|
+
try {
|
|
291
|
+
const contentCache = new FileContentCache(repoPath);
|
|
292
|
+
// Create writers for every node type up-front
|
|
293
|
+
const fileWriter = new BufferedCSVWriter(path.join(csvDir, 'file.csv'), 'id,name,filePath,content');
|
|
294
|
+
const folderWriter = new BufferedCSVWriter(path.join(csvDir, 'folder.csv'), 'id,name,filePath');
|
|
295
|
+
const codeElementHeader = 'id,name,filePath,startLine,endLine,isExported,content,description';
|
|
296
|
+
const functionWriter = new BufferedCSVWriter(path.join(csvDir, 'function.csv'), codeElementHeader);
|
|
297
|
+
const classWriter = new BufferedCSVWriter(path.join(csvDir, 'class.csv'), codeElementHeader);
|
|
298
|
+
const interfaceWriter = new BufferedCSVWriter(path.join(csvDir, 'interface.csv'), codeElementHeader);
|
|
299
|
+
const methodHeader = 'id,name,filePath,startLine,endLine,isExported,content,description,parameterCount,returnType';
|
|
300
|
+
const methodWriter = new BufferedCSVWriter(path.join(csvDir, 'method.csv'), methodHeader);
|
|
301
|
+
const codeElemWriter = new BufferedCSVWriter(path.join(csvDir, 'codeelement.csv'), codeElementHeader);
|
|
302
|
+
const communityWriter = new BufferedCSVWriter(path.join(csvDir, 'community.csv'), 'id,label,heuristicLabel,keywords,description,enrichedBy,cohesion,symbolCount');
|
|
303
|
+
const processWriter = new BufferedCSVWriter(path.join(csvDir, 'process.csv'), 'id,label,heuristicLabel,processType,stepCount,communities,entryPointId,terminalId');
|
|
304
|
+
// Section nodes have an extra 'level' column
|
|
305
|
+
const sectionWriter = new BufferedCSVWriter(path.join(csvDir, 'section.csv'), 'id,name,filePath,startLine,endLine,level,content,description');
|
|
306
|
+
// Route nodes for API endpoint mapping
|
|
307
|
+
const routeWriter = new BufferedCSVWriter(path.join(csvDir, 'route.csv'), 'id,name,filePath,responseKeys,errorKeys,middleware,method');
|
|
308
|
+
// Tool nodes for MCP tool definitions
|
|
309
|
+
const toolWriter = new BufferedCSVWriter(path.join(csvDir, 'tool.csv'), 'id,name,filePath,description');
|
|
310
|
+
// BasicBlock nodes — taint/PDG substrate (issue #2080). No `name` column;
|
|
311
|
+
// blocks are identified by id + source span. Emitted by no phase yet.
|
|
312
|
+
const basicBlockWriter = new BufferedCSVWriter(path.join(csvDir, 'basicblock.csv'), BASICBLOCK_CSV_HEADER);
|
|
313
|
+
// Multi-language node types share the same CSV shape (no isExported column)
|
|
314
|
+
const multiLangHeader = 'id,name,filePath,startLine,endLine,content,description';
|
|
315
|
+
const MULTI_LANG_TYPES = [
|
|
316
|
+
'Struct',
|
|
317
|
+
'Enum',
|
|
318
|
+
'Macro',
|
|
319
|
+
'Typedef',
|
|
320
|
+
'Union',
|
|
321
|
+
'Namespace',
|
|
322
|
+
'Trait',
|
|
323
|
+
'Impl',
|
|
324
|
+
'TypeAlias',
|
|
325
|
+
'Const',
|
|
326
|
+
'Static',
|
|
327
|
+
'Variable',
|
|
328
|
+
'Property',
|
|
329
|
+
'Record',
|
|
330
|
+
'Delegate',
|
|
331
|
+
'Annotation',
|
|
332
|
+
'Constructor',
|
|
333
|
+
'Template',
|
|
334
|
+
'Module',
|
|
335
|
+
];
|
|
336
|
+
const propertyHeader = 'id,name,filePath,startLine,endLine,content,description,declaredType';
|
|
337
|
+
const multiLangWriters = new Map();
|
|
338
|
+
for (const t of MULTI_LANG_TYPES) {
|
|
339
|
+
multiLangWriters.set(t, new BufferedCSVWriter(path.join(csvDir, `${t.toLowerCase()}.csv`), t === 'Property' ? propertyHeader : multiLangHeader));
|
|
340
|
+
}
|
|
341
|
+
const codeWriterMap = {
|
|
342
|
+
Function: functionWriter,
|
|
343
|
+
Class: classWriter,
|
|
344
|
+
Interface: interfaceWriter,
|
|
345
|
+
CodeElement: codeElemWriter,
|
|
346
|
+
};
|
|
347
|
+
// Deduplicate all node types — the pipeline can produce duplicate IDs across
|
|
348
|
+
// all symbol types (Class, Method, Function, etc.), not just File nodes.
|
|
349
|
+
// A single Set covering every label prevents PK violations on COPY.
|
|
350
|
+
const seenNodeIds = new Set();
|
|
351
|
+
// --- SINGLE PASS over all nodes ---
|
|
352
|
+
for (const node of orderedNodes(graph, sortOutput)) {
|
|
353
|
+
if (seenNodeIds.has(node.id))
|
|
354
|
+
continue;
|
|
355
|
+
seenNodeIds.add(node.id);
|
|
356
|
+
// addRow returns a promise only when it flushes; awaiting it once after the
|
|
357
|
+
// switch (instead of `await`-ing every addRow) skips a per-row microtask
|
|
358
|
+
// tick on the ~FLUSH_EVERY-1 buffered rows between flushes (#2203 U3).
|
|
359
|
+
let pending;
|
|
360
|
+
switch (node.label) {
|
|
361
|
+
case 'File': {
|
|
362
|
+
const content = await extractContent(node, contentCache);
|
|
363
|
+
pending = fileWriter.addRow([
|
|
364
|
+
escapeCSVField(node.id),
|
|
365
|
+
escapeCSVField(node.properties.name || ''),
|
|
366
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
367
|
+
escapeCSVField(content),
|
|
368
|
+
].join(','));
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
case 'Folder':
|
|
372
|
+
pending = folderWriter.addRow([
|
|
373
|
+
escapeCSVField(node.id),
|
|
374
|
+
escapeCSVField(node.properties.name || ''),
|
|
375
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
376
|
+
].join(','));
|
|
377
|
+
break;
|
|
378
|
+
case 'Community': {
|
|
379
|
+
const keywords = node.properties.keywords || [];
|
|
380
|
+
const keywordsStr = `[${keywords.map((k) => `'${k.replace(/\\/g, '\\\\').replace(/'/g, "''").replace(/,/g, '\\,')}'`).join(',')}]`;
|
|
381
|
+
pending = communityWriter.addRow([
|
|
382
|
+
escapeCSVField(node.id),
|
|
383
|
+
escapeCSVField(node.properties.name || ''),
|
|
384
|
+
escapeCSVField(node.properties.heuristicLabel || ''),
|
|
385
|
+
keywordsStr,
|
|
386
|
+
escapeCSVField(node.properties.description || ''),
|
|
387
|
+
escapeCSVField(node.properties.enrichedBy || 'heuristic'),
|
|
388
|
+
escapeCSVNumber(node.properties.cohesion, 0),
|
|
389
|
+
escapeCSVNumber(node.properties.symbolCount, 0),
|
|
390
|
+
].join(','));
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case 'Process': {
|
|
394
|
+
const communities = node.properties.communities || [];
|
|
395
|
+
const communitiesStr = `[${communities.map((c) => `'${c.replace(/'/g, "''")}'`).join(',')}]`;
|
|
396
|
+
pending = processWriter.addRow([
|
|
397
|
+
escapeCSVField(node.id),
|
|
398
|
+
escapeCSVField(node.properties.name || ''),
|
|
399
|
+
escapeCSVField(node.properties.heuristicLabel || ''),
|
|
400
|
+
escapeCSVField(node.properties.processType || ''),
|
|
401
|
+
escapeCSVNumber(node.properties.stepCount, 0),
|
|
402
|
+
escapeCSVField(communitiesStr),
|
|
403
|
+
escapeCSVField(node.properties.entryPointId || ''),
|
|
404
|
+
escapeCSVField(node.properties.terminalId || ''),
|
|
405
|
+
].join(','));
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case 'Method': {
|
|
399
409
|
const content = await extractContent(node, contentCache);
|
|
400
|
-
|
|
410
|
+
pending = methodWriter.addRow([
|
|
401
411
|
escapeCSVField(node.id),
|
|
402
412
|
escapeCSVField(node.properties.name || ''),
|
|
403
413
|
escapeCSVField(node.properties.filePath || ''),
|
|
@@ -406,90 +416,194 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
406
416
|
node.properties.isExported ? 'true' : 'false',
|
|
407
417
|
escapeCSVField(content),
|
|
408
418
|
escapeCSVField(node.properties.description || ''),
|
|
419
|
+
escapeCSVNumber(node.properties.parameterCount, 0),
|
|
420
|
+
escapeCSVField(node.properties.returnType || ''),
|
|
421
|
+
].join(','));
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
case 'Section': {
|
|
425
|
+
const content = await extractContent(node, contentCache);
|
|
426
|
+
pending = sectionWriter.addRow([
|
|
427
|
+
escapeCSVField(node.id),
|
|
428
|
+
escapeCSVField(node.properties.name || ''),
|
|
429
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
430
|
+
escapeCSVNumber(node.properties.startLine, -1),
|
|
431
|
+
escapeCSVNumber(node.properties.endLine, -1),
|
|
432
|
+
escapeCSVNumber(node.properties.level, 1),
|
|
433
|
+
escapeCSVField(content),
|
|
434
|
+
escapeCSVField(node.properties.description || ''),
|
|
435
|
+
].join(','));
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
case 'Route': {
|
|
439
|
+
const responseKeys = node.properties.responseKeys || [];
|
|
440
|
+
// LadybugDB array literal inside a quoted CSV field: escapeCSVField wraps in "..."
|
|
441
|
+
// and the array uses single-quoted elements
|
|
442
|
+
const keysStr = `[${responseKeys.map((k) => `'${k.replace(/'/g, "''")}'`).join(',')}]`;
|
|
443
|
+
const errorKeys = node.properties.errorKeys || [];
|
|
444
|
+
const errorKeysStr = `[${errorKeys.map((k) => `'${k.replace(/'/g, "''")}'`).join(',')}]`;
|
|
445
|
+
const middleware = node.properties.middleware || [];
|
|
446
|
+
const middlewareStr = `[${middleware.map((m) => `'${m.replace(/'/g, "''")}'`).join(',')}]`;
|
|
447
|
+
pending = routeWriter.addRow([
|
|
448
|
+
escapeCSVField(node.id),
|
|
449
|
+
escapeCSVField(node.properties.name || ''),
|
|
450
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
451
|
+
escapeCSVField(keysStr),
|
|
452
|
+
escapeCSVField(errorKeysStr),
|
|
453
|
+
escapeCSVField(middlewareStr),
|
|
454
|
+
escapeCSVField(String(node.properties.method ?? '')),
|
|
409
455
|
].join(','));
|
|
456
|
+
break;
|
|
410
457
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
458
|
+
case 'Tool':
|
|
459
|
+
pending = toolWriter.addRow([
|
|
460
|
+
escapeCSVField(node.id),
|
|
461
|
+
escapeCSVField(node.properties.name || ''),
|
|
462
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
463
|
+
escapeCSVField(node.properties.description || ''),
|
|
464
|
+
].join(','));
|
|
465
|
+
break;
|
|
466
|
+
case 'BasicBlock':
|
|
467
|
+
pending = basicBlockWriter.addRow(buildBasicBlockRow(node));
|
|
468
|
+
break;
|
|
469
|
+
default: {
|
|
470
|
+
// Code element nodes (Function, Class, Interface, CodeElement)
|
|
471
|
+
const writer = codeWriterMap[node.label];
|
|
472
|
+
if (writer) {
|
|
415
473
|
const content = await extractContent(node, contentCache);
|
|
416
|
-
|
|
474
|
+
pending = writer.addRow([
|
|
417
475
|
escapeCSVField(node.id),
|
|
418
476
|
escapeCSVField(node.properties.name || ''),
|
|
419
477
|
escapeCSVField(node.properties.filePath || ''),
|
|
420
478
|
escapeCSVNumber(node.properties.startLine, -1),
|
|
421
479
|
escapeCSVNumber(node.properties.endLine, -1),
|
|
480
|
+
node.properties.isExported ? 'true' : 'false',
|
|
422
481
|
escapeCSVField(content),
|
|
423
482
|
escapeCSVField(node.properties.description || ''),
|
|
424
|
-
...(node.label === 'Property'
|
|
425
|
-
? [escapeCSVField(node.properties.declaredType || '')]
|
|
426
|
-
: []),
|
|
427
483
|
].join(','));
|
|
428
484
|
}
|
|
485
|
+
else {
|
|
486
|
+
// Multi-language node types (Struct, Impl, Trait, Macro, etc.)
|
|
487
|
+
const mlWriter = multiLangWriters.get(node.label);
|
|
488
|
+
if (mlWriter) {
|
|
489
|
+
const content = await extractContent(node, contentCache);
|
|
490
|
+
pending = mlWriter.addRow([
|
|
491
|
+
escapeCSVField(node.id),
|
|
492
|
+
escapeCSVField(node.properties.name || ''),
|
|
493
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
494
|
+
escapeCSVNumber(node.properties.startLine, -1),
|
|
495
|
+
escapeCSVNumber(node.properties.endLine, -1),
|
|
496
|
+
escapeCSVField(content),
|
|
497
|
+
escapeCSVField(node.properties.description || ''),
|
|
498
|
+
...(node.label === 'Property'
|
|
499
|
+
? [escapeCSVField(node.properties.declaredType || '')]
|
|
500
|
+
: []),
|
|
501
|
+
].join(','));
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
// Unknown label: not in codeWriterMap or multiLangWriters, so there
|
|
505
|
+
// is no CSV table for it and it is intentionally NOT persisted —
|
|
506
|
+
// `pending` stays undefined, so the loop awaits nothing. Made
|
|
507
|
+
// explicit so a future node type isn't silently dropped here: wire
|
|
508
|
+
// it into one of the writer maps above (or this branch).
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
break;
|
|
429
512
|
}
|
|
430
|
-
break;
|
|
431
513
|
}
|
|
514
|
+
if (pending)
|
|
515
|
+
await pending;
|
|
432
516
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
[
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
517
|
+
// Finish all node writers
|
|
518
|
+
const allWriters = [
|
|
519
|
+
fileWriter,
|
|
520
|
+
folderWriter,
|
|
521
|
+
functionWriter,
|
|
522
|
+
classWriter,
|
|
523
|
+
interfaceWriter,
|
|
524
|
+
methodWriter,
|
|
525
|
+
codeElemWriter,
|
|
526
|
+
communityWriter,
|
|
527
|
+
processWriter,
|
|
528
|
+
sectionWriter,
|
|
529
|
+
routeWriter,
|
|
530
|
+
toolWriter,
|
|
531
|
+
basicBlockWriter,
|
|
532
|
+
...multiLangWriters.values(),
|
|
533
|
+
];
|
|
534
|
+
await Promise.all(allWriters.map((w) => w.finish()));
|
|
535
|
+
// Build the node-file manifest now (all writers are flushed; `.rows` is
|
|
536
|
+
// final). Hoisted above the relationship pass so `onNodePhaseComplete` can
|
|
537
|
+
// hand the caller a complete node manifest to start COPY-ing while we keep
|
|
538
|
+
// generating relationship CSVs below (#2203 overlap). The same map is
|
|
539
|
+
// returned, so the result is unchanged when no callback is supplied.
|
|
540
|
+
const nodeFiles = new Map();
|
|
541
|
+
const tableMap = [
|
|
542
|
+
['File', fileWriter],
|
|
543
|
+
['Folder', folderWriter],
|
|
544
|
+
['Function', functionWriter],
|
|
545
|
+
['Class', classWriter],
|
|
546
|
+
['Interface', interfaceWriter],
|
|
547
|
+
['Method', methodWriter],
|
|
548
|
+
['CodeElement', codeElemWriter],
|
|
549
|
+
['Community', communityWriter],
|
|
550
|
+
['Process', processWriter],
|
|
551
|
+
['Section', sectionWriter],
|
|
552
|
+
['Route', routeWriter],
|
|
553
|
+
['Tool', toolWriter],
|
|
554
|
+
['BasicBlock', basicBlockWriter],
|
|
555
|
+
...Array.from(multiLangWriters.entries()).map(([name, w]) => [name, w]),
|
|
556
|
+
];
|
|
557
|
+
for (const [name, writer] of tableMap) {
|
|
558
|
+
if (writer.rows > 0) {
|
|
559
|
+
nodeFiles.set(name, {
|
|
560
|
+
csvPath: path.join(csvDir, `${name.toLowerCase()}.csv`),
|
|
561
|
+
rows: writer.rows,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// Node CSVs are on disk; relationship CSVs have not been touched yet. Hand
|
|
566
|
+
// the manifest to the caller (not awaited — the rel pass runs concurrently).
|
|
567
|
+
onNodePhaseComplete?.(nodeFiles);
|
|
568
|
+
// --- Stream relationships directly to per-FROM→TO-label-pair files ---
|
|
569
|
+
// (#2203 U2) Route every edge to its pair file in this single pass. The old
|
|
570
|
+
// monolithic relations.csv — and its line-by-line re-read + per-edge regex
|
|
571
|
+
// re-split in loadGraphToLbug — are gone, so the ~1M-edge set is written and
|
|
572
|
+
// read once instead of twice. The router applies the SAME label-derivation +
|
|
573
|
+
// validTables filter as the legacy splitRelCsvByLabelPair, so the per-pair
|
|
574
|
+
// files are byte-identical (asserted by the differential test).
|
|
575
|
+
const relRouter = new RelPairRouter(csvDir, REL_CSV_HEADER, new Set(NODE_TABLES));
|
|
576
|
+
try {
|
|
577
|
+
let emitted = 0;
|
|
578
|
+
for (const rel of orderedRelationships(graph, sortOutput)) {
|
|
579
|
+
const pending = relRouter.route(rel.sourceId, rel.targetId, buildRelRow(rel));
|
|
580
|
+
if (pending)
|
|
581
|
+
await pending;
|
|
582
|
+
// Periodically hand the event loop back so the overlapped node COPY and
|
|
583
|
+
// write-stream drains run instead of starving behind this synchronous
|
|
584
|
+
// loop (#2226 F4). No effect on emitted bytes — pure scheduling.
|
|
585
|
+
if (++emitted % REL_YIELD_EVERY === 0)
|
|
586
|
+
await new Promise((r) => setImmediate(r));
|
|
587
|
+
}
|
|
588
|
+
await relRouter.close();
|
|
490
589
|
}
|
|
590
|
+
catch (err) {
|
|
591
|
+
relRouter.destroy();
|
|
592
|
+
// Rethrow the real stream error (EMFILE / disk-full) rather than the generic
|
|
593
|
+
// AbortError a pending drain-await rejects with — mirrors the retained
|
|
594
|
+
// splitRelCsvByLabelPair's `throw streamError ?? err`.
|
|
595
|
+
throw relRouter.lastError ?? err;
|
|
596
|
+
}
|
|
597
|
+
return {
|
|
598
|
+
nodeFiles,
|
|
599
|
+
relsByPair: relRouter.byPair,
|
|
600
|
+
relHeader: REL_CSV_HEADER,
|
|
601
|
+
skippedRels: relRouter.skipped,
|
|
602
|
+
totalValidRels: relRouter.total,
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
finally {
|
|
606
|
+
// Restore original process listener limit on every path (success or throw).
|
|
607
|
+
process.setMaxListeners(prevMax);
|
|
491
608
|
}
|
|
492
|
-
// Restore original process listener limit
|
|
493
|
-
process.setMaxListeners(prevMax);
|
|
494
|
-
return { nodeFiles, relCsvPath, relRows: relWriter.rows };
|
|
495
609
|
};
|