@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.
Files changed (324) hide show
  1. package/LICENSE +190 -0
  2. package/dist/api/GraphAPI.d.ts +87 -0
  3. package/dist/api/GraphAPI.d.ts.map +1 -0
  4. package/dist/api/GraphAPI.js +212 -0
  5. package/dist/api/GraphAPI.js.map +1 -0
  6. package/dist/api/GuaranteeAPI.d.ts +147 -0
  7. package/dist/api/GuaranteeAPI.d.ts.map +1 -0
  8. package/dist/api/GuaranteeAPI.js +290 -0
  9. package/dist/api/GuaranteeAPI.js.map +1 -0
  10. package/dist/config/ConfigLoader.d.ts +214 -0
  11. package/dist/config/ConfigLoader.d.ts.map +1 -0
  12. package/dist/config/ConfigLoader.js +441 -0
  13. package/dist/config/ConfigLoader.js.map +1 -0
  14. package/dist/config/index.d.ts +6 -0
  15. package/dist/config/index.d.ts.map +1 -0
  16. package/dist/config/index.js +5 -0
  17. package/dist/config/index.js.map +1 -0
  18. package/dist/core/CoverageAnalyzer.d.ts +65 -0
  19. package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
  20. package/dist/core/CoverageAnalyzer.js +199 -0
  21. package/dist/core/CoverageAnalyzer.js.map +1 -0
  22. package/dist/core/FileExplainer.d.ts +101 -0
  23. package/dist/core/FileExplainer.d.ts.map +1 -0
  24. package/dist/core/FileExplainer.js +140 -0
  25. package/dist/core/FileExplainer.js.map +1 -0
  26. package/dist/core/FileOverview.d.ts +124 -0
  27. package/dist/core/FileOverview.d.ts.map +1 -0
  28. package/dist/core/FileOverview.js +279 -0
  29. package/dist/core/FileOverview.js.map +1 -0
  30. package/dist/core/GrafemaUri.d.ts +66 -0
  31. package/dist/core/GrafemaUri.d.ts.map +1 -0
  32. package/dist/core/GrafemaUri.js +191 -0
  33. package/dist/core/GrafemaUri.js.map +1 -0
  34. package/dist/core/GraphBackend.d.ts +158 -0
  35. package/dist/core/GraphBackend.d.ts.map +1 -0
  36. package/dist/core/GraphBackend.js +85 -0
  37. package/dist/core/GraphBackend.js.map +1 -0
  38. package/dist/core/GraphFreshnessChecker.d.ts +33 -0
  39. package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
  40. package/dist/core/GraphFreshnessChecker.js +104 -0
  41. package/dist/core/GraphFreshnessChecker.js.map +1 -0
  42. package/dist/core/GuaranteeManager.d.ts +254 -0
  43. package/dist/core/GuaranteeManager.d.ts.map +1 -0
  44. package/dist/core/GuaranteeManager.js +447 -0
  45. package/dist/core/GuaranteeManager.js.map +1 -0
  46. package/dist/core/HashUtils.d.ts +24 -0
  47. package/dist/core/HashUtils.d.ts.map +1 -0
  48. package/dist/core/HashUtils.js +46 -0
  49. package/dist/core/HashUtils.js.map +1 -0
  50. package/dist/core/IncrementalReanalyzer.d.ts +33 -0
  51. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
  52. package/dist/core/IncrementalReanalyzer.js +67 -0
  53. package/dist/core/IncrementalReanalyzer.js.map +1 -0
  54. package/dist/core/ResourceRegistry.d.ts +17 -0
  55. package/dist/core/ResourceRegistry.d.ts.map +1 -0
  56. package/dist/core/ResourceRegistry.js +32 -0
  57. package/dist/core/ResourceRegistry.js.map +1 -0
  58. package/dist/core/SemanticId.d.ts +159 -0
  59. package/dist/core/SemanticId.d.ts.map +1 -0
  60. package/dist/core/SemanticId.js +291 -0
  61. package/dist/core/SemanticId.js.map +1 -0
  62. package/dist/core/VersionManager.d.ts +166 -0
  63. package/dist/core/VersionManager.d.ts.map +1 -0
  64. package/dist/core/VersionManager.js +239 -0
  65. package/dist/core/VersionManager.js.map +1 -0
  66. package/dist/core/brandNodeInternal.d.ts +14 -0
  67. package/dist/core/brandNodeInternal.d.ts.map +1 -0
  68. package/dist/core/brandNodeInternal.js +4 -0
  69. package/dist/core/brandNodeInternal.js.map +1 -0
  70. package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
  71. package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
  72. package/dist/core/nodes/GuaranteeNode.js +118 -0
  73. package/dist/core/nodes/GuaranteeNode.js.map +1 -0
  74. package/dist/core/nodes/IssueNode.d.ts +73 -0
  75. package/dist/core/nodes/IssueNode.d.ts.map +1 -0
  76. package/dist/core/nodes/IssueNode.js +130 -0
  77. package/dist/core/nodes/IssueNode.js.map +1 -0
  78. package/dist/core/nodes/NodeKind.d.ts +104 -0
  79. package/dist/core/nodes/NodeKind.d.ts.map +1 -0
  80. package/dist/core/nodes/NodeKind.js +166 -0
  81. package/dist/core/nodes/NodeKind.js.map +1 -0
  82. package/dist/diagnostics/DiagnosticCollector.d.ts +103 -0
  83. package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
  84. package/dist/diagnostics/DiagnosticCollector.js +133 -0
  85. package/dist/diagnostics/DiagnosticCollector.js.map +1 -0
  86. package/dist/diagnostics/DiagnosticReporter.d.ts +122 -0
  87. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
  88. package/dist/diagnostics/DiagnosticReporter.js +300 -0
  89. package/dist/diagnostics/DiagnosticReporter.js.map +1 -0
  90. package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
  91. package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
  92. package/dist/diagnostics/DiagnosticWriter.js +44 -0
  93. package/dist/diagnostics/DiagnosticWriter.js.map +1 -0
  94. package/dist/diagnostics/categories.d.ts +57 -0
  95. package/dist/diagnostics/categories.d.ts.map +1 -0
  96. package/dist/diagnostics/categories.js +71 -0
  97. package/dist/diagnostics/categories.js.map +1 -0
  98. package/dist/diagnostics/index.d.ts +17 -0
  99. package/dist/diagnostics/index.d.ts.map +1 -0
  100. package/dist/diagnostics/index.js +15 -0
  101. package/dist/diagnostics/index.js.map +1 -0
  102. package/dist/errors/GrafemaError.d.ts +200 -0
  103. package/dist/errors/GrafemaError.d.ts.map +1 -0
  104. package/dist/errors/GrafemaError.js +209 -0
  105. package/dist/errors/GrafemaError.js.map +1 -0
  106. package/dist/index.d.ts +75 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +76 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/instructions/index.d.ts +8 -0
  111. package/dist/instructions/index.d.ts.map +1 -0
  112. package/dist/instructions/index.js +20 -0
  113. package/dist/instructions/index.js.map +1 -0
  114. package/dist/instructions/onboarding.md +133 -0
  115. package/dist/knowledge/KnowledgeBase.d.ts +113 -0
  116. package/dist/knowledge/KnowledgeBase.d.ts.map +1 -0
  117. package/dist/knowledge/KnowledgeBase.js +420 -0
  118. package/dist/knowledge/KnowledgeBase.js.map +1 -0
  119. package/dist/knowledge/SemanticAddressResolver.d.ts +59 -0
  120. package/dist/knowledge/SemanticAddressResolver.d.ts.map +1 -0
  121. package/dist/knowledge/SemanticAddressResolver.js +160 -0
  122. package/dist/knowledge/SemanticAddressResolver.js.map +1 -0
  123. package/dist/knowledge/git-ingest.d.ts +58 -0
  124. package/dist/knowledge/git-ingest.d.ts.map +1 -0
  125. package/dist/knowledge/git-ingest.js +301 -0
  126. package/dist/knowledge/git-ingest.js.map +1 -0
  127. package/dist/knowledge/git-queries.d.ts +86 -0
  128. package/dist/knowledge/git-queries.d.ts.map +1 -0
  129. package/dist/knowledge/git-queries.js +177 -0
  130. package/dist/knowledge/git-queries.js.map +1 -0
  131. package/dist/knowledge/index.d.ts +14 -0
  132. package/dist/knowledge/index.d.ts.map +1 -0
  133. package/dist/knowledge/index.js +10 -0
  134. package/dist/knowledge/index.js.map +1 -0
  135. package/dist/knowledge/parser.d.ts +39 -0
  136. package/dist/knowledge/parser.d.ts.map +1 -0
  137. package/dist/knowledge/parser.js +292 -0
  138. package/dist/knowledge/parser.js.map +1 -0
  139. package/dist/knowledge/types.d.ts +133 -0
  140. package/dist/knowledge/types.d.ts.map +1 -0
  141. package/dist/knowledge/types.js +8 -0
  142. package/dist/knowledge/types.js.map +1 -0
  143. package/dist/logging/Logger.d.ts +98 -0
  144. package/dist/logging/Logger.d.ts.map +1 -0
  145. package/dist/logging/Logger.js +274 -0
  146. package/dist/logging/Logger.js.map +1 -0
  147. package/dist/notation/archetypes.d.ts +36 -0
  148. package/dist/notation/archetypes.d.ts.map +1 -0
  149. package/dist/notation/archetypes.js +173 -0
  150. package/dist/notation/archetypes.js.map +1 -0
  151. package/dist/notation/fold.d.ts +25 -0
  152. package/dist/notation/fold.d.ts.map +1 -0
  153. package/dist/notation/fold.js +598 -0
  154. package/dist/notation/fold.js.map +1 -0
  155. package/dist/notation/index.d.ts +18 -0
  156. package/dist/notation/index.d.ts.map +1 -0
  157. package/dist/notation/index.js +16 -0
  158. package/dist/notation/index.js.map +1 -0
  159. package/dist/notation/lodExtractor.d.ts +32 -0
  160. package/dist/notation/lodExtractor.d.ts.map +1 -0
  161. package/dist/notation/lodExtractor.js +149 -0
  162. package/dist/notation/lodExtractor.js.map +1 -0
  163. package/dist/notation/nameShortener.d.ts +22 -0
  164. package/dist/notation/nameShortener.d.ts.map +1 -0
  165. package/dist/notation/nameShortener.js +24 -0
  166. package/dist/notation/nameShortener.js.map +1 -0
  167. package/dist/notation/perspectives.d.ts +11 -0
  168. package/dist/notation/perspectives.d.ts.map +1 -0
  169. package/dist/notation/perspectives.js +16 -0
  170. package/dist/notation/perspectives.js.map +1 -0
  171. package/dist/notation/renderer.d.ts +31 -0
  172. package/dist/notation/renderer.d.ts.map +1 -0
  173. package/dist/notation/renderer.js +315 -0
  174. package/dist/notation/renderer.js.map +1 -0
  175. package/dist/notation/traceRenderer.d.ts +39 -0
  176. package/dist/notation/traceRenderer.d.ts.map +1 -0
  177. package/dist/notation/traceRenderer.js +358 -0
  178. package/dist/notation/traceRenderer.js.map +1 -0
  179. package/dist/notation/types.d.ts +66 -0
  180. package/dist/notation/types.d.ts.map +1 -0
  181. package/dist/notation/types.js +10 -0
  182. package/dist/notation/types.js.map +1 -0
  183. package/dist/queries/NodeContext.d.ts +81 -0
  184. package/dist/queries/NodeContext.d.ts.map +1 -0
  185. package/dist/queries/NodeContext.js +196 -0
  186. package/dist/queries/NodeContext.js.map +1 -0
  187. package/dist/queries/findCallsInFunction.d.ts +62 -0
  188. package/dist/queries/findCallsInFunction.d.ts.map +1 -0
  189. package/dist/queries/findCallsInFunction.js +169 -0
  190. package/dist/queries/findCallsInFunction.js.map +1 -0
  191. package/dist/queries/findContainingFunction.d.ts +57 -0
  192. package/dist/queries/findContainingFunction.d.ts.map +1 -0
  193. package/dist/queries/findContainingFunction.js +91 -0
  194. package/dist/queries/findContainingFunction.js.map +1 -0
  195. package/dist/queries/index.d.ts +18 -0
  196. package/dist/queries/index.d.ts.map +1 -0
  197. package/dist/queries/index.js +14 -0
  198. package/dist/queries/index.js.map +1 -0
  199. package/dist/queries/traceDataflow.d.ts +65 -0
  200. package/dist/queries/traceDataflow.d.ts.map +1 -0
  201. package/dist/queries/traceDataflow.js +754 -0
  202. package/dist/queries/traceDataflow.js.map +1 -0
  203. package/dist/queries/traceValues.d.ts +70 -0
  204. package/dist/queries/traceValues.d.ts.map +1 -0
  205. package/dist/queries/traceValues.js +373 -0
  206. package/dist/queries/traceValues.js.map +1 -0
  207. package/dist/queries/types.d.ts +166 -0
  208. package/dist/queries/types.d.ts.map +1 -0
  209. package/dist/queries/types.js +10 -0
  210. package/dist/queries/types.js.map +1 -0
  211. package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
  212. package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
  213. package/dist/schema/GraphSchemaExtractor.js +125 -0
  214. package/dist/schema/GraphSchemaExtractor.js.map +1 -0
  215. package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
  216. package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
  217. package/dist/schema/InterfaceSchemaExtractor.js +113 -0
  218. package/dist/schema/InterfaceSchemaExtractor.js.map +1 -0
  219. package/dist/schema/index.d.ts +5 -0
  220. package/dist/schema/index.d.ts.map +1 -0
  221. package/dist/schema/index.js +3 -0
  222. package/dist/schema/index.js.map +1 -0
  223. package/dist/storage/backends/RFDBServerBackend.d.ts +356 -0
  224. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
  225. package/dist/storage/backends/RFDBServerBackend.js +748 -0
  226. package/dist/storage/backends/RFDBServerBackend.js.map +1 -0
  227. package/dist/storage/backends/typeValidation.d.ts +47 -0
  228. package/dist/storage/backends/typeValidation.d.ts.map +1 -0
  229. package/dist/storage/backends/typeValidation.js +141 -0
  230. package/dist/storage/backends/typeValidation.js.map +1 -0
  231. package/dist/utils/findRfdbBinary.d.ts +67 -0
  232. package/dist/utils/findRfdbBinary.d.ts.map +1 -0
  233. package/dist/utils/findRfdbBinary.js +261 -0
  234. package/dist/utils/findRfdbBinary.js.map +1 -0
  235. package/dist/utils/lazyDownload.d.ts +43 -0
  236. package/dist/utils/lazyDownload.d.ts.map +1 -0
  237. package/dist/utils/lazyDownload.js +175 -0
  238. package/dist/utils/lazyDownload.js.map +1 -0
  239. package/dist/utils/moduleResolution.d.ts +134 -0
  240. package/dist/utils/moduleResolution.d.ts.map +1 -0
  241. package/dist/utils/moduleResolution.js +189 -0
  242. package/dist/utils/moduleResolution.js.map +1 -0
  243. package/dist/utils/resolveNodeFile.d.ts +13 -0
  244. package/dist/utils/resolveNodeFile.d.ts.map +1 -0
  245. package/dist/utils/resolveNodeFile.js +18 -0
  246. package/dist/utils/resolveNodeFile.js.map +1 -0
  247. package/dist/utils/startRfdbServer.d.ts +63 -0
  248. package/dist/utils/startRfdbServer.d.ts.map +1 -0
  249. package/dist/utils/startRfdbServer.js +142 -0
  250. package/dist/utils/startRfdbServer.js.map +1 -0
  251. package/dist/validation/PathValidator.d.ts +80 -0
  252. package/dist/validation/PathValidator.d.ts.map +1 -0
  253. package/dist/validation/PathValidator.js +252 -0
  254. package/dist/validation/PathValidator.js.map +1 -0
  255. package/dist/version.d.ts +11 -0
  256. package/dist/version.d.ts.map +1 -0
  257. package/dist/version.js +26 -0
  258. package/dist/version.js.map +1 -0
  259. package/package.json +50 -0
  260. package/src/api/GraphAPI.ts +307 -0
  261. package/src/api/GuaranteeAPI.ts +402 -0
  262. package/src/config/ConfigLoader.ts +653 -0
  263. package/src/config/index.ts +13 -0
  264. package/src/core/CoverageAnalyzer.ts +243 -0
  265. package/src/core/FileExplainer.ts +179 -0
  266. package/src/core/FileOverview.ts +397 -0
  267. package/src/core/GrafemaUri.ts +216 -0
  268. package/src/core/GraphBackend.ts +266 -0
  269. package/src/core/GraphFreshnessChecker.ts +145 -0
  270. package/src/core/GuaranteeManager.ts +684 -0
  271. package/src/core/HashUtils.ts +48 -0
  272. package/src/core/IncrementalReanalyzer.ts +106 -0
  273. package/src/core/ResourceRegistry.ts +39 -0
  274. package/src/core/SemanticId.ts +423 -0
  275. package/src/core/VersionManager.ts +405 -0
  276. package/src/core/brandNodeInternal.ts +16 -0
  277. package/src/core/nodes/GuaranteeNode.ts +162 -0
  278. package/src/core/nodes/IssueNode.ts +177 -0
  279. package/src/core/nodes/NodeKind.ts +192 -0
  280. package/src/diagnostics/DiagnosticCollector.ts +170 -0
  281. package/src/diagnostics/DiagnosticReporter.ts +395 -0
  282. package/src/diagnostics/DiagnosticWriter.ts +50 -0
  283. package/src/diagnostics/categories.ts +104 -0
  284. package/src/diagnostics/index.ts +30 -0
  285. package/src/errors/GrafemaError.ts +297 -0
  286. package/src/index.ts +261 -0
  287. package/src/instructions/index.ts +21 -0
  288. package/src/instructions/onboarding.md +133 -0
  289. package/src/knowledge/KnowledgeBase.ts +486 -0
  290. package/src/knowledge/SemanticAddressResolver.ts +191 -0
  291. package/src/knowledge/git-ingest.ts +402 -0
  292. package/src/knowledge/git-queries.ts +269 -0
  293. package/src/knowledge/index.ts +29 -0
  294. package/src/knowledge/parser.ts +294 -0
  295. package/src/knowledge/types.ts +146 -0
  296. package/src/logging/Logger.ts +303 -0
  297. package/src/notation/archetypes.ts +189 -0
  298. package/src/notation/fold.ts +696 -0
  299. package/src/notation/index.ts +27 -0
  300. package/src/notation/lodExtractor.ts +177 -0
  301. package/src/notation/nameShortener.ts +24 -0
  302. package/src/notation/perspectives.ts +18 -0
  303. package/src/notation/renderer.ts +394 -0
  304. package/src/notation/traceRenderer.ts +458 -0
  305. package/src/notation/types.ts +79 -0
  306. package/src/queries/NodeContext.ts +280 -0
  307. package/src/queries/findCallsInFunction.ts +249 -0
  308. package/src/queries/findContainingFunction.ts +124 -0
  309. package/src/queries/index.ts +44 -0
  310. package/src/queries/traceDataflow.ts +838 -0
  311. package/src/queries/traceValues.ts +531 -0
  312. package/src/queries/types.ts +191 -0
  313. package/src/schema/GraphSchemaExtractor.ts +177 -0
  314. package/src/schema/InterfaceSchemaExtractor.ts +173 -0
  315. package/src/schema/index.ts +5 -0
  316. package/src/storage/backends/RFDBServerBackend.ts +895 -0
  317. package/src/storage/backends/typeValidation.ts +154 -0
  318. package/src/utils/findRfdbBinary.ts +288 -0
  319. package/src/utils/lazyDownload.ts +206 -0
  320. package/src/utils/moduleResolution.ts +271 -0
  321. package/src/utils/resolveNodeFile.ts +18 -0
  322. package/src/utils/startRfdbServer.ts +197 -0
  323. package/src/validation/PathValidator.ts +334 -0
  324. 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
+ }