@grafema/util 0.3.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/dist/api/GraphAPI.d.ts +87 -0
- package/dist/api/GraphAPI.d.ts.map +1 -0
- package/dist/api/GraphAPI.js +212 -0
- package/dist/api/GraphAPI.js.map +1 -0
- package/dist/api/GuaranteeAPI.d.ts +147 -0
- package/dist/api/GuaranteeAPI.d.ts.map +1 -0
- package/dist/api/GuaranteeAPI.js +290 -0
- package/dist/api/GuaranteeAPI.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +214 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +441 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +199 -0
- package/dist/core/CoverageAnalyzer.js.map +1 -0
- package/dist/core/FileExplainer.d.ts +101 -0
- package/dist/core/FileExplainer.d.ts.map +1 -0
- package/dist/core/FileExplainer.js +140 -0
- package/dist/core/FileExplainer.js.map +1 -0
- package/dist/core/FileOverview.d.ts +124 -0
- package/dist/core/FileOverview.d.ts.map +1 -0
- package/dist/core/FileOverview.js +279 -0
- package/dist/core/FileOverview.js.map +1 -0
- package/dist/core/GrafemaUri.d.ts +66 -0
- package/dist/core/GrafemaUri.d.ts.map +1 -0
- package/dist/core/GrafemaUri.js +191 -0
- package/dist/core/GrafemaUri.js.map +1 -0
- package/dist/core/GraphBackend.d.ts +158 -0
- package/dist/core/GraphBackend.d.ts.map +1 -0
- package/dist/core/GraphBackend.js +85 -0
- package/dist/core/GraphBackend.js.map +1 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +104 -0
- package/dist/core/GraphFreshnessChecker.js.map +1 -0
- package/dist/core/GuaranteeManager.d.ts +254 -0
- package/dist/core/GuaranteeManager.d.ts.map +1 -0
- package/dist/core/GuaranteeManager.js +447 -0
- package/dist/core/GuaranteeManager.js.map +1 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +46 -0
- package/dist/core/HashUtils.js.map +1 -0
- package/dist/core/IncrementalReanalyzer.d.ts +33 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +67 -0
- package/dist/core/IncrementalReanalyzer.js.map +1 -0
- package/dist/core/ResourceRegistry.d.ts +17 -0
- package/dist/core/ResourceRegistry.d.ts.map +1 -0
- package/dist/core/ResourceRegistry.js +32 -0
- package/dist/core/ResourceRegistry.js.map +1 -0
- package/dist/core/SemanticId.d.ts +159 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +291 -0
- package/dist/core/SemanticId.js.map +1 -0
- package/dist/core/VersionManager.d.ts +166 -0
- package/dist/core/VersionManager.d.ts.map +1 -0
- package/dist/core/VersionManager.js +239 -0
- package/dist/core/VersionManager.js.map +1 -0
- package/dist/core/brandNodeInternal.d.ts +14 -0
- package/dist/core/brandNodeInternal.d.ts.map +1 -0
- package/dist/core/brandNodeInternal.js +4 -0
- package/dist/core/brandNodeInternal.js.map +1 -0
- package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
- package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
- package/dist/core/nodes/GuaranteeNode.js +118 -0
- package/dist/core/nodes/GuaranteeNode.js.map +1 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +130 -0
- package/dist/core/nodes/IssueNode.js.map +1 -0
- package/dist/core/nodes/NodeKind.d.ts +104 -0
- package/dist/core/nodes/NodeKind.d.ts.map +1 -0
- package/dist/core/nodes/NodeKind.js +166 -0
- package/dist/core/nodes/NodeKind.js.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +103 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +133 -0
- package/dist/diagnostics/DiagnosticCollector.js.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +122 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +300 -0
- package/dist/diagnostics/DiagnosticReporter.js.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +44 -0
- package/dist/diagnostics/DiagnosticWriter.js.map +1 -0
- package/dist/diagnostics/categories.d.ts +57 -0
- package/dist/diagnostics/categories.d.ts.map +1 -0
- package/dist/diagnostics/categories.js +71 -0
- package/dist/diagnostics/categories.js.map +1 -0
- package/dist/diagnostics/index.d.ts +17 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +15 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/errors/GrafemaError.d.ts +200 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +209 -0
- package/dist/errors/GrafemaError.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/instructions/index.d.ts +8 -0
- package/dist/instructions/index.d.ts.map +1 -0
- package/dist/instructions/index.js +20 -0
- package/dist/instructions/index.js.map +1 -0
- package/dist/instructions/onboarding.md +133 -0
- package/dist/knowledge/KnowledgeBase.d.ts +113 -0
- package/dist/knowledge/KnowledgeBase.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeBase.js +420 -0
- package/dist/knowledge/KnowledgeBase.js.map +1 -0
- package/dist/knowledge/SemanticAddressResolver.d.ts +59 -0
- package/dist/knowledge/SemanticAddressResolver.d.ts.map +1 -0
- package/dist/knowledge/SemanticAddressResolver.js +160 -0
- package/dist/knowledge/SemanticAddressResolver.js.map +1 -0
- package/dist/knowledge/git-ingest.d.ts +58 -0
- package/dist/knowledge/git-ingest.d.ts.map +1 -0
- package/dist/knowledge/git-ingest.js +301 -0
- package/dist/knowledge/git-ingest.js.map +1 -0
- package/dist/knowledge/git-queries.d.ts +86 -0
- package/dist/knowledge/git-queries.d.ts.map +1 -0
- package/dist/knowledge/git-queries.js +177 -0
- package/dist/knowledge/git-queries.js.map +1 -0
- package/dist/knowledge/index.d.ts +14 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +10 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/knowledge/parser.d.ts +39 -0
- package/dist/knowledge/parser.d.ts.map +1 -0
- package/dist/knowledge/parser.js +292 -0
- package/dist/knowledge/parser.js.map +1 -0
- package/dist/knowledge/types.d.ts +133 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +8 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/logging/Logger.d.ts +98 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +274 -0
- package/dist/logging/Logger.js.map +1 -0
- package/dist/notation/archetypes.d.ts +36 -0
- package/dist/notation/archetypes.d.ts.map +1 -0
- package/dist/notation/archetypes.js +173 -0
- package/dist/notation/archetypes.js.map +1 -0
- package/dist/notation/fold.d.ts +25 -0
- package/dist/notation/fold.d.ts.map +1 -0
- package/dist/notation/fold.js +598 -0
- package/dist/notation/fold.js.map +1 -0
- package/dist/notation/index.d.ts +18 -0
- package/dist/notation/index.d.ts.map +1 -0
- package/dist/notation/index.js +16 -0
- package/dist/notation/index.js.map +1 -0
- package/dist/notation/lodExtractor.d.ts +32 -0
- package/dist/notation/lodExtractor.d.ts.map +1 -0
- package/dist/notation/lodExtractor.js +149 -0
- package/dist/notation/lodExtractor.js.map +1 -0
- package/dist/notation/nameShortener.d.ts +22 -0
- package/dist/notation/nameShortener.d.ts.map +1 -0
- package/dist/notation/nameShortener.js +24 -0
- package/dist/notation/nameShortener.js.map +1 -0
- package/dist/notation/perspectives.d.ts +11 -0
- package/dist/notation/perspectives.d.ts.map +1 -0
- package/dist/notation/perspectives.js +16 -0
- package/dist/notation/perspectives.js.map +1 -0
- package/dist/notation/renderer.d.ts +31 -0
- package/dist/notation/renderer.d.ts.map +1 -0
- package/dist/notation/renderer.js +315 -0
- package/dist/notation/renderer.js.map +1 -0
- package/dist/notation/traceRenderer.d.ts +39 -0
- package/dist/notation/traceRenderer.d.ts.map +1 -0
- package/dist/notation/traceRenderer.js +358 -0
- package/dist/notation/traceRenderer.js.map +1 -0
- package/dist/notation/types.d.ts +66 -0
- package/dist/notation/types.d.ts.map +1 -0
- package/dist/notation/types.js +10 -0
- package/dist/notation/types.js.map +1 -0
- package/dist/queries/NodeContext.d.ts +81 -0
- package/dist/queries/NodeContext.d.ts.map +1 -0
- package/dist/queries/NodeContext.js +196 -0
- package/dist/queries/NodeContext.js.map +1 -0
- package/dist/queries/findCallsInFunction.d.ts +62 -0
- package/dist/queries/findCallsInFunction.d.ts.map +1 -0
- package/dist/queries/findCallsInFunction.js +169 -0
- package/dist/queries/findCallsInFunction.js.map +1 -0
- package/dist/queries/findContainingFunction.d.ts +57 -0
- package/dist/queries/findContainingFunction.d.ts.map +1 -0
- package/dist/queries/findContainingFunction.js +91 -0
- package/dist/queries/findContainingFunction.js.map +1 -0
- package/dist/queries/index.d.ts +18 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +14 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/traceDataflow.d.ts +65 -0
- package/dist/queries/traceDataflow.d.ts.map +1 -0
- package/dist/queries/traceDataflow.js +754 -0
- package/dist/queries/traceDataflow.js.map +1 -0
- package/dist/queries/traceValues.d.ts +70 -0
- package/dist/queries/traceValues.d.ts.map +1 -0
- package/dist/queries/traceValues.js +373 -0
- package/dist/queries/traceValues.js.map +1 -0
- package/dist/queries/types.d.ts +166 -0
- package/dist/queries/types.d.ts.map +1 -0
- package/dist/queries/types.js +10 -0
- package/dist/queries/types.js.map +1 -0
- package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
- package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +125 -0
- package/dist/schema/GraphSchemaExtractor.js.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +113 -0
- package/dist/schema/InterfaceSchemaExtractor.js.map +1 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +356 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.js +748 -0
- package/dist/storage/backends/RFDBServerBackend.js.map +1 -0
- package/dist/storage/backends/typeValidation.d.ts +47 -0
- package/dist/storage/backends/typeValidation.d.ts.map +1 -0
- package/dist/storage/backends/typeValidation.js +141 -0
- package/dist/storage/backends/typeValidation.js.map +1 -0
- package/dist/utils/findRfdbBinary.d.ts +67 -0
- package/dist/utils/findRfdbBinary.d.ts.map +1 -0
- package/dist/utils/findRfdbBinary.js +261 -0
- package/dist/utils/findRfdbBinary.js.map +1 -0
- package/dist/utils/lazyDownload.d.ts +43 -0
- package/dist/utils/lazyDownload.d.ts.map +1 -0
- package/dist/utils/lazyDownload.js +175 -0
- package/dist/utils/lazyDownload.js.map +1 -0
- package/dist/utils/moduleResolution.d.ts +134 -0
- package/dist/utils/moduleResolution.d.ts.map +1 -0
- package/dist/utils/moduleResolution.js +189 -0
- package/dist/utils/moduleResolution.js.map +1 -0
- package/dist/utils/resolveNodeFile.d.ts +13 -0
- package/dist/utils/resolveNodeFile.d.ts.map +1 -0
- package/dist/utils/resolveNodeFile.js +18 -0
- package/dist/utils/resolveNodeFile.js.map +1 -0
- package/dist/utils/startRfdbServer.d.ts +63 -0
- package/dist/utils/startRfdbServer.d.ts.map +1 -0
- package/dist/utils/startRfdbServer.js +142 -0
- package/dist/utils/startRfdbServer.js.map +1 -0
- package/dist/validation/PathValidator.d.ts +80 -0
- package/dist/validation/PathValidator.d.ts.map +1 -0
- package/dist/validation/PathValidator.js +252 -0
- package/dist/validation/PathValidator.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +26 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
- package/src/api/GraphAPI.ts +307 -0
- package/src/api/GuaranteeAPI.ts +402 -0
- package/src/config/ConfigLoader.ts +653 -0
- package/src/config/index.ts +13 -0
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/FileOverview.ts +397 -0
- package/src/core/GrafemaUri.ts +216 -0
- package/src/core/GraphBackend.ts +266 -0
- package/src/core/GraphFreshnessChecker.ts +145 -0
- package/src/core/GuaranteeManager.ts +684 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +106 -0
- package/src/core/ResourceRegistry.ts +39 -0
- package/src/core/SemanticId.ts +423 -0
- package/src/core/VersionManager.ts +405 -0
- package/src/core/brandNodeInternal.ts +16 -0
- package/src/core/nodes/GuaranteeNode.ts +162 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/NodeKind.ts +192 -0
- package/src/diagnostics/DiagnosticCollector.ts +170 -0
- package/src/diagnostics/DiagnosticReporter.ts +395 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/categories.ts +104 -0
- package/src/diagnostics/index.ts +30 -0
- package/src/errors/GrafemaError.ts +297 -0
- package/src/index.ts +261 -0
- package/src/instructions/index.ts +21 -0
- package/src/instructions/onboarding.md +133 -0
- package/src/knowledge/KnowledgeBase.ts +486 -0
- package/src/knowledge/SemanticAddressResolver.ts +191 -0
- package/src/knowledge/git-ingest.ts +402 -0
- package/src/knowledge/git-queries.ts +269 -0
- package/src/knowledge/index.ts +29 -0
- package/src/knowledge/parser.ts +294 -0
- package/src/knowledge/types.ts +146 -0
- package/src/logging/Logger.ts +303 -0
- package/src/notation/archetypes.ts +189 -0
- package/src/notation/fold.ts +696 -0
- package/src/notation/index.ts +27 -0
- package/src/notation/lodExtractor.ts +177 -0
- package/src/notation/nameShortener.ts +24 -0
- package/src/notation/perspectives.ts +18 -0
- package/src/notation/renderer.ts +394 -0
- package/src/notation/traceRenderer.ts +458 -0
- package/src/notation/types.ts +79 -0
- package/src/queries/NodeContext.ts +280 -0
- package/src/queries/findCallsInFunction.ts +249 -0
- package/src/queries/findContainingFunction.ts +124 -0
- package/src/queries/index.ts +44 -0
- package/src/queries/traceDataflow.ts +838 -0
- package/src/queries/traceValues.ts +531 -0
- package/src/queries/types.ts +191 -0
- package/src/schema/GraphSchemaExtractor.ts +177 -0
- package/src/schema/InterfaceSchemaExtractor.ts +173 -0
- package/src/schema/index.ts +5 -0
- package/src/storage/backends/RFDBServerBackend.ts +895 -0
- package/src/storage/backends/typeValidation.ts +154 -0
- package/src/utils/findRfdbBinary.ts +288 -0
- package/src/utils/lazyDownload.ts +206 -0
- package/src/utils/moduleResolution.ts +271 -0
- package/src/utils/resolveNodeFile.ts +18 -0
- package/src/utils/startRfdbServer.ts +197 -0
- package/src/validation/PathValidator.ts +334 -0
- package/src/version.ts +28 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphBackend - abstract base class for graph storage implementations
|
|
3
|
+
*
|
|
4
|
+
* This defines the full contract for graph storage backends.
|
|
5
|
+
* All operations are async for compatibility with disk-based storage.
|
|
6
|
+
*
|
|
7
|
+
* Implementations:
|
|
8
|
+
* - RFDBServerBackend (Rust-based, production)
|
|
9
|
+
* - TestBackend (wrapper over RFDBServerBackend for tests)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { NodeRecord } from '@grafema/types';
|
|
13
|
+
import type { EdgeRecord, EdgeType } from '@grafema/types';
|
|
14
|
+
|
|
15
|
+
// Re-export types for convenience
|
|
16
|
+
export type { NodeRecord as Node } from '@grafema/types';
|
|
17
|
+
export type { EdgeRecord as Edge, EdgeType } from '@grafema/types';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Query filter for finding nodes by attributes
|
|
21
|
+
*/
|
|
22
|
+
export interface AttrQuery {
|
|
23
|
+
kind?: number;
|
|
24
|
+
version?: string;
|
|
25
|
+
file_id?: string;
|
|
26
|
+
file?: string;
|
|
27
|
+
exported?: boolean;
|
|
28
|
+
type?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
/** When true, name and file filters use substring (contains) matching instead of exact match */
|
|
31
|
+
substringMatch?: boolean;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Graph statistics
|
|
37
|
+
*/
|
|
38
|
+
export interface GraphStats {
|
|
39
|
+
nodeCount: number;
|
|
40
|
+
edgeCount: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Exported graph data
|
|
45
|
+
*/
|
|
46
|
+
export interface GraphExport {
|
|
47
|
+
nodes: NodeRecord[];
|
|
48
|
+
edges: EdgeRecord[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Abstract GraphBackend class - base for all graph storage implementations
|
|
53
|
+
*/
|
|
54
|
+
export abstract class GraphBackend {
|
|
55
|
+
/**
|
|
56
|
+
* Initialize backend
|
|
57
|
+
*/
|
|
58
|
+
abstract initialize(): Promise<void>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Connect to storage (alias for initialize)
|
|
62
|
+
*/
|
|
63
|
+
async connect(): Promise<void> {
|
|
64
|
+
return this.initialize();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Close connection and flush data to disk
|
|
69
|
+
*/
|
|
70
|
+
abstract close(): Promise<void>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Clear all data
|
|
74
|
+
*/
|
|
75
|
+
abstract clear(): Promise<void>;
|
|
76
|
+
|
|
77
|
+
// ========================================
|
|
78
|
+
// Node Operations
|
|
79
|
+
// ========================================
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Add a single node
|
|
83
|
+
*/
|
|
84
|
+
abstract addNode(node: NodeRecord): Promise<void>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Add multiple nodes (batch operation)
|
|
88
|
+
*/
|
|
89
|
+
abstract addNodes(nodes: NodeRecord[]): Promise<void>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get node by ID
|
|
93
|
+
*/
|
|
94
|
+
abstract getNode(id: string): Promise<NodeRecord | null>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check if node exists
|
|
98
|
+
*/
|
|
99
|
+
abstract nodeExists(id: string): Promise<boolean>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Delete a node
|
|
103
|
+
*/
|
|
104
|
+
abstract deleteNode(id: string): Promise<void>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Find nodes by attributes
|
|
108
|
+
* @returns Array of node IDs
|
|
109
|
+
*/
|
|
110
|
+
abstract findByAttr(query: AttrQuery): Promise<string[]>;
|
|
111
|
+
|
|
112
|
+
// ========================================
|
|
113
|
+
// Edge Operations
|
|
114
|
+
// ========================================
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Add a single edge
|
|
118
|
+
*/
|
|
119
|
+
abstract addEdge(edge: EdgeRecord): Promise<void>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Add multiple edges (batch operation)
|
|
123
|
+
*/
|
|
124
|
+
abstract addEdges(edges: EdgeRecord[]): Promise<void>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Delete an edge
|
|
128
|
+
*/
|
|
129
|
+
abstract deleteEdge(src: string, dst: string, type: string): Promise<void>;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get outgoing edges from a node
|
|
133
|
+
* @param nodeId - Node ID
|
|
134
|
+
* @param edgeTypes - Filter by edge types (optional)
|
|
135
|
+
*/
|
|
136
|
+
abstract getOutgoingEdges(nodeId: string, edgeTypes?: EdgeType[] | null): Promise<EdgeRecord[]>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get incoming edges to a node
|
|
140
|
+
* @param nodeId - Node ID
|
|
141
|
+
* @param edgeTypes - Filter by edge types (optional)
|
|
142
|
+
*/
|
|
143
|
+
abstract getIncomingEdges(nodeId: string, edgeTypes?: EdgeType[] | null): Promise<EdgeRecord[]>;
|
|
144
|
+
|
|
145
|
+
// ========================================
|
|
146
|
+
// Graph Traversal
|
|
147
|
+
// ========================================
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* BFS traversal from start nodes
|
|
151
|
+
* @param startIds - Starting nodes
|
|
152
|
+
* @param maxDepth - Maximum depth
|
|
153
|
+
* @param edgeTypes - Edge types to traverse (as numbers)
|
|
154
|
+
* @returns Array of reachable node IDs
|
|
155
|
+
*/
|
|
156
|
+
abstract bfs(startIds: string[], maxDepth: number, edgeTypes: number[]): Promise<string[]>;
|
|
157
|
+
|
|
158
|
+
// ========================================
|
|
159
|
+
// Persistence
|
|
160
|
+
// ========================================
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Flush data to disk
|
|
164
|
+
*/
|
|
165
|
+
abstract flush(): Promise<void>;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get graph statistics
|
|
169
|
+
*/
|
|
170
|
+
abstract getStats(): Promise<GraphStats>;
|
|
171
|
+
|
|
172
|
+
// ========================================
|
|
173
|
+
// Compatibility Methods (for tests and GUI)
|
|
174
|
+
// ========================================
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Export entire graph to memory (only for tests!)
|
|
178
|
+
* WARNING: Do not use on large graphs
|
|
179
|
+
*/
|
|
180
|
+
abstract export(): Promise<GraphExport>;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Find nodes by predicate (for demo-gui compatibility)
|
|
184
|
+
* WARNING: May be slow on large graphs
|
|
185
|
+
*/
|
|
186
|
+
abstract findNodes(predicate: (node: NodeRecord) => boolean): Promise<NodeRecord[]>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get all nodes (for GUI - only for first level visualization)
|
|
190
|
+
* WARNING: Do not use on large graphs
|
|
191
|
+
*/
|
|
192
|
+
abstract getAllNodes(): Promise<NodeRecord[]>;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Get all edges (for GUI)
|
|
196
|
+
* WARNING: Do not use on large graphs
|
|
197
|
+
*/
|
|
198
|
+
abstract getAllEdges(): Promise<EdgeRecord[]>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Node type to numeric kind mapping
|
|
203
|
+
*/
|
|
204
|
+
const NODE_TYPE_TO_KIND: Record<string, number> = {
|
|
205
|
+
'PROJECT': 1,
|
|
206
|
+
'SERVICE': 2,
|
|
207
|
+
'FUNCTION': 3,
|
|
208
|
+
'CLASS': 4,
|
|
209
|
+
'METHOD': 5,
|
|
210
|
+
'VARIABLE': 6,
|
|
211
|
+
'PARAMETER': 7,
|
|
212
|
+
'MODULE': 8,
|
|
213
|
+
'ROUTE': 9,
|
|
214
|
+
'ENDPOINT': 10,
|
|
215
|
+
'FILE': 11,
|
|
216
|
+
'EXTERNAL_MODULE': 12,
|
|
217
|
+
'IMPORT': 13,
|
|
218
|
+
'EXPORT': 14,
|
|
219
|
+
'CALL_SITE': 15,
|
|
220
|
+
'METHOD_CALL': 16,
|
|
221
|
+
'SCOPE': 17,
|
|
222
|
+
'VARIABLE_DECLARATION': 18,
|
|
223
|
+
'CONSTANT': 19,
|
|
224
|
+
'EVENT_LISTENER': 20,
|
|
225
|
+
'HTTP_REQUEST': 21,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Convert node type to numeric kind
|
|
230
|
+
*/
|
|
231
|
+
export function typeToKind(type: string): number {
|
|
232
|
+
return NODE_TYPE_TO_KIND[type] || 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Edge type to numeric mapping
|
|
237
|
+
*/
|
|
238
|
+
const EDGE_TYPE_TO_NUMBER: Record<string, number> = {
|
|
239
|
+
'CONTAINS': 1,
|
|
240
|
+
'DEPENDS_ON': 2,
|
|
241
|
+
'CALLS': 3,
|
|
242
|
+
'EXTENDS': 4,
|
|
243
|
+
'IMPLEMENTS': 5,
|
|
244
|
+
'USES': 6,
|
|
245
|
+
'DEFINES': 7,
|
|
246
|
+
'IMPORTS': 8,
|
|
247
|
+
'EXPORTS': 9,
|
|
248
|
+
'ROUTES_TO': 10,
|
|
249
|
+
'DECLARES': 11,
|
|
250
|
+
'HAS_SCOPE': 12,
|
|
251
|
+
'CAPTURES': 13,
|
|
252
|
+
'MODIFIES': 14,
|
|
253
|
+
'WRITES_TO': 15,
|
|
254
|
+
'INSTANCE_OF': 16,
|
|
255
|
+
'HANDLED_BY': 17,
|
|
256
|
+
'HAS_CALLBACK': 18,
|
|
257
|
+
'MAKES_REQUEST': 19,
|
|
258
|
+
'IMPORTS_FROM': 20,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Convert edge type to number
|
|
263
|
+
*/
|
|
264
|
+
export function edgeTypeToNumber(type: string): number {
|
|
265
|
+
return EDGE_TYPE_TO_NUMBER[type] || 0;
|
|
266
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphFreshnessChecker - checks if graph data matches current files
|
|
3
|
+
*
|
|
4
|
+
* Compares contentHash stored in MODULE nodes against current file hashes.
|
|
5
|
+
* Used by `grafema check` to detect when files have changed since analysis.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { access, constants } from 'fs/promises';
|
|
9
|
+
import { calculateFileHashAsync } from './HashUtils.js';
|
|
10
|
+
import { resolveNodeFile } from '../utils/resolveNodeFile.js';
|
|
11
|
+
import type { NodeRecord } from '@grafema/types';
|
|
12
|
+
|
|
13
|
+
export interface StaleModule {
|
|
14
|
+
id: string;
|
|
15
|
+
file: string;
|
|
16
|
+
storedHash: string;
|
|
17
|
+
currentHash: string | null;
|
|
18
|
+
reason: 'changed' | 'deleted' | 'unreadable';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FreshnessResult {
|
|
22
|
+
isFresh: boolean;
|
|
23
|
+
staleModules: StaleModule[];
|
|
24
|
+
freshCount: number;
|
|
25
|
+
staleCount: number;
|
|
26
|
+
deletedCount: number;
|
|
27
|
+
checkDurationMs: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FreshnessGraph {
|
|
31
|
+
queryNodes(query: { type: string }): AsyncGenerator<NodeRecord, void, unknown>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ModuleInfo {
|
|
35
|
+
id: string;
|
|
36
|
+
file: string;
|
|
37
|
+
contentHash: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const BATCH_SIZE = 50;
|
|
41
|
+
|
|
42
|
+
export class GraphFreshnessChecker {
|
|
43
|
+
async checkFreshness(graph: FreshnessGraph, projectPath?: string): Promise<FreshnessResult> {
|
|
44
|
+
const startTime = Date.now();
|
|
45
|
+
|
|
46
|
+
const modules: ModuleInfo[] = [];
|
|
47
|
+
for await (const node of graph.queryNodes({ type: 'MODULE' })) {
|
|
48
|
+
if (node.file && typeof node.contentHash === 'string') {
|
|
49
|
+
modules.push({
|
|
50
|
+
id: node.id,
|
|
51
|
+
file: node.file,
|
|
52
|
+
contentHash: node.contentHash
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (modules.length === 0) {
|
|
58
|
+
return {
|
|
59
|
+
isFresh: true,
|
|
60
|
+
staleModules: [],
|
|
61
|
+
freshCount: 0,
|
|
62
|
+
staleCount: 0,
|
|
63
|
+
deletedCount: 0,
|
|
64
|
+
checkDurationMs: Date.now() - startTime
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const staleModules: StaleModule[] = [];
|
|
69
|
+
let freshCount = 0;
|
|
70
|
+
let deletedCount = 0;
|
|
71
|
+
|
|
72
|
+
for (let i = 0; i < modules.length; i += BATCH_SIZE) {
|
|
73
|
+
const batch = modules.slice(i, i + BATCH_SIZE);
|
|
74
|
+
const results = await Promise.all(
|
|
75
|
+
batch.map(module => this._checkModuleFreshness(module, projectPath))
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
for (const result of results) {
|
|
79
|
+
if (result === null) {
|
|
80
|
+
freshCount++;
|
|
81
|
+
} else {
|
|
82
|
+
staleModules.push(result);
|
|
83
|
+
if (result.reason === 'deleted') {
|
|
84
|
+
deletedCount++;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
isFresh: staleModules.length === 0,
|
|
92
|
+
staleModules,
|
|
93
|
+
freshCount,
|
|
94
|
+
staleCount: staleModules.length,
|
|
95
|
+
deletedCount,
|
|
96
|
+
checkDurationMs: Date.now() - startTime
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private async _checkModuleFreshness(module: ModuleInfo, projectPath?: string): Promise<StaleModule | null> {
|
|
101
|
+
const absoluteFile = projectPath ? resolveNodeFile(module.file, projectPath) : module.file;
|
|
102
|
+
const exists = await this._fileExists(absoluteFile);
|
|
103
|
+
if (!exists) {
|
|
104
|
+
return {
|
|
105
|
+
id: module.id,
|
|
106
|
+
file: module.file,
|
|
107
|
+
storedHash: module.contentHash,
|
|
108
|
+
currentHash: null,
|
|
109
|
+
reason: 'deleted'
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const currentHash = await calculateFileHashAsync(absoluteFile);
|
|
114
|
+
if (currentHash === null) {
|
|
115
|
+
return {
|
|
116
|
+
id: module.id,
|
|
117
|
+
file: module.file,
|
|
118
|
+
storedHash: module.contentHash,
|
|
119
|
+
currentHash: null,
|
|
120
|
+
reason: 'unreadable'
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (currentHash !== module.contentHash) {
|
|
125
|
+
return {
|
|
126
|
+
id: module.id,
|
|
127
|
+
file: module.file,
|
|
128
|
+
storedHash: module.contentHash,
|
|
129
|
+
currentHash,
|
|
130
|
+
reason: 'changed'
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private async _fileExists(filePath: string): Promise<boolean> {
|
|
138
|
+
try {
|
|
139
|
+
await access(filePath, constants.R_OK);
|
|
140
|
+
return true;
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|