@danielsimonjr/memory-mcp 0.48.0 → 9.8.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 (209) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +2000 -194
  3. package/dist/__tests__/file-path.test.js +7 -11
  4. package/dist/__tests__/knowledge-graph.test.js +3 -8
  5. package/dist/core/EntityManager.d.ts +266 -0
  6. package/dist/core/EntityManager.d.ts.map +1 -0
  7. package/dist/core/EntityManager.js +85 -133
  8. package/dist/core/GraphEventEmitter.d.ts +202 -0
  9. package/dist/core/GraphEventEmitter.d.ts.map +1 -0
  10. package/dist/core/GraphEventEmitter.js +346 -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 +643 -31
  14. package/dist/core/GraphTraversal.d.ts +141 -0
  15. package/dist/core/GraphTraversal.d.ts.map +1 -0
  16. package/dist/core/GraphTraversal.js +573 -0
  17. package/dist/core/HierarchyManager.d.ts +111 -0
  18. package/dist/core/HierarchyManager.d.ts.map +1 -0
  19. package/dist/{features → core}/HierarchyManager.js +14 -9
  20. package/dist/core/ManagerContext.d.ts +72 -0
  21. package/dist/core/ManagerContext.d.ts.map +1 -0
  22. package/dist/core/ManagerContext.js +118 -0
  23. package/dist/core/ObservationManager.d.ts +85 -0
  24. package/dist/core/ObservationManager.d.ts.map +1 -0
  25. package/dist/core/ObservationManager.js +51 -57
  26. package/dist/core/RelationManager.d.ts +131 -0
  27. package/dist/core/RelationManager.d.ts.map +1 -0
  28. package/dist/core/RelationManager.js +31 -7
  29. package/dist/core/SQLiteStorage.d.ts +354 -0
  30. package/dist/core/SQLiteStorage.d.ts.map +1 -0
  31. package/dist/core/SQLiteStorage.js +917 -0
  32. package/dist/core/StorageFactory.d.ts +45 -0
  33. package/dist/core/StorageFactory.d.ts.map +1 -0
  34. package/dist/core/StorageFactory.js +64 -0
  35. package/dist/core/TransactionManager.d.ts +464 -0
  36. package/dist/core/TransactionManager.d.ts.map +1 -0
  37. package/dist/core/TransactionManager.js +490 -13
  38. package/dist/core/index.d.ts +17 -0
  39. package/dist/core/index.d.ts.map +1 -0
  40. package/dist/core/index.js +12 -2
  41. package/dist/features/AnalyticsManager.d.ts +44 -0
  42. package/dist/features/AnalyticsManager.d.ts.map +1 -0
  43. package/dist/features/AnalyticsManager.js +3 -2
  44. package/dist/features/ArchiveManager.d.ts +133 -0
  45. package/dist/features/ArchiveManager.d.ts.map +1 -0
  46. package/dist/features/ArchiveManager.js +221 -14
  47. package/dist/features/CompressionManager.d.ts +117 -0
  48. package/dist/features/CompressionManager.d.ts.map +1 -0
  49. package/dist/features/CompressionManager.js +189 -20
  50. package/dist/features/IOManager.d.ts +225 -0
  51. package/dist/features/IOManager.d.ts.map +1 -0
  52. package/dist/features/IOManager.js +1041 -0
  53. package/dist/features/StreamingExporter.d.ts +123 -0
  54. package/dist/features/StreamingExporter.d.ts.map +1 -0
  55. package/dist/features/StreamingExporter.js +203 -0
  56. package/dist/features/TagManager.d.ts +147 -0
  57. package/dist/features/TagManager.d.ts.map +1 -0
  58. package/dist/features/index.d.ts +12 -0
  59. package/dist/features/index.d.ts.map +1 -0
  60. package/dist/features/index.js +5 -6
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +10 -10
  64. package/dist/memory.jsonl +1 -26
  65. package/dist/search/BasicSearch.d.ts +51 -0
  66. package/dist/search/BasicSearch.d.ts.map +1 -0
  67. package/dist/search/BasicSearch.js +9 -3
  68. package/dist/search/BooleanSearch.d.ts +98 -0
  69. package/dist/search/BooleanSearch.d.ts.map +1 -0
  70. package/dist/search/BooleanSearch.js +156 -9
  71. package/dist/search/EmbeddingService.d.ts +178 -0
  72. package/dist/search/EmbeddingService.d.ts.map +1 -0
  73. package/dist/search/EmbeddingService.js +358 -0
  74. package/dist/search/FuzzySearch.d.ts +118 -0
  75. package/dist/search/FuzzySearch.d.ts.map +1 -0
  76. package/dist/search/FuzzySearch.js +241 -25
  77. package/dist/search/QueryCostEstimator.d.ts +111 -0
  78. package/dist/search/QueryCostEstimator.d.ts.map +1 -0
  79. package/dist/search/QueryCostEstimator.js +355 -0
  80. package/dist/search/RankedSearch.d.ts +71 -0
  81. package/dist/search/RankedSearch.d.ts.map +1 -0
  82. package/dist/search/RankedSearch.js +54 -6
  83. package/dist/search/SavedSearchManager.d.ts +79 -0
  84. package/dist/search/SavedSearchManager.d.ts.map +1 -0
  85. package/dist/search/SearchFilterChain.d.ts +120 -0
  86. package/dist/search/SearchFilterChain.d.ts.map +1 -0
  87. package/dist/search/SearchFilterChain.js +2 -4
  88. package/dist/search/SearchManager.d.ts +326 -0
  89. package/dist/search/SearchManager.d.ts.map +1 -0
  90. package/dist/search/SearchManager.js +148 -0
  91. package/dist/search/SearchSuggestions.d.ts +27 -0
  92. package/dist/search/SearchSuggestions.d.ts.map +1 -0
  93. package/dist/search/SearchSuggestions.js +1 -1
  94. package/dist/search/SemanticSearch.d.ts +149 -0
  95. package/dist/search/SemanticSearch.d.ts.map +1 -0
  96. package/dist/search/SemanticSearch.js +323 -0
  97. package/dist/search/TFIDFEventSync.d.ts +85 -0
  98. package/dist/search/TFIDFEventSync.d.ts.map +1 -0
  99. package/dist/search/TFIDFEventSync.js +133 -0
  100. package/dist/search/TFIDFIndexManager.d.ts +151 -0
  101. package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
  102. package/dist/search/TFIDFIndexManager.js +232 -17
  103. package/dist/search/VectorStore.d.ts +235 -0
  104. package/dist/search/VectorStore.d.ts.map +1 -0
  105. package/dist/search/VectorStore.js +311 -0
  106. package/dist/search/index.d.ts +21 -0
  107. package/dist/search/index.d.ts.map +1 -0
  108. package/dist/search/index.js +12 -0
  109. package/dist/server/MCPServer.d.ts +21 -0
  110. package/dist/server/MCPServer.d.ts.map +1 -0
  111. package/dist/server/MCPServer.js +4 -4
  112. package/dist/server/responseCompressor.d.ts +94 -0
  113. package/dist/server/responseCompressor.d.ts.map +1 -0
  114. package/dist/server/responseCompressor.js +127 -0
  115. package/dist/server/toolDefinitions.d.ts +27 -0
  116. package/dist/server/toolDefinitions.d.ts.map +1 -0
  117. package/dist/server/toolDefinitions.js +188 -17
  118. package/dist/server/toolHandlers.d.ts +41 -0
  119. package/dist/server/toolHandlers.d.ts.map +1 -0
  120. package/dist/server/toolHandlers.js +467 -75
  121. package/dist/types/index.d.ts +13 -0
  122. package/dist/types/index.d.ts.map +1 -0
  123. package/dist/types/index.js +1 -1
  124. package/dist/types/types.d.ts +1654 -0
  125. package/dist/types/types.d.ts.map +1 -0
  126. package/dist/types/types.js +9 -0
  127. package/dist/utils/compressedCache.d.ts +192 -0
  128. package/dist/utils/compressedCache.d.ts.map +1 -0
  129. package/dist/utils/compressedCache.js +309 -0
  130. package/dist/utils/compressionUtil.d.ts +214 -0
  131. package/dist/utils/compressionUtil.d.ts.map +1 -0
  132. package/dist/utils/compressionUtil.js +247 -0
  133. package/dist/utils/constants.d.ts +245 -0
  134. package/dist/utils/constants.d.ts.map +1 -0
  135. package/dist/utils/constants.js +124 -0
  136. package/dist/utils/entityUtils.d.ts +321 -0
  137. package/dist/utils/entityUtils.d.ts.map +1 -0
  138. package/dist/utils/entityUtils.js +434 -4
  139. package/dist/utils/errors.d.ts +95 -0
  140. package/dist/utils/errors.d.ts.map +1 -0
  141. package/dist/utils/errors.js +24 -0
  142. package/dist/utils/formatters.d.ts +145 -0
  143. package/dist/utils/formatters.d.ts.map +1 -0
  144. package/dist/utils/{paginationUtils.js → formatters.js} +54 -3
  145. package/dist/utils/index.d.ts +23 -0
  146. package/dist/utils/index.d.ts.map +1 -0
  147. package/dist/utils/index.js +69 -31
  148. package/dist/utils/indexes.d.ts +270 -0
  149. package/dist/utils/indexes.d.ts.map +1 -0
  150. package/dist/utils/indexes.js +526 -0
  151. package/dist/utils/logger.d.ts +24 -0
  152. package/dist/utils/logger.d.ts.map +1 -0
  153. package/dist/utils/operationUtils.d.ts +124 -0
  154. package/dist/utils/operationUtils.d.ts.map +1 -0
  155. package/dist/utils/operationUtils.js +175 -0
  156. package/dist/utils/parallelUtils.d.ts +72 -0
  157. package/dist/utils/parallelUtils.d.ts.map +1 -0
  158. package/dist/utils/parallelUtils.js +169 -0
  159. package/dist/utils/schemas.d.ts +374 -0
  160. package/dist/utils/schemas.d.ts.map +1 -0
  161. package/dist/utils/schemas.js +302 -2
  162. package/dist/utils/searchAlgorithms.d.ts +99 -0
  163. package/dist/utils/searchAlgorithms.d.ts.map +1 -0
  164. package/dist/utils/searchAlgorithms.js +167 -0
  165. package/dist/utils/searchCache.d.ts +108 -0
  166. package/dist/utils/searchCache.d.ts.map +1 -0
  167. package/dist/utils/taskScheduler.d.ts +290 -0
  168. package/dist/utils/taskScheduler.d.ts.map +1 -0
  169. package/dist/utils/taskScheduler.js +466 -0
  170. package/dist/workers/index.d.ts +12 -0
  171. package/dist/workers/index.d.ts.map +1 -0
  172. package/dist/workers/index.js +9 -0
  173. package/dist/workers/levenshteinWorker.d.ts +60 -0
  174. package/dist/workers/levenshteinWorker.d.ts.map +1 -0
  175. package/dist/workers/levenshteinWorker.js +98 -0
  176. package/package.json +17 -4
  177. package/dist/__tests__/edge-cases/edge-cases.test.js +0 -406
  178. package/dist/__tests__/integration/workflows.test.js +0 -449
  179. package/dist/__tests__/performance/benchmarks.test.js +0 -413
  180. package/dist/__tests__/unit/core/EntityManager.test.js +0 -334
  181. package/dist/__tests__/unit/core/GraphStorage.test.js +0 -205
  182. package/dist/__tests__/unit/core/RelationManager.test.js +0 -274
  183. package/dist/__tests__/unit/features/CompressionManager.test.js +0 -350
  184. package/dist/__tests__/unit/search/BasicSearch.test.js +0 -311
  185. package/dist/__tests__/unit/search/BooleanSearch.test.js +0 -432
  186. package/dist/__tests__/unit/search/FuzzySearch.test.js +0 -448
  187. package/dist/__tests__/unit/search/RankedSearch.test.js +0 -379
  188. package/dist/__tests__/unit/utils/levenshtein.test.js +0 -77
  189. package/dist/core/KnowledgeGraphManager.js +0 -423
  190. package/dist/features/BackupManager.js +0 -311
  191. package/dist/features/ExportManager.js +0 -305
  192. package/dist/features/ImportExportManager.js +0 -50
  193. package/dist/features/ImportManager.js +0 -328
  194. package/dist/memory-saved-searches.jsonl +0 -0
  195. package/dist/memory-tag-aliases.jsonl +0 -0
  196. package/dist/types/analytics.types.js +0 -6
  197. package/dist/types/entity.types.js +0 -7
  198. package/dist/types/import-export.types.js +0 -7
  199. package/dist/types/search.types.js +0 -7
  200. package/dist/types/tag.types.js +0 -6
  201. package/dist/utils/dateUtils.js +0 -89
  202. package/dist/utils/filterUtils.js +0 -155
  203. package/dist/utils/levenshtein.js +0 -62
  204. package/dist/utils/pathUtils.js +0 -115
  205. package/dist/utils/responseFormatter.js +0 -55
  206. package/dist/utils/tagUtils.js +0 -107
  207. package/dist/utils/tfidf.js +0 -90
  208. package/dist/utils/validationHelper.js +0 -99
  209. package/dist/utils/validationUtils.js +0 -109
@@ -7,8 +7,9 @@
7
7
  *
8
8
  * @module core/TransactionManager
9
9
  */
10
- import { BackupManager } from '../features/BackupManager.js';
10
+ import { IOManager } from '../features/IOManager.js';
11
11
  import { KnowledgeGraphError } from '../utils/errors.js';
12
+ import { checkCancellation, createProgressReporter, createProgress } from '../utils/index.js';
12
13
  /**
13
14
  * Types of operations that can be performed in a transaction.
14
15
  */
@@ -52,11 +53,11 @@ export class TransactionManager {
52
53
  storage;
53
54
  operations = [];
54
55
  inTransaction = false;
55
- backupManager;
56
+ ioManager;
56
57
  transactionBackup;
57
58
  constructor(storage) {
58
59
  this.storage = storage;
59
- this.backupManager = new BackupManager(storage);
60
+ this.ioManager = new IOManager(storage);
60
61
  }
61
62
  /**
62
63
  * Begin a new transaction.
@@ -191,7 +192,11 @@ export class TransactionManager {
191
192
  * Creates a backup before applying changes. If any operation fails,
192
193
  * automatically rolls back to the pre-transaction state.
193
194
  *
195
+ * Phase 9B: Supports progress tracking and cancellation via LongRunningOperationOptions.
196
+ *
197
+ * @param options - Optional progress/cancellation options (Phase 9B)
194
198
  * @returns Promise resolving to transaction result
199
+ * @throws {OperationCancelledError} If operation is cancelled via signal (Phase 9B)
195
200
  *
196
201
  * @example
197
202
  * ```typescript
@@ -205,32 +210,63 @@ export class TransactionManager {
205
210
  * } else {
206
211
  * console.error(`Transaction failed: ${result.error}`);
207
212
  * }
213
+ *
214
+ * // With progress tracking (Phase 9B)
215
+ * const result = await txManager.commit({
216
+ * onProgress: (p) => console.log(`${p.percentage}% complete`),
217
+ * });
208
218
  * ```
209
219
  */
210
- async commit() {
220
+ async commit(options) {
211
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'));
212
226
  try {
213
- // Create backup for rollback
214
- this.transactionBackup = await this.backupManager.createBackup('Transaction backup (auto-created)');
215
- // Load current graph
216
- const graph = await this.storage.loadGraph();
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();
217
241
  const timestamp = new Date().toISOString();
218
- // Apply all operations
242
+ reportProgress?.(createProgress(30, 100, 'graph loaded'));
243
+ // Phase 3: Apply all operations (30-80% progress)
219
244
  let operationsExecuted = 0;
220
245
  for (const operation of this.operations) {
246
+ // Check for cancellation between operations
247
+ checkCancellation(options?.signal, 'commit');
221
248
  this.applyOperation(graph, operation, timestamp);
222
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'));
223
253
  }
224
- // Save the modified graph
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'));
225
258
  await this.storage.saveGraph(graph);
259
+ reportProgress?.(createProgress(95, 100, 'graph saved'));
226
260
  // Clean up transaction state
227
261
  this.inTransaction = false;
228
262
  this.operations = [];
229
263
  // Delete the transaction backup (no longer needed)
230
264
  if (this.transactionBackup) {
231
- await this.backupManager.deleteBackup(this.transactionBackup);
265
+ await this.ioManager.deleteBackup(this.transactionBackup);
232
266
  this.transactionBackup = undefined;
233
267
  }
268
+ // Report completion
269
+ reportProgress?.(createProgress(100, 100, 'commit'));
234
270
  return {
235
271
  success: true,
236
272
  operationsExecuted,
@@ -273,10 +309,10 @@ export class TransactionManager {
273
309
  }
274
310
  try {
275
311
  // Restore from backup
276
- await this.backupManager.restoreFromBackup(this.transactionBackup);
312
+ await this.ioManager.restoreFromBackup(this.transactionBackup);
277
313
  // Clean up
278
314
  const backupUsed = this.transactionBackup;
279
- await this.backupManager.deleteBackup(this.transactionBackup);
315
+ await this.ioManager.deleteBackup(this.transactionBackup);
280
316
  this.inTransaction = false;
281
317
  this.operations = [];
282
318
  this.transactionBackup = undefined;
@@ -387,3 +423,444 @@ export class TransactionManager {
387
423
  }
388
424
  }
389
425
  }
426
+ // ==================== Phase 10 Sprint 1: BatchTransaction ====================
427
+ /**
428
+ * Phase 10 Sprint 1: Fluent API for building and executing batch transactions.
429
+ *
430
+ * BatchTransaction provides a builder pattern for accumulating multiple
431
+ * graph operations and executing them atomically in a single transaction.
432
+ * This reduces I/O overhead and ensures consistency across related changes.
433
+ *
434
+ * @example
435
+ * ```typescript
436
+ * const storage = new GraphStorage('/data/memory.jsonl');
437
+ * const batch = new BatchTransaction(storage);
438
+ *
439
+ * // Build the batch with fluent API
440
+ * const result = await batch
441
+ * .createEntity({ name: 'Alice', entityType: 'person', observations: ['Developer'] })
442
+ * .createEntity({ name: 'Bob', entityType: 'person', observations: ['Designer'] })
443
+ * .createRelation({ from: 'Alice', to: 'Bob', relationType: 'knows' })
444
+ * .updateEntity('Alice', { importance: 8 })
445
+ * .execute();
446
+ *
447
+ * if (result.success) {
448
+ * console.log(`Batch completed: ${result.operationsExecuted} operations in ${result.executionTimeMs}ms`);
449
+ * }
450
+ * ```
451
+ */
452
+ export class BatchTransaction {
453
+ operations = [];
454
+ storage;
455
+ /**
456
+ * Create a new BatchTransaction instance.
457
+ *
458
+ * @param storage - GraphStorage instance to execute operations against
459
+ */
460
+ constructor(storage) {
461
+ this.storage = storage;
462
+ }
463
+ /**
464
+ * Add a create entity operation to the batch.
465
+ *
466
+ * @param entity - Entity to create (without timestamps)
467
+ * @returns This BatchTransaction for chaining
468
+ *
469
+ * @example
470
+ * ```typescript
471
+ * batch.createEntity({
472
+ * name: 'Alice',
473
+ * entityType: 'person',
474
+ * observations: ['Software engineer'],
475
+ * importance: 8
476
+ * });
477
+ * ```
478
+ */
479
+ createEntity(entity) {
480
+ this.operations.push({ type: 'createEntity', data: entity });
481
+ return this;
482
+ }
483
+ /**
484
+ * Add an update entity operation to the batch.
485
+ *
486
+ * @param name - Name of entity to update
487
+ * @param updates - Partial entity updates
488
+ * @returns This BatchTransaction for chaining
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * batch.updateEntity('Alice', { importance: 9 });
493
+ * ```
494
+ */
495
+ updateEntity(name, updates) {
496
+ this.operations.push({ type: 'updateEntity', data: { name, updates } });
497
+ return this;
498
+ }
499
+ /**
500
+ * Add a delete entity operation to the batch.
501
+ *
502
+ * @param name - Name of entity to delete
503
+ * @returns This BatchTransaction for chaining
504
+ *
505
+ * @example
506
+ * ```typescript
507
+ * batch.deleteEntity('OldEntity');
508
+ * ```
509
+ */
510
+ deleteEntity(name) {
511
+ this.operations.push({ type: 'deleteEntity', data: { name } });
512
+ return this;
513
+ }
514
+ /**
515
+ * Add a create relation operation to the batch.
516
+ *
517
+ * @param relation - Relation to create (without timestamps)
518
+ * @returns This BatchTransaction for chaining
519
+ *
520
+ * @example
521
+ * ```typescript
522
+ * batch.createRelation({
523
+ * from: 'Alice',
524
+ * to: 'Bob',
525
+ * relationType: 'mentors'
526
+ * });
527
+ * ```
528
+ */
529
+ createRelation(relation) {
530
+ this.operations.push({ type: 'createRelation', data: relation });
531
+ return this;
532
+ }
533
+ /**
534
+ * Add a delete relation operation to the batch.
535
+ *
536
+ * @param from - Source entity name
537
+ * @param to - Target entity name
538
+ * @param relationType - Type of relation
539
+ * @returns This BatchTransaction for chaining
540
+ *
541
+ * @example
542
+ * ```typescript
543
+ * batch.deleteRelation('Alice', 'Bob', 'mentors');
544
+ * ```
545
+ */
546
+ deleteRelation(from, to, relationType) {
547
+ this.operations.push({ type: 'deleteRelation', data: { from, to, relationType } });
548
+ return this;
549
+ }
550
+ /**
551
+ * Add observations to an existing entity.
552
+ *
553
+ * @param name - Name of entity to add observations to
554
+ * @param observations - Observations to add
555
+ * @returns This BatchTransaction for chaining
556
+ *
557
+ * @example
558
+ * ```typescript
559
+ * batch.addObservations('Alice', ['Knows TypeScript', 'Leads team']);
560
+ * ```
561
+ */
562
+ addObservations(name, observations) {
563
+ this.operations.push({ type: 'addObservations', data: { name, observations } });
564
+ return this;
565
+ }
566
+ /**
567
+ * Delete observations from an existing entity.
568
+ *
569
+ * @param name - Name of entity to delete observations from
570
+ * @param observations - Observations to delete
571
+ * @returns This BatchTransaction for chaining
572
+ *
573
+ * @example
574
+ * ```typescript
575
+ * batch.deleteObservations('Alice', ['Old fact']);
576
+ * ```
577
+ */
578
+ deleteObservations(name, observations) {
579
+ this.operations.push({ type: 'deleteObservations', data: { name, observations } });
580
+ return this;
581
+ }
582
+ /**
583
+ * Add multiple operations from an array.
584
+ *
585
+ * @param operations - Array of batch operations
586
+ * @returns This BatchTransaction for chaining
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * batch.addOperations([
591
+ * { type: 'createEntity', data: { name: 'A', entityType: 'x', observations: [] } },
592
+ * { type: 'createEntity', data: { name: 'B', entityType: 'x', observations: [] } }
593
+ * ]);
594
+ * ```
595
+ */
596
+ addOperations(operations) {
597
+ this.operations.push(...operations);
598
+ return this;
599
+ }
600
+ /**
601
+ * Get the number of operations in this batch.
602
+ *
603
+ * @returns Number of operations queued
604
+ */
605
+ size() {
606
+ return this.operations.length;
607
+ }
608
+ /**
609
+ * Clear all operations from the batch.
610
+ *
611
+ * @returns This BatchTransaction for chaining
612
+ */
613
+ clear() {
614
+ this.operations = [];
615
+ return this;
616
+ }
617
+ /**
618
+ * Get a copy of the operations in this batch.
619
+ *
620
+ * @returns Array of batch operations
621
+ */
622
+ getOperations() {
623
+ return [...this.operations];
624
+ }
625
+ /**
626
+ * Execute all operations in the batch atomically.
627
+ *
628
+ * All operations are applied within a single transaction. If any
629
+ * operation fails, all changes are rolled back (when stopOnError is true).
630
+ *
631
+ * @param options - Batch execution options
632
+ * @returns Promise resolving to batch result
633
+ *
634
+ * @example
635
+ * ```typescript
636
+ * const result = await batch.execute();
637
+ * if (result.success) {
638
+ * console.log(`Created ${result.entitiesCreated} entities`);
639
+ * } else {
640
+ * console.error(`Failed at operation ${result.failedOperationIndex}: ${result.error}`);
641
+ * }
642
+ * ```
643
+ */
644
+ async execute(options = {}) {
645
+ const startTime = Date.now();
646
+ const { stopOnError = true, validateBeforeExecute = true } = options;
647
+ const result = {
648
+ success: true,
649
+ operationsExecuted: 0,
650
+ entitiesCreated: 0,
651
+ entitiesUpdated: 0,
652
+ entitiesDeleted: 0,
653
+ relationsCreated: 0,
654
+ relationsDeleted: 0,
655
+ executionTimeMs: 0,
656
+ };
657
+ if (this.operations.length === 0) {
658
+ result.executionTimeMs = Date.now() - startTime;
659
+ return result;
660
+ }
661
+ // Load graph for mutation
662
+ const graph = await this.storage.getGraphForMutation();
663
+ const timestamp = new Date().toISOString();
664
+ // Optional: Validate all operations before executing
665
+ if (validateBeforeExecute) {
666
+ const validationError = this.validateOperations(graph);
667
+ if (validationError) {
668
+ return {
669
+ ...result,
670
+ success: false,
671
+ error: validationError.message,
672
+ failedOperationIndex: validationError.index,
673
+ executionTimeMs: Date.now() - startTime,
674
+ };
675
+ }
676
+ }
677
+ // Execute operations
678
+ for (let i = 0; i < this.operations.length; i++) {
679
+ const operation = this.operations[i];
680
+ try {
681
+ this.applyBatchOperation(graph, operation, timestamp, result);
682
+ result.operationsExecuted++;
683
+ }
684
+ catch (error) {
685
+ result.success = false;
686
+ result.error = error instanceof Error ? error.message : String(error);
687
+ result.failedOperationIndex = i;
688
+ if (stopOnError) {
689
+ result.executionTimeMs = Date.now() - startTime;
690
+ return result;
691
+ }
692
+ }
693
+ }
694
+ // Save the modified graph if successful (or if stopOnError is false)
695
+ if (result.success || !stopOnError) {
696
+ try {
697
+ await this.storage.saveGraph(graph);
698
+ }
699
+ catch (error) {
700
+ result.success = false;
701
+ result.error = `Failed to save graph: ${error instanceof Error ? error.message : String(error)}`;
702
+ }
703
+ }
704
+ result.executionTimeMs = Date.now() - startTime;
705
+ return result;
706
+ }
707
+ /**
708
+ * Validate all operations before executing.
709
+ * @private
710
+ */
711
+ validateOperations(graph) {
712
+ const entityNames = new Set(graph.entities.map(e => e.name));
713
+ const pendingCreates = new Set();
714
+ const pendingDeletes = new Set();
715
+ for (let i = 0; i < this.operations.length; i++) {
716
+ const op = this.operations[i];
717
+ switch (op.type) {
718
+ case 'createEntity': {
719
+ const name = op.data.name;
720
+ if (entityNames.has(name) && !pendingDeletes.has(name)) {
721
+ return { message: `Entity "${name}" already exists`, index: i };
722
+ }
723
+ if (pendingCreates.has(name)) {
724
+ return { message: `Duplicate create for entity "${name}" in batch`, index: i };
725
+ }
726
+ pendingCreates.add(name);
727
+ break;
728
+ }
729
+ case 'updateEntity':
730
+ case 'addObservations':
731
+ case 'deleteObservations': {
732
+ const name = op.data.name;
733
+ const exists = (entityNames.has(name) || pendingCreates.has(name)) && !pendingDeletes.has(name);
734
+ if (!exists) {
735
+ return { message: `Entity "${name}" not found`, index: i };
736
+ }
737
+ break;
738
+ }
739
+ case 'deleteEntity': {
740
+ const name = op.data.name;
741
+ const exists = (entityNames.has(name) || pendingCreates.has(name)) && !pendingDeletes.has(name);
742
+ if (!exists) {
743
+ return { message: `Entity "${name}" not found for deletion`, index: i };
744
+ }
745
+ pendingDeletes.add(name);
746
+ break;
747
+ }
748
+ case 'createRelation': {
749
+ const { from, to } = op.data;
750
+ const fromExists = (entityNames.has(from) || pendingCreates.has(from)) && !pendingDeletes.has(from);
751
+ const toExists = (entityNames.has(to) || pendingCreates.has(to)) && !pendingDeletes.has(to);
752
+ if (!fromExists) {
753
+ return { message: `Source entity "${from}" not found for relation`, index: i };
754
+ }
755
+ if (!toExists) {
756
+ return { message: `Target entity "${to}" not found for relation`, index: i };
757
+ }
758
+ break;
759
+ }
760
+ case 'deleteRelation': {
761
+ // Relations are validated at execution time
762
+ break;
763
+ }
764
+ }
765
+ }
766
+ return null;
767
+ }
768
+ /**
769
+ * Apply a single batch operation to the graph.
770
+ * @private
771
+ */
772
+ applyBatchOperation(graph, operation, timestamp, result) {
773
+ switch (operation.type) {
774
+ case 'createEntity': {
775
+ const entity = {
776
+ ...operation.data,
777
+ createdAt: timestamp,
778
+ lastModified: timestamp,
779
+ };
780
+ if (graph.entities.some(e => e.name === entity.name)) {
781
+ throw new KnowledgeGraphError(`Entity "${entity.name}" already exists`, 'DUPLICATE_ENTITY');
782
+ }
783
+ graph.entities.push(entity);
784
+ result.entitiesCreated++;
785
+ break;
786
+ }
787
+ case 'updateEntity': {
788
+ const { name, updates } = operation.data;
789
+ const entity = graph.entities.find(e => e.name === name);
790
+ if (!entity) {
791
+ throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
792
+ }
793
+ Object.assign(entity, updates);
794
+ entity.lastModified = timestamp;
795
+ result.entitiesUpdated++;
796
+ break;
797
+ }
798
+ case 'deleteEntity': {
799
+ const { name } = operation.data;
800
+ const index = graph.entities.findIndex(e => e.name === name);
801
+ if (index === -1) {
802
+ throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
803
+ }
804
+ graph.entities.splice(index, 1);
805
+ // Delete related relations
806
+ graph.relations = graph.relations.filter(r => r.from !== name && r.to !== name);
807
+ result.entitiesDeleted++;
808
+ break;
809
+ }
810
+ case 'createRelation': {
811
+ const relation = {
812
+ ...operation.data,
813
+ createdAt: timestamp,
814
+ lastModified: timestamp,
815
+ };
816
+ const exists = graph.relations.some(r => r.from === relation.from && r.to === relation.to && r.relationType === relation.relationType);
817
+ if (exists) {
818
+ throw new KnowledgeGraphError(`Relation "${relation.from}" -> "${relation.to}" (${relation.relationType}) already exists`, 'DUPLICATE_RELATION');
819
+ }
820
+ graph.relations.push(relation);
821
+ result.relationsCreated++;
822
+ break;
823
+ }
824
+ case 'deleteRelation': {
825
+ const { from, to, relationType } = operation.data;
826
+ const index = graph.relations.findIndex(r => r.from === from && r.to === to && r.relationType === relationType);
827
+ if (index === -1) {
828
+ throw new KnowledgeGraphError(`Relation "${from}" -> "${to}" (${relationType}) not found`, 'RELATION_NOT_FOUND');
829
+ }
830
+ graph.relations.splice(index, 1);
831
+ result.relationsDeleted++;
832
+ break;
833
+ }
834
+ case 'addObservations': {
835
+ const { name, observations } = operation.data;
836
+ const entity = graph.entities.find(e => e.name === name);
837
+ if (!entity) {
838
+ throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
839
+ }
840
+ // Add only new observations
841
+ const existingSet = new Set(entity.observations);
842
+ const newObs = observations.filter((o) => !existingSet.has(o));
843
+ entity.observations.push(...newObs);
844
+ entity.lastModified = timestamp;
845
+ result.entitiesUpdated++;
846
+ break;
847
+ }
848
+ case 'deleteObservations': {
849
+ const { name, observations } = operation.data;
850
+ const entity = graph.entities.find(e => e.name === name);
851
+ if (!entity) {
852
+ throw new KnowledgeGraphError(`Entity "${name}" not found`, 'ENTITY_NOT_FOUND');
853
+ }
854
+ const toDelete = new Set(observations);
855
+ entity.observations = entity.observations.filter((o) => !toDelete.has(o));
856
+ entity.lastModified = timestamp;
857
+ result.entitiesUpdated++;
858
+ break;
859
+ }
860
+ default: {
861
+ const _exhaustiveCheck = operation;
862
+ throw new KnowledgeGraphError(`Unknown batch operation type: ${_exhaustiveCheck.type}`, 'UNKNOWN_OPERATION');
863
+ }
864
+ }
865
+ }
866
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Core Module Barrel Export
3
+ * Phase 4: Added ObservationManager, HierarchyManager, and GraphTraversal exports
4
+ */
5
+ export { GraphStorage } from './GraphStorage.js';
6
+ export { SQLiteStorage } from './SQLiteStorage.js';
7
+ export { EntityManager } from './EntityManager.js';
8
+ export { RelationManager } from './RelationManager.js';
9
+ export { ObservationManager } from './ObservationManager.js';
10
+ export { HierarchyManager } from './HierarchyManager.js';
11
+ export { ManagerContext } from './ManagerContext.js';
12
+ export { GraphTraversal } from './GraphTraversal.js';
13
+ export { ManagerContext as KnowledgeGraphManager } from './ManagerContext.js';
14
+ export { TransactionManager, OperationType, BatchTransaction, type TransactionOperation, type TransactionResult, } from './TransactionManager.js';
15
+ export { createStorage, createStorageFromPath } from './StorageFactory.js';
16
+ export { GraphEventEmitter } from './GraphEventEmitter.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,9 +1,19 @@
1
1
  /**
2
2
  * Core Module Barrel Export
3
+ * Phase 4: Added ObservationManager, HierarchyManager, and GraphTraversal exports
3
4
  */
4
5
  export { GraphStorage } from './GraphStorage.js';
6
+ export { SQLiteStorage } from './SQLiteStorage.js';
5
7
  export { EntityManager } from './EntityManager.js';
6
8
  export { RelationManager } from './RelationManager.js';
7
9
  export { ObservationManager } from './ObservationManager.js';
8
- export { KnowledgeGraphManager } from './KnowledgeGraphManager.js';
9
- export { TransactionManager, OperationType, } from './TransactionManager.js';
10
+ export { HierarchyManager } from './HierarchyManager.js';
11
+ export { ManagerContext } from './ManagerContext.js';
12
+ // Phase 4 Sprint 6-8: Graph traversal algorithms
13
+ export { GraphTraversal } from './GraphTraversal.js';
14
+ // Backward compatibility alias
15
+ export { ManagerContext as KnowledgeGraphManager } from './ManagerContext.js';
16
+ export { TransactionManager, OperationType, BatchTransaction, } from './TransactionManager.js';
17
+ export { createStorage, createStorageFromPath } from './StorageFactory.js';
18
+ // Phase 10 Sprint 2: Graph change events
19
+ export { GraphEventEmitter } from './GraphEventEmitter.js';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Analytics Manager
3
+ *
4
+ * Handles graph statistics and validation operations.
5
+ * Extracted from SearchManager (Phase 4: Consolidate God Objects).
6
+ *
7
+ * @module features/AnalyticsManager
8
+ */
9
+ import type { GraphStorage } from '../core/GraphStorage.js';
10
+ import type { GraphStats, ValidationReport } from '../types/index.js';
11
+ /**
12
+ * Manages analytics operations for the knowledge graph.
13
+ */
14
+ export declare class AnalyticsManager {
15
+ private storage;
16
+ constructor(storage: GraphStorage);
17
+ /**
18
+ * Validate the knowledge graph structure and data integrity.
19
+ *
20
+ * Checks for:
21
+ * - Orphaned relations (pointing to non-existent entities)
22
+ * - Duplicate entity names
23
+ * - Invalid entity data (missing name/type, invalid observations)
24
+ * - Isolated entities (no relations)
25
+ * - Empty observations
26
+ * - Missing metadata (createdAt, lastModified)
27
+ *
28
+ * @returns Validation report with errors, warnings, and summary
29
+ */
30
+ validateGraph(): Promise<ValidationReport>;
31
+ /**
32
+ * Get comprehensive statistics about the knowledge graph.
33
+ *
34
+ * Provides metrics including:
35
+ * - Total counts of entities and relations
36
+ * - Entity and relation type distributions
37
+ * - Oldest and newest entities/relations
38
+ * - Date ranges for entities and relations
39
+ *
40
+ * @returns Graph statistics object
41
+ */
42
+ getGraphStats(): Promise<GraphStats>;
43
+ }
44
+ //# sourceMappingURL=AnalyticsManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsManager.d.ts","sourceRoot":"","sources":["../../src/features/AnalyticsManager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAsC,MAAM,mBAAmB,CAAC;AAE1G;;GAEG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAEzC;;;;;;;;;;;;OAYG;IACG,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAmIhD;;;;;;;;;;OAUG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;CAsE3C"}
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * Analytics Manager
3
3
  *
4
- * Provides graph validation and analytics capabilities.
4
+ * Handles graph statistics and validation operations.
5
+ * Extracted from SearchManager (Phase 4: Consolidate God Objects).
5
6
  *
6
7
  * @module features/AnalyticsManager
7
8
  */
8
9
  /**
9
- * Performs validation and analytics on the knowledge graph.
10
+ * Manages analytics operations for the knowledge graph.
10
11
  */
11
12
  export class AnalyticsManager {
12
13
  storage;