@danielsimonjr/memoryjs 1.0.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 (295) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +266 -0
  3. package/dist/core/EntityManager.d.ts +268 -0
  4. package/dist/core/EntityManager.d.ts.map +1 -0
  5. package/dist/core/EntityManager.js +512 -0
  6. package/dist/core/EntityManager.js.map +1 -0
  7. package/dist/core/GraphEventEmitter.d.ts +202 -0
  8. package/dist/core/GraphEventEmitter.d.ts.map +1 -0
  9. package/dist/core/GraphEventEmitter.js +347 -0
  10. package/dist/core/GraphEventEmitter.js.map +1 -0
  11. package/dist/core/GraphStorage.d.ts +395 -0
  12. package/dist/core/GraphStorage.d.ts.map +1 -0
  13. package/dist/core/GraphStorage.js +786 -0
  14. package/dist/core/GraphStorage.js.map +1 -0
  15. package/dist/core/GraphTraversal.d.ts +141 -0
  16. package/dist/core/GraphTraversal.d.ts.map +1 -0
  17. package/dist/core/GraphTraversal.js +574 -0
  18. package/dist/core/GraphTraversal.js.map +1 -0
  19. package/dist/core/HierarchyManager.d.ts +111 -0
  20. package/dist/core/HierarchyManager.d.ts.map +1 -0
  21. package/dist/core/HierarchyManager.js +225 -0
  22. package/dist/core/HierarchyManager.js.map +1 -0
  23. package/dist/core/ManagerContext.d.ts +76 -0
  24. package/dist/core/ManagerContext.d.ts.map +1 -0
  25. package/dist/core/ManagerContext.js +129 -0
  26. package/dist/core/ManagerContext.js.map +1 -0
  27. package/dist/core/ObservationManager.d.ts +85 -0
  28. package/dist/core/ObservationManager.d.ts.map +1 -0
  29. package/dist/core/ObservationManager.js +124 -0
  30. package/dist/core/ObservationManager.js.map +1 -0
  31. package/dist/core/RelationManager.d.ts +131 -0
  32. package/dist/core/RelationManager.d.ts.map +1 -0
  33. package/dist/core/RelationManager.js +212 -0
  34. package/dist/core/RelationManager.js.map +1 -0
  35. package/dist/core/SQLiteStorage.d.ts +354 -0
  36. package/dist/core/SQLiteStorage.d.ts.map +1 -0
  37. package/dist/core/SQLiteStorage.js +919 -0
  38. package/dist/core/SQLiteStorage.js.map +1 -0
  39. package/dist/core/StorageFactory.d.ts +45 -0
  40. package/dist/core/StorageFactory.d.ts.map +1 -0
  41. package/dist/core/StorageFactory.js +65 -0
  42. package/dist/core/StorageFactory.js.map +1 -0
  43. package/dist/core/TransactionManager.d.ts +464 -0
  44. package/dist/core/TransactionManager.d.ts.map +1 -0
  45. package/dist/core/TransactionManager.js +869 -0
  46. package/dist/core/TransactionManager.js.map +1 -0
  47. package/dist/core/index.d.ts +17 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +20 -0
  50. package/dist/core/index.js.map +1 -0
  51. package/dist/features/AnalyticsManager.d.ts +44 -0
  52. package/dist/features/AnalyticsManager.d.ts.map +1 -0
  53. package/dist/features/AnalyticsManager.js +224 -0
  54. package/dist/features/AnalyticsManager.js.map +1 -0
  55. package/dist/features/ArchiveManager.d.ts +133 -0
  56. package/dist/features/ArchiveManager.d.ts.map +1 -0
  57. package/dist/features/ArchiveManager.js +282 -0
  58. package/dist/features/ArchiveManager.js.map +1 -0
  59. package/dist/features/CompressionManager.d.ts +119 -0
  60. package/dist/features/CompressionManager.d.ts.map +1 -0
  61. package/dist/features/CompressionManager.js +470 -0
  62. package/dist/features/CompressionManager.js.map +1 -0
  63. package/dist/features/IOManager.d.ts +225 -0
  64. package/dist/features/IOManager.d.ts.map +1 -0
  65. package/dist/features/IOManager.js +1093 -0
  66. package/dist/features/IOManager.js.map +1 -0
  67. package/dist/features/KeywordExtractor.d.ts +61 -0
  68. package/dist/features/KeywordExtractor.d.ts.map +1 -0
  69. package/dist/features/KeywordExtractor.js +127 -0
  70. package/dist/features/KeywordExtractor.js.map +1 -0
  71. package/dist/features/ObservationNormalizer.d.ts +90 -0
  72. package/dist/features/ObservationNormalizer.d.ts.map +1 -0
  73. package/dist/features/ObservationNormalizer.js +194 -0
  74. package/dist/features/ObservationNormalizer.js.map +1 -0
  75. package/dist/features/StreamingExporter.d.ts +128 -0
  76. package/dist/features/StreamingExporter.d.ts.map +1 -0
  77. package/dist/features/StreamingExporter.js +212 -0
  78. package/dist/features/StreamingExporter.js.map +1 -0
  79. package/dist/features/TagManager.d.ts +147 -0
  80. package/dist/features/TagManager.d.ts.map +1 -0
  81. package/dist/features/TagManager.js +211 -0
  82. package/dist/features/TagManager.js.map +1 -0
  83. package/dist/features/index.d.ts +14 -0
  84. package/dist/features/index.d.ts.map +1 -0
  85. package/dist/features/index.js +15 -0
  86. package/dist/features/index.js.map +1 -0
  87. package/dist/index.d.ts +15 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +20 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/search/BM25Search.d.ts +148 -0
  92. package/dist/search/BM25Search.d.ts.map +1 -0
  93. package/dist/search/BM25Search.js +340 -0
  94. package/dist/search/BM25Search.js.map +1 -0
  95. package/dist/search/BasicSearch.d.ts +51 -0
  96. package/dist/search/BasicSearch.d.ts.map +1 -0
  97. package/dist/search/BasicSearch.js +138 -0
  98. package/dist/search/BasicSearch.js.map +1 -0
  99. package/dist/search/BooleanSearch.d.ts +98 -0
  100. package/dist/search/BooleanSearch.d.ts.map +1 -0
  101. package/dist/search/BooleanSearch.js +431 -0
  102. package/dist/search/BooleanSearch.js.map +1 -0
  103. package/dist/search/EarlyTerminationManager.d.ts +140 -0
  104. package/dist/search/EarlyTerminationManager.d.ts.map +1 -0
  105. package/dist/search/EarlyTerminationManager.js +280 -0
  106. package/dist/search/EarlyTerminationManager.js.map +1 -0
  107. package/dist/search/EmbeddingCache.d.ts +175 -0
  108. package/dist/search/EmbeddingCache.d.ts.map +1 -0
  109. package/dist/search/EmbeddingCache.js +247 -0
  110. package/dist/search/EmbeddingCache.js.map +1 -0
  111. package/dist/search/EmbeddingService.d.ts +277 -0
  112. package/dist/search/EmbeddingService.d.ts.map +1 -0
  113. package/dist/search/EmbeddingService.js +531 -0
  114. package/dist/search/EmbeddingService.js.map +1 -0
  115. package/dist/search/FuzzySearch.d.ts +118 -0
  116. package/dist/search/FuzzySearch.d.ts.map +1 -0
  117. package/dist/search/FuzzySearch.js +313 -0
  118. package/dist/search/FuzzySearch.js.map +1 -0
  119. package/dist/search/HybridScorer.d.ts +181 -0
  120. package/dist/search/HybridScorer.d.ts.map +1 -0
  121. package/dist/search/HybridScorer.js +258 -0
  122. package/dist/search/HybridScorer.js.map +1 -0
  123. package/dist/search/HybridSearchManager.d.ts +80 -0
  124. package/dist/search/HybridSearchManager.d.ts.map +1 -0
  125. package/dist/search/HybridSearchManager.js +188 -0
  126. package/dist/search/HybridSearchManager.js.map +1 -0
  127. package/dist/search/IncrementalIndexer.d.ts +201 -0
  128. package/dist/search/IncrementalIndexer.d.ts.map +1 -0
  129. package/dist/search/IncrementalIndexer.js +343 -0
  130. package/dist/search/IncrementalIndexer.js.map +1 -0
  131. package/dist/search/OptimizedInvertedIndex.d.ts +163 -0
  132. package/dist/search/OptimizedInvertedIndex.d.ts.map +1 -0
  133. package/dist/search/OptimizedInvertedIndex.js +359 -0
  134. package/dist/search/OptimizedInvertedIndex.js.map +1 -0
  135. package/dist/search/ParallelSearchExecutor.d.ts +172 -0
  136. package/dist/search/ParallelSearchExecutor.d.ts.map +1 -0
  137. package/dist/search/ParallelSearchExecutor.js +310 -0
  138. package/dist/search/ParallelSearchExecutor.js.map +1 -0
  139. package/dist/search/QuantizedVectorStore.d.ts +171 -0
  140. package/dist/search/QuantizedVectorStore.d.ts.map +1 -0
  141. package/dist/search/QuantizedVectorStore.js +308 -0
  142. package/dist/search/QuantizedVectorStore.js.map +1 -0
  143. package/dist/search/QueryAnalyzer.d.ts +76 -0
  144. package/dist/search/QueryAnalyzer.d.ts.map +1 -0
  145. package/dist/search/QueryAnalyzer.js +228 -0
  146. package/dist/search/QueryAnalyzer.js.map +1 -0
  147. package/dist/search/QueryCostEstimator.d.ts +244 -0
  148. package/dist/search/QueryCostEstimator.d.ts.map +1 -0
  149. package/dist/search/QueryCostEstimator.js +653 -0
  150. package/dist/search/QueryCostEstimator.js.map +1 -0
  151. package/dist/search/QueryPlanCache.d.ts +220 -0
  152. package/dist/search/QueryPlanCache.d.ts.map +1 -0
  153. package/dist/search/QueryPlanCache.js +380 -0
  154. package/dist/search/QueryPlanCache.js.map +1 -0
  155. package/dist/search/QueryPlanner.d.ts +58 -0
  156. package/dist/search/QueryPlanner.d.ts.map +1 -0
  157. package/dist/search/QueryPlanner.js +138 -0
  158. package/dist/search/QueryPlanner.js.map +1 -0
  159. package/dist/search/RankedSearch.d.ts +71 -0
  160. package/dist/search/RankedSearch.d.ts.map +1 -0
  161. package/dist/search/RankedSearch.js +239 -0
  162. package/dist/search/RankedSearch.js.map +1 -0
  163. package/dist/search/ReflectionManager.d.ts +120 -0
  164. package/dist/search/ReflectionManager.d.ts.map +1 -0
  165. package/dist/search/ReflectionManager.js +232 -0
  166. package/dist/search/ReflectionManager.js.map +1 -0
  167. package/dist/search/SavedSearchManager.d.ts +79 -0
  168. package/dist/search/SavedSearchManager.d.ts.map +1 -0
  169. package/dist/search/SavedSearchManager.js +147 -0
  170. package/dist/search/SavedSearchManager.js.map +1 -0
  171. package/dist/search/SearchFilterChain.d.ts +120 -0
  172. package/dist/search/SearchFilterChain.d.ts.map +1 -0
  173. package/dist/search/SearchFilterChain.js +186 -0
  174. package/dist/search/SearchFilterChain.js.map +1 -0
  175. package/dist/search/SearchManager.d.ts +326 -0
  176. package/dist/search/SearchManager.d.ts.map +1 -0
  177. package/dist/search/SearchManager.js +454 -0
  178. package/dist/search/SearchManager.js.map +1 -0
  179. package/dist/search/SearchSuggestions.d.ts +27 -0
  180. package/dist/search/SearchSuggestions.d.ts.map +1 -0
  181. package/dist/search/SearchSuggestions.js +58 -0
  182. package/dist/search/SearchSuggestions.js.map +1 -0
  183. package/dist/search/SemanticSearch.d.ts +149 -0
  184. package/dist/search/SemanticSearch.d.ts.map +1 -0
  185. package/dist/search/SemanticSearch.js +324 -0
  186. package/dist/search/SemanticSearch.js.map +1 -0
  187. package/dist/search/SymbolicSearch.d.ts +61 -0
  188. package/dist/search/SymbolicSearch.d.ts.map +1 -0
  189. package/dist/search/SymbolicSearch.js +164 -0
  190. package/dist/search/SymbolicSearch.js.map +1 -0
  191. package/dist/search/TFIDFEventSync.d.ts +85 -0
  192. package/dist/search/TFIDFEventSync.d.ts.map +1 -0
  193. package/dist/search/TFIDFEventSync.js +134 -0
  194. package/dist/search/TFIDFEventSync.js.map +1 -0
  195. package/dist/search/TFIDFIndexManager.d.ts +151 -0
  196. package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
  197. package/dist/search/TFIDFIndexManager.js +433 -0
  198. package/dist/search/TFIDFIndexManager.js.map +1 -0
  199. package/dist/search/VectorStore.d.ts +235 -0
  200. package/dist/search/VectorStore.d.ts.map +1 -0
  201. package/dist/search/VectorStore.js +312 -0
  202. package/dist/search/VectorStore.js.map +1 -0
  203. package/dist/search/index.d.ts +35 -0
  204. package/dist/search/index.d.ts.map +1 -0
  205. package/dist/search/index.js +53 -0
  206. package/dist/search/index.js.map +1 -0
  207. package/dist/types/index.d.ts +13 -0
  208. package/dist/types/index.d.ts.map +1 -0
  209. package/dist/types/index.js +13 -0
  210. package/dist/types/index.js.map +1 -0
  211. package/dist/types/types.d.ts +1811 -0
  212. package/dist/types/types.d.ts.map +1 -0
  213. package/dist/types/types.js +10 -0
  214. package/dist/types/types.js.map +1 -0
  215. package/dist/utils/BatchProcessor.d.ts +271 -0
  216. package/dist/utils/BatchProcessor.d.ts.map +1 -0
  217. package/dist/utils/BatchProcessor.js +377 -0
  218. package/dist/utils/BatchProcessor.js.map +1 -0
  219. package/dist/utils/MemoryMonitor.d.ts +176 -0
  220. package/dist/utils/MemoryMonitor.d.ts.map +1 -0
  221. package/dist/utils/MemoryMonitor.js +306 -0
  222. package/dist/utils/MemoryMonitor.js.map +1 -0
  223. package/dist/utils/WorkerPoolManager.d.ts +233 -0
  224. package/dist/utils/WorkerPoolManager.d.ts.map +1 -0
  225. package/dist/utils/WorkerPoolManager.js +421 -0
  226. package/dist/utils/WorkerPoolManager.js.map +1 -0
  227. package/dist/utils/compressedCache.d.ts +221 -0
  228. package/dist/utils/compressedCache.d.ts.map +1 -0
  229. package/dist/utils/compressedCache.js +349 -0
  230. package/dist/utils/compressedCache.js.map +1 -0
  231. package/dist/utils/compressionUtil.d.ts +214 -0
  232. package/dist/utils/compressionUtil.d.ts.map +1 -0
  233. package/dist/utils/compressionUtil.js +248 -0
  234. package/dist/utils/compressionUtil.js.map +1 -0
  235. package/dist/utils/constants.d.ts +245 -0
  236. package/dist/utils/constants.d.ts.map +1 -0
  237. package/dist/utils/constants.js +253 -0
  238. package/dist/utils/constants.js.map +1 -0
  239. package/dist/utils/entityUtils.d.ts +379 -0
  240. package/dist/utils/entityUtils.d.ts.map +1 -0
  241. package/dist/utils/entityUtils.js +649 -0
  242. package/dist/utils/entityUtils.js.map +1 -0
  243. package/dist/utils/errors.d.ts +95 -0
  244. package/dist/utils/errors.d.ts.map +1 -0
  245. package/dist/utils/errors.js +146 -0
  246. package/dist/utils/errors.js.map +1 -0
  247. package/dist/utils/formatters.d.ts +145 -0
  248. package/dist/utils/formatters.d.ts.map +1 -0
  249. package/dist/utils/formatters.js +133 -0
  250. package/dist/utils/formatters.js.map +1 -0
  251. package/dist/utils/index.d.ts +26 -0
  252. package/dist/utils/index.d.ts.map +1 -0
  253. package/dist/utils/index.js +88 -0
  254. package/dist/utils/index.js.map +1 -0
  255. package/dist/utils/indexes.d.ts +270 -0
  256. package/dist/utils/indexes.d.ts.map +1 -0
  257. package/dist/utils/indexes.js +527 -0
  258. package/dist/utils/indexes.js.map +1 -0
  259. package/dist/utils/logger.d.ts +31 -0
  260. package/dist/utils/logger.d.ts.map +1 -0
  261. package/dist/utils/logger.js +41 -0
  262. package/dist/utils/logger.js.map +1 -0
  263. package/dist/utils/operationUtils.d.ts +124 -0
  264. package/dist/utils/operationUtils.d.ts.map +1 -0
  265. package/dist/utils/operationUtils.js +176 -0
  266. package/dist/utils/operationUtils.js.map +1 -0
  267. package/dist/utils/parallelUtils.d.ts +76 -0
  268. package/dist/utils/parallelUtils.d.ts.map +1 -0
  269. package/dist/utils/parallelUtils.js +192 -0
  270. package/dist/utils/parallelUtils.js.map +1 -0
  271. package/dist/utils/schemas.d.ts +556 -0
  272. package/dist/utils/schemas.d.ts.map +1 -0
  273. package/dist/utils/schemas.js +485 -0
  274. package/dist/utils/schemas.js.map +1 -0
  275. package/dist/utils/searchAlgorithms.d.ts +99 -0
  276. package/dist/utils/searchAlgorithms.d.ts.map +1 -0
  277. package/dist/utils/searchAlgorithms.js +168 -0
  278. package/dist/utils/searchAlgorithms.js.map +1 -0
  279. package/dist/utils/searchCache.d.ts +108 -0
  280. package/dist/utils/searchCache.d.ts.map +1 -0
  281. package/dist/utils/searchCache.js +210 -0
  282. package/dist/utils/searchCache.js.map +1 -0
  283. package/dist/utils/taskScheduler.d.ts +294 -0
  284. package/dist/utils/taskScheduler.d.ts.map +1 -0
  285. package/dist/utils/taskScheduler.js +487 -0
  286. package/dist/utils/taskScheduler.js.map +1 -0
  287. package/dist/workers/index.d.ts +12 -0
  288. package/dist/workers/index.d.ts.map +1 -0
  289. package/dist/workers/index.js +10 -0
  290. package/dist/workers/index.js.map +1 -0
  291. package/dist/workers/levenshteinWorker.d.ts +60 -0
  292. package/dist/workers/levenshteinWorker.d.ts.map +1 -0
  293. package/dist/workers/levenshteinWorker.js +99 -0
  294. package/dist/workers/levenshteinWorker.js.map +1 -0
  295. package/package.json +69 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Observation Manager
3
+ *
4
+ * Handles observation CRUD operations for entities.
5
+ * Extracted from EntityManager (Phase 4: Consolidate God Objects).
6
+ *
7
+ * @module core/ObservationManager
8
+ */
9
+ import { EntityNotFoundError } from '../utils/errors.js';
10
+ /**
11
+ * Manages observation operations for entities in the knowledge graph.
12
+ */
13
+ export class ObservationManager {
14
+ storage;
15
+ constructor(storage) {
16
+ this.storage = storage;
17
+ }
18
+ /**
19
+ * Add observations to multiple entities in a single batch operation.
20
+ *
21
+ * This method performs the following operations:
22
+ * - Adds new observations to specified entities
23
+ * - Filters out duplicate observations (already present)
24
+ * - Updates lastModified timestamp only if new observations were added
25
+ * - ATOMIC: All updates are saved in a single operation
26
+ *
27
+ * @param observations - Array of entity names and observations to add
28
+ * @returns Promise resolving to array of results showing which observations were added
29
+ * @throws {EntityNotFoundError} If any entity is not found
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const manager = new ObservationManager(storage);
34
+ *
35
+ * // Add observations to multiple entities
36
+ * const results = await manager.addObservations([
37
+ * { entityName: 'Alice', contents: ['Completed project X', 'Started project Y'] },
38
+ * { entityName: 'Bob', contents: ['Joined team meeting'] }
39
+ * ]);
40
+ *
41
+ * // Check what was added (duplicates are filtered out)
42
+ * results.forEach(r => {
43
+ * console.log(`${r.entityName}: added ${r.addedObservations.length} new observations`);
44
+ * });
45
+ * ```
46
+ */
47
+ async addObservations(observations) {
48
+ // Get mutable graph for atomic update
49
+ const graph = await this.storage.getGraphForMutation();
50
+ const timestamp = new Date().toISOString();
51
+ const results = [];
52
+ let hasChanges = false;
53
+ for (const o of observations) {
54
+ const entity = graph.entities.find(e => e.name === o.entityName);
55
+ if (!entity) {
56
+ throw new EntityNotFoundError(o.entityName);
57
+ }
58
+ const newObservations = o.contents.filter(content => !entity.observations.includes(content));
59
+ if (newObservations.length > 0) {
60
+ // Add new observations directly to the entity
61
+ entity.observations.push(...newObservations);
62
+ entity.lastModified = timestamp;
63
+ hasChanges = true;
64
+ }
65
+ results.push({ entityName: o.entityName, addedObservations: newObservations });
66
+ }
67
+ // Save all changes in a single atomic operation
68
+ if (hasChanges) {
69
+ await this.storage.saveGraph(graph);
70
+ }
71
+ return results;
72
+ }
73
+ /**
74
+ * Delete observations from multiple entities in a single batch operation.
75
+ *
76
+ * This method performs the following operations:
77
+ * - Removes specified observations from entities
78
+ * - Updates lastModified timestamp only if observations were deleted
79
+ * - Silently ignores entities that don't exist (no error thrown)
80
+ * - ATOMIC: All deletions are saved in a single operation
81
+ *
82
+ * @param deletions - Array of entity names and observations to delete
83
+ * @returns Promise that resolves when deletion is complete
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const manager = new ObservationManager(storage);
88
+ *
89
+ * // Delete observations from multiple entities
90
+ * await manager.deleteObservations([
91
+ * { entityName: 'Alice', observations: ['Old observation 1', 'Old observation 2'] },
92
+ * { entityName: 'Bob', observations: ['Outdated info'] }
93
+ * ]);
94
+ *
95
+ * // Safe to delete from non-existent entities (no error)
96
+ * await manager.deleteObservations([
97
+ * { entityName: 'NonExistent', observations: ['Some text'] }
98
+ * ]); // No error thrown
99
+ * ```
100
+ */
101
+ async deleteObservations(deletions) {
102
+ // Get mutable graph for atomic update
103
+ const graph = await this.storage.getGraphForMutation();
104
+ const timestamp = new Date().toISOString();
105
+ let hasChanges = false;
106
+ deletions.forEach(d => {
107
+ const entity = graph.entities.find(e => e.name === d.entityName);
108
+ if (entity) {
109
+ const originalLength = entity.observations.length;
110
+ entity.observations = entity.observations.filter(o => !d.observations.includes(o));
111
+ // Update lastModified timestamp if observations were deleted
112
+ if (entity.observations.length < originalLength) {
113
+ entity.lastModified = timestamp;
114
+ hasChanges = true;
115
+ }
116
+ }
117
+ });
118
+ // Save all changes in a single atomic operation
119
+ if (hasChanges) {
120
+ await this.storage.saveGraph(graph);
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=ObservationManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObservationManager.js","sourceRoot":"","sources":["../../src/core/ObservationManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Relation Manager
3
+ *
4
+ * Handles CRUD operations for relations in the knowledge graph.
5
+ *
6
+ * @module core/RelationManager
7
+ */
8
+ import type { Relation } from '../types/index.js';
9
+ import type { GraphStorage } from './GraphStorage.js';
10
+ /**
11
+ * Manages relation operations with automatic timestamp handling.
12
+ */
13
+ export declare class RelationManager {
14
+ private storage;
15
+ constructor(storage: GraphStorage);
16
+ /**
17
+ * Create multiple relations in a single batch operation.
18
+ *
19
+ * This method performs the following operations:
20
+ * - Validates that all referenced entities exist (prevents dangling relations)
21
+ * - Filters out duplicate relations (same from, to, and relationType)
22
+ * - Automatically adds createdAt and lastModified timestamps
23
+ *
24
+ * A relation is considered duplicate if another relation exists with the same:
25
+ * - from entity name
26
+ * - to entity name
27
+ * - relationType
28
+ *
29
+ * @param relations - Array of relations to create
30
+ * @returns Promise resolving to array of newly created relations (excludes duplicates)
31
+ * @throws {ValidationError} If any relation references non-existent entities
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const manager = new RelationManager(storage);
36
+ *
37
+ * // Create single relation
38
+ * const results = await manager.createRelations([{
39
+ * from: 'Alice',
40
+ * to: 'Bob',
41
+ * relationType: 'works_with'
42
+ * }]);
43
+ *
44
+ * // Create multiple relations at once
45
+ * await manager.createRelations([
46
+ * { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
47
+ * { from: 'Bob', to: 'Project_X', relationType: 'leads' },
48
+ * { from: 'Charlie', to: 'Alice', relationType: 'reports_to' }
49
+ * ]);
50
+ *
51
+ * // Duplicate relations are filtered out
52
+ * await manager.createRelations([
53
+ * { from: 'Alice', to: 'Bob', relationType: 'works_with' } // Already exists, won't be added
54
+ * ]);
55
+ * ```
56
+ */
57
+ createRelations(relations: Relation[]): Promise<Relation[]>;
58
+ /**
59
+ * Delete multiple relations in a single batch operation.
60
+ *
61
+ * This method performs the following operations:
62
+ * - Removes all specified relations from the graph
63
+ * - Automatically updates lastModified timestamp for all affected entities
64
+ * - Silently ignores relations that don't exist (no error thrown)
65
+ *
66
+ * An entity is considered "affected" if it appears as either the source (from)
67
+ * or target (to) of any deleted relation.
68
+ *
69
+ * @param relations - Array of relations to delete. Each relation is matched by from, to, and relationType.
70
+ * @returns Promise that resolves when deletion is complete
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const manager = new RelationManager(storage);
75
+ *
76
+ * // Delete single relation
77
+ * await manager.deleteRelations([{
78
+ * from: 'Alice',
79
+ * to: 'Bob',
80
+ * relationType: 'works_with'
81
+ * }]);
82
+ *
83
+ * // Delete multiple relations at once
84
+ * await manager.deleteRelations([
85
+ * { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
86
+ * { from: 'Bob', to: 'Project_X', relationType: 'leads' }
87
+ * ]);
88
+ * // Note: Alice, Bob, and Project_X will all have their lastModified timestamp updated
89
+ *
90
+ * // Safe to delete non-existent relations
91
+ * await manager.deleteRelations([
92
+ * { from: 'NonExistent', to: 'AlsoNonExistent', relationType: 'fake' } // No error
93
+ * ]);
94
+ * ```
95
+ */
96
+ deleteRelations(relations: Relation[]): Promise<void>;
97
+ /**
98
+ * Retrieve all relations involving a specific entity.
99
+ *
100
+ * This is a read-only operation that returns all relations where the specified
101
+ * entity appears as either the source (from) or target (to) of the relation.
102
+ * Entity names are case-sensitive.
103
+ *
104
+ * @param entityName - The unique name of the entity to find relations for
105
+ * @returns Promise resolving to array of Relation objects (empty array if no relations found)
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const manager = new RelationManager(storage);
110
+ *
111
+ * // Get all relations for an entity
112
+ * const aliceRelations = await manager.getRelations('Alice');
113
+ * // Returns: [
114
+ * // { from: 'Alice', to: 'Bob', relationType: 'works_with' },
115
+ * // { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
116
+ * // { from: 'Charlie', to: 'Alice', relationType: 'reports_to' }
117
+ * // ]
118
+ *
119
+ * // Process relations by type
120
+ * const relations = await manager.getRelations('Alice');
121
+ * const outgoing = relations.filter(r => r.from === 'Alice');
122
+ * const incoming = relations.filter(r => r.to === 'Alice');
123
+ *
124
+ * // Handle entity with no relations
125
+ * const noRelations = await manager.getRelations('IsolatedEntity');
126
+ * console.log(noRelations); // []
127
+ * ```
128
+ */
129
+ getRelations(entityName: string): Promise<Relation[]>;
130
+ }
131
+ //# sourceMappingURL=RelationManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationManager.d.ts","sourceRoot":"","sources":["../../src/core/RelationManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKtD;;GAEG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACG,eAAe,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAiEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACG,eAAe,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAK5D"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Relation Manager
3
+ *
4
+ * Handles CRUD operations for relations in the knowledge graph.
5
+ *
6
+ * @module core/RelationManager
7
+ */
8
+ import { ValidationError } from '../utils/errors.js';
9
+ import { BatchCreateRelationsSchema, DeleteRelationsSchema } from '../utils/index.js';
10
+ import { GRAPH_LIMITS } from '../utils/constants.js';
11
+ /**
12
+ * Manages relation operations with automatic timestamp handling.
13
+ */
14
+ export class RelationManager {
15
+ storage;
16
+ constructor(storage) {
17
+ this.storage = storage;
18
+ }
19
+ /**
20
+ * Create multiple relations in a single batch operation.
21
+ *
22
+ * This method performs the following operations:
23
+ * - Validates that all referenced entities exist (prevents dangling relations)
24
+ * - Filters out duplicate relations (same from, to, and relationType)
25
+ * - Automatically adds createdAt and lastModified timestamps
26
+ *
27
+ * A relation is considered duplicate if another relation exists with the same:
28
+ * - from entity name
29
+ * - to entity name
30
+ * - relationType
31
+ *
32
+ * @param relations - Array of relations to create
33
+ * @returns Promise resolving to array of newly created relations (excludes duplicates)
34
+ * @throws {ValidationError} If any relation references non-existent entities
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const manager = new RelationManager(storage);
39
+ *
40
+ * // Create single relation
41
+ * const results = await manager.createRelations([{
42
+ * from: 'Alice',
43
+ * to: 'Bob',
44
+ * relationType: 'works_with'
45
+ * }]);
46
+ *
47
+ * // Create multiple relations at once
48
+ * await manager.createRelations([
49
+ * { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
50
+ * { from: 'Bob', to: 'Project_X', relationType: 'leads' },
51
+ * { from: 'Charlie', to: 'Alice', relationType: 'reports_to' }
52
+ * ]);
53
+ *
54
+ * // Duplicate relations are filtered out
55
+ * await manager.createRelations([
56
+ * { from: 'Alice', to: 'Bob', relationType: 'works_with' } // Already exists, won't be added
57
+ * ]);
58
+ * ```
59
+ */
60
+ async createRelations(relations) {
61
+ // Validate input
62
+ const validation = BatchCreateRelationsSchema.safeParse(relations);
63
+ if (!validation.success) {
64
+ const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
65
+ throw new ValidationError('Invalid relation data', errors);
66
+ }
67
+ // Use read-only graph for checking existing relations and entity existence
68
+ const readGraph = await this.storage.loadGraph();
69
+ const timestamp = new Date().toISOString();
70
+ // Build set of existing entity names for O(1) lookup
71
+ const existingEntityNames = new Set(readGraph.entities.map(e => e.name));
72
+ // Validate that all referenced entities exist (fixes bug 7.2 from analysis)
73
+ const danglingRelations = [];
74
+ for (const relation of relations) {
75
+ const missingEntities = [];
76
+ if (!existingEntityNames.has(relation.from)) {
77
+ missingEntities.push(relation.from);
78
+ }
79
+ if (!existingEntityNames.has(relation.to)) {
80
+ missingEntities.push(relation.to);
81
+ }
82
+ if (missingEntities.length > 0) {
83
+ danglingRelations.push(`Relation from "${relation.from}" to "${relation.to}" references non-existent entities: ${missingEntities.join(', ')}`);
84
+ }
85
+ }
86
+ if (danglingRelations.length > 0) {
87
+ throw new ValidationError('Relations reference non-existent entities', danglingRelations);
88
+ }
89
+ // Check graph size limits
90
+ const relationsToAdd = relations.filter(r => !readGraph.relations.some(existing => existing.from === r.from &&
91
+ existing.to === r.to &&
92
+ existing.relationType === r.relationType));
93
+ if (readGraph.relations.length + relationsToAdd.length > GRAPH_LIMITS.MAX_RELATIONS) {
94
+ throw new ValidationError('Graph size limit exceeded', [`Adding ${relationsToAdd.length} relations would exceed maximum of ${GRAPH_LIMITS.MAX_RELATIONS} relations`]);
95
+ }
96
+ const newRelations = relationsToAdd
97
+ .map(r => ({
98
+ ...r,
99
+ createdAt: r.createdAt || timestamp,
100
+ lastModified: r.lastModified || timestamp,
101
+ }));
102
+ // Get mutable copy for write operation
103
+ const graph = await this.storage.getGraphForMutation();
104
+ graph.relations.push(...newRelations);
105
+ await this.storage.saveGraph(graph);
106
+ return newRelations;
107
+ }
108
+ /**
109
+ * Delete multiple relations in a single batch operation.
110
+ *
111
+ * This method performs the following operations:
112
+ * - Removes all specified relations from the graph
113
+ * - Automatically updates lastModified timestamp for all affected entities
114
+ * - Silently ignores relations that don't exist (no error thrown)
115
+ *
116
+ * An entity is considered "affected" if it appears as either the source (from)
117
+ * or target (to) of any deleted relation.
118
+ *
119
+ * @param relations - Array of relations to delete. Each relation is matched by from, to, and relationType.
120
+ * @returns Promise that resolves when deletion is complete
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const manager = new RelationManager(storage);
125
+ *
126
+ * // Delete single relation
127
+ * await manager.deleteRelations([{
128
+ * from: 'Alice',
129
+ * to: 'Bob',
130
+ * relationType: 'works_with'
131
+ * }]);
132
+ *
133
+ * // Delete multiple relations at once
134
+ * await manager.deleteRelations([
135
+ * { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
136
+ * { from: 'Bob', to: 'Project_X', relationType: 'leads' }
137
+ * ]);
138
+ * // Note: Alice, Bob, and Project_X will all have their lastModified timestamp updated
139
+ *
140
+ * // Safe to delete non-existent relations
141
+ * await manager.deleteRelations([
142
+ * { from: 'NonExistent', to: 'AlsoNonExistent', relationType: 'fake' } // No error
143
+ * ]);
144
+ * ```
145
+ */
146
+ async deleteRelations(relations) {
147
+ // Validate input
148
+ const validation = DeleteRelationsSchema.safeParse(relations);
149
+ if (!validation.success) {
150
+ const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
151
+ throw new ValidationError('Invalid relation data', errors);
152
+ }
153
+ const graph = await this.storage.getGraphForMutation();
154
+ const timestamp = new Date().toISOString();
155
+ // Track affected entities
156
+ const affectedEntityNames = new Set();
157
+ relations.forEach(rel => {
158
+ affectedEntityNames.add(rel.from);
159
+ affectedEntityNames.add(rel.to);
160
+ });
161
+ // OPTIMIZED: Use Set<string> for O(1) lookup instead of O(n) array.some()
162
+ // Create composite keys for relations to delete
163
+ const relationsToDeleteSet = new Set(relations.map(r => `${r.from}|${r.to}|${r.relationType}`));
164
+ // Remove relations with O(1) Set lookup per relation instead of O(m) array scan
165
+ graph.relations = graph.relations.filter(r => !relationsToDeleteSet.has(`${r.from}|${r.to}|${r.relationType}`));
166
+ // Update lastModified for affected entities
167
+ graph.entities.forEach(entity => {
168
+ if (affectedEntityNames.has(entity.name)) {
169
+ entity.lastModified = timestamp;
170
+ }
171
+ });
172
+ await this.storage.saveGraph(graph);
173
+ }
174
+ /**
175
+ * Retrieve all relations involving a specific entity.
176
+ *
177
+ * This is a read-only operation that returns all relations where the specified
178
+ * entity appears as either the source (from) or target (to) of the relation.
179
+ * Entity names are case-sensitive.
180
+ *
181
+ * @param entityName - The unique name of the entity to find relations for
182
+ * @returns Promise resolving to array of Relation objects (empty array if no relations found)
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const manager = new RelationManager(storage);
187
+ *
188
+ * // Get all relations for an entity
189
+ * const aliceRelations = await manager.getRelations('Alice');
190
+ * // Returns: [
191
+ * // { from: 'Alice', to: 'Bob', relationType: 'works_with' },
192
+ * // { from: 'Alice', to: 'Project_X', relationType: 'contributes_to' },
193
+ * // { from: 'Charlie', to: 'Alice', relationType: 'reports_to' }
194
+ * // ]
195
+ *
196
+ * // Process relations by type
197
+ * const relations = await manager.getRelations('Alice');
198
+ * const outgoing = relations.filter(r => r.from === 'Alice');
199
+ * const incoming = relations.filter(r => r.to === 'Alice');
200
+ *
201
+ * // Handle entity with no relations
202
+ * const noRelations = await manager.getRelations('IsolatedEntity');
203
+ * console.log(noRelations); // []
204
+ * ```
205
+ */
206
+ async getRelations(entityName) {
207
+ // OPTIMIZED: Uses RelationIndex for O(1) lookup instead of O(n) array scan
208
+ await this.storage.ensureLoaded();
209
+ return this.storage.getRelationsFor(entityName);
210
+ }
211
+ }
212
+ //# sourceMappingURL=RelationManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationManager.js","sourceRoot":"","sources":["../../src/core/RelationManager.ts"],"names":[],"mappings":"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"}