mindgraph-core 0.1.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.
Files changed (169) hide show
  1. package/dist/embeddings/embedder-interface.d.ts +15 -0
  2. package/dist/embeddings/embedder-interface.d.ts.map +1 -0
  3. package/dist/embeddings/embedder-interface.js +2 -0
  4. package/dist/embeddings/embedder-interface.js.map +1 -0
  5. package/dist/embeddings/ollama-embedder.d.ts +21 -0
  6. package/dist/embeddings/ollama-embedder.d.ts.map +1 -0
  7. package/dist/embeddings/ollama-embedder.js +78 -0
  8. package/dist/embeddings/ollama-embedder.js.map +1 -0
  9. package/dist/embeddings/transformers-embedder.d.ts +20 -0
  10. package/dist/embeddings/transformers-embedder.d.ts.map +1 -0
  11. package/dist/embeddings/transformers-embedder.js +61 -0
  12. package/dist/embeddings/transformers-embedder.js.map +1 -0
  13. package/dist/extraction/anthropic-extractor.d.ts +17 -0
  14. package/dist/extraction/anthropic-extractor.d.ts.map +1 -0
  15. package/dist/extraction/anthropic-extractor.js +43 -0
  16. package/dist/extraction/anthropic-extractor.js.map +1 -0
  17. package/dist/extraction/basic-extractor.d.ts +17 -0
  18. package/dist/extraction/basic-extractor.d.ts.map +1 -0
  19. package/dist/extraction/basic-extractor.js +135 -0
  20. package/dist/extraction/basic-extractor.js.map +1 -0
  21. package/dist/extraction/confidence-gate.d.ts +7 -0
  22. package/dist/extraction/confidence-gate.d.ts.map +1 -0
  23. package/dist/extraction/confidence-gate.js +13 -0
  24. package/dist/extraction/confidence-gate.js.map +1 -0
  25. package/dist/extraction/contradiction-detector.d.ts +46 -0
  26. package/dist/extraction/contradiction-detector.d.ts.map +1 -0
  27. package/dist/extraction/contradiction-detector.js +205 -0
  28. package/dist/extraction/contradiction-detector.js.map +1 -0
  29. package/dist/extraction/entity-index.d.ts +31 -0
  30. package/dist/extraction/entity-index.d.ts.map +1 -0
  31. package/dist/extraction/entity-index.js +90 -0
  32. package/dist/extraction/entity-index.js.map +1 -0
  33. package/dist/extraction/entity-resolver.d.ts +28 -0
  34. package/dist/extraction/entity-resolver.d.ts.map +1 -0
  35. package/dist/extraction/entity-resolver.js +111 -0
  36. package/dist/extraction/entity-resolver.js.map +1 -0
  37. package/dist/extraction/extractor-interface.d.ts +51 -0
  38. package/dist/extraction/extractor-interface.d.ts.map +1 -0
  39. package/dist/extraction/extractor-interface.js +2 -0
  40. package/dist/extraction/extractor-interface.js.map +1 -0
  41. package/dist/extraction/llm-extractor.d.ts +21 -0
  42. package/dist/extraction/llm-extractor.d.ts.map +1 -0
  43. package/dist/extraction/llm-extractor.js +97 -0
  44. package/dist/extraction/llm-extractor.js.map +1 -0
  45. package/dist/extraction/ollama-extractor.d.ts +18 -0
  46. package/dist/extraction/ollama-extractor.d.ts.map +1 -0
  47. package/dist/extraction/ollama-extractor.js +50 -0
  48. package/dist/extraction/ollama-extractor.js.map +1 -0
  49. package/dist/extraction/open-loop-detector.d.ts +24 -0
  50. package/dist/extraction/open-loop-detector.d.ts.map +1 -0
  51. package/dist/extraction/open-loop-detector.js +187 -0
  52. package/dist/extraction/open-loop-detector.js.map +1 -0
  53. package/dist/extraction/openai-extractor.d.ts +20 -0
  54. package/dist/extraction/openai-extractor.d.ts.map +1 -0
  55. package/dist/extraction/openai-extractor.js +44 -0
  56. package/dist/extraction/openai-extractor.js.map +1 -0
  57. package/dist/extraction/prompts/entity-extraction.d.ts +2 -0
  58. package/dist/extraction/prompts/entity-extraction.d.ts.map +1 -0
  59. package/dist/extraction/prompts/entity-extraction.js +42 -0
  60. package/dist/extraction/prompts/entity-extraction.js.map +1 -0
  61. package/dist/extraction/prompts/proposition-extraction.d.ts +2 -0
  62. package/dist/extraction/prompts/proposition-extraction.d.ts.map +1 -0
  63. package/dist/extraction/prompts/proposition-extraction.js +39 -0
  64. package/dist/extraction/prompts/proposition-extraction.js.map +1 -0
  65. package/dist/extraction/prompts/thought-extraction.d.ts +2 -0
  66. package/dist/extraction/prompts/thought-extraction.d.ts.map +1 -0
  67. package/dist/extraction/prompts/thought-extraction.js +41 -0
  68. package/dist/extraction/prompts/thought-extraction.js.map +1 -0
  69. package/dist/index.d.ts +41 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +33 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/ingestion/chunk-id.d.ts +27 -0
  74. package/dist/ingestion/chunk-id.d.ts.map +1 -0
  75. package/dist/ingestion/chunk-id.js +45 -0
  76. package/dist/ingestion/chunk-id.js.map +1 -0
  77. package/dist/ingestion/chunker.d.ts +29 -0
  78. package/dist/ingestion/chunker.d.ts.map +1 -0
  79. package/dist/ingestion/chunker.js +182 -0
  80. package/dist/ingestion/chunker.js.map +1 -0
  81. package/dist/ingestion/hasher.d.ts +7 -0
  82. package/dist/ingestion/hasher.d.ts.map +1 -0
  83. package/dist/ingestion/hasher.js +18 -0
  84. package/dist/ingestion/hasher.js.map +1 -0
  85. package/dist/ingestion/pipeline.d.ts +58 -0
  86. package/dist/ingestion/pipeline.d.ts.map +1 -0
  87. package/dist/ingestion/pipeline.js +653 -0
  88. package/dist/ingestion/pipeline.js.map +1 -0
  89. package/dist/models/citation.d.ts +2 -0
  90. package/dist/models/citation.d.ts.map +1 -0
  91. package/dist/models/citation.js +2 -0
  92. package/dist/models/citation.js.map +1 -0
  93. package/dist/models/extraction-result.d.ts +2 -0
  94. package/dist/models/extraction-result.d.ts.map +1 -0
  95. package/dist/models/extraction-result.js +2 -0
  96. package/dist/models/extraction-result.js.map +1 -0
  97. package/dist/models/query-result.d.ts +2 -0
  98. package/dist/models/query-result.d.ts.map +1 -0
  99. package/dist/models/query-result.js +2 -0
  100. package/dist/models/query-result.js.map +1 -0
  101. package/dist/query/answer-builder.d.ts +15 -0
  102. package/dist/query/answer-builder.d.ts.map +1 -0
  103. package/dist/query/answer-builder.js +51 -0
  104. package/dist/query/answer-builder.js.map +1 -0
  105. package/dist/query/citation-builder.d.ts +19 -0
  106. package/dist/query/citation-builder.d.ts.map +1 -0
  107. package/dist/query/citation-builder.js +54 -0
  108. package/dist/query/citation-builder.js.map +1 -0
  109. package/dist/query/graph-data.d.ts +39 -0
  110. package/dist/query/graph-data.d.ts.map +1 -0
  111. package/dist/query/graph-data.js +115 -0
  112. package/dist/query/graph-data.js.map +1 -0
  113. package/dist/query/graph-search.d.ts +43 -0
  114. package/dist/query/graph-search.d.ts.map +1 -0
  115. package/dist/query/graph-search.js +315 -0
  116. package/dist/query/graph-search.js.map +1 -0
  117. package/dist/query/query-engine.d.ts +41 -0
  118. package/dist/query/query-engine.d.ts.map +1 -0
  119. package/dist/query/query-engine.js +178 -0
  120. package/dist/query/query-engine.js.map +1 -0
  121. package/dist/query/semantic-search.d.ts +26 -0
  122. package/dist/query/semantic-search.d.ts.map +1 -0
  123. package/dist/query/semantic-search.js +132 -0
  124. package/dist/query/semantic-search.js.map +1 -0
  125. package/dist/schema/edge-types.d.ts +95 -0
  126. package/dist/schema/edge-types.d.ts.map +1 -0
  127. package/dist/schema/edge-types.js +6 -0
  128. package/dist/schema/edge-types.js.map +1 -0
  129. package/dist/schema/node-types.d.ts +100 -0
  130. package/dist/schema/node-types.d.ts.map +1 -0
  131. package/dist/schema/node-types.js +6 -0
  132. package/dist/schema/node-types.js.map +1 -0
  133. package/dist/schema/types.d.ts +134 -0
  134. package/dist/schema/types.d.ts.map +1 -0
  135. package/dist/schema/types.js +52 -0
  136. package/dist/schema/types.js.map +1 -0
  137. package/dist/schema/validation.d.ts +6 -0
  138. package/dist/schema/validation.d.ts.map +1 -0
  139. package/dist/schema/validation.js +140 -0
  140. package/dist/schema/validation.js.map +1 -0
  141. package/dist/storage/export-import.d.ts +28 -0
  142. package/dist/storage/export-import.d.ts.map +1 -0
  143. package/dist/storage/export-import.js +189 -0
  144. package/dist/storage/export-import.js.map +1 -0
  145. package/dist/storage/memory/memory-adapter.d.ts +36 -0
  146. package/dist/storage/memory/memory-adapter.d.ts.map +1 -0
  147. package/dist/storage/memory/memory-adapter.js +231 -0
  148. package/dist/storage/memory/memory-adapter.js.map +1 -0
  149. package/dist/storage/sqlite/graph-traversal.d.ts +11 -0
  150. package/dist/storage/sqlite/graph-traversal.d.ts.map +1 -0
  151. package/dist/storage/sqlite/graph-traversal.js +79 -0
  152. package/dist/storage/sqlite/graph-traversal.js.map +1 -0
  153. package/dist/storage/sqlite/query-builder.d.ts +8 -0
  154. package/dist/storage/sqlite/query-builder.d.ts.map +1 -0
  155. package/dist/storage/sqlite/query-builder.js +55 -0
  156. package/dist/storage/sqlite/query-builder.js.map +1 -0
  157. package/dist/storage/sqlite/sqlite-adapter.d.ts +53 -0
  158. package/dist/storage/sqlite/sqlite-adapter.d.ts.map +1 -0
  159. package/dist/storage/sqlite/sqlite-adapter.js +497 -0
  160. package/dist/storage/sqlite/sqlite-adapter.js.map +1 -0
  161. package/dist/storage/storage-interface.d.ts +64 -0
  162. package/dist/storage/storage-interface.d.ts.map +1 -0
  163. package/dist/storage/storage-interface.js +2 -0
  164. package/dist/storage/storage-interface.js.map +1 -0
  165. package/dist/utils/retry-fetch.d.ts +20 -0
  166. package/dist/utils/retry-fetch.d.ts.map +1 -0
  167. package/dist/utils/retry-fetch.js +71 -0
  168. package/dist/utils/retry-fetch.js.map +1 -0
  169. package/package.json +28 -0
@@ -0,0 +1,140 @@
1
+ import { NodeType, RelType } from './types.js';
2
+ // ─── Confidence gating ─────────────────────────────────────────────
3
+ const DEFAULT_CONFIDENCE_THRESHOLD = 0.5;
4
+ export function passesConfidenceGate(data, threshold = DEFAULT_CONFIDENCE_THRESHOLD) {
5
+ if (typeof data.confidence === 'number') {
6
+ return data.confidence >= threshold;
7
+ }
8
+ return true; // no confidence field → pass
9
+ }
10
+ // ─── Node validation ───────────────────────────────────────────────
11
+ const REQUIRED_NODE_FIELDS = {
12
+ [NodeType.Note]: ['title', 'path', 'contentHash'],
13
+ [NodeType.Chunk]: ['notePath', 'text', 'startOffset', 'endOffset', 'contentHash'],
14
+ [NodeType.Entity]: ['name', 'entityType'],
15
+ [NodeType.Concept]: ['name'],
16
+ [NodeType.Location]: ['name', 'locationType'],
17
+ [NodeType.Event]: ['name'],
18
+ [NodeType.Proposition]: ['statement', 'statementHash'],
19
+ [NodeType.Thought]: ['statement', 'stance'],
20
+ [NodeType.Agent]: ['name', 'agentType'],
21
+ [NodeType.Emotion]: ['name'],
22
+ [NodeType.EmotionalEvent]: ['emotion', 'intensity'],
23
+ [NodeType.ReasoningChain]: ['topic'],
24
+ [NodeType.ReasoningStep]: ['stepIndex', 'claim'],
25
+ };
26
+ export function validateNode(node) {
27
+ const errors = [];
28
+ if (!node.id)
29
+ errors.push('Node id is required');
30
+ if (!node.nodeType)
31
+ errors.push('Node nodeType is required');
32
+ if (!Object.values(NodeType).includes(node.nodeType)) {
33
+ errors.push(`Unknown nodeType: ${node.nodeType}`);
34
+ }
35
+ const required = REQUIRED_NODE_FIELDS[node.nodeType];
36
+ if (required) {
37
+ for (const field of required) {
38
+ if (node.data[field] === undefined || node.data[field] === null) {
39
+ errors.push(`${node.nodeType} node requires field: ${field}`);
40
+ }
41
+ }
42
+ }
43
+ return errors;
44
+ }
45
+ // ─── Edge validation ───────────────────────────────────────────────
46
+ /** Rules for which node types can appear as source/target for a given rel type. */
47
+ const EDGE_CONSTRAINTS = {
48
+ [RelType.HAS_CHUNK]: {
49
+ source: [NodeType.Note],
50
+ target: [NodeType.Chunk],
51
+ },
52
+ [RelType.DERIVED_FROM]: {
53
+ target: [NodeType.Chunk],
54
+ },
55
+ [RelType.MENTIONS]: {
56
+ source: [NodeType.Chunk],
57
+ target: [NodeType.Entity, NodeType.Concept, NodeType.Location],
58
+ },
59
+ [RelType.BELIEVES]: {
60
+ source: [NodeType.Agent],
61
+ target: [NodeType.Proposition],
62
+ },
63
+ [RelType.ENDORSES]: {
64
+ source: [NodeType.Agent],
65
+ target: [NodeType.Thought],
66
+ },
67
+ [RelType.ABOUT]: {
68
+ source: [NodeType.Proposition, NodeType.Thought],
69
+ target: [NodeType.Entity, NodeType.Concept, NodeType.Event],
70
+ },
71
+ [RelType.SUPPORTS]: {
72
+ source: [NodeType.Proposition, NodeType.Thought],
73
+ target: [NodeType.Proposition, NodeType.Thought],
74
+ },
75
+ [RelType.CONTRADICTS]: {
76
+ source: [NodeType.Proposition, NodeType.Thought],
77
+ target: [NodeType.Proposition, NodeType.Thought],
78
+ },
79
+ };
80
+ export function validateEdge(edge, sourceNode, targetNode) {
81
+ const errors = [];
82
+ if (!edge.id)
83
+ errors.push('Edge id is required');
84
+ if (!edge.sourceId)
85
+ errors.push('Edge sourceId is required');
86
+ if (!edge.targetId)
87
+ errors.push('Edge targetId is required');
88
+ if (!edge.relType)
89
+ errors.push('Edge relType is required');
90
+ if (!Object.values(RelType).includes(edge.relType)) {
91
+ errors.push(`Unknown relType: ${edge.relType}`);
92
+ }
93
+ // Check type constraints if nodes are provided
94
+ const constraints = EDGE_CONSTRAINTS[edge.relType];
95
+ if (constraints) {
96
+ if (constraints.source && sourceNode && !constraints.source.includes(sourceNode.nodeType)) {
97
+ errors.push(`${edge.relType} edge source must be one of [${constraints.source.join(', ')}], got ${sourceNode.nodeType}`);
98
+ }
99
+ if (constraints.target && targetNode && !constraints.target.includes(targetNode.nodeType)) {
100
+ errors.push(`${edge.relType} edge target must be one of [${constraints.target.join(', ')}], got ${targetNode.nodeType}`);
101
+ }
102
+ }
103
+ // DERIVED_FROM must have provenance
104
+ if (edge.relType === RelType.DERIVED_FROM) {
105
+ const prov = edge.data?.provenance;
106
+ if (!prov) {
107
+ errors.push('DERIVED_FROM edge requires provenance data');
108
+ }
109
+ else {
110
+ if (!prov.notePath)
111
+ errors.push('Provenance requires notePath');
112
+ if (!prov.chunkId)
113
+ errors.push('Provenance requires chunkId');
114
+ if (typeof prov.startOffset !== 'number')
115
+ errors.push('Provenance requires startOffset');
116
+ if (typeof prov.endOffset !== 'number')
117
+ errors.push('Provenance requires endOffset');
118
+ }
119
+ }
120
+ return errors;
121
+ }
122
+ // ─── Provenance validation ─────────────────────────────────────────
123
+ export function validateProvenance(prov) {
124
+ const errors = [];
125
+ if (!prov.notePath)
126
+ errors.push('notePath is required');
127
+ if (!prov.chunkId)
128
+ errors.push('chunkId is required');
129
+ if (typeof prov.startOffset !== 'number' || prov.startOffset < 0) {
130
+ errors.push('startOffset must be a non-negative number');
131
+ }
132
+ if (typeof prov.endOffset !== 'number' || prov.endOffset < 0) {
133
+ errors.push('endOffset must be a non-negative number');
134
+ }
135
+ if (prov.endOffset <= prov.startOffset) {
136
+ errors.push('endOffset must be greater than startOffset');
137
+ }
138
+ return errors;
139
+ }
140
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/schema/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAmD,MAAM,YAAY,CAAC;AAEhG,sEAAsE;AAEtE,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEzC,MAAM,UAAU,oBAAoB,CAClC,IAA6B,EAC7B,YAAoB,4BAA4B;IAEhD,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,6BAA6B;AAC5C,CAAC;AAED,sEAAsE;AAEtE,MAAM,oBAAoB,GAA+B;IACvD,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC;IACjD,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,CAAC;IACjF,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;IACzC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC;IAC5B,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC;IAC7C,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;IAC1B,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;IACtD,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC3C,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;IACvC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC;IAC5B,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;IACnD,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC;IACpC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC;CACjD,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,yBAAyB,KAAK,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,sEAAsE;AAEtE,mFAAmF;AACnF,MAAM,gBAAgB,GAElB;IACF,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QACnB,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;QACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KACzB;IACD,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;QACtB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KACzB;IACD,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxB,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC;KAC/D;IACD,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxB,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;KAC/B;IACD,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxB,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;KAC3B;IACD,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACf,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;QAChD,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;KAC5D;IACD,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;QAChD,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;KACjD;IACD,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QACrB,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;QAChD,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;KACjD;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,IAAe,EACf,UAAsB,EACtB,UAAsB;IAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,+CAA+C;IAC/C,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,WAAW,CAAC,MAAM,IAAI,UAAU,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1F,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,CAAC,OAAO,gCAAgC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,QAAQ,EAAE,CAC5G,CAAC;QACJ,CAAC;QACD,IAAI,WAAW,CAAC,MAAM,IAAI,UAAU,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1F,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,CAAC,OAAO,gCAAgC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,QAAQ,EAAE,CAC5G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAoC,CAAC;QAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAChE,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC9D,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACzF,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,sEAAsE;AAEtE,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACtD,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { StorageAdapter } from './storage-interface.js';
2
+ export type ImportStrategy = 'replace' | 'merge' | 'skip_existing';
3
+ export interface ImportResult {
4
+ nodesImported: number;
5
+ edgesImported: number;
6
+ embeddingsImported: number;
7
+ nodesSkipped: number;
8
+ edgesSkipped: number;
9
+ errors: string[];
10
+ }
11
+ export declare class GraphExporter {
12
+ private storage;
13
+ constructor(storage: StorageAdapter);
14
+ /**
15
+ * Export all graph data as JSONL string.
16
+ * Line 1: header, then nodes, edges, embeddings.
17
+ */
18
+ export(): Promise<string>;
19
+ }
20
+ export declare class GraphImporter {
21
+ private storage;
22
+ constructor(storage: StorageAdapter);
23
+ /**
24
+ * Import graph data from a JSONL string.
25
+ */
26
+ import(jsonlData: string, strategy?: ImportStrategy): Promise<ImportResult>;
27
+ }
28
+ //# sourceMappingURL=export-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-import.d.ts","sourceRoot":"","sources":["../../src/storage/export-import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAiB7D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,eAAe,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAwBD,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CA+DhC;AAID,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAwB,GAAG,OAAO,CAAC,YAAY,CAAC;CAyG3F"}
@@ -0,0 +1,189 @@
1
+ // ─── Helpers ──────────────────────────────────────────────────────
2
+ function float32ToBase64(arr) {
3
+ const bytes = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
4
+ let binary = '';
5
+ for (let i = 0; i < bytes.length; i++) {
6
+ binary += String.fromCharCode(bytes[i]);
7
+ }
8
+ return btoa(binary);
9
+ }
10
+ function base64ToFloat32(base64, dimensions) {
11
+ const binary = atob(base64);
12
+ const bytes = new Uint8Array(binary.length);
13
+ for (let i = 0; i < binary.length; i++) {
14
+ bytes[i] = binary.charCodeAt(i);
15
+ }
16
+ return new Float32Array(bytes.buffer, bytes.byteOffset, dimensions);
17
+ }
18
+ // ─── GraphExporter ────────────────────────────────────────────────
19
+ export class GraphExporter {
20
+ constructor(storage) {
21
+ this.storage = storage;
22
+ }
23
+ /**
24
+ * Export all graph data as JSONL string.
25
+ * Line 1: header, then nodes, edges, embeddings.
26
+ */
27
+ async export() {
28
+ const stats = await this.storage.getStats();
29
+ const lines = [];
30
+ // Header
31
+ let schemaVersion = 0;
32
+ if (typeof this.storage.getSchemaVersion === 'function') {
33
+ schemaVersion = this.storage.getSchemaVersion();
34
+ }
35
+ // Collect embedding model ID from first embedding if available
36
+ let embeddingModelId = null;
37
+ const header = {
38
+ format: 'mindgraph-jsonl',
39
+ schemaVersion,
40
+ embeddingModelId: null, // updated below
41
+ exportedAt: new Date().toISOString(),
42
+ nodeCount: stats.nodeCount,
43
+ edgeCount: stats.edgeCount,
44
+ embeddingCount: stats.embeddingCount,
45
+ };
46
+ // Nodes
47
+ const nodes = await this.storage.queryNodes({});
48
+ const nodeLines = [];
49
+ for (const node of nodes) {
50
+ nodeLines.push(JSON.stringify({ type: 'node', data: node }));
51
+ }
52
+ // Edges
53
+ const edges = await this.storage.queryEdges({});
54
+ const edgeLines = [];
55
+ for (const edge of edges) {
56
+ edgeLines.push(JSON.stringify({ type: 'edge', data: edge }));
57
+ }
58
+ // Embeddings — query all chunks and get their embeddings
59
+ const embeddingLines = [];
60
+ const chunks = await this.storage.queryNodes({ nodeType: 'CHUNK' });
61
+ for (const chunk of chunks) {
62
+ const embedding = await this.storage.getEmbedding(chunk.id);
63
+ if (embedding) {
64
+ if (!embeddingModelId)
65
+ embeddingModelId = embedding.modelId;
66
+ embeddingLines.push(JSON.stringify({
67
+ type: 'embedding',
68
+ data: {
69
+ chunkId: embedding.chunkId,
70
+ vector: float32ToBase64(embedding.vector),
71
+ modelId: embedding.modelId,
72
+ dimensions: embedding.dimensions,
73
+ createdAt: embedding.createdAt,
74
+ },
75
+ }));
76
+ }
77
+ }
78
+ header.embeddingModelId = embeddingModelId;
79
+ lines.push(JSON.stringify({ type: 'header', data: header }));
80
+ lines.push(...nodeLines, ...edgeLines, ...embeddingLines);
81
+ return lines.join('\n') + '\n';
82
+ }
83
+ }
84
+ // ─── GraphImporter ────────────────────────────────────────────────
85
+ export class GraphImporter {
86
+ constructor(storage) {
87
+ this.storage = storage;
88
+ }
89
+ /**
90
+ * Import graph data from a JSONL string.
91
+ */
92
+ async import(jsonlData, strategy = 'merge') {
93
+ const result = {
94
+ nodesImported: 0,
95
+ edgesImported: 0,
96
+ embeddingsImported: 0,
97
+ nodesSkipped: 0,
98
+ edgesSkipped: 0,
99
+ errors: [],
100
+ };
101
+ const lines = jsonlData.trim().split('\n').filter(Boolean);
102
+ if (lines.length === 0) {
103
+ result.errors.push('Empty import data');
104
+ return result;
105
+ }
106
+ // Parse header
107
+ let header = null;
108
+ try {
109
+ const firstLine = JSON.parse(lines[0]);
110
+ if (firstLine.type === 'header') {
111
+ header = firstLine.data;
112
+ if (header.format !== 'mindgraph-jsonl') {
113
+ result.errors.push(`Unknown format: ${header.format}`);
114
+ return result;
115
+ }
116
+ }
117
+ }
118
+ catch (e) {
119
+ result.errors.push(`Failed to parse header: ${e}`);
120
+ return result;
121
+ }
122
+ // If strategy is replace, wipe existing data first
123
+ if (strategy === 'replace') {
124
+ const allNodes = await this.storage.queryNodes({});
125
+ for (const node of allNodes) {
126
+ await this.storage.deleteEdgesByNode(node.id);
127
+ await this.storage.deleteNode(node.id);
128
+ }
129
+ }
130
+ // Process data lines (skip header)
131
+ const startIdx = header ? 1 : 0;
132
+ for (let i = startIdx; i < lines.length; i++) {
133
+ try {
134
+ const line = JSON.parse(lines[i]);
135
+ switch (line.type) {
136
+ case 'node': {
137
+ const node = line.data;
138
+ if (strategy === 'skip_existing') {
139
+ const existing = await this.storage.getNode(node.id);
140
+ if (existing) {
141
+ result.nodesSkipped++;
142
+ break;
143
+ }
144
+ }
145
+ await this.storage.upsertNode(node);
146
+ result.nodesImported++;
147
+ break;
148
+ }
149
+ case 'edge': {
150
+ const edge = line.data;
151
+ if (strategy === 'skip_existing') {
152
+ const existing = await this.storage.getEdge(edge.id);
153
+ if (existing) {
154
+ result.edgesSkipped++;
155
+ break;
156
+ }
157
+ }
158
+ await this.storage.upsertEdge(edge);
159
+ result.edgesImported++;
160
+ break;
161
+ }
162
+ case 'embedding': {
163
+ const emb = line.data;
164
+ const vector = base64ToFloat32(emb.vector, emb.dimensions);
165
+ await this.storage.upsertEmbedding({
166
+ chunkId: emb.chunkId,
167
+ vector,
168
+ modelId: emb.modelId,
169
+ dimensions: emb.dimensions,
170
+ createdAt: emb.createdAt,
171
+ });
172
+ result.embeddingsImported++;
173
+ break;
174
+ }
175
+ case 'header':
176
+ // Already processed
177
+ break;
178
+ default:
179
+ result.errors.push(`Unknown line type at line ${i + 1}: ${line.type}`);
180
+ }
181
+ }
182
+ catch (e) {
183
+ result.errors.push(`Error at line ${i + 1}: ${e}`);
184
+ }
185
+ }
186
+ return result;
187
+ }
188
+ }
189
+ //# sourceMappingURL=export-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-import.js","sourceRoot":"","sources":["../../src/storage/export-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { StorageAdapter, NodeQuery, EdgeQuery, TraversalOptions, SimilarityQuery, FullTextQuery } from '../storage-interface.js';
2
+ import type { GraphNode, GraphEdge, EmbeddingRecord, SearchResult, NodeType } from '../../schema/types.js';
3
+ export declare class MemoryAdapter implements StorageAdapter {
4
+ private nodes;
5
+ private edges;
6
+ private embeddings;
7
+ private ftsEntries;
8
+ initialize(): Promise<void>;
9
+ close(): Promise<void>;
10
+ upsertNode(node: GraphNode): Promise<void>;
11
+ getNode(id: string): Promise<GraphNode | null>;
12
+ queryNodes(query: NodeQuery): Promise<GraphNode[]>;
13
+ deleteNode(id: string): Promise<void>;
14
+ deleteNodesByData(nodeType: NodeType, field: string, value: unknown): Promise<number>;
15
+ upsertEdge(edge: GraphEdge): Promise<void>;
16
+ getEdge(id: string): Promise<GraphEdge | null>;
17
+ queryEdges(query: EdgeQuery): Promise<GraphEdge[]>;
18
+ deleteEdge(id: string): Promise<void>;
19
+ deleteEdgesByNode(nodeId: string): Promise<number>;
20
+ traverse(options: TraversalOptions): Promise<GraphNode[]>;
21
+ upsertEmbedding(record: EmbeddingRecord): Promise<void>;
22
+ getEmbedding(chunkId: string): Promise<EmbeddingRecord | null>;
23
+ similaritySearch(query: SimilarityQuery): Promise<SearchResult[]>;
24
+ deleteEmbedding(chunkId: string): Promise<void>;
25
+ fullTextSearch(query: FullTextQuery): Promise<SearchResult[]>;
26
+ upsertFTSEntry(chunkId: string, text: string): Promise<void>;
27
+ deleteFTSEntry(chunkId: string): Promise<void>;
28
+ transaction<T>(fn: () => Promise<T>): Promise<T>;
29
+ getStats(): Promise<{
30
+ nodeCount: number;
31
+ edgeCount: number;
32
+ embeddingCount: number;
33
+ nodeCountByType: Record<string, number>;
34
+ }>;
35
+ }
36
+ //# sourceMappingURL=memory-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-adapter.d.ts","sourceRoot":"","sources":["../../../src/storage/memory/memory-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,eAAe,EACf,YAAY,EACZ,QAAQ,EACT,MAAM,uBAAuB,CAAC;AAe/B,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,UAAU,CAAwD;IAEpE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAI9C,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA2BlD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAarF,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAI9C,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBlD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAalD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA4CzD,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAI9D,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAiCjE,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA2B7D,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAMhD,QAAQ,IAAI,OAAO,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,CAAC;CAaH"}
@@ -0,0 +1,231 @@
1
+ function cosineSimilarity(a, b) {
2
+ let dotProduct = 0;
3
+ let normA = 0;
4
+ let normB = 0;
5
+ for (let i = 0; i < a.length; i++) {
6
+ dotProduct += a[i] * b[i];
7
+ normA += a[i] * a[i];
8
+ normB += b[i] * b[i];
9
+ }
10
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
11
+ return denom === 0 ? 0 : dotProduct / denom;
12
+ }
13
+ export class MemoryAdapter {
14
+ constructor() {
15
+ this.nodes = new Map();
16
+ this.edges = new Map();
17
+ this.embeddings = new Map();
18
+ this.ftsEntries = new Map();
19
+ }
20
+ async initialize() {
21
+ // no-op
22
+ }
23
+ async close() {
24
+ this.nodes.clear();
25
+ this.edges.clear();
26
+ this.embeddings.clear();
27
+ this.ftsEntries.clear();
28
+ }
29
+ // ─── Node CRUD ───────────────────────────────────────────────────
30
+ async upsertNode(node) {
31
+ this.nodes.set(node.id, { ...node });
32
+ }
33
+ async getNode(id) {
34
+ return this.nodes.get(id) ?? null;
35
+ }
36
+ async queryNodes(query) {
37
+ let results = Array.from(this.nodes.values());
38
+ if (query.nodeType) {
39
+ results = results.filter((n) => n.nodeType === query.nodeType);
40
+ }
41
+ if (query.where) {
42
+ results = results.filter((n) => {
43
+ for (const [key, value] of Object.entries(query.where)) {
44
+ if (n.data[key] !== value)
45
+ return false;
46
+ }
47
+ return true;
48
+ });
49
+ }
50
+ if (query.offset) {
51
+ results = results.slice(query.offset);
52
+ }
53
+ if (query.limit) {
54
+ results = results.slice(0, query.limit);
55
+ }
56
+ return results;
57
+ }
58
+ async deleteNode(id) {
59
+ this.nodes.delete(id);
60
+ }
61
+ async deleteNodesByData(nodeType, field, value) {
62
+ let count = 0;
63
+ for (const [id, node] of this.nodes) {
64
+ if (node.nodeType === nodeType && node.data[field] === value) {
65
+ this.nodes.delete(id);
66
+ count++;
67
+ }
68
+ }
69
+ return count;
70
+ }
71
+ // ─── Edge CRUD ───────────────────────────────────────────────────
72
+ async upsertEdge(edge) {
73
+ this.edges.set(edge.id, { ...edge });
74
+ }
75
+ async getEdge(id) {
76
+ return this.edges.get(id) ?? null;
77
+ }
78
+ async queryEdges(query) {
79
+ let results = Array.from(this.edges.values());
80
+ if (query.sourceId) {
81
+ results = results.filter((e) => e.sourceId === query.sourceId);
82
+ }
83
+ if (query.targetId) {
84
+ results = results.filter((e) => e.targetId === query.targetId);
85
+ }
86
+ if (query.relType) {
87
+ results = results.filter((e) => e.relType === query.relType);
88
+ }
89
+ if (query.limit) {
90
+ results = results.slice(0, query.limit);
91
+ }
92
+ return results;
93
+ }
94
+ async deleteEdge(id) {
95
+ this.edges.delete(id);
96
+ }
97
+ async deleteEdgesByNode(nodeId) {
98
+ let count = 0;
99
+ for (const [id, edge] of this.edges) {
100
+ if (edge.sourceId === nodeId || edge.targetId === nodeId) {
101
+ this.edges.delete(id);
102
+ count++;
103
+ }
104
+ }
105
+ return count;
106
+ }
107
+ // ─── Graph traversal ────────────────────────────────────────────
108
+ async traverse(options) {
109
+ const visited = new Set();
110
+ const result = [];
111
+ const maxDepth = options.maxDepth ?? 3;
112
+ const direction = options.direction ?? 'outbound';
113
+ const queue = [
114
+ { nodeId: options.startNodeId, depth: 0 },
115
+ ];
116
+ while (queue.length > 0) {
117
+ const { nodeId, depth } = queue.shift();
118
+ if (visited.has(nodeId) || depth > maxDepth)
119
+ continue;
120
+ visited.add(nodeId);
121
+ const node = this.nodes.get(nodeId);
122
+ if (!node)
123
+ continue;
124
+ // Add to results if it passes the filter (but always continue traversal)
125
+ const passesFilter = !options.nodeTypeFilter || options.nodeTypeFilter.includes(node.nodeType);
126
+ if (nodeId !== options.startNodeId && passesFilter) {
127
+ result.push(node);
128
+ }
129
+ // Find connected edges
130
+ for (const edge of this.edges.values()) {
131
+ const relTypeMatch = !options.relTypes || options.relTypes.includes(edge.relType);
132
+ if (!relTypeMatch)
133
+ continue;
134
+ if ((direction === 'outbound' || direction === 'both') && edge.sourceId === nodeId) {
135
+ queue.push({ nodeId: edge.targetId, depth: depth + 1 });
136
+ }
137
+ if ((direction === 'inbound' || direction === 'both') && edge.targetId === nodeId) {
138
+ queue.push({ nodeId: edge.sourceId, depth: depth + 1 });
139
+ }
140
+ }
141
+ }
142
+ return result;
143
+ }
144
+ // ─── Embeddings ──────────────────────────────────────────────────
145
+ async upsertEmbedding(record) {
146
+ this.embeddings.set(record.chunkId, { ...record });
147
+ }
148
+ async getEmbedding(chunkId) {
149
+ return this.embeddings.get(chunkId) ?? null;
150
+ }
151
+ async similaritySearch(query) {
152
+ const results = [];
153
+ for (const record of this.embeddings.values()) {
154
+ if (query.modelId && record.modelId !== query.modelId)
155
+ continue;
156
+ const score = cosineSimilarity(query.vector, record.vector);
157
+ if (query.threshold && score < query.threshold)
158
+ continue;
159
+ results.push({ chunkId: record.chunkId, score });
160
+ }
161
+ results.sort((a, b) => b.score - a.score);
162
+ const topK = results.slice(0, query.topK);
163
+ // Enrich with node data
164
+ const searchResults = [];
165
+ for (const r of topK) {
166
+ const chunkNode = this.nodes.get(r.chunkId);
167
+ if (chunkNode) {
168
+ searchResults.push({
169
+ chunkId: r.chunkId,
170
+ nodeId: r.chunkId,
171
+ score: r.score,
172
+ text: chunkNode.data.text ?? '',
173
+ notePath: chunkNode.data.notePath ?? '',
174
+ });
175
+ }
176
+ }
177
+ return searchResults;
178
+ }
179
+ async deleteEmbedding(chunkId) {
180
+ this.embeddings.delete(chunkId);
181
+ }
182
+ // ─── Full-text search ────────────────────────────────────────────
183
+ async fullTextSearch(query) {
184
+ // Parse FTS5-style queries: strip quotes, handle OR operator
185
+ const rawTerms = query.query.toLowerCase().split(/\s+/);
186
+ const terms = rawTerms
187
+ .filter((t) => t !== 'or' && t !== 'and' && t !== 'not')
188
+ .map((t) => t.replace(/^"|"$/g, ''));
189
+ const results = [];
190
+ for (const entry of this.ftsEntries.values()) {
191
+ const textLower = entry.text.toLowerCase();
192
+ // OR semantics: match if any term is found
193
+ const matches = terms.some((term) => term.length > 0 && textLower.includes(term));
194
+ if (matches) {
195
+ const chunkNode = this.nodes.get(entry.chunkId);
196
+ results.push({
197
+ chunkId: entry.chunkId,
198
+ nodeId: entry.chunkId,
199
+ score: 1.0,
200
+ text: entry.text,
201
+ notePath: chunkNode ? chunkNode.data.notePath ?? '' : '',
202
+ });
203
+ }
204
+ }
205
+ return results.slice(0, query.limit ?? 20);
206
+ }
207
+ async upsertFTSEntry(chunkId, text) {
208
+ this.ftsEntries.set(chunkId, { chunkId, text });
209
+ }
210
+ async deleteFTSEntry(chunkId) {
211
+ this.ftsEntries.delete(chunkId);
212
+ }
213
+ // ─── Bulk operations ─────────────────────────────────────────────
214
+ async transaction(fn) {
215
+ return fn(); // no real transaction in memory
216
+ }
217
+ // ─── Stats ───────────────────────────────────────────────────────
218
+ async getStats() {
219
+ const nodeCountByType = {};
220
+ for (const node of this.nodes.values()) {
221
+ nodeCountByType[node.nodeType] = (nodeCountByType[node.nodeType] ?? 0) + 1;
222
+ }
223
+ return {
224
+ nodeCount: this.nodes.size,
225
+ edgeCount: this.edges.size,
226
+ embeddingCount: this.embeddings.size,
227
+ nodeCountByType,
228
+ };
229
+ }
230
+ }
231
+ //# sourceMappingURL=memory-adapter.js.map