@optave/codegraph 3.7.0 → 3.8.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/README.md +28 -16
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +195 -30
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/metrics.d.ts +0 -3
- package/dist/ast-analysis/metrics.d.ts.map +1 -1
- package/dist/ast-analysis/metrics.js +30 -13
- package/dist/ast-analysis/metrics.js.map +1 -1
- package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
- package/dist/ast-analysis/rules/javascript.js +0 -1
- package/dist/ast-analysis/rules/javascript.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +24 -19
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +55 -39
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitor.js +91 -70
- package/dist/ast-analysis/visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +52 -129
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +32 -39
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js +57 -38
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/ast.js +2 -2
- package/dist/cli/commands/ast.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +16 -2
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +29 -26
- package/dist/db/connection.js.map +1 -1
- package/dist/db/query-builder.d.ts.map +1 -1
- package/dist/db/query-builder.js +16 -5
- package/dist/db/query-builder.js.map +1 -1
- package/dist/db/repository/base.d.ts +10 -0
- package/dist/db/repository/base.d.ts.map +1 -1
- package/dist/db/repository/base.js +17 -0
- package/dist/db/repository/base.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts +6 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +77 -1
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/db/repository/nodes.d.ts.map +1 -1
- package/dist/db/repository/nodes.js +8 -4
- package/dist/db/repository/nodes.js.map +1 -1
- package/dist/db/repository/sqlite-repository.d.ts +3 -0
- package/dist/db/repository/sqlite-repository.d.ts.map +1 -1
- package/dist/db/repository/sqlite-repository.js +26 -0
- package/dist/db/repository/sqlite-repository.js.map +1 -1
- package/dist/domain/analysis/brief.d.ts.map +1 -1
- package/dist/domain/analysis/brief.js +13 -17
- package/dist/domain/analysis/brief.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +14 -11
- package/dist/domain/analysis/context.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +53 -52
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +2 -7
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +33 -31
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/implementations.d.ts.map +1 -1
- package/dist/domain/analysis/implementations.js +11 -19
- package/dist/domain/analysis/implementations.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +55 -76
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/query-helpers.d.ts +7 -0
- package/dist/domain/analysis/query-helpers.d.ts.map +1 -1
- package/dist/domain/analysis/query-helpers.js +15 -1
- package/dist/domain/analysis/query-helpers.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +315 -43
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +106 -1
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.js +17 -5
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +99 -51
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +34 -7
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js +50 -26
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +95 -84
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.d.ts +6 -0
- package/dist/domain/graph/cycles.d.ts.map +1 -1
- package/dist/domain/graph/cycles.js +114 -22
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/resolve.js +1 -1
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts +2 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +170 -75
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +1 -6
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +101 -32
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/generator.js +1 -1
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/domain/search/models.d.ts +4 -3
- package/dist/domain/search/models.d.ts.map +1 -1
- package/dist/domain/search/models.js +18 -5
- package/dist/domain/search/models.js.map +1 -1
- package/dist/domain/search/search/hybrid.d.ts.map +1 -1
- package/dist/domain/search/search/hybrid.js +29 -18
- package/dist/domain/search/search/hybrid.js.map +1 -1
- package/dist/extractors/clojure.d.ts +12 -0
- package/dist/extractors/clojure.d.ts.map +1 -0
- package/dist/extractors/clojure.js +245 -0
- package/dist/extractors/clojure.js.map +1 -0
- package/dist/extractors/cuda.d.ts +11 -0
- package/dist/extractors/cuda.d.ts.map +1 -0
- package/dist/extractors/cuda.js +302 -0
- package/dist/extractors/cuda.js.map +1 -0
- package/dist/extractors/erlang.d.ts +14 -0
- package/dist/extractors/erlang.d.ts.map +1 -0
- package/dist/extractors/erlang.js +239 -0
- package/dist/extractors/erlang.js.map +1 -0
- package/dist/extractors/fsharp.d.ts +13 -0
- package/dist/extractors/fsharp.d.ts.map +1 -0
- package/dist/extractors/fsharp.js +218 -0
- package/dist/extractors/fsharp.js.map +1 -0
- package/dist/extractors/gleam.d.ts +14 -0
- package/dist/extractors/gleam.d.ts.map +1 -0
- package/dist/extractors/gleam.js +229 -0
- package/dist/extractors/gleam.js.map +1 -0
- package/dist/extractors/go.js +36 -33
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/groovy.d.ts +10 -0
- package/dist/extractors/groovy.d.ts.map +1 -0
- package/dist/extractors/groovy.js +304 -0
- package/dist/extractors/groovy.js.map +1 -0
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +40 -29
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/index.d.ts +11 -0
- package/dist/extractors/index.d.ts.map +1 -1
- package/dist/extractors/index.js +11 -0
- package/dist/extractors/index.js.map +1 -1
- package/dist/extractors/java.js +58 -46
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.js +46 -45
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/julia.d.ts +16 -0
- package/dist/extractors/julia.d.ts.map +1 -0
- package/dist/extractors/julia.js +287 -0
- package/dist/extractors/julia.js.map +1 -0
- package/dist/extractors/kotlin.js +84 -78
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/objc.d.ts +9 -0
- package/dist/extractors/objc.d.ts.map +1 -0
- package/dist/extractors/objc.js +406 -0
- package/dist/extractors/objc.js.map +1 -0
- package/dist/extractors/ocaml.js +74 -0
- package/dist/extractors/ocaml.js.map +1 -1
- package/dist/extractors/python.js +29 -24
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/r.d.ts +13 -0
- package/dist/extractors/r.d.ts.map +1 -0
- package/dist/extractors/r.js +251 -0
- package/dist/extractors/r.js.map +1 -0
- package/dist/extractors/rust.js +41 -32
- package/dist/extractors/rust.js.map +1 -1
- package/dist/extractors/solidity.d.ts +9 -0
- package/dist/extractors/solidity.d.ts.map +1 -0
- package/dist/extractors/solidity.js +365 -0
- package/dist/extractors/solidity.js.map +1 -0
- package/dist/extractors/swift.js +83 -81
- package/dist/extractors/swift.js.map +1 -1
- package/dist/extractors/verilog.d.ts +9 -0
- package/dist/extractors/verilog.d.ts.map +1 -0
- package/dist/extractors/verilog.js +286 -0
- package/dist/extractors/verilog.js.map +1 -0
- package/dist/extractors/zig.js +58 -60
- package/dist/extractors/zig.js.map +1 -1
- package/dist/features/ast.d.ts +16 -14
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +84 -83
- package/dist/features/ast.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +8 -6
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +69 -72
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/communities.d.ts.map +1 -1
- package/dist/features/communities.js +19 -7
- package/dist/features/communities.js.map +1 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +120 -125
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +136 -137
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js +84 -79
- package/dist/features/flow.js.map +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +69 -65
- package/dist/features/structure-query.js.map +1 -1
- package/dist/graph/algorithms/bfs.d.ts +2 -0
- package/dist/graph/algorithms/bfs.d.ts.map +1 -1
- package/dist/graph/algorithms/bfs.js +27 -0
- package/dist/graph/algorithms/bfs.js.map +1 -1
- package/dist/graph/algorithms/centrality.d.ts +2 -0
- package/dist/graph/algorithms/centrality.d.ts.map +1 -1
- package/dist/graph/algorithms/centrality.js +28 -0
- package/dist/graph/algorithms/centrality.js.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.js +70 -55
- package/dist/graph/algorithms/leiden/optimiser.js.map +1 -1
- package/dist/graph/algorithms/leiden/partition.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/partition.js +288 -266
- package/dist/graph/algorithms/leiden/partition.js.map +1 -1
- package/dist/graph/algorithms/louvain.d.ts +3 -4
- package/dist/graph/algorithms/louvain.d.ts.map +1 -1
- package/dist/graph/algorithms/louvain.js +29 -0
- package/dist/graph/algorithms/louvain.js.map +1 -1
- package/dist/graph/algorithms/shortest-path.d.ts +2 -0
- package/dist/graph/algorithms/shortest-path.d.ts.map +1 -1
- package/dist/graph/algorithms/shortest-path.js +18 -1
- package/dist/graph/algorithms/shortest-path.js.map +1 -1
- package/dist/graph/model.d.ts.map +1 -1
- package/dist/graph/model.js +5 -1
- package/dist/graph/model.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +6 -4
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/suppress.d.ts +25 -0
- package/dist/infrastructure/suppress.d.ts.map +1 -0
- package/dist/infrastructure/suppress.js +43 -0
- package/dist/infrastructure/suppress.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +29 -24
- package/dist/mcp/server.js.map +1 -1
- package/dist/presentation/dataflow.d.ts.map +1 -1
- package/dist/presentation/dataflow.js +47 -38
- package/dist/presentation/dataflow.js.map +1 -1
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -1
- package/dist/presentation/diff-impact-mermaid.js +60 -51
- package/dist/presentation/diff-impact-mermaid.js.map +1 -1
- package/dist/presentation/queries-cli/exports.d.ts.map +1 -1
- package/dist/presentation/queries-cli/exports.js +20 -14
- package/dist/presentation/queries-cli/exports.js.map +1 -1
- package/dist/presentation/queries-cli/impact.d.ts.map +1 -1
- package/dist/presentation/queries-cli/impact.js +15 -13
- package/dist/presentation/queries-cli/impact.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js +101 -79
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
- package/dist/presentation/queries-cli/overview.js +25 -16
- package/dist/presentation/queries-cli/overview.js.map +1 -1
- package/dist/presentation/queries-cli/path.js +26 -20
- package/dist/presentation/queries-cli/path.js.map +1 -1
- package/dist/presentation/result-formatter.d.ts +10 -0
- package/dist/presentation/result-formatter.d.ts.map +1 -1
- package/dist/presentation/result-formatter.js +16 -1
- package/dist/presentation/result-formatter.js.map +1 -1
- package/dist/presentation/viewer.d.ts.map +1 -1
- package/dist/presentation/viewer.js +18 -12
- package/dist/presentation/viewer.js.map +1 -1
- package/dist/shared/errors.d.ts +5 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +5 -0
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/hierarchy.d.ts +8 -2
- package/dist/shared/hierarchy.d.ts.map +1 -1
- package/dist/shared/hierarchy.js +42 -1
- package/dist/shared/hierarchy.js.map +1 -1
- package/dist/shared/normalize.d.ts +6 -1
- package/dist/shared/normalize.d.ts.map +1 -1
- package/dist/shared/normalize.js +20 -12
- package/dist/shared/normalize.js.map +1 -1
- package/dist/shared/paginate.d.ts +0 -9
- package/dist/shared/paginate.d.ts.map +1 -1
- package/dist/shared/paginate.js +0 -15
- package/dist/shared/paginate.js.map +1 -1
- package/dist/types.d.ts +129 -3
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-clojure.wasm +0 -0
- package/grammars/tree-sitter-cuda.wasm +0 -0
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/grammars/tree-sitter-fsharp.wasm +0 -0
- package/grammars/tree-sitter-gleam.wasm +0 -0
- package/grammars/tree-sitter-groovy.wasm +0 -0
- package/grammars/tree-sitter-julia.wasm +0 -0
- package/grammars/tree-sitter-objc.wasm +0 -0
- package/grammars/tree-sitter-ocaml_interface.wasm +0 -0
- package/grammars/tree-sitter-r.wasm +0 -0
- package/grammars/tree-sitter-solidity.wasm +0 -0
- package/grammars/tree-sitter-verilog.wasm +0 -0
- package/package.json +18 -7
- package/src/ast-analysis/engine.ts +245 -42
- package/src/ast-analysis/metrics.ts +33 -11
- package/src/ast-analysis/rules/javascript.ts +0 -1
- package/src/ast-analysis/shared.ts +33 -24
- package/src/ast-analysis/visitor-utils.ts +52 -32
- package/src/ast-analysis/visitor.ts +132 -71
- package/src/ast-analysis/visitors/ast-store-visitor.ts +49 -119
- package/src/ast-analysis/visitors/complexity-visitor.ts +35 -40
- package/src/ast-analysis/visitors/dataflow-visitor.ts +87 -43
- package/src/cli/commands/ast.ts +2 -2
- package/src/cli/commands/watch.ts +16 -2
- package/src/db/connection.ts +29 -28
- package/src/db/query-builder.ts +15 -3
- package/src/db/repository/base.ts +20 -0
- package/src/db/repository/native-repository.ts +79 -1
- package/src/db/repository/nodes.ts +13 -8
- package/src/db/repository/sqlite-repository.ts +29 -0
- package/src/domain/analysis/brief.ts +15 -25
- package/src/domain/analysis/context.ts +17 -10
- package/src/domain/analysis/dependencies.ts +67 -76
- package/src/domain/analysis/fn-impact.ts +36 -43
- package/src/domain/analysis/implementations.ts +11 -17
- package/src/domain/analysis/module-map.ts +58 -92
- package/src/domain/analysis/query-helpers.ts +18 -1
- package/src/domain/graph/builder/pipeline.ts +366 -41
- package/src/domain/graph/builder/stages/build-edges.ts +162 -1
- package/src/domain/graph/builder/stages/collect-files.ts +18 -7
- package/src/domain/graph/builder/stages/detect-changes.ts +110 -56
- package/src/domain/graph/builder/stages/finalize.ts +41 -11
- package/src/domain/graph/builder/stages/insert-nodes.ts +75 -39
- package/src/domain/graph/builder/stages/resolve-imports.ts +122 -100
- package/src/domain/graph/cycles.ts +110 -23
- package/src/domain/graph/resolve.ts +1 -1
- package/src/domain/graph/watcher.ts +202 -96
- package/src/domain/parser.ts +122 -28
- package/src/domain/search/generator.ts +1 -1
- package/src/domain/search/models.ts +17 -4
- package/src/domain/search/search/hybrid.ts +69 -51
- package/src/extractors/clojure.ts +273 -0
- package/src/extractors/cuda.ts +316 -0
- package/src/extractors/erlang.ts +252 -0
- package/src/extractors/fsharp.ts +253 -0
- package/src/extractors/gleam.ts +246 -0
- package/src/extractors/go.ts +43 -33
- package/src/extractors/groovy.ts +332 -0
- package/src/extractors/helpers.ts +37 -23
- package/src/extractors/index.ts +11 -0
- package/src/extractors/java.ts +66 -47
- package/src/extractors/javascript.ts +45 -46
- package/src/extractors/julia.ts +318 -0
- package/src/extractors/kotlin.ts +84 -77
- package/src/extractors/objc.ts +431 -0
- package/src/extractors/ocaml.ts +78 -0
- package/src/extractors/python.ts +31 -25
- package/src/extractors/r.ts +253 -0
- package/src/extractors/rust.ts +37 -29
- package/src/extractors/solidity.ts +394 -0
- package/src/extractors/swift.ts +81 -80
- package/src/extractors/verilog.ts +315 -0
- package/src/extractors/zig.ts +58 -61
- package/src/features/ast.ts +131 -112
- package/src/features/audit.ts +8 -6
- package/src/features/branch-compare.ts +105 -79
- package/src/features/communities.ts +25 -10
- package/src/features/complexity.ts +171 -134
- package/src/features/dataflow.ts +165 -175
- package/src/features/flow.ts +129 -92
- package/src/features/structure-query.ts +79 -64
- package/src/graph/algorithms/bfs.ts +34 -0
- package/src/graph/algorithms/centrality.ts +30 -0
- package/src/graph/algorithms/leiden/optimiser.ts +99 -55
- package/src/graph/algorithms/leiden/partition.ts +359 -294
- package/src/graph/algorithms/louvain.ts +31 -4
- package/src/graph/algorithms/shortest-path.ts +20 -1
- package/src/graph/model.ts +6 -1
- package/src/infrastructure/config.ts +6 -4
- package/src/infrastructure/suppress.ts +47 -0
- package/src/mcp/server.ts +53 -37
- package/src/presentation/dataflow.ts +50 -44
- package/src/presentation/diff-impact-mermaid.ts +104 -62
- package/src/presentation/queries-cli/exports.ts +21 -13
- package/src/presentation/queries-cli/impact.ts +15 -13
- package/src/presentation/queries-cli/inspect.ts +100 -81
- package/src/presentation/queries-cli/overview.ts +26 -16
- package/src/presentation/queries-cli/path.ts +33 -25
- package/src/presentation/result-formatter.ts +19 -1
- package/src/presentation/viewer.ts +42 -14
- package/src/shared/errors.ts +6 -0
- package/src/shared/hierarchy.ts +50 -2
- package/src/shared/normalize.ts +31 -12
- package/src/shared/paginate.ts +0 -17
- package/src/types.ts +138 -3
|
@@ -68,6 +68,67 @@ interface DirectoryEntry {
|
|
|
68
68
|
subdirectories: string[];
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function buildDirectoryEntry(
|
|
72
|
+
d: DirRow,
|
|
73
|
+
filesStmt: { all(...params: unknown[]): unknown[] },
|
|
74
|
+
subdirsStmt: { all(...params: unknown[]): unknown[] },
|
|
75
|
+
noTests: boolean,
|
|
76
|
+
): DirectoryEntry {
|
|
77
|
+
let files = filesStmt.all(d.id) as FileMetricRow[];
|
|
78
|
+
if (noTests) files = files.filter((f) => !isTestFile(f.name));
|
|
79
|
+
|
|
80
|
+
const subdirs = subdirsStmt.all(d.id) as { name: string }[];
|
|
81
|
+
|
|
82
|
+
const fileCount = noTests ? files.length : d.file_count || 0;
|
|
83
|
+
return {
|
|
84
|
+
directory: d.name,
|
|
85
|
+
fileCount,
|
|
86
|
+
symbolCount: d.symbol_count || 0,
|
|
87
|
+
fanIn: d.fan_in || 0,
|
|
88
|
+
fanOut: d.fan_out || 0,
|
|
89
|
+
cohesion: d.cohesion,
|
|
90
|
+
density: fileCount > 0 ? (d.symbol_count || 0) / fileCount : 0,
|
|
91
|
+
files: files.map((f) => ({
|
|
92
|
+
file: f.name,
|
|
93
|
+
lineCount: f.line_count || 0,
|
|
94
|
+
symbolCount: f.symbol_count || 0,
|
|
95
|
+
importCount: f.import_count || 0,
|
|
96
|
+
exportCount: f.export_count || 0,
|
|
97
|
+
fanIn: f.fan_in || 0,
|
|
98
|
+
fanOut: f.fan_out || 0,
|
|
99
|
+
})),
|
|
100
|
+
subdirectories: subdirs.map((s) => s.name),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function applyFileLimit(
|
|
105
|
+
result: DirectoryEntry[],
|
|
106
|
+
fileLimit: number,
|
|
107
|
+
): { directories: DirectoryEntry[]; count: number; suppressed: number; warning: string } | null {
|
|
108
|
+
const totalFiles = result.reduce((sum, d) => sum + d.files.length, 0);
|
|
109
|
+
if (totalFiles <= fileLimit) return null;
|
|
110
|
+
|
|
111
|
+
let shown = 0;
|
|
112
|
+
for (const d of result) {
|
|
113
|
+
const remaining = fileLimit - shown;
|
|
114
|
+
if (remaining <= 0) {
|
|
115
|
+
d.files = [];
|
|
116
|
+
} else if (d.files.length > remaining) {
|
|
117
|
+
d.files = d.files.slice(0, remaining);
|
|
118
|
+
shown = fileLimit;
|
|
119
|
+
} else {
|
|
120
|
+
shown += d.files.length;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const suppressed = totalFiles - fileLimit;
|
|
124
|
+
return {
|
|
125
|
+
directories: result,
|
|
126
|
+
count: result.length,
|
|
127
|
+
suppressed,
|
|
128
|
+
warning: `${suppressed} files omitted (showing ${fileLimit}/${totalFiles}). Use --full to show all files, or narrow with --directory.`,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
71
132
|
export function structureData(
|
|
72
133
|
customDbPath?: string,
|
|
73
134
|
opts: StructureDataOpts = {},
|
|
@@ -115,73 +176,27 @@ export function structureData(
|
|
|
115
176
|
dirs.sort(sortFn);
|
|
116
177
|
|
|
117
178
|
// Get file metrics for each directory
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
JOIN nodes n ON e.target_id = n.id
|
|
135
|
-
WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'directory'
|
|
136
|
-
`)
|
|
137
|
-
.all(d.id) as { name: string }[];
|
|
138
|
-
|
|
139
|
-
const fileCount = noTests ? files.length : d.file_count || 0;
|
|
140
|
-
return {
|
|
141
|
-
directory: d.name,
|
|
142
|
-
fileCount,
|
|
143
|
-
symbolCount: d.symbol_count || 0,
|
|
144
|
-
fanIn: d.fan_in || 0,
|
|
145
|
-
fanOut: d.fan_out || 0,
|
|
146
|
-
cohesion: d.cohesion,
|
|
147
|
-
density: fileCount > 0 ? (d.symbol_count || 0) / fileCount : 0,
|
|
148
|
-
files: files.map((f) => ({
|
|
149
|
-
file: f.name,
|
|
150
|
-
lineCount: f.line_count || 0,
|
|
151
|
-
symbolCount: f.symbol_count || 0,
|
|
152
|
-
importCount: f.import_count || 0,
|
|
153
|
-
exportCount: f.export_count || 0,
|
|
154
|
-
fanIn: f.fan_in || 0,
|
|
155
|
-
fanOut: f.fan_out || 0,
|
|
156
|
-
})),
|
|
157
|
-
subdirectories: subdirs.map((s) => s.name),
|
|
158
|
-
};
|
|
159
|
-
});
|
|
179
|
+
const filesStmt = db.prepare(`
|
|
180
|
+
SELECT n.name, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count, nm.fan_in, nm.fan_out
|
|
181
|
+
FROM edges e
|
|
182
|
+
JOIN nodes n ON e.target_id = n.id
|
|
183
|
+
LEFT JOIN node_metrics nm ON n.id = nm.node_id
|
|
184
|
+
WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'file'
|
|
185
|
+
`);
|
|
186
|
+
const subdirsStmt = db.prepare(`
|
|
187
|
+
SELECT n.name
|
|
188
|
+
FROM edges e
|
|
189
|
+
JOIN nodes n ON e.target_id = n.id
|
|
190
|
+
WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'directory'
|
|
191
|
+
`);
|
|
192
|
+
const result: DirectoryEntry[] = dirs.map((d) =>
|
|
193
|
+
buildDirectoryEntry(d, filesStmt, subdirsStmt, noTests),
|
|
194
|
+
);
|
|
160
195
|
|
|
161
196
|
// Apply global file limit unless full mode
|
|
162
197
|
if (!full) {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
165
|
-
let shown = 0;
|
|
166
|
-
for (const d of result) {
|
|
167
|
-
const remaining = fileLimit - shown;
|
|
168
|
-
if (remaining <= 0) {
|
|
169
|
-
d.files = [];
|
|
170
|
-
} else if (d.files.length > remaining) {
|
|
171
|
-
d.files = d.files.slice(0, remaining);
|
|
172
|
-
shown = fileLimit;
|
|
173
|
-
} else {
|
|
174
|
-
shown += d.files.length;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
const suppressed = totalFiles - fileLimit;
|
|
178
|
-
return {
|
|
179
|
-
directories: result,
|
|
180
|
-
count: result.length,
|
|
181
|
-
suppressed,
|
|
182
|
-
warning: `${suppressed} files omitted (showing ${fileLimit}/${totalFiles}). Use --full to show all files, or narrow with --directory.`,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
198
|
+
const limited = applyFileLimit(result, fileLimit);
|
|
199
|
+
if (limited) return limited;
|
|
185
200
|
}
|
|
186
201
|
|
|
187
202
|
const base = { directories: result, count: result.length };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadNative } from '../../infrastructure/native.js';
|
|
1
2
|
import type { CodeGraph } from '../model.js';
|
|
2
3
|
|
|
3
4
|
export interface BfsOpts {
|
|
@@ -8,6 +9,8 @@ export interface BfsOpts {
|
|
|
8
9
|
/**
|
|
9
10
|
* Breadth-first traversal on a CodeGraph.
|
|
10
11
|
*
|
|
12
|
+
* Tries the native Rust implementation first, falls back to JS.
|
|
13
|
+
*
|
|
11
14
|
* @returns nodeId → depth from nearest start node
|
|
12
15
|
*/
|
|
13
16
|
export function bfs(
|
|
@@ -19,6 +22,37 @@ export function bfs(
|
|
|
19
22
|
const direction = opts.direction ?? 'forward';
|
|
20
23
|
const starts = Array.isArray(startIds) ? startIds : [startIds];
|
|
21
24
|
|
|
25
|
+
const native = loadNative();
|
|
26
|
+
if (native?.bfsTraversal) {
|
|
27
|
+
const edges = graph.toEdgeArray();
|
|
28
|
+
const nativeMaxDepth = maxDepth === Infinity ? null : maxDepth;
|
|
29
|
+
// Undirected graphs deduplicate edges to one canonical direction in toEdgeArray(),
|
|
30
|
+
// so the Rust side must traverse both directions to preserve symmetry.
|
|
31
|
+
const nativeDirection = !graph.directed ? 'both' : direction;
|
|
32
|
+
const result = native.bfsTraversal(edges, starts, nativeMaxDepth, nativeDirection);
|
|
33
|
+
const depths = new Map<string, number>();
|
|
34
|
+
for (const entry of result) {
|
|
35
|
+
depths.set(entry.node, entry.depth);
|
|
36
|
+
}
|
|
37
|
+
// The Rust side only knows nodes referenced by edges; restore any isolated start nodes.
|
|
38
|
+
for (const startId of starts) {
|
|
39
|
+
if (graph.hasNode(startId) && !depths.has(startId)) {
|
|
40
|
+
depths.set(startId, 0);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return depths;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return bfsJS(graph, starts, maxDepth, direction);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Pure JS fallback for BFS (used when native addon is unavailable). */
|
|
50
|
+
function bfsJS(
|
|
51
|
+
graph: CodeGraph,
|
|
52
|
+
starts: string[],
|
|
53
|
+
maxDepth: number,
|
|
54
|
+
direction: string,
|
|
55
|
+
): Map<string, number> {
|
|
22
56
|
const depths = new Map<string, number>();
|
|
23
57
|
const queue: string[] = [];
|
|
24
58
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadNative } from '../../infrastructure/native.js';
|
|
1
2
|
import type { CodeGraph } from '../model.js';
|
|
2
3
|
|
|
3
4
|
export interface FanInOut {
|
|
@@ -7,8 +8,37 @@ export interface FanInOut {
|
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Fan-in / fan-out centrality for all nodes in a CodeGraph.
|
|
11
|
+
*
|
|
12
|
+
* Tries the native Rust implementation first, falls back to JS.
|
|
10
13
|
*/
|
|
11
14
|
export function fanInOut(graph: CodeGraph): Map<string, FanInOut> {
|
|
15
|
+
const native = loadNative();
|
|
16
|
+
if (native?.fanInOut) {
|
|
17
|
+
let edges = graph.toEdgeArray();
|
|
18
|
+
if (!graph.directed) {
|
|
19
|
+
// Undirected: toEdgeArray() deduplicates to one canonical direction;
|
|
20
|
+
// mirror each edge so the Rust side counts symmetric in/out degrees.
|
|
21
|
+
edges = [...edges, ...edges.map((e) => ({ source: e.target, target: e.source }))];
|
|
22
|
+
}
|
|
23
|
+
const nativeResult = native.fanInOut(edges);
|
|
24
|
+
const result = new Map<string, FanInOut>();
|
|
25
|
+
for (const entry of nativeResult) {
|
|
26
|
+
result.set(entry.node, { fanIn: entry.fanIn, fanOut: entry.fanOut });
|
|
27
|
+
}
|
|
28
|
+
// Ensure isolated nodes (no edges) are included
|
|
29
|
+
for (const id of graph.nodeIds()) {
|
|
30
|
+
if (!result.has(id)) {
|
|
31
|
+
result.set(id, { fanIn: 0, fanOut: 0 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return fanInOutJS(graph);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Pure JS fallback for fan-in/out. */
|
|
41
|
+
function fanInOutJS(graph: CodeGraph): Map<string, FanInOut> {
|
|
12
42
|
const result = new Map<string, FanInOut>();
|
|
13
43
|
for (const id of graph.nodeIds()) {
|
|
14
44
|
result.set(id, {
|
|
@@ -18,6 +18,13 @@ const DEFAULT_MAX_LEVELS: number = 50;
|
|
|
18
18
|
const DEFAULT_MAX_LOCAL_PASSES: number = 20;
|
|
19
19
|
const GAIN_EPSILON: number = 1e-12;
|
|
20
20
|
|
|
21
|
+
/** Pre-allocated scratch buffers for refinement candidate collection. */
|
|
22
|
+
interface RefinementScratch {
|
|
23
|
+
candC: Int32Array;
|
|
24
|
+
candGain: Float64Array;
|
|
25
|
+
candWeight: Float64Array;
|
|
26
|
+
}
|
|
27
|
+
|
|
21
28
|
const CandidateStrategy = {
|
|
22
29
|
Neighbors: 0,
|
|
23
30
|
All: 1,
|
|
@@ -335,6 +342,79 @@ function buildCoarseGraph(g: GraphAdapter, p: Partition): CodeGraph {
|
|
|
335
342
|
return coarse;
|
|
336
343
|
}
|
|
337
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Collect eligible candidate communities for node `v` during refinement.
|
|
347
|
+
* A candidate must: (a) be in the same macro-community, (b) respect the size
|
|
348
|
+
* limit, and (c) produce a positive quality gain above GAIN_EPSILON.
|
|
349
|
+
* Returns the number of collected candidates written into `scratch`.
|
|
350
|
+
*/
|
|
351
|
+
function collectRefinementCandidates(
|
|
352
|
+
p: Partition,
|
|
353
|
+
g: GraphAdapter,
|
|
354
|
+
v: number,
|
|
355
|
+
touchedCount: number,
|
|
356
|
+
macroV: number,
|
|
357
|
+
commMacro: Int32Array,
|
|
358
|
+
maxSize: number,
|
|
359
|
+
opts: NormalizedOptions,
|
|
360
|
+
scratch: RefinementScratch,
|
|
361
|
+
): number {
|
|
362
|
+
let candLen: number = 0;
|
|
363
|
+
for (let t = 0; t < touchedCount; t++) {
|
|
364
|
+
const c: number = p.getCandidateCommunityAt(t);
|
|
365
|
+
if (c === p.nodeCommunity[v]!) continue;
|
|
366
|
+
if (commMacro[c]! !== macroV) continue;
|
|
367
|
+
if (maxSize < Infinity) {
|
|
368
|
+
const nextSize: number = p.getCommunityTotalSize(c) + g.size[v]!;
|
|
369
|
+
if (nextSize > maxSize) continue;
|
|
370
|
+
}
|
|
371
|
+
const gain: number = computeQualityGain(p, v, c, opts);
|
|
372
|
+
if (gain > GAIN_EPSILON) {
|
|
373
|
+
scratch.candC[candLen] = c;
|
|
374
|
+
scratch.candGain[candLen] = gain;
|
|
375
|
+
candLen++;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return candLen;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Boltzmann probabilistic selection from collected candidates (Algorithm 3).
|
|
383
|
+
* Returns the chosen community ID, or -1 if the node should stay as singleton.
|
|
384
|
+
*
|
|
385
|
+
* p(v, C) is proportional to exp(deltaH / theta), with the "stay as singleton"
|
|
386
|
+
* option (deltaH = 0) included. For numerical stability, the max gain is
|
|
387
|
+
* subtracted before exponentiation.
|
|
388
|
+
*/
|
|
389
|
+
function boltzmannSelectCandidate(
|
|
390
|
+
candLen: number,
|
|
391
|
+
theta: number,
|
|
392
|
+
rng: () => number,
|
|
393
|
+
scratch: RefinementScratch,
|
|
394
|
+
): number {
|
|
395
|
+
let maxGain: number = 0;
|
|
396
|
+
for (let i = 0; i < candLen; i++) {
|
|
397
|
+
if (scratch.candGain[i]! > maxGain) maxGain = scratch.candGain[i]!;
|
|
398
|
+
}
|
|
399
|
+
// "Stay as singleton" weight: exp((0 - maxGain) / theta)
|
|
400
|
+
const stayWeight: number = Math.exp((0 - maxGain) / theta);
|
|
401
|
+
let totalWeight: number = stayWeight;
|
|
402
|
+
for (let i = 0; i < candLen; i++) {
|
|
403
|
+
scratch.candWeight[i] = Math.exp((scratch.candGain[i]! - maxGain) / theta);
|
|
404
|
+
totalWeight += scratch.candWeight[i]!;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const r: number = rng() * totalWeight;
|
|
408
|
+
if (r < stayWeight) return -1; // node stays as singleton
|
|
409
|
+
|
|
410
|
+
let cumulative: number = stayWeight;
|
|
411
|
+
for (let i = 0; i < candLen; i++) {
|
|
412
|
+
cumulative += scratch.candWeight[i]!;
|
|
413
|
+
if (r < cumulative) return scratch.candC[i]!;
|
|
414
|
+
}
|
|
415
|
+
return scratch.candC[candLen - 1]!; // fallback
|
|
416
|
+
}
|
|
417
|
+
|
|
338
418
|
/**
|
|
339
419
|
* True Leiden refinement phase (Algorithm 3, Traag et al. 2019).
|
|
340
420
|
*
|
|
@@ -380,10 +460,12 @@ function refineWithinCoarseCommunities(
|
|
|
380
460
|
shuffleArrayInPlace(order, rng);
|
|
381
461
|
|
|
382
462
|
// Pre-allocate flat arrays for candidate collection to avoid per-node GC pressure.
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
463
|
+
const scratch: RefinementScratch = {
|
|
464
|
+
candC: new Int32Array(g.n),
|
|
465
|
+
candGain: new Float64Array(g.n),
|
|
466
|
+
candWeight: new Float64Array(g.n),
|
|
467
|
+
};
|
|
468
|
+
const maxSize: number = Number.isFinite(opts.maxCommunitySize) ? opts.maxCommunitySize : Infinity;
|
|
387
469
|
|
|
388
470
|
for (let idx = 0; idx < order.length; idx++) {
|
|
389
471
|
const v: number = order[idx]!;
|
|
@@ -394,59 +476,21 @@ function refineWithinCoarseCommunities(
|
|
|
394
476
|
|
|
395
477
|
const macroV: number = macro[v]!;
|
|
396
478
|
const touchedCount: number = p.accumulateNeighborCommunityEdgeWeights(v);
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const nextSize: number = p.getCommunityTotalSize(c) + g.size[v]!;
|
|
409
|
-
if (nextSize > maxSize) continue;
|
|
410
|
-
}
|
|
411
|
-
const gain: number = computeQualityGain(p, v, c, opts);
|
|
412
|
-
if (gain > GAIN_EPSILON) {
|
|
413
|
-
candC[candLen] = c;
|
|
414
|
-
candGain[candLen] = gain;
|
|
415
|
-
candLen++;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
479
|
+
const candLen: number = collectRefinementCandidates(
|
|
480
|
+
p,
|
|
481
|
+
g,
|
|
482
|
+
v,
|
|
483
|
+
touchedCount,
|
|
484
|
+
macroV,
|
|
485
|
+
commMacro,
|
|
486
|
+
maxSize,
|
|
487
|
+
opts,
|
|
488
|
+
scratch,
|
|
489
|
+
);
|
|
419
490
|
if (candLen === 0) continue;
|
|
420
491
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
// For numerical stability, subtract the max gain before exponentiation.
|
|
424
|
-
let maxGain: number = 0;
|
|
425
|
-
for (let i = 0; i < candLen; i++) {
|
|
426
|
-
if (candGain[i]! > maxGain) maxGain = candGain[i]!;
|
|
427
|
-
}
|
|
428
|
-
// "Stay as singleton" weight: exp((0 - maxGain) / theta)
|
|
429
|
-
const stayWeight: number = Math.exp((0 - maxGain) / theta);
|
|
430
|
-
let totalWeight: number = stayWeight;
|
|
431
|
-
for (let i = 0; i < candLen; i++) {
|
|
432
|
-
candWeight[i] = Math.exp((candGain[i]! - maxGain) / theta);
|
|
433
|
-
totalWeight += candWeight[i]!;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
const r: number = rng() * totalWeight;
|
|
437
|
-
if (r < stayWeight) continue; // node stays as singleton
|
|
438
|
-
|
|
439
|
-
let cumulative: number = stayWeight;
|
|
440
|
-
let chosenC: number = candC[candLen - 1]!; // fallback
|
|
441
|
-
for (let i = 0; i < candLen; i++) {
|
|
442
|
-
cumulative += candWeight[i]!;
|
|
443
|
-
if (r < cumulative) {
|
|
444
|
-
chosenC = candC[i]!;
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
p.moveNodeToCommunity(v, chosenC);
|
|
492
|
+
const chosenC: number = boltzmannSelectCandidate(candLen, theta, rng, scratch);
|
|
493
|
+
if (chosenC >= 0) p.moveNodeToCommunity(v, chosenC);
|
|
450
494
|
}
|
|
451
495
|
return p;
|
|
452
496
|
}
|