@danielsimonjr/memoryjs 1.0.0 → 1.2.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 (300) hide show
  1. package/README.md +385 -113
  2. package/README.md.backup-1768084780988 +266 -0
  3. package/dist/index.cjs +24156 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +16967 -0
  6. package/dist/index.d.ts +16963 -11
  7. package/dist/index.js +23887 -19
  8. package/dist/index.js.map +1 -1
  9. package/dist/workers/levenshteinWorker.cjs +102 -0
  10. package/dist/workers/levenshteinWorker.cjs.map +1 -0
  11. package/dist/workers/levenshteinWorker.js +57 -91
  12. package/dist/workers/levenshteinWorker.js.map +1 -1
  13. package/package.json +75 -69
  14. package/dist/core/EntityManager.d.ts +0 -268
  15. package/dist/core/EntityManager.d.ts.map +0 -1
  16. package/dist/core/EntityManager.js +0 -512
  17. package/dist/core/EntityManager.js.map +0 -1
  18. package/dist/core/GraphEventEmitter.d.ts +0 -202
  19. package/dist/core/GraphEventEmitter.d.ts.map +0 -1
  20. package/dist/core/GraphEventEmitter.js +0 -347
  21. package/dist/core/GraphEventEmitter.js.map +0 -1
  22. package/dist/core/GraphStorage.d.ts +0 -395
  23. package/dist/core/GraphStorage.d.ts.map +0 -1
  24. package/dist/core/GraphStorage.js +0 -786
  25. package/dist/core/GraphStorage.js.map +0 -1
  26. package/dist/core/GraphTraversal.d.ts +0 -141
  27. package/dist/core/GraphTraversal.d.ts.map +0 -1
  28. package/dist/core/GraphTraversal.js +0 -574
  29. package/dist/core/GraphTraversal.js.map +0 -1
  30. package/dist/core/HierarchyManager.d.ts +0 -111
  31. package/dist/core/HierarchyManager.d.ts.map +0 -1
  32. package/dist/core/HierarchyManager.js +0 -225
  33. package/dist/core/HierarchyManager.js.map +0 -1
  34. package/dist/core/ManagerContext.d.ts +0 -76
  35. package/dist/core/ManagerContext.d.ts.map +0 -1
  36. package/dist/core/ManagerContext.js +0 -129
  37. package/dist/core/ManagerContext.js.map +0 -1
  38. package/dist/core/ObservationManager.d.ts +0 -85
  39. package/dist/core/ObservationManager.d.ts.map +0 -1
  40. package/dist/core/ObservationManager.js +0 -124
  41. package/dist/core/ObservationManager.js.map +0 -1
  42. package/dist/core/RelationManager.d.ts +0 -131
  43. package/dist/core/RelationManager.d.ts.map +0 -1
  44. package/dist/core/RelationManager.js +0 -212
  45. package/dist/core/RelationManager.js.map +0 -1
  46. package/dist/core/SQLiteStorage.d.ts +0 -354
  47. package/dist/core/SQLiteStorage.d.ts.map +0 -1
  48. package/dist/core/SQLiteStorage.js +0 -919
  49. package/dist/core/SQLiteStorage.js.map +0 -1
  50. package/dist/core/StorageFactory.d.ts +0 -45
  51. package/dist/core/StorageFactory.d.ts.map +0 -1
  52. package/dist/core/StorageFactory.js +0 -65
  53. package/dist/core/StorageFactory.js.map +0 -1
  54. package/dist/core/TransactionManager.d.ts +0 -464
  55. package/dist/core/TransactionManager.d.ts.map +0 -1
  56. package/dist/core/TransactionManager.js +0 -869
  57. package/dist/core/TransactionManager.js.map +0 -1
  58. package/dist/core/index.d.ts +0 -17
  59. package/dist/core/index.d.ts.map +0 -1
  60. package/dist/core/index.js +0 -20
  61. package/dist/core/index.js.map +0 -1
  62. package/dist/features/AnalyticsManager.d.ts +0 -44
  63. package/dist/features/AnalyticsManager.d.ts.map +0 -1
  64. package/dist/features/AnalyticsManager.js +0 -224
  65. package/dist/features/AnalyticsManager.js.map +0 -1
  66. package/dist/features/ArchiveManager.d.ts +0 -133
  67. package/dist/features/ArchiveManager.d.ts.map +0 -1
  68. package/dist/features/ArchiveManager.js +0 -282
  69. package/dist/features/ArchiveManager.js.map +0 -1
  70. package/dist/features/CompressionManager.d.ts +0 -119
  71. package/dist/features/CompressionManager.d.ts.map +0 -1
  72. package/dist/features/CompressionManager.js +0 -470
  73. package/dist/features/CompressionManager.js.map +0 -1
  74. package/dist/features/IOManager.d.ts +0 -225
  75. package/dist/features/IOManager.d.ts.map +0 -1
  76. package/dist/features/IOManager.js +0 -1093
  77. package/dist/features/IOManager.js.map +0 -1
  78. package/dist/features/KeywordExtractor.d.ts +0 -61
  79. package/dist/features/KeywordExtractor.d.ts.map +0 -1
  80. package/dist/features/KeywordExtractor.js +0 -127
  81. package/dist/features/KeywordExtractor.js.map +0 -1
  82. package/dist/features/ObservationNormalizer.d.ts +0 -90
  83. package/dist/features/ObservationNormalizer.d.ts.map +0 -1
  84. package/dist/features/ObservationNormalizer.js +0 -194
  85. package/dist/features/ObservationNormalizer.js.map +0 -1
  86. package/dist/features/StreamingExporter.d.ts +0 -128
  87. package/dist/features/StreamingExporter.d.ts.map +0 -1
  88. package/dist/features/StreamingExporter.js +0 -212
  89. package/dist/features/StreamingExporter.js.map +0 -1
  90. package/dist/features/TagManager.d.ts +0 -147
  91. package/dist/features/TagManager.d.ts.map +0 -1
  92. package/dist/features/TagManager.js +0 -211
  93. package/dist/features/TagManager.js.map +0 -1
  94. package/dist/features/index.d.ts +0 -14
  95. package/dist/features/index.d.ts.map +0 -1
  96. package/dist/features/index.js +0 -15
  97. package/dist/features/index.js.map +0 -1
  98. package/dist/index.d.ts.map +0 -1
  99. package/dist/search/BM25Search.d.ts +0 -148
  100. package/dist/search/BM25Search.d.ts.map +0 -1
  101. package/dist/search/BM25Search.js +0 -340
  102. package/dist/search/BM25Search.js.map +0 -1
  103. package/dist/search/BasicSearch.d.ts +0 -51
  104. package/dist/search/BasicSearch.d.ts.map +0 -1
  105. package/dist/search/BasicSearch.js +0 -138
  106. package/dist/search/BasicSearch.js.map +0 -1
  107. package/dist/search/BooleanSearch.d.ts +0 -98
  108. package/dist/search/BooleanSearch.d.ts.map +0 -1
  109. package/dist/search/BooleanSearch.js +0 -431
  110. package/dist/search/BooleanSearch.js.map +0 -1
  111. package/dist/search/EarlyTerminationManager.d.ts +0 -140
  112. package/dist/search/EarlyTerminationManager.d.ts.map +0 -1
  113. package/dist/search/EarlyTerminationManager.js +0 -280
  114. package/dist/search/EarlyTerminationManager.js.map +0 -1
  115. package/dist/search/EmbeddingCache.d.ts +0 -175
  116. package/dist/search/EmbeddingCache.d.ts.map +0 -1
  117. package/dist/search/EmbeddingCache.js +0 -247
  118. package/dist/search/EmbeddingCache.js.map +0 -1
  119. package/dist/search/EmbeddingService.d.ts +0 -277
  120. package/dist/search/EmbeddingService.d.ts.map +0 -1
  121. package/dist/search/EmbeddingService.js +0 -531
  122. package/dist/search/EmbeddingService.js.map +0 -1
  123. package/dist/search/FuzzySearch.d.ts +0 -118
  124. package/dist/search/FuzzySearch.d.ts.map +0 -1
  125. package/dist/search/FuzzySearch.js +0 -313
  126. package/dist/search/FuzzySearch.js.map +0 -1
  127. package/dist/search/HybridScorer.d.ts +0 -181
  128. package/dist/search/HybridScorer.d.ts.map +0 -1
  129. package/dist/search/HybridScorer.js +0 -258
  130. package/dist/search/HybridScorer.js.map +0 -1
  131. package/dist/search/HybridSearchManager.d.ts +0 -80
  132. package/dist/search/HybridSearchManager.d.ts.map +0 -1
  133. package/dist/search/HybridSearchManager.js +0 -188
  134. package/dist/search/HybridSearchManager.js.map +0 -1
  135. package/dist/search/IncrementalIndexer.d.ts +0 -201
  136. package/dist/search/IncrementalIndexer.d.ts.map +0 -1
  137. package/dist/search/IncrementalIndexer.js +0 -343
  138. package/dist/search/IncrementalIndexer.js.map +0 -1
  139. package/dist/search/OptimizedInvertedIndex.d.ts +0 -163
  140. package/dist/search/OptimizedInvertedIndex.d.ts.map +0 -1
  141. package/dist/search/OptimizedInvertedIndex.js +0 -359
  142. package/dist/search/OptimizedInvertedIndex.js.map +0 -1
  143. package/dist/search/ParallelSearchExecutor.d.ts +0 -172
  144. package/dist/search/ParallelSearchExecutor.d.ts.map +0 -1
  145. package/dist/search/ParallelSearchExecutor.js +0 -310
  146. package/dist/search/ParallelSearchExecutor.js.map +0 -1
  147. package/dist/search/QuantizedVectorStore.d.ts +0 -171
  148. package/dist/search/QuantizedVectorStore.d.ts.map +0 -1
  149. package/dist/search/QuantizedVectorStore.js +0 -308
  150. package/dist/search/QuantizedVectorStore.js.map +0 -1
  151. package/dist/search/QueryAnalyzer.d.ts +0 -76
  152. package/dist/search/QueryAnalyzer.d.ts.map +0 -1
  153. package/dist/search/QueryAnalyzer.js +0 -228
  154. package/dist/search/QueryAnalyzer.js.map +0 -1
  155. package/dist/search/QueryCostEstimator.d.ts +0 -244
  156. package/dist/search/QueryCostEstimator.d.ts.map +0 -1
  157. package/dist/search/QueryCostEstimator.js +0 -653
  158. package/dist/search/QueryCostEstimator.js.map +0 -1
  159. package/dist/search/QueryPlanCache.d.ts +0 -220
  160. package/dist/search/QueryPlanCache.d.ts.map +0 -1
  161. package/dist/search/QueryPlanCache.js +0 -380
  162. package/dist/search/QueryPlanCache.js.map +0 -1
  163. package/dist/search/QueryPlanner.d.ts +0 -58
  164. package/dist/search/QueryPlanner.d.ts.map +0 -1
  165. package/dist/search/QueryPlanner.js +0 -138
  166. package/dist/search/QueryPlanner.js.map +0 -1
  167. package/dist/search/RankedSearch.d.ts +0 -71
  168. package/dist/search/RankedSearch.d.ts.map +0 -1
  169. package/dist/search/RankedSearch.js +0 -239
  170. package/dist/search/RankedSearch.js.map +0 -1
  171. package/dist/search/ReflectionManager.d.ts +0 -120
  172. package/dist/search/ReflectionManager.d.ts.map +0 -1
  173. package/dist/search/ReflectionManager.js +0 -232
  174. package/dist/search/ReflectionManager.js.map +0 -1
  175. package/dist/search/SavedSearchManager.d.ts +0 -79
  176. package/dist/search/SavedSearchManager.d.ts.map +0 -1
  177. package/dist/search/SavedSearchManager.js +0 -147
  178. package/dist/search/SavedSearchManager.js.map +0 -1
  179. package/dist/search/SearchFilterChain.d.ts +0 -120
  180. package/dist/search/SearchFilterChain.d.ts.map +0 -1
  181. package/dist/search/SearchFilterChain.js +0 -186
  182. package/dist/search/SearchFilterChain.js.map +0 -1
  183. package/dist/search/SearchManager.d.ts +0 -326
  184. package/dist/search/SearchManager.d.ts.map +0 -1
  185. package/dist/search/SearchManager.js +0 -454
  186. package/dist/search/SearchManager.js.map +0 -1
  187. package/dist/search/SearchSuggestions.d.ts +0 -27
  188. package/dist/search/SearchSuggestions.d.ts.map +0 -1
  189. package/dist/search/SearchSuggestions.js +0 -58
  190. package/dist/search/SearchSuggestions.js.map +0 -1
  191. package/dist/search/SemanticSearch.d.ts +0 -149
  192. package/dist/search/SemanticSearch.d.ts.map +0 -1
  193. package/dist/search/SemanticSearch.js +0 -324
  194. package/dist/search/SemanticSearch.js.map +0 -1
  195. package/dist/search/SymbolicSearch.d.ts +0 -61
  196. package/dist/search/SymbolicSearch.d.ts.map +0 -1
  197. package/dist/search/SymbolicSearch.js +0 -164
  198. package/dist/search/SymbolicSearch.js.map +0 -1
  199. package/dist/search/TFIDFEventSync.d.ts +0 -85
  200. package/dist/search/TFIDFEventSync.d.ts.map +0 -1
  201. package/dist/search/TFIDFEventSync.js +0 -134
  202. package/dist/search/TFIDFEventSync.js.map +0 -1
  203. package/dist/search/TFIDFIndexManager.d.ts +0 -151
  204. package/dist/search/TFIDFIndexManager.d.ts.map +0 -1
  205. package/dist/search/TFIDFIndexManager.js +0 -433
  206. package/dist/search/TFIDFIndexManager.js.map +0 -1
  207. package/dist/search/VectorStore.d.ts +0 -235
  208. package/dist/search/VectorStore.d.ts.map +0 -1
  209. package/dist/search/VectorStore.js +0 -312
  210. package/dist/search/VectorStore.js.map +0 -1
  211. package/dist/search/index.d.ts +0 -35
  212. package/dist/search/index.d.ts.map +0 -1
  213. package/dist/search/index.js +0 -53
  214. package/dist/search/index.js.map +0 -1
  215. package/dist/types/index.d.ts +0 -13
  216. package/dist/types/index.d.ts.map +0 -1
  217. package/dist/types/index.js +0 -13
  218. package/dist/types/index.js.map +0 -1
  219. package/dist/types/types.d.ts +0 -1811
  220. package/dist/types/types.d.ts.map +0 -1
  221. package/dist/types/types.js +0 -10
  222. package/dist/types/types.js.map +0 -1
  223. package/dist/utils/BatchProcessor.d.ts +0 -271
  224. package/dist/utils/BatchProcessor.d.ts.map +0 -1
  225. package/dist/utils/BatchProcessor.js +0 -377
  226. package/dist/utils/BatchProcessor.js.map +0 -1
  227. package/dist/utils/MemoryMonitor.d.ts +0 -176
  228. package/dist/utils/MemoryMonitor.d.ts.map +0 -1
  229. package/dist/utils/MemoryMonitor.js +0 -306
  230. package/dist/utils/MemoryMonitor.js.map +0 -1
  231. package/dist/utils/WorkerPoolManager.d.ts +0 -233
  232. package/dist/utils/WorkerPoolManager.d.ts.map +0 -1
  233. package/dist/utils/WorkerPoolManager.js +0 -421
  234. package/dist/utils/WorkerPoolManager.js.map +0 -1
  235. package/dist/utils/compressedCache.d.ts +0 -221
  236. package/dist/utils/compressedCache.d.ts.map +0 -1
  237. package/dist/utils/compressedCache.js +0 -349
  238. package/dist/utils/compressedCache.js.map +0 -1
  239. package/dist/utils/compressionUtil.d.ts +0 -214
  240. package/dist/utils/compressionUtil.d.ts.map +0 -1
  241. package/dist/utils/compressionUtil.js +0 -248
  242. package/dist/utils/compressionUtil.js.map +0 -1
  243. package/dist/utils/constants.d.ts +0 -245
  244. package/dist/utils/constants.d.ts.map +0 -1
  245. package/dist/utils/constants.js +0 -253
  246. package/dist/utils/constants.js.map +0 -1
  247. package/dist/utils/entityUtils.d.ts +0 -379
  248. package/dist/utils/entityUtils.d.ts.map +0 -1
  249. package/dist/utils/entityUtils.js +0 -649
  250. package/dist/utils/entityUtils.js.map +0 -1
  251. package/dist/utils/errors.d.ts +0 -95
  252. package/dist/utils/errors.d.ts.map +0 -1
  253. package/dist/utils/errors.js +0 -146
  254. package/dist/utils/errors.js.map +0 -1
  255. package/dist/utils/formatters.d.ts +0 -145
  256. package/dist/utils/formatters.d.ts.map +0 -1
  257. package/dist/utils/formatters.js +0 -133
  258. package/dist/utils/formatters.js.map +0 -1
  259. package/dist/utils/index.d.ts +0 -26
  260. package/dist/utils/index.d.ts.map +0 -1
  261. package/dist/utils/index.js +0 -88
  262. package/dist/utils/index.js.map +0 -1
  263. package/dist/utils/indexes.d.ts +0 -270
  264. package/dist/utils/indexes.d.ts.map +0 -1
  265. package/dist/utils/indexes.js +0 -527
  266. package/dist/utils/indexes.js.map +0 -1
  267. package/dist/utils/logger.d.ts +0 -31
  268. package/dist/utils/logger.d.ts.map +0 -1
  269. package/dist/utils/logger.js +0 -41
  270. package/dist/utils/logger.js.map +0 -1
  271. package/dist/utils/operationUtils.d.ts +0 -124
  272. package/dist/utils/operationUtils.d.ts.map +0 -1
  273. package/dist/utils/operationUtils.js +0 -176
  274. package/dist/utils/operationUtils.js.map +0 -1
  275. package/dist/utils/parallelUtils.d.ts +0 -76
  276. package/dist/utils/parallelUtils.d.ts.map +0 -1
  277. package/dist/utils/parallelUtils.js +0 -192
  278. package/dist/utils/parallelUtils.js.map +0 -1
  279. package/dist/utils/schemas.d.ts +0 -556
  280. package/dist/utils/schemas.d.ts.map +0 -1
  281. package/dist/utils/schemas.js +0 -485
  282. package/dist/utils/schemas.js.map +0 -1
  283. package/dist/utils/searchAlgorithms.d.ts +0 -99
  284. package/dist/utils/searchAlgorithms.d.ts.map +0 -1
  285. package/dist/utils/searchAlgorithms.js +0 -168
  286. package/dist/utils/searchAlgorithms.js.map +0 -1
  287. package/dist/utils/searchCache.d.ts +0 -108
  288. package/dist/utils/searchCache.d.ts.map +0 -1
  289. package/dist/utils/searchCache.js +0 -210
  290. package/dist/utils/searchCache.js.map +0 -1
  291. package/dist/utils/taskScheduler.d.ts +0 -294
  292. package/dist/utils/taskScheduler.d.ts.map +0 -1
  293. package/dist/utils/taskScheduler.js +0 -487
  294. package/dist/utils/taskScheduler.js.map +0 -1
  295. package/dist/workers/index.d.ts +0 -12
  296. package/dist/workers/index.d.ts.map +0 -1
  297. package/dist/workers/index.js +0 -10
  298. package/dist/workers/index.js.map +0 -1
  299. package/dist/workers/levenshteinWorker.d.ts +0 -60
  300. package/dist/workers/levenshteinWorker.d.ts.map +0 -1
@@ -1,869 +0,0 @@
1
- /**
2
- * Transaction Manager
3
- *
4
- * Provides atomic transaction support for knowledge graph operations.
5
- * Ensures data consistency by allowing multiple operations to be
6
- * grouped together and committed atomically, with automatic rollback on failure.
7
- *
8
- * @module core/TransactionManager
9
- */
10
- import { IOManager } from '../features/IOManager.js';
11
- import { KnowledgeGraphError } from '../utils/errors.js';
12
- import { checkCancellation, createProgressReporter, createProgress, sanitizeObject } from '../utils/index.js';
13
- /**
14
- * Types of operations that can be performed in a transaction.
15
- */
16
- export var OperationType;
17
- (function (OperationType) {
18
- OperationType["CREATE_ENTITY"] = "CREATE_ENTITY";
19
- OperationType["UPDATE_ENTITY"] = "UPDATE_ENTITY";
20
- OperationType["DELETE_ENTITY"] = "DELETE_ENTITY";
21
- OperationType["CREATE_RELATION"] = "CREATE_RELATION";
22
- OperationType["DELETE_RELATION"] = "DELETE_RELATION";
23
- })(OperationType || (OperationType = {}));
24
- /**
25
- * Manages atomic transactions for knowledge graph operations.
26
- *
27
- * Provides ACID-like guarantees:
28
- * - Atomicity: All operations succeed or all fail
29
- * - Consistency: Graph is always in a valid state
30
- * - Isolation: Each transaction operates on a snapshot
31
- * - Durability: Changes are persisted to disk
32
- *
33
- * @example
34
- * ```typescript
35
- * const storage = new GraphStorage('/data/memory.jsonl');
36
- * const txManager = new TransactionManager(storage);
37
- *
38
- * // Begin transaction
39
- * txManager.begin();
40
- *
41
- * // Stage operations
42
- * txManager.createEntity({ name: 'Alice', entityType: 'person', observations: [] });
43
- * txManager.createRelation({ from: 'Alice', to: 'Bob', relationType: 'knows' });
44
- *
45
- * // Commit atomically (or rollback on error)
46
- * const result = await txManager.commit();
47
- * if (result.success) {
48
- * console.log(`Transaction completed: ${result.operationsExecuted} operations`);
49
- * }
50
- * ```
51
- */
52
- export class TransactionManager {
53
- storage;
54
- operations = [];
55
- inTransaction = false;
56
- ioManager;
57
- transactionBackup;
58
- constructor(storage) {
59
- this.storage = storage;
60
- this.ioManager = new IOManager(storage);
61
- }
62
- /**
63
- * Begin a new transaction.
64
- *
65
- * Creates a backup of the current state for rollback purposes.
66
- * Only one transaction can be active at a time.
67
- *
68
- * @throws {KnowledgeGraphError} If a transaction is already in progress
69
- *
70
- * @example
71
- * ```typescript
72
- * txManager.begin();
73
- * // ... stage operations ...
74
- * await txManager.commit();
75
- * ```
76
- */
77
- begin() {
78
- if (this.inTransaction) {
79
- throw new KnowledgeGraphError('Transaction already in progress', 'TRANSACTION_ACTIVE');
80
- }
81
- this.operations = [];
82
- this.inTransaction = true;
83
- }
84
- /**
85
- * Stage a create entity operation.
86
- *
87
- * @param entity - Entity to create (without timestamps)
88
- *
89
- * @example
90
- * ```typescript
91
- * txManager.begin();
92
- * txManager.createEntity({
93
- * name: 'Alice',
94
- * entityType: 'person',
95
- * observations: ['Software engineer'],
96
- * importance: 8
97
- * });
98
- * ```
99
- */
100
- createEntity(entity) {
101
- this.ensureInTransaction();
102
- this.operations.push({
103
- type: OperationType.CREATE_ENTITY,
104
- data: entity,
105
- });
106
- }
107
- /**
108
- * Stage an update entity operation.
109
- *
110
- * @param name - Name of entity to update
111
- * @param updates - Partial entity updates
112
- *
113
- * @example
114
- * ```typescript
115
- * txManager.begin();
116
- * txManager.updateEntity('Alice', {
117
- * importance: 9,
118
- * observations: ['Lead software engineer']
119
- * });
120
- * ```
121
- */
122
- updateEntity(name, updates) {
123
- this.ensureInTransaction();
124
- this.operations.push({
125
- type: OperationType.UPDATE_ENTITY,
126
- data: { name, updates },
127
- });
128
- }
129
- /**
130
- * Stage a delete entity operation.
131
- *
132
- * @param name - Name of entity to delete
133
- *
134
- * @example
135
- * ```typescript
136
- * txManager.begin();
137
- * txManager.deleteEntity('OldEntity');
138
- * ```
139
- */
140
- deleteEntity(name) {
141
- this.ensureInTransaction();
142
- this.operations.push({
143
- type: OperationType.DELETE_ENTITY,
144
- data: { name },
145
- });
146
- }
147
- /**
148
- * Stage a create relation operation.
149
- *
150
- * @param relation - Relation to create (without timestamps)
151
- *
152
- * @example
153
- * ```typescript
154
- * txManager.begin();
155
- * txManager.createRelation({
156
- * from: 'Alice',
157
- * to: 'Bob',
158
- * relationType: 'mentors'
159
- * });
160
- * ```
161
- */
162
- createRelation(relation) {
163
- this.ensureInTransaction();
164
- this.operations.push({
165
- type: OperationType.CREATE_RELATION,
166
- data: relation,
167
- });
168
- }
169
- /**
170
- * Stage a delete relation operation.
171
- *
172
- * @param from - Source entity name
173
- * @param to - Target entity name
174
- * @param relationType - Type of relation
175
- *
176
- * @example
177
- * ```typescript
178
- * txManager.begin();
179
- * txManager.deleteRelation('Alice', 'Bob', 'mentors');
180
- * ```
181
- */
182
- deleteRelation(from, to, relationType) {
183
- this.ensureInTransaction();
184
- this.operations.push({
185
- type: OperationType.DELETE_RELATION,
186
- data: { from, to, relationType },
187
- });
188
- }
189
- /**
190
- * Commit the transaction, applying all staged operations atomically.
191
- *
192
- * Creates a backup before applying changes. If any operation fails,
193
- * automatically rolls back to the pre-transaction state.
194
- *
195
- * Phase 9B: Supports progress tracking and cancellation via LongRunningOperationOptions.
196
- *
197
- * @param options - Optional progress/cancellation options (Phase 9B)
198
- * @returns Promise resolving to transaction result
199
- * @throws {OperationCancelledError} If operation is cancelled via signal (Phase 9B)
200
- *
201
- * @example
202
- * ```typescript
203
- * txManager.begin();
204
- * txManager.createEntity({ name: 'Alice', entityType: 'person', observations: [] });
205
- * txManager.createRelation({ from: 'Alice', to: 'Bob', relationType: 'knows' });
206
- *
207
- * const result = await txManager.commit();
208
- * if (result.success) {
209
- * console.log(`Committed ${result.operationsExecuted} operations`);
210
- * } else {
211
- * console.error(`Transaction failed: ${result.error}`);
212
- * }
213
- *
214
- * // With progress tracking (Phase 9B)
215
- * const result = await txManager.commit({
216
- * onProgress: (p) => console.log(`${p.percentage}% complete`),
217
- * });
218
- * ```
219
- */
220
- async commit(options) {
221
- this.ensureInTransaction();
222
- // Setup progress reporter
223
- const reportProgress = createProgressReporter(options?.onProgress);
224
- const totalOperations = this.operations.length;
225
- reportProgress?.(createProgress(0, 100, 'commit'));
226
- try {
227
- // Check for early cancellation (inside try block to handle gracefully)
228
- checkCancellation(options?.signal, 'commit');
229
- // Phase 1: Create backup for rollback (0-20% progress)
230
- reportProgress?.(createProgress(5, 100, 'creating backup'));
231
- const backupResult = await this.ioManager.createBackup({
232
- description: 'Transaction backup (auto-created)',
233
- });
234
- this.transactionBackup = backupResult.path;
235
- // Check for cancellation after backup
236
- checkCancellation(options?.signal, 'commit');
237
- reportProgress?.(createProgress(20, 100, 'backup created'));
238
- // Phase 2: Load graph (20-30% progress)
239
- reportProgress?.(createProgress(25, 100, 'loading graph'));
240
- const graph = await this.storage.getGraphForMutation();
241
- const timestamp = new Date().toISOString();
242
- reportProgress?.(createProgress(30, 100, 'graph loaded'));
243
- // Phase 3: Apply all operations (30-80% progress)
244
- let operationsExecuted = 0;
245
- for (const operation of this.operations) {
246
- // Check for cancellation between operations
247
- checkCancellation(options?.signal, 'commit');
248
- this.applyOperation(graph, operation, timestamp);
249
- operationsExecuted++;
250
- // Map operation progress (0-100%) to overall progress (30-80%)
251
- const opProgress = totalOperations > 0 ? Math.round(30 + (operationsExecuted / totalOperations) * 50) : 80;
252
- reportProgress?.(createProgress(opProgress, 100, 'applying operations'));
253
- }
254
- // Check for cancellation before save
255
- checkCancellation(options?.signal, 'commit');
256
- // Phase 4: Save the modified graph (80-95% progress)
257
- reportProgress?.(createProgress(85, 100, 'saving graph'));
258
- await this.storage.saveGraph(graph);
259
- reportProgress?.(createProgress(95, 100, 'graph saved'));
260
- // Clean up transaction state
261
- this.inTransaction = false;
262
- this.operations = [];
263
- // Delete the transaction backup (no longer needed)
264
- if (this.transactionBackup) {
265
- await this.ioManager.deleteBackup(this.transactionBackup);
266
- this.transactionBackup = undefined;
267
- }
268
- // Report completion
269
- reportProgress?.(createProgress(100, 100, 'commit'));
270
- return {
271
- success: true,
272
- operationsExecuted,
273
- };
274
- }
275
- catch (error) {
276
- // Rollback on error
277
- const rollbackResult = await this.rollback();
278
- return {
279
- success: false,
280
- operationsExecuted: 0,
281
- error: error instanceof Error ? error.message : String(error),
282
- rollbackBackup: rollbackResult.backupUsed,
283
- };
284
- }
285
- }
286
- /**
287
- * Rollback the current transaction.
288
- *
289
- * Restores the graph to the pre-transaction state using the backup.
290
- * Automatically called by commit() on failure.
291
- *
292
- * @returns Promise resolving to rollback result
293
- *
294
- * @example
295
- * ```typescript
296
- * txManager.begin();
297
- * txManager.createEntity({ name: 'Test', entityType: 'temp', observations: [] });
298
- *
299
- * // Explicit rollback (e.g., user cancellation)
300
- * const result = await txManager.rollback();
301
- * console.log(`Rolled back, restored from: ${result.backupUsed}`);
302
- * ```
303
- */
304
- async rollback() {
305
- if (!this.transactionBackup) {
306
- this.inTransaction = false;
307
- this.operations = [];
308
- return { success: false };
309
- }
310
- try {
311
- // Restore from backup
312
- await this.ioManager.restoreFromBackup(this.transactionBackup);
313
- // Clean up
314
- const backupUsed = this.transactionBackup;
315
- await this.ioManager.deleteBackup(this.transactionBackup);
316
- this.inTransaction = false;
317
- this.operations = [];
318
- this.transactionBackup = undefined;
319
- return { success: true, backupUsed };
320
- }
321
- catch (error) {
322
- // Rollback failed - keep backup for manual recovery
323
- this.inTransaction = false;
324
- this.operations = [];
325
- return { success: false, backupUsed: this.transactionBackup };
326
- }
327
- }
328
- /**
329
- * Check if a transaction is currently in progress.
330
- *
331
- * @returns True if transaction is active
332
- */
333
- isInTransaction() {
334
- return this.inTransaction;
335
- }
336
- /**
337
- * Get the number of staged operations in the current transaction.
338
- *
339
- * @returns Number of operations staged
340
- */
341
- getOperationCount() {
342
- return this.operations.length;
343
- }
344
- /**
345
- * Ensure a transaction is in progress, or throw an error.
346
- *
347
- * @private
348
- */
349
- ensureInTransaction() {
350
- if (!this.inTransaction) {
351
- throw new KnowledgeGraphError('No transaction in progress. Call begin() first.', 'NO_TRANSACTION');
352
- }
353
- }
354
- /**
355
- * Apply a single operation to the graph.
356
- *
357
- * @private
358
- */
359
- applyOperation(graph, operation, timestamp) {
360
- switch (operation.type) {
361
- case OperationType.CREATE_ENTITY: {
362
- const entity = {
363
- ...operation.data,
364
- createdAt: timestamp,
365
- lastModified: timestamp,
366
- };
367
- // Check for duplicates
368
- if (graph.entities.some(e => e.name === entity.name)) {
369
- throw new KnowledgeGraphError(`Entity "${entity.name}" already exists`, 'DUPLICATE_ENTITY');
370
- }
371
- graph.entities.push(entity);
372
- break;
373
- }
374
- case OperationType.UPDATE_ENTITY: {
375
- const { name, updates } = operation.data;
376
- const entity = graph.entities.find(e => e.name === name);
377
- if (!entity) {
378
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
379
- }
380
- // Sanitize updates to prevent prototype pollution
381
- Object.assign(entity, sanitizeObject(updates));
382
- entity.lastModified = timestamp;
383
- break;
384
- }
385
- case OperationType.DELETE_ENTITY: {
386
- const { name } = operation.data;
387
- const index = graph.entities.findIndex(e => e.name === name);
388
- if (index === -1) {
389
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
390
- }
391
- graph.entities.splice(index, 1);
392
- // Delete related relations
393
- graph.relations = graph.relations.filter(r => r.from !== name && r.to !== name);
394
- break;
395
- }
396
- case OperationType.CREATE_RELATION: {
397
- const relation = {
398
- ...operation.data,
399
- createdAt: timestamp,
400
- lastModified: timestamp,
401
- };
402
- // Check for duplicates
403
- const exists = graph.relations.some(r => r.from === relation.from && r.to === relation.to && r.relationType === relation.relationType);
404
- if (exists) {
405
- throw new KnowledgeGraphError(`Relation "${relation.from}" -> "${relation.to}" (${relation.relationType}) already exists`, 'DUPLICATE_RELATION');
406
- }
407
- graph.relations.push(relation);
408
- break;
409
- }
410
- case OperationType.DELETE_RELATION: {
411
- const { from, to, relationType } = operation.data;
412
- const index = graph.relations.findIndex(r => r.from === from && r.to === to && r.relationType === relationType);
413
- if (index === -1) {
414
- throw new KnowledgeGraphError(`Relation "${from}" -> "${to}" (${relationType}) not found`, 'RELATION_NOT_FOUND');
415
- }
416
- graph.relations.splice(index, 1);
417
- break;
418
- }
419
- default: {
420
- // Exhaustiveness check - TypeScript will error if we miss a case
421
- const _exhaustiveCheck = operation;
422
- throw new KnowledgeGraphError(`Unknown operation type: ${_exhaustiveCheck.type}`, 'UNKNOWN_OPERATION');
423
- }
424
- }
425
- }
426
- }
427
- // ==================== Phase 10 Sprint 1: BatchTransaction ====================
428
- /**
429
- * Phase 10 Sprint 1: Fluent API for building and executing batch transactions.
430
- *
431
- * BatchTransaction provides a builder pattern for accumulating multiple
432
- * graph operations and executing them atomically in a single transaction.
433
- * This reduces I/O overhead and ensures consistency across related changes.
434
- *
435
- * @example
436
- * ```typescript
437
- * const storage = new GraphStorage('/data/memory.jsonl');
438
- * const batch = new BatchTransaction(storage);
439
- *
440
- * // Build the batch with fluent API
441
- * const result = await batch
442
- * .createEntity({ name: 'Alice', entityType: 'person', observations: ['Developer'] })
443
- * .createEntity({ name: 'Bob', entityType: 'person', observations: ['Designer'] })
444
- * .createRelation({ from: 'Alice', to: 'Bob', relationType: 'knows' })
445
- * .updateEntity('Alice', { importance: 8 })
446
- * .execute();
447
- *
448
- * if (result.success) {
449
- * console.log(`Batch completed: ${result.operationsExecuted} operations in ${result.executionTimeMs}ms`);
450
- * }
451
- * ```
452
- */
453
- export class BatchTransaction {
454
- operations = [];
455
- storage;
456
- /**
457
- * Create a new BatchTransaction instance.
458
- *
459
- * @param storage - GraphStorage instance to execute operations against
460
- */
461
- constructor(storage) {
462
- this.storage = storage;
463
- }
464
- /**
465
- * Add a create entity operation to the batch.
466
- *
467
- * @param entity - Entity to create (without timestamps)
468
- * @returns This BatchTransaction for chaining
469
- *
470
- * @example
471
- * ```typescript
472
- * batch.createEntity({
473
- * name: 'Alice',
474
- * entityType: 'person',
475
- * observations: ['Software engineer'],
476
- * importance: 8
477
- * });
478
- * ```
479
- */
480
- createEntity(entity) {
481
- this.operations.push({ type: 'createEntity', data: entity });
482
- return this;
483
- }
484
- /**
485
- * Add an update entity operation to the batch.
486
- *
487
- * @param name - Name of entity to update
488
- * @param updates - Partial entity updates
489
- * @returns This BatchTransaction for chaining
490
- *
491
- * @example
492
- * ```typescript
493
- * batch.updateEntity('Alice', { importance: 9 });
494
- * ```
495
- */
496
- updateEntity(name, updates) {
497
- this.operations.push({ type: 'updateEntity', data: { name, updates } });
498
- return this;
499
- }
500
- /**
501
- * Add a delete entity operation to the batch.
502
- *
503
- * @param name - Name of entity to delete
504
- * @returns This BatchTransaction for chaining
505
- *
506
- * @example
507
- * ```typescript
508
- * batch.deleteEntity('OldEntity');
509
- * ```
510
- */
511
- deleteEntity(name) {
512
- this.operations.push({ type: 'deleteEntity', data: { name } });
513
- return this;
514
- }
515
- /**
516
- * Add a create relation operation to the batch.
517
- *
518
- * @param relation - Relation to create (without timestamps)
519
- * @returns This BatchTransaction for chaining
520
- *
521
- * @example
522
- * ```typescript
523
- * batch.createRelation({
524
- * from: 'Alice',
525
- * to: 'Bob',
526
- * relationType: 'mentors'
527
- * });
528
- * ```
529
- */
530
- createRelation(relation) {
531
- this.operations.push({ type: 'createRelation', data: relation });
532
- return this;
533
- }
534
- /**
535
- * Add a delete relation operation to the batch.
536
- *
537
- * @param from - Source entity name
538
- * @param to - Target entity name
539
- * @param relationType - Type of relation
540
- * @returns This BatchTransaction for chaining
541
- *
542
- * @example
543
- * ```typescript
544
- * batch.deleteRelation('Alice', 'Bob', 'mentors');
545
- * ```
546
- */
547
- deleteRelation(from, to, relationType) {
548
- this.operations.push({ type: 'deleteRelation', data: { from, to, relationType } });
549
- return this;
550
- }
551
- /**
552
- * Add observations to an existing entity.
553
- *
554
- * @param name - Name of entity to add observations to
555
- * @param observations - Observations to add
556
- * @returns This BatchTransaction for chaining
557
- *
558
- * @example
559
- * ```typescript
560
- * batch.addObservations('Alice', ['Knows TypeScript', 'Leads team']);
561
- * ```
562
- */
563
- addObservations(name, observations) {
564
- this.operations.push({ type: 'addObservations', data: { name, observations } });
565
- return this;
566
- }
567
- /**
568
- * Delete observations from an existing entity.
569
- *
570
- * @param name - Name of entity to delete observations from
571
- * @param observations - Observations to delete
572
- * @returns This BatchTransaction for chaining
573
- *
574
- * @example
575
- * ```typescript
576
- * batch.deleteObservations('Alice', ['Old fact']);
577
- * ```
578
- */
579
- deleteObservations(name, observations) {
580
- this.operations.push({ type: 'deleteObservations', data: { name, observations } });
581
- return this;
582
- }
583
- /**
584
- * Add multiple operations from an array.
585
- *
586
- * @param operations - Array of batch operations
587
- * @returns This BatchTransaction for chaining
588
- *
589
- * @example
590
- * ```typescript
591
- * batch.addOperations([
592
- * { type: 'createEntity', data: { name: 'A', entityType: 'x', observations: [] } },
593
- * { type: 'createEntity', data: { name: 'B', entityType: 'x', observations: [] } }
594
- * ]);
595
- * ```
596
- */
597
- addOperations(operations) {
598
- this.operations.push(...operations);
599
- return this;
600
- }
601
- /**
602
- * Get the number of operations in this batch.
603
- *
604
- * @returns Number of operations queued
605
- */
606
- size() {
607
- return this.operations.length;
608
- }
609
- /**
610
- * Clear all operations from the batch.
611
- *
612
- * @returns This BatchTransaction for chaining
613
- */
614
- clear() {
615
- this.operations = [];
616
- return this;
617
- }
618
- /**
619
- * Get a copy of the operations in this batch.
620
- *
621
- * @returns Array of batch operations
622
- */
623
- getOperations() {
624
- return [...this.operations];
625
- }
626
- /**
627
- * Execute all operations in the batch atomically.
628
- *
629
- * All operations are applied within a single transaction. If any
630
- * operation fails, all changes are rolled back (when stopOnError is true).
631
- *
632
- * @param options - Batch execution options
633
- * @returns Promise resolving to batch result
634
- *
635
- * @example
636
- * ```typescript
637
- * const result = await batch.execute();
638
- * if (result.success) {
639
- * console.log(`Created ${result.entitiesCreated} entities`);
640
- * } else {
641
- * console.error(`Failed at operation ${result.failedOperationIndex}: ${result.error}`);
642
- * }
643
- * ```
644
- */
645
- async execute(options = {}) {
646
- const startTime = Date.now();
647
- const { stopOnError = true, validateBeforeExecute = true } = options;
648
- const result = {
649
- success: true,
650
- operationsExecuted: 0,
651
- entitiesCreated: 0,
652
- entitiesUpdated: 0,
653
- entitiesDeleted: 0,
654
- relationsCreated: 0,
655
- relationsDeleted: 0,
656
- executionTimeMs: 0,
657
- };
658
- if (this.operations.length === 0) {
659
- result.executionTimeMs = Date.now() - startTime;
660
- return result;
661
- }
662
- // Load graph for mutation
663
- const graph = await this.storage.getGraphForMutation();
664
- const timestamp = new Date().toISOString();
665
- // Optional: Validate all operations before executing
666
- if (validateBeforeExecute) {
667
- const validationError = this.validateOperations(graph);
668
- if (validationError) {
669
- return {
670
- ...result,
671
- success: false,
672
- error: validationError.message,
673
- failedOperationIndex: validationError.index,
674
- executionTimeMs: Date.now() - startTime,
675
- };
676
- }
677
- }
678
- // Execute operations
679
- for (let i = 0; i < this.operations.length; i++) {
680
- const operation = this.operations[i];
681
- try {
682
- this.applyBatchOperation(graph, operation, timestamp, result);
683
- result.operationsExecuted++;
684
- }
685
- catch (error) {
686
- result.success = false;
687
- result.error = error instanceof Error ? error.message : String(error);
688
- result.failedOperationIndex = i;
689
- if (stopOnError) {
690
- result.executionTimeMs = Date.now() - startTime;
691
- return result;
692
- }
693
- }
694
- }
695
- // Save the modified graph if successful (or if stopOnError is false)
696
- if (result.success || !stopOnError) {
697
- try {
698
- await this.storage.saveGraph(graph);
699
- }
700
- catch (error) {
701
- result.success = false;
702
- result.error = `Failed to save graph: ${error instanceof Error ? error.message : String(error)}`;
703
- }
704
- }
705
- result.executionTimeMs = Date.now() - startTime;
706
- return result;
707
- }
708
- /**
709
- * Validate all operations before executing.
710
- * @private
711
- */
712
- validateOperations(graph) {
713
- const entityNames = new Set(graph.entities.map(e => e.name));
714
- const pendingCreates = new Set();
715
- const pendingDeletes = new Set();
716
- for (let i = 0; i < this.operations.length; i++) {
717
- const op = this.operations[i];
718
- switch (op.type) {
719
- case 'createEntity': {
720
- const name = op.data.name;
721
- if (entityNames.has(name) && !pendingDeletes.has(name)) {
722
- return { message: `Entity "${name}" already exists`, index: i };
723
- }
724
- if (pendingCreates.has(name)) {
725
- return { message: `Duplicate create for entity "${name}" in batch`, index: i };
726
- }
727
- pendingCreates.add(name);
728
- break;
729
- }
730
- case 'updateEntity':
731
- case 'addObservations':
732
- case 'deleteObservations': {
733
- const name = op.data.name;
734
- const exists = (entityNames.has(name) || pendingCreates.has(name)) && !pendingDeletes.has(name);
735
- if (!exists) {
736
- return { message: `Entity "${name}" not found`, index: i };
737
- }
738
- break;
739
- }
740
- case 'deleteEntity': {
741
- const name = op.data.name;
742
- const exists = (entityNames.has(name) || pendingCreates.has(name)) && !pendingDeletes.has(name);
743
- if (!exists) {
744
- return { message: `Entity "${name}" not found for deletion`, index: i };
745
- }
746
- pendingDeletes.add(name);
747
- break;
748
- }
749
- case 'createRelation': {
750
- const { from, to } = op.data;
751
- const fromExists = (entityNames.has(from) || pendingCreates.has(from)) && !pendingDeletes.has(from);
752
- const toExists = (entityNames.has(to) || pendingCreates.has(to)) && !pendingDeletes.has(to);
753
- if (!fromExists) {
754
- return { message: `Source entity "${from}" not found for relation`, index: i };
755
- }
756
- if (!toExists) {
757
- return { message: `Target entity "${to}" not found for relation`, index: i };
758
- }
759
- break;
760
- }
761
- case 'deleteRelation': {
762
- // Relations are validated at execution time
763
- break;
764
- }
765
- }
766
- }
767
- return null;
768
- }
769
- /**
770
- * Apply a single batch operation to the graph.
771
- * @private
772
- */
773
- applyBatchOperation(graph, operation, timestamp, result) {
774
- switch (operation.type) {
775
- case 'createEntity': {
776
- const entity = {
777
- ...operation.data,
778
- createdAt: timestamp,
779
- lastModified: timestamp,
780
- };
781
- if (graph.entities.some(e => e.name === entity.name)) {
782
- throw new KnowledgeGraphError(`Entity "${entity.name}" already exists`, 'DUPLICATE_ENTITY');
783
- }
784
- graph.entities.push(entity);
785
- result.entitiesCreated++;
786
- break;
787
- }
788
- case 'updateEntity': {
789
- const { name, updates } = operation.data;
790
- const entity = graph.entities.find(e => e.name === name);
791
- if (!entity) {
792
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
793
- }
794
- // Sanitize updates to prevent prototype pollution
795
- Object.assign(entity, sanitizeObject(updates));
796
- entity.lastModified = timestamp;
797
- result.entitiesUpdated++;
798
- break;
799
- }
800
- case 'deleteEntity': {
801
- const { name } = operation.data;
802
- const index = graph.entities.findIndex(e => e.name === name);
803
- if (index === -1) {
804
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
805
- }
806
- graph.entities.splice(index, 1);
807
- // Delete related relations
808
- graph.relations = graph.relations.filter(r => r.from !== name && r.to !== name);
809
- result.entitiesDeleted++;
810
- break;
811
- }
812
- case 'createRelation': {
813
- const relation = {
814
- ...operation.data,
815
- createdAt: timestamp,
816
- lastModified: timestamp,
817
- };
818
- const exists = graph.relations.some(r => r.from === relation.from && r.to === relation.to && r.relationType === relation.relationType);
819
- if (exists) {
820
- throw new KnowledgeGraphError(`Relation "${relation.from}" -> "${relation.to}" (${relation.relationType}) already exists`, 'DUPLICATE_RELATION');
821
- }
822
- graph.relations.push(relation);
823
- result.relationsCreated++;
824
- break;
825
- }
826
- case 'deleteRelation': {
827
- const { from, to, relationType } = operation.data;
828
- const index = graph.relations.findIndex(r => r.from === from && r.to === to && r.relationType === relationType);
829
- if (index === -1) {
830
- throw new KnowledgeGraphError(`Relation "${from}" -> "${to}" (${relationType}) not found`, 'RELATION_NOT_FOUND');
831
- }
832
- graph.relations.splice(index, 1);
833
- result.relationsDeleted++;
834
- break;
835
- }
836
- case 'addObservations': {
837
- const { name, observations } = operation.data;
838
- const entity = graph.entities.find(e => e.name === name);
839
- if (!entity) {
840
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
841
- }
842
- // Add only new observations
843
- const existingSet = new Set(entity.observations);
844
- const newObs = observations.filter((o) => !existingSet.has(o));
845
- entity.observations.push(...newObs);
846
- entity.lastModified = timestamp;
847
- result.entitiesUpdated++;
848
- break;
849
- }
850
- case 'deleteObservations': {
851
- const { name, observations } = operation.data;
852
- const entity = graph.entities.find(e => e.name === name);
853
- if (!entity) {
854
- throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
855
- }
856
- const toDelete = new Set(observations);
857
- entity.observations = entity.observations.filter((o) => !toDelete.has(o));
858
- entity.lastModified = timestamp;
859
- result.entitiesUpdated++;
860
- break;
861
- }
862
- default: {
863
- const _exhaustiveCheck = operation;
864
- throw new KnowledgeGraphError(`Unknown batch operation type: ${_exhaustiveCheck.type}`, 'UNKNOWN_OPERATION');
865
- }
866
- }
867
- }
868
- }
869
- //# sourceMappingURL=TransactionManager.js.map