@mycodemap/mycodemap 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/README.md +307 -243
- package/dist/ai/claude.d.ts +38 -0
- package/dist/ai/claude.d.ts.map +1 -0
- package/dist/ai/claude.js +169 -0
- package/dist/ai/claude.js.map +1 -0
- package/dist/ai/codex.d.ts +38 -0
- package/dist/ai/codex.d.ts.map +1 -0
- package/dist/ai/codex.js +169 -0
- package/dist/ai/codex.js.map +1 -0
- package/dist/ai/factory.d.ts +48 -0
- package/dist/ai/factory.d.ts.map +1 -0
- package/dist/ai/factory.js +95 -0
- package/dist/ai/factory.js.map +1 -0
- package/dist/ai/index.d.ts +12 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +29 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/provider.d.ts +70 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +31 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ai/subagent-caller.d.ts +90 -0
- package/dist/ai/subagent-caller.d.ts.map +1 -0
- package/dist/ai/subagent-caller.js +280 -0
- package/dist/ai/subagent-caller.js.map +1 -0
- package/dist/ai/types.d.ts +70 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +5 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/commands/analyze-options.d.ts +36 -0
- package/dist/cli/commands/analyze-options.d.ts.map +1 -0
- package/dist/cli/commands/analyze-options.js +147 -0
- package/dist/cli/commands/analyze-options.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +93 -4
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +592 -176
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/ci.d.ts +47 -1
- package/dist/cli/commands/ci.d.ts.map +1 -1
- package/dist/cli/commands/ci.js +208 -1
- package/dist/cli/commands/ci.js.map +1 -1
- package/dist/cli/commands/design.d.ts +47 -0
- package/dist/cli/commands/design.d.ts.map +1 -0
- package/dist/cli/commands/design.js +268 -0
- package/dist/cli/commands/design.js.map +1 -0
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +2 -2
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +8 -2
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +151 -22
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +2 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/server.d.ts.map +1 -1
- package/dist/cli/commands/server.js +2 -5
- package/dist/cli/commands/server.js.map +1 -1
- package/dist/cli/commands/ship/checker.d.ts.map +1 -1
- package/dist/cli/commands/ship/checker.js +0 -3
- package/dist/cli/commands/ship/checker.js.map +1 -1
- package/dist/cli/commands/ship/pipeline.d.ts.map +1 -1
- package/dist/cli/commands/ship/pipeline.js +8 -1
- package/dist/cli/commands/ship/pipeline.js.map +1 -1
- package/dist/cli/commands/ship/publisher.d.ts +9 -1
- package/dist/cli/commands/ship/publisher.d.ts.map +1 -1
- package/dist/cli/commands/ship/publisher.js +149 -6
- package/dist/cli/commands/ship/publisher.js.map +1 -1
- package/dist/cli/commands/ship/rules/quality-rules.d.ts +0 -1
- package/dist/cli/commands/ship/rules/quality-rules.d.ts.map +1 -1
- package/dist/cli/commands/ship/rules/quality-rules.js +4 -76
- package/dist/cli/commands/ship/rules/quality-rules.js.map +1 -1
- package/dist/cli/commands/workflow.js +4 -4
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/config-loader.d.ts +31 -0
- package/dist/cli/config-loader.d.ts.map +1 -0
- package/dist/cli/config-loader.js +235 -0
- package/dist/cli/config-loader.js.map +1 -0
- package/dist/cli/design-contract-loader.d.ts +15 -0
- package/dist/cli/design-contract-loader.d.ts.map +1 -0
- package/dist/cli/design-contract-loader.js +175 -0
- package/dist/cli/design-contract-loader.js.map +1 -0
- package/dist/cli/design-contract-schema.d.ts +11 -0
- package/dist/cli/design-contract-schema.d.ts.map +1 -0
- package/dist/cli/design-contract-schema.js +75 -0
- package/dist/cli/design-contract-schema.js.map +1 -0
- package/dist/cli/design-handoff-builder.d.ts +15 -0
- package/dist/cli/design-handoff-builder.d.ts.map +1 -0
- package/dist/cli/design-handoff-builder.js +345 -0
- package/dist/cli/design-handoff-builder.js.map +1 -0
- package/dist/cli/design-scope-resolver.d.ts +8 -0
- package/dist/cli/design-scope-resolver.d.ts.map +1 -0
- package/dist/cli/design-scope-resolver.js +712 -0
- package/dist/cli/design-scope-resolver.js.map +1 -0
- package/dist/cli/design-verification-builder.d.ts +8 -0
- package/dist/cli/design-verification-builder.d.ts.map +1 -0
- package/dist/cli/design-verification-builder.js +369 -0
- package/dist/cli/design-verification-builder.js.map +1 -0
- package/dist/cli/index.js +20 -63
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/removed-commands.d.ts +9 -0
- package/dist/cli/removed-commands.d.ts.map +1 -0
- package/dist/cli/removed-commands.js +48 -0
- package/dist/cli/removed-commands.js.map +1 -0
- package/dist/cli/storage-runtime.d.ts +8 -0
- package/dist/cli/storage-runtime.d.ts.map +1 -0
- package/dist/cli/storage-runtime.js +14 -0
- package/dist/cli/storage-runtime.js.map +1 -0
- package/dist/cli/tree-sitter-check.d.ts.map +1 -1
- package/dist/cli/tree-sitter-check.js +0 -1
- package/dist/cli/tree-sitter-check.js.map +1 -1
- package/dist/cli-new/commands/export.d.ts.map +1 -1
- package/dist/cli-new/commands/export.js +2 -2
- package/dist/cli-new/commands/export.js.map +1 -1
- package/dist/cli-new/commands/query.d.ts.map +1 -1
- package/dist/cli-new/commands/query.js +5 -4
- package/dist/cli-new/commands/query.js.map +1 -1
- package/dist/cli-new/commands/server.d.ts.map +1 -1
- package/dist/cli-new/commands/server.js +2 -6
- package/dist/cli-new/commands/server.js.map +1 -1
- package/dist/cli-new/index.d.ts.map +1 -1
- package/dist/cli-new/index.js +0 -2
- package/dist/cli-new/index.js.map +1 -1
- package/dist/core/analyzer.d.ts.map +1 -1
- package/dist/core/analyzer.js +7 -39
- package/dist/core/analyzer.js.map +1 -1
- package/dist/core/file-discovery.d.ts +17 -0
- package/dist/core/file-discovery.d.ts.map +1 -0
- package/dist/core/file-discovery.js +75 -0
- package/dist/core/file-discovery.js.map +1 -0
- package/dist/core/global-index.d.ts +5 -0
- package/dist/core/global-index.d.ts.map +1 -1
- package/dist/core/global-index.js +71 -21
- package/dist/core/global-index.js.map +1 -1
- package/dist/generator/ai-overview.d.ts +51 -0
- package/dist/generator/ai-overview.d.ts.map +1 -0
- package/dist/generator/ai-overview.js +160 -0
- package/dist/generator/ai-overview.js.map +1 -0
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +8 -0
- package/dist/generator/index.js.map +1 -1
- package/dist/infrastructure/parser/implementations/GoParser.d.ts +2 -5
- package/dist/infrastructure/parser/implementations/GoParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/GoParser.js +2 -5
- package/dist/infrastructure/parser/implementations/GoParser.js.map +1 -1
- package/dist/infrastructure/parser/implementations/PythonParser.d.ts +1 -5
- package/dist/infrastructure/parser/implementations/PythonParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/PythonParser.js +1 -5
- package/dist/infrastructure/parser/implementations/PythonParser.js.map +1 -1
- package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts +1 -5
- package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/TypeScriptParser.js +1 -5
- package/dist/infrastructure/parser/implementations/TypeScriptParser.js.map +1 -1
- package/dist/infrastructure/storage/StorageFactory.d.ts +12 -6
- package/dist/infrastructure/storage/StorageFactory.d.ts.map +1 -1
- package/dist/infrastructure/storage/StorageFactory.js +59 -43
- package/dist/infrastructure/storage/StorageFactory.js.map +1 -1
- package/dist/infrastructure/storage/adapters/FileSystemStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/FileSystemStorage.js +24 -137
- package/dist/infrastructure/storage/adapters/FileSystemStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts +10 -18
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.js +103 -146
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts +0 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.js +16 -136
- package/dist/infrastructure/storage/adapters/MemoryStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts +9 -17
- package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/Neo4jStorage.js +78 -138
- package/dist/infrastructure/storage/adapters/Neo4jStorage.js.map +1 -1
- package/dist/infrastructure/storage/graph-helpers.d.ts +16 -0
- package/dist/infrastructure/storage/graph-helpers.d.ts.map +1 -0
- package/dist/infrastructure/storage/graph-helpers.js +161 -0
- package/dist/infrastructure/storage/graph-helpers.js.map +1 -0
- package/dist/infrastructure/storage/index.d.ts.map +1 -1
- package/dist/interface/config/index.d.ts +10 -1
- package/dist/interface/config/index.d.ts.map +1 -1
- package/dist/interface/types/design-contract.d.ts +68 -0
- package/dist/interface/types/design-contract.d.ts.map +1 -0
- package/dist/interface/types/design-contract.js +7 -0
- package/dist/interface/types/design-contract.js.map +1 -0
- package/dist/interface/types/design-handoff.d.ts +68 -0
- package/dist/interface/types/design-handoff.d.ts.map +1 -0
- package/dist/interface/types/design-handoff.js +4 -0
- package/dist/interface/types/design-handoff.js.map +1 -0
- package/dist/interface/types/design-mapping.d.ts +51 -0
- package/dist/interface/types/design-mapping.d.ts.map +1 -0
- package/dist/interface/types/design-mapping.js +4 -0
- package/dist/interface/types/design-mapping.js.map +1 -0
- package/dist/interface/types/design-verification.d.ts +49 -0
- package/dist/interface/types/design-verification.d.ts.map +1 -0
- package/dist/interface/types/design-verification.js +4 -0
- package/dist/interface/types/design-verification.js.map +1 -0
- package/dist/interface/types/index.d.ts +17 -0
- package/dist/interface/types/index.d.ts.map +1 -1
- package/dist/interface/types/storage.d.ts +1 -4
- package/dist/interface/types/storage.d.ts.map +1 -1
- package/dist/orchestrator/ai-feed-generator.d.ts +210 -0
- package/dist/orchestrator/ai-feed-generator.d.ts.map +1 -0
- package/dist/orchestrator/ai-feed-generator.js +377 -0
- package/dist/orchestrator/ai-feed-generator.js.map +1 -0
- package/dist/orchestrator/confidence.d.ts +9 -9
- package/dist/orchestrator/confidence.d.ts.map +1 -1
- package/dist/orchestrator/confidence.js +44 -67
- package/dist/orchestrator/confidence.js.map +1 -1
- package/dist/orchestrator/file-header-scanner.d.ts.map +1 -1
- package/dist/orchestrator/file-header-scanner.js +22 -31
- package/dist/orchestrator/file-header-scanner.js.map +1 -1
- package/dist/orchestrator/intent-router.d.ts +2 -11
- package/dist/orchestrator/intent-router.d.ts.map +1 -1
- package/dist/orchestrator/intent-router.js +58 -49
- package/dist/orchestrator/intent-router.js.map +1 -1
- package/dist/orchestrator/tool-orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/tool-orchestrator.js +6 -4
- package/dist/orchestrator/tool-orchestrator.js.map +1 -1
- package/dist/orchestrator/types.d.ts +113 -2
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/orchestrator/types.js +29 -0
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/orchestrator/workflow/config.d.ts +4 -12
- package/dist/orchestrator/workflow/config.d.ts.map +1 -1
- package/dist/orchestrator/workflow/config.js +4 -6
- package/dist/orchestrator/workflow/config.js.map +1 -1
- package/dist/orchestrator/workflow/git-analyzer.d.ts.map +1 -1
- package/dist/orchestrator/workflow/git-analyzer.js +9 -19
- package/dist/orchestrator/workflow/git-analyzer.js.map +1 -1
- package/dist/orchestrator/workflow/phase-inheritance.d.ts.map +1 -1
- package/dist/orchestrator/workflow/phase-inheritance.js +14 -23
- package/dist/orchestrator/workflow/phase-inheritance.js.map +1 -1
- package/dist/orchestrator/workflow/result-fusion.d.ts.map +1 -1
- package/dist/orchestrator/workflow/result-fusion.js +9 -11
- package/dist/orchestrator/workflow/result-fusion.js.map +1 -1
- package/dist/orchestrator/workflow/templates.d.ts +4 -1
- package/dist/orchestrator/workflow/templates.d.ts.map +1 -1
- package/dist/orchestrator/workflow/templates.js +49 -207
- package/dist/orchestrator/workflow/templates.js.map +1 -1
- package/dist/orchestrator/workflow/test-linker.d.ts.map +1 -1
- package/dist/orchestrator/workflow/test-linker.js +12 -24
- package/dist/orchestrator/workflow/test-linker.js.map +1 -1
- package/dist/orchestrator/workflow/types.d.ts +11 -8
- package/dist/orchestrator/workflow/types.d.ts.map +1 -1
- package/dist/orchestrator/workflow/types.js +8 -1
- package/dist/orchestrator/workflow/types.js.map +1 -1
- package/dist/orchestrator/workflow/visualizer.d.ts.map +1 -1
- package/dist/orchestrator/workflow/visualizer.js +7 -9
- package/dist/orchestrator/workflow/visualizer.js.map +1 -1
- package/dist/orchestrator/workflow/workflow-context.d.ts.map +1 -1
- package/dist/orchestrator/workflow/workflow-context.js +3 -5
- package/dist/orchestrator/workflow/workflow-context.js.map +1 -1
- package/dist/orchestrator/workflow/workflow-orchestrator.d.ts +0 -4
- package/dist/orchestrator/workflow/workflow-orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/workflow/workflow-orchestrator.js +7 -99
- package/dist/orchestrator/workflow/workflow-orchestrator.js.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +2 -2
- package/dist/parser/index.js.map +1 -1
- package/dist/plugins/index.d.ts +5 -3
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +19 -8
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/plugin-loader.d.ts +21 -6
- package/dist/plugins/plugin-loader.d.ts.map +1 -1
- package/dist/plugins/plugin-loader.js +170 -54
- package/dist/plugins/plugin-loader.js.map +1 -1
- package/dist/plugins/plugin-registry.d.ts +7 -4
- package/dist/plugins/plugin-registry.d.ts.map +1 -1
- package/dist/plugins/plugin-registry.js +62 -14
- package/dist/plugins/plugin-registry.js.map +1 -1
- package/dist/plugins/types.d.ts +16 -6
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -1
- package/dist/server/handlers/AnalysisHandler.d.ts +16 -2
- package/dist/server/handlers/AnalysisHandler.d.ts.map +1 -1
- package/dist/server/handlers/AnalysisHandler.js +31 -47
- package/dist/server/handlers/AnalysisHandler.js.map +1 -1
- package/dist/server/routes/api.d.ts.map +1 -1
- package/dist/server/routes/api.js +31 -12
- package/dist/server/routes/api.js.map +1 -1
- package/docs/AI_ASSISTANT_SETUP.md +3 -1
- package/docs/SETUP_GUIDE.md +41 -17
- package/docs/ai-guide/COMMANDS.md +179 -102
- package/docs/ai-guide/INTEGRATION.md +23 -21
- package/docs/ai-guide/OUTPUT.md +621 -10
- package/docs/ai-guide/PATTERNS.md +77 -18
- package/docs/ai-guide/PROMPTS.md +24 -18
- package/docs/ai-guide/QUICKSTART.md +35 -19
- package/docs/ai-guide/README.md +22 -4
- package/docs/archive/test-report-symbol-search.md +384 -0
- package/docs/archive/test-scenario-4-complexity-analysis.md +460 -0
- package/docs/archive/test_report_scenario5.md +615 -0
- package/docs/archive/test_scenario_3_impact_analysis_report.md +520 -0
- package/docs/product-specs/DESIGN_CONTRACT_TEMPLATE.md +79 -0
- package/docs/product-specs/MVP3-ARCHITECTURE-COMPARISON.md +159 -434
- package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-PRD.md +169 -261
- package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-TECH-PRD.md +201 -1259
- package/docs/product-specs/README.md +9 -1
- package/docs/rules/architecture-guardrails.md +1 -2
- package/docs/rules/engineering-with-codex-openai.md +20 -10
- package/docs/rules/validation.md +29 -4
- package/mycodemap.config.schema.json +76 -5
- package/package.json +1 -1
- package/scripts/experiments/arcadedb-http-smoke.mjs +90 -0
- package/scripts/sync-analyze-docs.js +500 -0
- package/scripts/validate-ai-docs.js +54 -1
- package/scripts/validate-docs.js +992 -25
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// 内存存储适配器 - 用于测试和轻量级场景的内存存储
|
|
5
5
|
// ============================================
|
|
6
6
|
import { StorageBase } from '../interfaces/StorageBase.js';
|
|
7
|
+
import { calculateImpactInGraph, cloneCodeGraph, createEmptyCodeGraph, deleteModuleFromGraph, detectCyclesInGraph, findCalleesInGraph, findCallersInGraph, findDependenciesInGraph, findDependentsInGraph, getProjectStatisticsFromGraph, upsertModuleInGraph, } from '../graph-helpers.js';
|
|
7
8
|
/**
|
|
8
9
|
* 内存存储适配器
|
|
9
10
|
*
|
|
@@ -16,61 +17,43 @@ import { StorageBase } from '../interfaces/StorageBase.js';
|
|
|
16
17
|
export class MemoryStorage extends StorageBase {
|
|
17
18
|
type = 'memory';
|
|
18
19
|
/** 内存中的代码图 */
|
|
19
|
-
graph =
|
|
20
|
+
graph = createEmptyCodeGraph();
|
|
20
21
|
// ============================================
|
|
21
22
|
// 生命周期管理
|
|
22
23
|
// ============================================
|
|
23
24
|
async doInitialize() {
|
|
24
25
|
// 内存存储无需特殊初始化
|
|
25
|
-
this.graph = this.
|
|
26
|
+
this.graph = createEmptyCodeGraph(this.projectPath ?? '');
|
|
26
27
|
}
|
|
27
28
|
async doClose() {
|
|
28
29
|
// 清理内存
|
|
29
|
-
this.graph = this.
|
|
30
|
+
this.graph = createEmptyCodeGraph(this.projectPath ?? '');
|
|
30
31
|
}
|
|
31
32
|
// ============================================
|
|
32
33
|
// 项目级别操作
|
|
33
34
|
// ============================================
|
|
34
35
|
async saveCodeGraph(graph) {
|
|
35
36
|
this.ensureInitialized();
|
|
36
|
-
this.graph =
|
|
37
|
-
project: { ...graph.project },
|
|
38
|
-
modules: [...graph.modules],
|
|
39
|
-
symbols: [...graph.symbols],
|
|
40
|
-
dependencies: [...graph.dependencies],
|
|
41
|
-
};
|
|
37
|
+
this.graph = cloneCodeGraph(graph);
|
|
42
38
|
}
|
|
43
39
|
async loadCodeGraph() {
|
|
44
40
|
this.ensureInitialized();
|
|
45
|
-
return
|
|
46
|
-
project: { ...this.graph.project },
|
|
47
|
-
modules: [...this.graph.modules],
|
|
48
|
-
symbols: [...this.graph.symbols],
|
|
49
|
-
dependencies: [...this.graph.dependencies],
|
|
50
|
-
};
|
|
41
|
+
return cloneCodeGraph(this.graph);
|
|
51
42
|
}
|
|
52
43
|
async deleteProject() {
|
|
53
44
|
this.ensureInitialized();
|
|
54
|
-
this.graph = this.
|
|
45
|
+
this.graph = createEmptyCodeGraph(this.projectPath ?? '');
|
|
55
46
|
}
|
|
56
47
|
// ============================================
|
|
57
48
|
// 增量更新
|
|
58
49
|
// ============================================
|
|
59
50
|
async updateModule(module) {
|
|
60
51
|
this.ensureInitialized();
|
|
61
|
-
|
|
62
|
-
if (index >= 0) {
|
|
63
|
-
this.graph.modules[index] = { ...module };
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
this.graph.modules.push({ ...module });
|
|
67
|
-
}
|
|
52
|
+
this.graph = upsertModuleInGraph(this.graph, module);
|
|
68
53
|
}
|
|
69
54
|
async deleteModule(moduleId) {
|
|
70
55
|
this.ensureInitialized();
|
|
71
|
-
this.graph
|
|
72
|
-
this.graph.symbols = this.graph.symbols.filter(s => s.moduleId !== moduleId);
|
|
73
|
-
this.graph.dependencies = this.graph.dependencies.filter(d => d.sourceId !== moduleId && d.targetId !== moduleId);
|
|
56
|
+
this.graph = deleteModuleFromGraph(this.graph, moduleId);
|
|
74
57
|
}
|
|
75
58
|
// ============================================
|
|
76
59
|
// 查询操作
|
|
@@ -93,137 +76,34 @@ export class MemoryStorage extends StorageBase {
|
|
|
93
76
|
}
|
|
94
77
|
async findDependencies(moduleId) {
|
|
95
78
|
this.ensureInitialized();
|
|
96
|
-
return this.graph
|
|
79
|
+
return findDependenciesInGraph(this.graph, moduleId);
|
|
97
80
|
}
|
|
98
81
|
async findDependents(moduleId) {
|
|
99
82
|
this.ensureInitialized();
|
|
100
|
-
return this.graph
|
|
83
|
+
return findDependentsInGraph(this.graph, moduleId);
|
|
101
84
|
}
|
|
102
85
|
async findCallers(functionId) {
|
|
103
86
|
this.ensureInitialized();
|
|
104
|
-
|
|
105
|
-
for (const dep of this.graph.dependencies) {
|
|
106
|
-
if (dep.targetId === functionId && dep.type === 'call') {
|
|
107
|
-
callerIds.add(dep.sourceId);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const results = [];
|
|
111
|
-
for (const id of callerIds) {
|
|
112
|
-
const symbol = this.graph.symbols.find(s => s.id === id);
|
|
113
|
-
if (symbol)
|
|
114
|
-
results.push(symbol);
|
|
115
|
-
}
|
|
116
|
-
return results;
|
|
87
|
+
return findCallersInGraph(this.graph, functionId);
|
|
117
88
|
}
|
|
118
89
|
async findCallees(functionId) {
|
|
119
90
|
this.ensureInitialized();
|
|
120
|
-
|
|
121
|
-
for (const dep of this.graph.dependencies) {
|
|
122
|
-
if (dep.sourceId === functionId && dep.type === 'call') {
|
|
123
|
-
calleeIds.add(dep.targetId);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
const results = [];
|
|
127
|
-
for (const id of calleeIds) {
|
|
128
|
-
const symbol = this.graph.symbols.find(s => s.id === id);
|
|
129
|
-
if (symbol)
|
|
130
|
-
results.push(symbol);
|
|
131
|
-
}
|
|
132
|
-
return results;
|
|
91
|
+
return findCalleesInGraph(this.graph, functionId);
|
|
133
92
|
}
|
|
134
93
|
// ============================================
|
|
135
94
|
// 分析操作
|
|
136
95
|
// ============================================
|
|
137
96
|
async detectCycles() {
|
|
138
97
|
this.ensureInitialized();
|
|
139
|
-
|
|
140
|
-
const visited = new Set();
|
|
141
|
-
const inStack = new Set();
|
|
142
|
-
const dfs = (nodeId, path) => {
|
|
143
|
-
if (inStack.has(nodeId)) {
|
|
144
|
-
const cycleStart = path.indexOf(nodeId);
|
|
145
|
-
const cycleModules = path.slice(cycleStart);
|
|
146
|
-
cycles.push({
|
|
147
|
-
modules: cycleModules,
|
|
148
|
-
length: cycleModules.length,
|
|
149
|
-
});
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
if (visited.has(nodeId)) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
visited.add(nodeId);
|
|
156
|
-
inStack.add(nodeId);
|
|
157
|
-
for (const dep of this.graph.dependencies) {
|
|
158
|
-
if (dep.sourceId === nodeId) {
|
|
159
|
-
dfs(dep.targetId, [...path, nodeId]);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
inStack.delete(nodeId);
|
|
163
|
-
};
|
|
164
|
-
for (const module of this.graph.modules) {
|
|
165
|
-
if (!visited.has(module.id)) {
|
|
166
|
-
dfs(module.id, []);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return cycles;
|
|
98
|
+
return detectCyclesInGraph(this.graph);
|
|
170
99
|
}
|
|
171
100
|
async calculateImpact(moduleId, depth) {
|
|
172
101
|
this.ensureInitialized();
|
|
173
|
-
|
|
174
|
-
const visited = new Set();
|
|
175
|
-
const queue = [{ id: moduleId, level: 0 }];
|
|
176
|
-
while (queue.length > 0) {
|
|
177
|
-
const { id, level } = queue.shift();
|
|
178
|
-
if (visited.has(id) || level > depth) {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
visited.add(id);
|
|
182
|
-
if (level > 0) {
|
|
183
|
-
const module = this.graph.modules.find(m => m.id === id);
|
|
184
|
-
if (module) {
|
|
185
|
-
affectedModules.push({ ...module });
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
for (const dep of this.graph.dependencies) {
|
|
189
|
-
if (dep.targetId === id && !visited.has(dep.sourceId)) {
|
|
190
|
-
queue.push({ id: dep.sourceId, level: level + 1 });
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
rootModule: moduleId,
|
|
196
|
-
affectedModules,
|
|
197
|
-
depth,
|
|
198
|
-
};
|
|
102
|
+
return calculateImpactInGraph(this.graph, moduleId, depth);
|
|
199
103
|
}
|
|
200
104
|
async getStatistics() {
|
|
201
105
|
this.ensureInitialized();
|
|
202
|
-
|
|
203
|
-
return {
|
|
204
|
-
totalModules: this.graph.modules.length,
|
|
205
|
-
totalSymbols: this.graph.symbols.length,
|
|
206
|
-
totalDependencies: this.graph.dependencies.length,
|
|
207
|
-
totalLines,
|
|
208
|
-
averageComplexity: 0,
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
// ============================================
|
|
212
|
-
// 私有方法
|
|
213
|
-
// ============================================
|
|
214
|
-
createEmptyGraph() {
|
|
215
|
-
return {
|
|
216
|
-
project: {
|
|
217
|
-
id: '',
|
|
218
|
-
name: '',
|
|
219
|
-
rootPath: this.projectPath ?? '',
|
|
220
|
-
createdAt: new Date(),
|
|
221
|
-
updatedAt: new Date(),
|
|
222
|
-
},
|
|
223
|
-
modules: [],
|
|
224
|
-
symbols: [],
|
|
225
|
-
dependencies: [],
|
|
226
|
-
};
|
|
106
|
+
return getProjectStatisticsFromGraph(this.graph);
|
|
227
107
|
}
|
|
228
108
|
}
|
|
229
109
|
//# sourceMappingURL=MemoryStorage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryStorage.js","sourceRoot":"","sources":["../../../../src/infrastructure/storage/adapters/MemoryStorage.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,qFAAqF;AACrF,+CAA+C;AAC/C,4BAA4B;AAC5B,+CAA+C;AAa/C,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"MemoryStorage.js","sourceRoot":"","sources":["../../../../src/infrastructure/storage/adapters/MemoryStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,24 +7,15 @@ import { StorageBase } from '../interfaces/StorageBase.js';
|
|
|
7
7
|
* 安装:npm install neo4j-driver
|
|
8
8
|
*
|
|
9
9
|
* 特点:
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
14
|
-
*
|
|
15
|
-
* TODO-DEBT [L1] [日期:2026-03-17] [作者:AI] [原因:MVP阶段暂不实现完整功能]
|
|
16
|
-
* 问题:目前使用内存 fallback 实现
|
|
17
|
-
* 风险:无法连接真实 Neo4j 实例
|
|
18
|
-
* 偿还计划:V1.0 实现完整 Neo4j 集成
|
|
10
|
+
* - 连接远程/本地 Neo4j 实例
|
|
11
|
+
* - 用 snapshot 节点持久化完整 CodeGraph
|
|
12
|
+
* - 查询/分析接口与共享 storage contract 保持一致
|
|
13
|
+
* - 错误语义显式暴露,不再静默 fallback
|
|
19
14
|
*/
|
|
20
15
|
export declare class Neo4jStorage extends StorageBase {
|
|
21
16
|
readonly type: "neo4j";
|
|
22
|
-
/** Neo4j 驱动 */
|
|
23
17
|
private driver;
|
|
24
|
-
|
|
25
|
-
private memoryGraph;
|
|
26
|
-
/** 存储配置 */
|
|
27
|
-
private dbConfig;
|
|
18
|
+
private readonly dbConfig;
|
|
28
19
|
constructor(config: StorageConfig);
|
|
29
20
|
protected doInitialize(): Promise<void>;
|
|
30
21
|
protected doClose(): Promise<void>;
|
|
@@ -39,11 +30,12 @@ export declare class Neo4jStorage extends StorageBase {
|
|
|
39
30
|
findSymbolById(id: string): Promise<Symbol | null>;
|
|
40
31
|
findDependencies(moduleId: string): Promise<Dependency[]>;
|
|
41
32
|
findDependents(moduleId: string): Promise<Dependency[]>;
|
|
42
|
-
findCallers(
|
|
43
|
-
findCallees(
|
|
33
|
+
findCallers(functionId: string): Promise<Symbol[]>;
|
|
34
|
+
findCallees(functionId: string): Promise<Symbol[]>;
|
|
44
35
|
detectCycles(): Promise<Cycle[]>;
|
|
45
36
|
calculateImpact(moduleId: string, depth: number): Promise<ImpactResult>;
|
|
46
37
|
getStatistics(): Promise<ProjectStatistics>;
|
|
47
|
-
private
|
|
38
|
+
private getDriver;
|
|
39
|
+
private runStatement;
|
|
48
40
|
}
|
|
49
41
|
//# sourceMappingURL=Neo4jStorage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Neo4jStorage.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/storage/adapters/Neo4jStorage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,KAAK,EACL,YAAY,EACZ,iBAAiB,EAClB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,UAAU,EACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAgB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"Neo4jStorage.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/storage/adapters/Neo4jStorage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,KAAK,EACL,YAAY,EACZ,iBAAiB,EAClB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,UAAU,EACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAgB,MAAM,8BAA8B,CAAC;AA4DzE;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IAEjC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,MAAM,EAAE,aAAa;cAKjB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cAkB7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQlC,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9C,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC;IAkBnC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMlD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMlD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMjD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMlD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKzD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKvD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlD,YAAY,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAKhC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKvE,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAKjD,OAAO,CAAC,SAAS;YAWH,YAAY;CAkB3B"}
|
|
@@ -4,219 +4,159 @@
|
|
|
4
4
|
// Neo4j 存储适配器 - 企业级图数据库后端
|
|
5
5
|
// ============================================
|
|
6
6
|
import { StorageBase, StorageError } from '../interfaces/StorageBase.js';
|
|
7
|
+
import { calculateImpactInGraph, createEmptyCodeGraph, deleteModuleFromGraph, deserializeCodeGraphSnapshot, detectCyclesInGraph, findCalleesInGraph, findCallersInGraph, findDependenciesInGraph, findDependentsInGraph, getProjectStatisticsFromGraph, serializeCodeGraphSnapshot, upsertModuleInGraph, } from '../graph-helpers.js';
|
|
8
|
+
async function loadNeo4jModule() {
|
|
9
|
+
const moduleName = 'neo4j-driver';
|
|
10
|
+
return await import(moduleName);
|
|
11
|
+
}
|
|
12
|
+
function normalizeNeo4jValue(value) {
|
|
13
|
+
if (typeof value === 'object' &&
|
|
14
|
+
value !== null &&
|
|
15
|
+
'toNumber' in value &&
|
|
16
|
+
typeof value.toNumber === 'function') {
|
|
17
|
+
return value.toNumber();
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
7
21
|
/**
|
|
8
22
|
* Neo4j 存储适配器(可选依赖)
|
|
9
23
|
*
|
|
10
24
|
* 安装:npm install neo4j-driver
|
|
11
25
|
*
|
|
12
26
|
* 特点:
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
*
|
|
18
|
-
* TODO-DEBT [L1] [日期:2026-03-17] [作者:AI] [原因:MVP阶段暂不实现完整功能]
|
|
19
|
-
* 问题:目前使用内存 fallback 实现
|
|
20
|
-
* 风险:无法连接真实 Neo4j 实例
|
|
21
|
-
* 偿还计划:V1.0 实现完整 Neo4j 集成
|
|
27
|
+
* - 连接远程/本地 Neo4j 实例
|
|
28
|
+
* - 用 snapshot 节点持久化完整 CodeGraph
|
|
29
|
+
* - 查询/分析接口与共享 storage contract 保持一致
|
|
30
|
+
* - 错误语义显式暴露,不再静默 fallback
|
|
22
31
|
*/
|
|
23
32
|
export class Neo4jStorage extends StorageBase {
|
|
24
33
|
type = 'neo4j';
|
|
25
|
-
/** Neo4j 驱动 */
|
|
26
34
|
driver = null;
|
|
27
|
-
/** 内存 fallback */
|
|
28
|
-
memoryGraph = this.createEmptyGraph();
|
|
29
|
-
/** 存储配置 */
|
|
30
35
|
dbConfig;
|
|
31
36
|
constructor(config) {
|
|
32
37
|
super();
|
|
33
38
|
this.dbConfig = config;
|
|
34
39
|
}
|
|
35
|
-
// ============================================
|
|
36
|
-
// 生命周期管理
|
|
37
|
-
// ============================================
|
|
38
40
|
async doInitialize() {
|
|
39
41
|
try {
|
|
40
|
-
|
|
41
|
-
// @ts-expect-error neo4j-driver is optional dependency
|
|
42
|
-
const neo4j = await import('neo4j-driver');
|
|
42
|
+
const neo4j = await loadNeo4jModule();
|
|
43
43
|
const uri = this.dbConfig.uri ?? 'bolt://localhost:7687';
|
|
44
44
|
const username = this.dbConfig.username ?? 'neo4j';
|
|
45
45
|
const password = this.dbConfig.password ?? 'password';
|
|
46
46
|
this.driver = neo4j.driver(uri, neo4j.auth.basic(username, password));
|
|
47
|
-
|
|
48
|
-
const session = this.driver.session();
|
|
49
|
-
await session.run('RETURN 1');
|
|
50
|
-
await session.close();
|
|
47
|
+
await this.driver.verifyConnectivity();
|
|
51
48
|
}
|
|
52
|
-
catch {
|
|
53
|
-
|
|
54
|
-
console.warn('Neo4j not available, falling back to memory mode');
|
|
55
|
-
this.memoryGraph = this.createEmptyGraph();
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new StorageError('Failed to initialize Neo4j storage', 'NEO4J_INIT_FAILED', error);
|
|
56
51
|
}
|
|
57
52
|
}
|
|
58
53
|
async doClose() {
|
|
59
|
-
if (this.driver
|
|
54
|
+
if (this.driver) {
|
|
60
55
|
await this.driver.close();
|
|
61
56
|
}
|
|
62
57
|
this.driver = null;
|
|
63
58
|
}
|
|
64
|
-
// ============================================
|
|
65
|
-
// 项目级别操作
|
|
66
|
-
// ============================================
|
|
67
59
|
async saveCodeGraph(graph) {
|
|
68
60
|
this.ensureInitialized();
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
// TODO: 实现 Neo4j 持久化
|
|
79
|
-
throw new StorageError('Neo4j persistence not yet implemented', 'NOT_IMPLEMENTED');
|
|
61
|
+
await this.runStatement('MATCH (s:CodeMapSnapshot) DETACH DELETE s');
|
|
62
|
+
await this.runStatement('CREATE (s:CodeMapSnapshot {id: $id, projectId: $projectId, graph: $graph, updatedAt: $updatedAt})', {
|
|
63
|
+
id: 'codemap-snapshot',
|
|
64
|
+
projectId: graph.project.id,
|
|
65
|
+
graph: serializeCodeGraphSnapshot(graph),
|
|
66
|
+
updatedAt: new Date().toISOString(),
|
|
67
|
+
});
|
|
80
68
|
}
|
|
81
69
|
async loadCodeGraph() {
|
|
82
70
|
this.ensureInitialized();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
const result = await this.runStatement('MATCH (s:CodeMapSnapshot) RETURN s.graph AS graph LIMIT 1');
|
|
72
|
+
const record = result.records[0];
|
|
73
|
+
const snapshot = typeof record?.get === 'function'
|
|
74
|
+
? normalizeNeo4jValue(record.get('graph'))
|
|
75
|
+
: null;
|
|
76
|
+
if (typeof snapshot !== 'string') {
|
|
77
|
+
return createEmptyCodeGraph(this.projectPath ?? '');
|
|
90
78
|
}
|
|
91
|
-
|
|
92
|
-
throw new StorageError('Neo4j loading not yet implemented', 'NOT_IMPLEMENTED');
|
|
79
|
+
return deserializeCodeGraphSnapshot(snapshot, this.projectPath ?? '');
|
|
93
80
|
}
|
|
94
81
|
async deleteProject() {
|
|
95
82
|
this.ensureInitialized();
|
|
96
|
-
|
|
97
|
-
// TODO: 删除 Neo4j 数据
|
|
83
|
+
await this.runStatement('MATCH (s:CodeMapSnapshot) DETACH DELETE s');
|
|
98
84
|
}
|
|
99
|
-
// ============================================
|
|
100
|
-
// 增量更新
|
|
101
|
-
// ============================================
|
|
102
85
|
async updateModule(module) {
|
|
103
86
|
this.ensureInitialized();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (index >= 0) {
|
|
107
|
-
this.memoryGraph.modules[index] = { ...module };
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
this.memoryGraph.modules.push({ ...module });
|
|
111
|
-
}
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// TODO: 实现 Neo4j 更新
|
|
87
|
+
const graph = await this.loadCodeGraph();
|
|
88
|
+
await this.saveCodeGraph(upsertModuleInGraph(graph, module));
|
|
115
89
|
}
|
|
116
90
|
async deleteModule(moduleId) {
|
|
117
91
|
this.ensureInitialized();
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.memoryGraph.symbols = this.memoryGraph.symbols.filter(s => s.moduleId !== moduleId);
|
|
121
|
-
this.memoryGraph.dependencies = this.memoryGraph.dependencies.filter(d => d.sourceId !== moduleId && d.targetId !== moduleId);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
// TODO: 实现 Neo4j 删除
|
|
92
|
+
const graph = await this.loadCodeGraph();
|
|
93
|
+
await this.saveCodeGraph(deleteModuleFromGraph(graph, moduleId));
|
|
125
94
|
}
|
|
126
|
-
// ============================================
|
|
127
|
-
// 查询操作
|
|
128
|
-
// ============================================
|
|
129
95
|
async findModuleById(id) {
|
|
130
96
|
this.ensureInitialized();
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
return null;
|
|
97
|
+
const graph = await this.loadCodeGraph();
|
|
98
|
+
return graph.modules.find(module => module.id === id) ?? null;
|
|
135
99
|
}
|
|
136
100
|
async findModulesByPath(path) {
|
|
137
101
|
this.ensureInitialized();
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
return [];
|
|
102
|
+
const graph = await this.loadCodeGraph();
|
|
103
|
+
return graph.modules.filter(module => module.path.includes(path));
|
|
142
104
|
}
|
|
143
105
|
async findSymbolByName(name) {
|
|
144
106
|
this.ensureInitialized();
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
return [];
|
|
107
|
+
const graph = await this.loadCodeGraph();
|
|
108
|
+
return graph.symbols.filter(symbol => symbol.name.includes(name));
|
|
149
109
|
}
|
|
150
110
|
async findSymbolById(id) {
|
|
151
111
|
this.ensureInitialized();
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
return null;
|
|
112
|
+
const graph = await this.loadCodeGraph();
|
|
113
|
+
return graph.symbols.find(symbol => symbol.id === id) ?? null;
|
|
156
114
|
}
|
|
157
115
|
async findDependencies(moduleId) {
|
|
158
116
|
this.ensureInitialized();
|
|
159
|
-
|
|
160
|
-
return this.memoryGraph.dependencies.filter(d => d.sourceId === moduleId);
|
|
161
|
-
}
|
|
162
|
-
return [];
|
|
117
|
+
return findDependenciesInGraph(await this.loadCodeGraph(), moduleId);
|
|
163
118
|
}
|
|
164
119
|
async findDependents(moduleId) {
|
|
165
120
|
this.ensureInitialized();
|
|
166
|
-
|
|
167
|
-
return this.memoryGraph.dependencies.filter(d => d.targetId === moduleId);
|
|
168
|
-
}
|
|
169
|
-
return [];
|
|
121
|
+
return findDependentsInGraph(await this.loadCodeGraph(), moduleId);
|
|
170
122
|
}
|
|
171
|
-
async findCallers(
|
|
123
|
+
async findCallers(functionId) {
|
|
172
124
|
this.ensureInitialized();
|
|
173
|
-
return
|
|
125
|
+
return findCallersInGraph(await this.loadCodeGraph(), functionId);
|
|
174
126
|
}
|
|
175
|
-
async findCallees(
|
|
127
|
+
async findCallees(functionId) {
|
|
176
128
|
this.ensureInitialized();
|
|
177
|
-
return
|
|
129
|
+
return findCalleesInGraph(await this.loadCodeGraph(), functionId);
|
|
178
130
|
}
|
|
179
|
-
// ============================================
|
|
180
|
-
// 分析操作
|
|
181
|
-
// ============================================
|
|
182
131
|
async detectCycles() {
|
|
183
132
|
this.ensureInitialized();
|
|
184
|
-
return
|
|
133
|
+
return detectCyclesInGraph(await this.loadCodeGraph());
|
|
185
134
|
}
|
|
186
135
|
async calculateImpact(moduleId, depth) {
|
|
187
136
|
this.ensureInitialized();
|
|
188
|
-
return
|
|
189
|
-
rootModule: moduleId,
|
|
190
|
-
affectedModules: [],
|
|
191
|
-
depth,
|
|
192
|
-
};
|
|
137
|
+
return calculateImpactInGraph(await this.loadCodeGraph(), moduleId, depth);
|
|
193
138
|
}
|
|
194
139
|
async getStatistics() {
|
|
195
140
|
this.ensureInitialized();
|
|
196
|
-
return
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
modules: [],
|
|
217
|
-
symbols: [],
|
|
218
|
-
dependencies: [],
|
|
219
|
-
};
|
|
141
|
+
return getProjectStatisticsFromGraph(await this.loadCodeGraph());
|
|
142
|
+
}
|
|
143
|
+
getDriver() {
|
|
144
|
+
if (!this.driver) {
|
|
145
|
+
throw new StorageError('Neo4j driver not initialized', 'NEO4J_DRIVER_NOT_READY');
|
|
146
|
+
}
|
|
147
|
+
return this.driver;
|
|
148
|
+
}
|
|
149
|
+
async runStatement(query, params) {
|
|
150
|
+
const session = this.getDriver().session();
|
|
151
|
+
try {
|
|
152
|
+
return await session.run(query, params);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new StorageError('Failed to execute Neo4j query', 'NEO4J_QUERY_FAILED', error);
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await session.close();
|
|
159
|
+
}
|
|
220
160
|
}
|
|
221
161
|
}
|
|
222
162
|
//# sourceMappingURL=Neo4jStorage.js.map
|