@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.
- package/LICENSE +22 -0
- package/README.md +266 -0
- package/dist/core/EntityManager.d.ts +268 -0
- package/dist/core/EntityManager.d.ts.map +1 -0
- package/dist/core/EntityManager.js +512 -0
- package/dist/core/EntityManager.js.map +1 -0
- package/dist/core/GraphEventEmitter.d.ts +202 -0
- package/dist/core/GraphEventEmitter.d.ts.map +1 -0
- package/dist/core/GraphEventEmitter.js +347 -0
- package/dist/core/GraphEventEmitter.js.map +1 -0
- package/dist/core/GraphStorage.d.ts +395 -0
- package/dist/core/GraphStorage.d.ts.map +1 -0
- package/dist/core/GraphStorage.js +786 -0
- package/dist/core/GraphStorage.js.map +1 -0
- package/dist/core/GraphTraversal.d.ts +141 -0
- package/dist/core/GraphTraversal.d.ts.map +1 -0
- package/dist/core/GraphTraversal.js +574 -0
- package/dist/core/GraphTraversal.js.map +1 -0
- package/dist/core/HierarchyManager.d.ts +111 -0
- package/dist/core/HierarchyManager.d.ts.map +1 -0
- package/dist/core/HierarchyManager.js +225 -0
- package/dist/core/HierarchyManager.js.map +1 -0
- package/dist/core/ManagerContext.d.ts +76 -0
- package/dist/core/ManagerContext.d.ts.map +1 -0
- package/dist/core/ManagerContext.js +129 -0
- package/dist/core/ManagerContext.js.map +1 -0
- package/dist/core/ObservationManager.d.ts +85 -0
- package/dist/core/ObservationManager.d.ts.map +1 -0
- package/dist/core/ObservationManager.js +124 -0
- package/dist/core/ObservationManager.js.map +1 -0
- package/dist/core/RelationManager.d.ts +131 -0
- package/dist/core/RelationManager.d.ts.map +1 -0
- package/dist/core/RelationManager.js +212 -0
- package/dist/core/RelationManager.js.map +1 -0
- package/dist/core/SQLiteStorage.d.ts +354 -0
- package/dist/core/SQLiteStorage.d.ts.map +1 -0
- package/dist/core/SQLiteStorage.js +919 -0
- package/dist/core/SQLiteStorage.js.map +1 -0
- package/dist/core/StorageFactory.d.ts +45 -0
- package/dist/core/StorageFactory.d.ts.map +1 -0
- package/dist/core/StorageFactory.js +65 -0
- package/dist/core/StorageFactory.js.map +1 -0
- package/dist/core/TransactionManager.d.ts +464 -0
- package/dist/core/TransactionManager.d.ts.map +1 -0
- package/dist/core/TransactionManager.js +869 -0
- package/dist/core/TransactionManager.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/features/AnalyticsManager.d.ts +44 -0
- package/dist/features/AnalyticsManager.d.ts.map +1 -0
- package/dist/features/AnalyticsManager.js +224 -0
- package/dist/features/AnalyticsManager.js.map +1 -0
- package/dist/features/ArchiveManager.d.ts +133 -0
- package/dist/features/ArchiveManager.d.ts.map +1 -0
- package/dist/features/ArchiveManager.js +282 -0
- package/dist/features/ArchiveManager.js.map +1 -0
- package/dist/features/CompressionManager.d.ts +119 -0
- package/dist/features/CompressionManager.d.ts.map +1 -0
- package/dist/features/CompressionManager.js +470 -0
- package/dist/features/CompressionManager.js.map +1 -0
- package/dist/features/IOManager.d.ts +225 -0
- package/dist/features/IOManager.d.ts.map +1 -0
- package/dist/features/IOManager.js +1093 -0
- package/dist/features/IOManager.js.map +1 -0
- package/dist/features/KeywordExtractor.d.ts +61 -0
- package/dist/features/KeywordExtractor.d.ts.map +1 -0
- package/dist/features/KeywordExtractor.js +127 -0
- package/dist/features/KeywordExtractor.js.map +1 -0
- package/dist/features/ObservationNormalizer.d.ts +90 -0
- package/dist/features/ObservationNormalizer.d.ts.map +1 -0
- package/dist/features/ObservationNormalizer.js +194 -0
- package/dist/features/ObservationNormalizer.js.map +1 -0
- package/dist/features/StreamingExporter.d.ts +128 -0
- package/dist/features/StreamingExporter.d.ts.map +1 -0
- package/dist/features/StreamingExporter.js +212 -0
- package/dist/features/StreamingExporter.js.map +1 -0
- package/dist/features/TagManager.d.ts +147 -0
- package/dist/features/TagManager.d.ts.map +1 -0
- package/dist/features/TagManager.js +211 -0
- package/dist/features/TagManager.js.map +1 -0
- package/dist/features/index.d.ts +14 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +15 -0
- package/dist/features/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/search/BM25Search.d.ts +148 -0
- package/dist/search/BM25Search.d.ts.map +1 -0
- package/dist/search/BM25Search.js +340 -0
- package/dist/search/BM25Search.js.map +1 -0
- package/dist/search/BasicSearch.d.ts +51 -0
- package/dist/search/BasicSearch.d.ts.map +1 -0
- package/dist/search/BasicSearch.js +138 -0
- package/dist/search/BasicSearch.js.map +1 -0
- package/dist/search/BooleanSearch.d.ts +98 -0
- package/dist/search/BooleanSearch.d.ts.map +1 -0
- package/dist/search/BooleanSearch.js +431 -0
- package/dist/search/BooleanSearch.js.map +1 -0
- package/dist/search/EarlyTerminationManager.d.ts +140 -0
- package/dist/search/EarlyTerminationManager.d.ts.map +1 -0
- package/dist/search/EarlyTerminationManager.js +280 -0
- package/dist/search/EarlyTerminationManager.js.map +1 -0
- package/dist/search/EmbeddingCache.d.ts +175 -0
- package/dist/search/EmbeddingCache.d.ts.map +1 -0
- package/dist/search/EmbeddingCache.js +247 -0
- package/dist/search/EmbeddingCache.js.map +1 -0
- package/dist/search/EmbeddingService.d.ts +277 -0
- package/dist/search/EmbeddingService.d.ts.map +1 -0
- package/dist/search/EmbeddingService.js +531 -0
- package/dist/search/EmbeddingService.js.map +1 -0
- package/dist/search/FuzzySearch.d.ts +118 -0
- package/dist/search/FuzzySearch.d.ts.map +1 -0
- package/dist/search/FuzzySearch.js +313 -0
- package/dist/search/FuzzySearch.js.map +1 -0
- package/dist/search/HybridScorer.d.ts +181 -0
- package/dist/search/HybridScorer.d.ts.map +1 -0
- package/dist/search/HybridScorer.js +258 -0
- package/dist/search/HybridScorer.js.map +1 -0
- package/dist/search/HybridSearchManager.d.ts +80 -0
- package/dist/search/HybridSearchManager.d.ts.map +1 -0
- package/dist/search/HybridSearchManager.js +188 -0
- package/dist/search/HybridSearchManager.js.map +1 -0
- package/dist/search/IncrementalIndexer.d.ts +201 -0
- package/dist/search/IncrementalIndexer.d.ts.map +1 -0
- package/dist/search/IncrementalIndexer.js +343 -0
- package/dist/search/IncrementalIndexer.js.map +1 -0
- package/dist/search/OptimizedInvertedIndex.d.ts +163 -0
- package/dist/search/OptimizedInvertedIndex.d.ts.map +1 -0
- package/dist/search/OptimizedInvertedIndex.js +359 -0
- package/dist/search/OptimizedInvertedIndex.js.map +1 -0
- package/dist/search/ParallelSearchExecutor.d.ts +172 -0
- package/dist/search/ParallelSearchExecutor.d.ts.map +1 -0
- package/dist/search/ParallelSearchExecutor.js +310 -0
- package/dist/search/ParallelSearchExecutor.js.map +1 -0
- package/dist/search/QuantizedVectorStore.d.ts +171 -0
- package/dist/search/QuantizedVectorStore.d.ts.map +1 -0
- package/dist/search/QuantizedVectorStore.js +308 -0
- package/dist/search/QuantizedVectorStore.js.map +1 -0
- package/dist/search/QueryAnalyzer.d.ts +76 -0
- package/dist/search/QueryAnalyzer.d.ts.map +1 -0
- package/dist/search/QueryAnalyzer.js +228 -0
- package/dist/search/QueryAnalyzer.js.map +1 -0
- package/dist/search/QueryCostEstimator.d.ts +244 -0
- package/dist/search/QueryCostEstimator.d.ts.map +1 -0
- package/dist/search/QueryCostEstimator.js +653 -0
- package/dist/search/QueryCostEstimator.js.map +1 -0
- package/dist/search/QueryPlanCache.d.ts +220 -0
- package/dist/search/QueryPlanCache.d.ts.map +1 -0
- package/dist/search/QueryPlanCache.js +380 -0
- package/dist/search/QueryPlanCache.js.map +1 -0
- package/dist/search/QueryPlanner.d.ts +58 -0
- package/dist/search/QueryPlanner.d.ts.map +1 -0
- package/dist/search/QueryPlanner.js +138 -0
- package/dist/search/QueryPlanner.js.map +1 -0
- package/dist/search/RankedSearch.d.ts +71 -0
- package/dist/search/RankedSearch.d.ts.map +1 -0
- package/dist/search/RankedSearch.js +239 -0
- package/dist/search/RankedSearch.js.map +1 -0
- package/dist/search/ReflectionManager.d.ts +120 -0
- package/dist/search/ReflectionManager.d.ts.map +1 -0
- package/dist/search/ReflectionManager.js +232 -0
- package/dist/search/ReflectionManager.js.map +1 -0
- package/dist/search/SavedSearchManager.d.ts +79 -0
- package/dist/search/SavedSearchManager.d.ts.map +1 -0
- package/dist/search/SavedSearchManager.js +147 -0
- package/dist/search/SavedSearchManager.js.map +1 -0
- package/dist/search/SearchFilterChain.d.ts +120 -0
- package/dist/search/SearchFilterChain.d.ts.map +1 -0
- package/dist/search/SearchFilterChain.js +186 -0
- package/dist/search/SearchFilterChain.js.map +1 -0
- package/dist/search/SearchManager.d.ts +326 -0
- package/dist/search/SearchManager.d.ts.map +1 -0
- package/dist/search/SearchManager.js +454 -0
- package/dist/search/SearchManager.js.map +1 -0
- package/dist/search/SearchSuggestions.d.ts +27 -0
- package/dist/search/SearchSuggestions.d.ts.map +1 -0
- package/dist/search/SearchSuggestions.js +58 -0
- package/dist/search/SearchSuggestions.js.map +1 -0
- package/dist/search/SemanticSearch.d.ts +149 -0
- package/dist/search/SemanticSearch.d.ts.map +1 -0
- package/dist/search/SemanticSearch.js +324 -0
- package/dist/search/SemanticSearch.js.map +1 -0
- package/dist/search/SymbolicSearch.d.ts +61 -0
- package/dist/search/SymbolicSearch.d.ts.map +1 -0
- package/dist/search/SymbolicSearch.js +164 -0
- package/dist/search/SymbolicSearch.js.map +1 -0
- package/dist/search/TFIDFEventSync.d.ts +85 -0
- package/dist/search/TFIDFEventSync.d.ts.map +1 -0
- package/dist/search/TFIDFEventSync.js +134 -0
- package/dist/search/TFIDFEventSync.js.map +1 -0
- package/dist/search/TFIDFIndexManager.d.ts +151 -0
- package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
- package/dist/search/TFIDFIndexManager.js +433 -0
- package/dist/search/TFIDFIndexManager.js.map +1 -0
- package/dist/search/VectorStore.d.ts +235 -0
- package/dist/search/VectorStore.d.ts.map +1 -0
- package/dist/search/VectorStore.js +312 -0
- package/dist/search/VectorStore.js.map +1 -0
- package/dist/search/index.d.ts +35 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +53 -0
- package/dist/search/index.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/types.d.ts +1811 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +10 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/BatchProcessor.d.ts +271 -0
- package/dist/utils/BatchProcessor.d.ts.map +1 -0
- package/dist/utils/BatchProcessor.js +377 -0
- package/dist/utils/BatchProcessor.js.map +1 -0
- package/dist/utils/MemoryMonitor.d.ts +176 -0
- package/dist/utils/MemoryMonitor.d.ts.map +1 -0
- package/dist/utils/MemoryMonitor.js +306 -0
- package/dist/utils/MemoryMonitor.js.map +1 -0
- package/dist/utils/WorkerPoolManager.d.ts +233 -0
- package/dist/utils/WorkerPoolManager.d.ts.map +1 -0
- package/dist/utils/WorkerPoolManager.js +421 -0
- package/dist/utils/WorkerPoolManager.js.map +1 -0
- package/dist/utils/compressedCache.d.ts +221 -0
- package/dist/utils/compressedCache.d.ts.map +1 -0
- package/dist/utils/compressedCache.js +349 -0
- package/dist/utils/compressedCache.js.map +1 -0
- package/dist/utils/compressionUtil.d.ts +214 -0
- package/dist/utils/compressionUtil.d.ts.map +1 -0
- package/dist/utils/compressionUtil.js +248 -0
- package/dist/utils/compressionUtil.js.map +1 -0
- package/dist/utils/constants.d.ts +245 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +253 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/entityUtils.d.ts +379 -0
- package/dist/utils/entityUtils.d.ts.map +1 -0
- package/dist/utils/entityUtils.js +649 -0
- package/dist/utils/entityUtils.js.map +1 -0
- package/dist/utils/errors.d.ts +95 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +146 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/formatters.d.ts +145 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +133 -0
- package/dist/utils/formatters.js.map +1 -0
- package/dist/utils/index.d.ts +26 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +88 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/indexes.d.ts +270 -0
- package/dist/utils/indexes.d.ts.map +1 -0
- package/dist/utils/indexes.js +527 -0
- package/dist/utils/indexes.js.map +1 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +41 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/operationUtils.d.ts +124 -0
- package/dist/utils/operationUtils.d.ts.map +1 -0
- package/dist/utils/operationUtils.js +176 -0
- package/dist/utils/operationUtils.js.map +1 -0
- package/dist/utils/parallelUtils.d.ts +76 -0
- package/dist/utils/parallelUtils.d.ts.map +1 -0
- package/dist/utils/parallelUtils.js +192 -0
- package/dist/utils/parallelUtils.js.map +1 -0
- package/dist/utils/schemas.d.ts +556 -0
- package/dist/utils/schemas.d.ts.map +1 -0
- package/dist/utils/schemas.js +485 -0
- package/dist/utils/schemas.js.map +1 -0
- package/dist/utils/searchAlgorithms.d.ts +99 -0
- package/dist/utils/searchAlgorithms.d.ts.map +1 -0
- package/dist/utils/searchAlgorithms.js +168 -0
- package/dist/utils/searchAlgorithms.js.map +1 -0
- package/dist/utils/searchCache.d.ts +108 -0
- package/dist/utils/searchCache.d.ts.map +1 -0
- package/dist/utils/searchCache.js +210 -0
- package/dist/utils/searchCache.js.map +1 -0
- package/dist/utils/taskScheduler.d.ts +294 -0
- package/dist/utils/taskScheduler.d.ts.map +1 -0
- package/dist/utils/taskScheduler.js +487 -0
- package/dist/utils/taskScheduler.js.map +1 -0
- package/dist/workers/index.d.ts +12 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +10 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/levenshteinWorker.d.ts +60 -0
- package/dist/workers/levenshteinWorker.d.ts.map +1 -0
- package/dist/workers/levenshteinWorker.js +99 -0
- package/dist/workers/levenshteinWorker.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity Manager
|
|
3
|
+
*
|
|
4
|
+
* Handles CRUD operations for entities in the knowledge graph.
|
|
5
|
+
* Focused on core entity and tag operations only (Phase 4: Consolidate God Objects).
|
|
6
|
+
*
|
|
7
|
+
* @module core/EntityManager
|
|
8
|
+
*/
|
|
9
|
+
import { EntityNotFoundError, InvalidImportanceError, ValidationError } from '../utils/errors.js';
|
|
10
|
+
import { BatchCreateEntitiesSchema, UpdateEntitySchema, EntityNamesSchema, checkCancellation, createProgressReporter, createProgress, sanitizeObject, } from '../utils/index.js';
|
|
11
|
+
import { GRAPH_LIMITS } from '../utils/constants.js';
|
|
12
|
+
/**
|
|
13
|
+
* Minimum importance value (least important).
|
|
14
|
+
* Note: Use IMPORTANCE_RANGE from constants.ts for external access.
|
|
15
|
+
*/
|
|
16
|
+
const MIN_IMPORTANCE = 0;
|
|
17
|
+
/**
|
|
18
|
+
* Maximum importance value (most important).
|
|
19
|
+
* Note: Use IMPORTANCE_RANGE from constants.ts for external access.
|
|
20
|
+
*/
|
|
21
|
+
const MAX_IMPORTANCE = 10;
|
|
22
|
+
/**
|
|
23
|
+
* Manages entity operations with automatic timestamp handling.
|
|
24
|
+
*/
|
|
25
|
+
export class EntityManager {
|
|
26
|
+
storage;
|
|
27
|
+
constructor(storage) {
|
|
28
|
+
this.storage = storage;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create multiple entities in a single batch operation.
|
|
32
|
+
*
|
|
33
|
+
* This method performs the following operations:
|
|
34
|
+
* - Filters out entities that already exist (duplicate names)
|
|
35
|
+
* - Automatically adds createdAt and lastModified timestamps
|
|
36
|
+
* - Normalizes all tags to lowercase for consistent searching
|
|
37
|
+
* - Validates importance values (must be between 0-10)
|
|
38
|
+
*
|
|
39
|
+
* Phase 9B: Supports progress tracking and cancellation via LongRunningOperationOptions.
|
|
40
|
+
*
|
|
41
|
+
* @param entities - Array of entities to create. Each entity must have a unique name.
|
|
42
|
+
* @param options - Optional progress/cancellation options (Phase 9B)
|
|
43
|
+
* @returns Promise resolving to array of newly created entities (excludes duplicates)
|
|
44
|
+
* @throws {InvalidImportanceError} If any entity has importance outside the valid range [0-10]
|
|
45
|
+
* @throws {OperationCancelledError} If operation is cancelled via signal (Phase 9B)
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const manager = new EntityManager(storage);
|
|
50
|
+
*
|
|
51
|
+
* // Create single entity
|
|
52
|
+
* const results = await manager.createEntities([{
|
|
53
|
+
* name: 'Alice',
|
|
54
|
+
* entityType: 'person',
|
|
55
|
+
* observations: ['Works as engineer', 'Lives in Seattle'],
|
|
56
|
+
* importance: 7,
|
|
57
|
+
* tags: ['Team', 'Engineering']
|
|
58
|
+
* }]);
|
|
59
|
+
*
|
|
60
|
+
* // Create multiple entities at once
|
|
61
|
+
* const users = await manager.createEntities([
|
|
62
|
+
* { name: 'Bob', entityType: 'person', observations: [] },
|
|
63
|
+
* { name: 'Charlie', entityType: 'person', observations: [] }
|
|
64
|
+
* ]);
|
|
65
|
+
*
|
|
66
|
+
* // With progress tracking and cancellation (Phase 9B)
|
|
67
|
+
* const controller = new AbortController();
|
|
68
|
+
* const results = await manager.createEntities(largeEntityArray, {
|
|
69
|
+
* signal: controller.signal,
|
|
70
|
+
* onProgress: (p) => console.log(`${p.percentage}% complete`),
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
async createEntities(entities, options) {
|
|
75
|
+
// Check for early cancellation
|
|
76
|
+
checkCancellation(options?.signal, 'createEntities');
|
|
77
|
+
// Validate input
|
|
78
|
+
const validation = BatchCreateEntitiesSchema.safeParse(entities);
|
|
79
|
+
if (!validation.success) {
|
|
80
|
+
const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
|
|
81
|
+
throw new ValidationError('Invalid entity data', errors);
|
|
82
|
+
}
|
|
83
|
+
// Setup progress reporter
|
|
84
|
+
const reportProgress = createProgressReporter(options?.onProgress);
|
|
85
|
+
const total = entities.length;
|
|
86
|
+
reportProgress?.(createProgress(0, total, 'createEntities'));
|
|
87
|
+
// Use read-only graph for checking existing entities
|
|
88
|
+
const readGraph = await this.storage.loadGraph();
|
|
89
|
+
const timestamp = new Date().toISOString();
|
|
90
|
+
// Check graph size limits
|
|
91
|
+
const entitiesToAdd = entities.filter(e => !readGraph.entities.some(existing => existing.name === e.name));
|
|
92
|
+
if (readGraph.entities.length + entitiesToAdd.length > GRAPH_LIMITS.MAX_ENTITIES) {
|
|
93
|
+
throw new ValidationError('Graph size limit exceeded', [`Adding ${entitiesToAdd.length} entities would exceed maximum of ${GRAPH_LIMITS.MAX_ENTITIES} entities`]);
|
|
94
|
+
}
|
|
95
|
+
// Check for cancellation before processing
|
|
96
|
+
checkCancellation(options?.signal, 'createEntities');
|
|
97
|
+
const newEntities = [];
|
|
98
|
+
let processed = 0;
|
|
99
|
+
for (const e of entitiesToAdd) {
|
|
100
|
+
// Check for cancellation periodically
|
|
101
|
+
checkCancellation(options?.signal, 'createEntities');
|
|
102
|
+
const entity = {
|
|
103
|
+
...e,
|
|
104
|
+
createdAt: e.createdAt || timestamp,
|
|
105
|
+
lastModified: e.lastModified || timestamp,
|
|
106
|
+
};
|
|
107
|
+
// Normalize tags to lowercase
|
|
108
|
+
if (e.tags) {
|
|
109
|
+
entity.tags = e.tags.map(tag => tag.toLowerCase());
|
|
110
|
+
}
|
|
111
|
+
// Validate importance
|
|
112
|
+
if (e.importance !== undefined) {
|
|
113
|
+
if (e.importance < MIN_IMPORTANCE || e.importance > MAX_IMPORTANCE) {
|
|
114
|
+
throw new InvalidImportanceError(e.importance, MIN_IMPORTANCE, MAX_IMPORTANCE);
|
|
115
|
+
}
|
|
116
|
+
entity.importance = e.importance;
|
|
117
|
+
}
|
|
118
|
+
newEntities.push(entity);
|
|
119
|
+
processed++;
|
|
120
|
+
reportProgress?.(createProgress(processed, entitiesToAdd.length, 'createEntities'));
|
|
121
|
+
}
|
|
122
|
+
// OPTIMIZED: Use append for single entity, bulk save for multiple
|
|
123
|
+
// (N individual appends is slower than one bulk write)
|
|
124
|
+
if (newEntities.length === 1) {
|
|
125
|
+
await this.storage.appendEntity(newEntities[0]);
|
|
126
|
+
}
|
|
127
|
+
else if (newEntities.length > 1) {
|
|
128
|
+
const graph = await this.storage.getGraphForMutation();
|
|
129
|
+
graph.entities.push(...newEntities);
|
|
130
|
+
await this.storage.saveGraph(graph);
|
|
131
|
+
}
|
|
132
|
+
// Report completion
|
|
133
|
+
reportProgress?.(createProgress(entitiesToAdd.length, entitiesToAdd.length, 'createEntities'));
|
|
134
|
+
return newEntities;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Delete multiple entities by name in a single batch operation.
|
|
138
|
+
*
|
|
139
|
+
* This method performs cascading deletion:
|
|
140
|
+
* - Removes all specified entities from the graph
|
|
141
|
+
* - Automatically removes all relations where these entities are source or target
|
|
142
|
+
* - Silently ignores entity names that don't exist (no error thrown)
|
|
143
|
+
*
|
|
144
|
+
* @param entityNames - Array of entity names to delete
|
|
145
|
+
* @returns Promise that resolves when deletion is complete
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const manager = new EntityManager(storage);
|
|
150
|
+
*
|
|
151
|
+
* // Delete single entity
|
|
152
|
+
* await manager.deleteEntities(['Alice']);
|
|
153
|
+
*
|
|
154
|
+
* // Delete multiple entities at once
|
|
155
|
+
* await manager.deleteEntities(['Bob', 'Charlie', 'Dave']);
|
|
156
|
+
*
|
|
157
|
+
* // Safe to delete non-existent entities (no error)
|
|
158
|
+
* await manager.deleteEntities(['NonExistent']); // No error thrown
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
async deleteEntities(entityNames) {
|
|
162
|
+
// Validate input
|
|
163
|
+
const validation = EntityNamesSchema.safeParse(entityNames);
|
|
164
|
+
if (!validation.success) {
|
|
165
|
+
const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
|
|
166
|
+
throw new ValidationError('Invalid entity names', errors);
|
|
167
|
+
}
|
|
168
|
+
const graph = await this.storage.getGraphForMutation();
|
|
169
|
+
// OPTIMIZED: Use Set for O(1) lookups instead of O(n) includes()
|
|
170
|
+
const namesToDelete = new Set(entityNames);
|
|
171
|
+
graph.entities = graph.entities.filter(e => !namesToDelete.has(e.name));
|
|
172
|
+
graph.relations = graph.relations.filter(r => !namesToDelete.has(r.from) && !namesToDelete.has(r.to));
|
|
173
|
+
await this.storage.saveGraph(graph);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Retrieve a single entity by its unique name.
|
|
177
|
+
*
|
|
178
|
+
* This is a read-only operation that does not modify the graph.
|
|
179
|
+
* Entity names are case-sensitive.
|
|
180
|
+
*
|
|
181
|
+
* @param name - The unique name of the entity to retrieve
|
|
182
|
+
* @returns Promise resolving to the Entity object if found, or null if not found
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const manager = new EntityManager(storage);
|
|
187
|
+
*
|
|
188
|
+
* // Get an existing entity
|
|
189
|
+
* const alice = await manager.getEntity('Alice');
|
|
190
|
+
* if (alice) {
|
|
191
|
+
* console.log(alice.observations);
|
|
192
|
+
* console.log(alice.importance);
|
|
193
|
+
* }
|
|
194
|
+
*
|
|
195
|
+
* // Handle non-existent entity
|
|
196
|
+
* const missing = await manager.getEntity('NonExistent');
|
|
197
|
+
* console.log(missing); // null
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
async getEntity(name) {
|
|
201
|
+
const graph = await this.storage.loadGraph();
|
|
202
|
+
return graph.entities.find(e => e.name === name) || null;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Update one or more fields of an existing entity.
|
|
206
|
+
*
|
|
207
|
+
* This method allows partial updates - only the fields specified in the updates
|
|
208
|
+
* object will be changed. All other fields remain unchanged.
|
|
209
|
+
* The lastModified timestamp is automatically updated.
|
|
210
|
+
*
|
|
211
|
+
* @param name - The unique name of the entity to update
|
|
212
|
+
* @param updates - Partial entity object containing only the fields to update
|
|
213
|
+
* @returns Promise resolving to the fully updated Entity object
|
|
214
|
+
* @throws {EntityNotFoundError} If no entity with the given name exists
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const manager = new EntityManager(storage);
|
|
219
|
+
*
|
|
220
|
+
* // Update importance only
|
|
221
|
+
* const updated = await manager.updateEntity('Alice', {
|
|
222
|
+
* importance: 9
|
|
223
|
+
* });
|
|
224
|
+
*
|
|
225
|
+
* // Update multiple fields
|
|
226
|
+
* await manager.updateEntity('Bob', {
|
|
227
|
+
* entityType: 'senior_engineer',
|
|
228
|
+
* tags: ['leadership', 'architecture'],
|
|
229
|
+
* observations: ['Led project X', 'Designed system Y']
|
|
230
|
+
* });
|
|
231
|
+
*
|
|
232
|
+
* // Add observations (requires reading existing entity first)
|
|
233
|
+
* const entity = await manager.getEntity('Charlie');
|
|
234
|
+
* if (entity) {
|
|
235
|
+
* await manager.updateEntity('Charlie', {
|
|
236
|
+
* observations: [...entity.observations, 'New observation']
|
|
237
|
+
* });
|
|
238
|
+
* }
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
async updateEntity(name, updates) {
|
|
242
|
+
// Validate input
|
|
243
|
+
const validation = UpdateEntitySchema.safeParse(updates);
|
|
244
|
+
if (!validation.success) {
|
|
245
|
+
const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
|
|
246
|
+
throw new ValidationError('Invalid update data', errors);
|
|
247
|
+
}
|
|
248
|
+
const graph = await this.storage.getGraphForMutation();
|
|
249
|
+
const entity = graph.entities.find(e => e.name === name);
|
|
250
|
+
if (!entity) {
|
|
251
|
+
throw new EntityNotFoundError(name);
|
|
252
|
+
}
|
|
253
|
+
// Apply updates (sanitized to prevent prototype pollution)
|
|
254
|
+
Object.assign(entity, sanitizeObject(updates));
|
|
255
|
+
entity.lastModified = new Date().toISOString();
|
|
256
|
+
await this.storage.saveGraph(graph);
|
|
257
|
+
return entity;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Update multiple entities in a single batch operation.
|
|
261
|
+
*
|
|
262
|
+
* This method is more efficient than calling updateEntity multiple times
|
|
263
|
+
* as it loads and saves the graph only once. All updates are applied atomically.
|
|
264
|
+
* The lastModified timestamp is automatically updated for all entities.
|
|
265
|
+
*
|
|
266
|
+
* @param updates - Array of updates, each containing entity name and changes
|
|
267
|
+
* @returns Promise resolving to array of updated entities
|
|
268
|
+
* @throws {EntityNotFoundError} If any entity is not found
|
|
269
|
+
* @throws {ValidationError} If any update data is invalid
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* const manager = new EntityManager(storage);
|
|
274
|
+
*
|
|
275
|
+
* // Update multiple entities at once
|
|
276
|
+
* const updated = await manager.batchUpdate([
|
|
277
|
+
* { name: 'Alice', updates: { importance: 9 } },
|
|
278
|
+
* { name: 'Bob', updates: { importance: 8, tags: ['senior'] } },
|
|
279
|
+
* { name: 'Charlie', updates: { entityType: 'lead_engineer' } }
|
|
280
|
+
* ]);
|
|
281
|
+
*
|
|
282
|
+
* console.log(`Updated ${updated.length} entities`);
|
|
283
|
+
*
|
|
284
|
+
* // Efficiently update many entities (single graph load/save)
|
|
285
|
+
* const massUpdate = employees.map(name => ({
|
|
286
|
+
* name,
|
|
287
|
+
* updates: { tags: ['team-2024'] }
|
|
288
|
+
* }));
|
|
289
|
+
* await manager.batchUpdate(massUpdate);
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
async batchUpdate(updates) {
|
|
293
|
+
// Validate all updates first
|
|
294
|
+
for (const { updates: updateData } of updates) {
|
|
295
|
+
const validation = UpdateEntitySchema.safeParse(updateData);
|
|
296
|
+
if (!validation.success) {
|
|
297
|
+
const errors = validation.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
|
|
298
|
+
throw new ValidationError('Invalid update data', errors);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const graph = await this.storage.getGraphForMutation();
|
|
302
|
+
const timestamp = new Date().toISOString();
|
|
303
|
+
const updatedEntities = [];
|
|
304
|
+
// OPTIMIZED: Build Map for O(1) lookups instead of O(n) find() per update
|
|
305
|
+
const entityIndex = new Map();
|
|
306
|
+
graph.entities.forEach((e, i) => entityIndex.set(e.name, i));
|
|
307
|
+
for (const { name, updates: updateData } of updates) {
|
|
308
|
+
const idx = entityIndex.get(name);
|
|
309
|
+
if (idx === undefined) {
|
|
310
|
+
throw new EntityNotFoundError(name);
|
|
311
|
+
}
|
|
312
|
+
const entity = graph.entities[idx];
|
|
313
|
+
// Apply updates (sanitized to prevent prototype pollution)
|
|
314
|
+
Object.assign(entity, sanitizeObject(updateData));
|
|
315
|
+
entity.lastModified = timestamp;
|
|
316
|
+
updatedEntities.push(entity);
|
|
317
|
+
}
|
|
318
|
+
await this.storage.saveGraph(graph);
|
|
319
|
+
return updatedEntities;
|
|
320
|
+
}
|
|
321
|
+
// ============================================================
|
|
322
|
+
// TAG OPERATIONS
|
|
323
|
+
// ============================================================
|
|
324
|
+
/**
|
|
325
|
+
* Add tags to an entity.
|
|
326
|
+
*
|
|
327
|
+
* Tags are normalized to lowercase and duplicates are filtered out.
|
|
328
|
+
*
|
|
329
|
+
* @param entityName - Name of the entity
|
|
330
|
+
* @param tags - Tags to add
|
|
331
|
+
* @returns Result with entity name and added tags
|
|
332
|
+
* @throws {EntityNotFoundError} If entity is not found
|
|
333
|
+
*/
|
|
334
|
+
async addTags(entityName, tags) {
|
|
335
|
+
// OPTIMIZED: Use O(1) NameIndex lookup instead of loadGraph() + O(n) find()
|
|
336
|
+
const entity = this.storage.getEntityByName(entityName);
|
|
337
|
+
if (!entity) {
|
|
338
|
+
throw new EntityNotFoundError(entityName);
|
|
339
|
+
}
|
|
340
|
+
// Initialize tags array if it doesn't exist
|
|
341
|
+
const existingTags = entity.tags || [];
|
|
342
|
+
// Normalize tags to lowercase and filter out duplicates
|
|
343
|
+
const normalizedTags = tags.map(tag => tag.toLowerCase());
|
|
344
|
+
const newTags = normalizedTags.filter(tag => !existingTags.includes(tag));
|
|
345
|
+
if (newTags.length > 0) {
|
|
346
|
+
// OPTIMIZED: Use updateEntity for in-place update + append
|
|
347
|
+
await this.storage.updateEntity(entityName, { tags: [...existingTags, ...newTags] });
|
|
348
|
+
}
|
|
349
|
+
return { entityName, addedTags: newTags };
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Remove tags from an entity.
|
|
353
|
+
*
|
|
354
|
+
* @param entityName - Name of the entity
|
|
355
|
+
* @param tags - Tags to remove
|
|
356
|
+
* @returns Result with entity name and removed tags
|
|
357
|
+
* @throws {EntityNotFoundError} If entity is not found
|
|
358
|
+
*/
|
|
359
|
+
async removeTags(entityName, tags) {
|
|
360
|
+
// OPTIMIZED: Use O(1) NameIndex lookup instead of loadGraph() + O(n) find()
|
|
361
|
+
const entity = this.storage.getEntityByName(entityName);
|
|
362
|
+
if (!entity) {
|
|
363
|
+
throw new EntityNotFoundError(entityName);
|
|
364
|
+
}
|
|
365
|
+
if (!entity.tags) {
|
|
366
|
+
return { entityName, removedTags: [] };
|
|
367
|
+
}
|
|
368
|
+
// Normalize tags to lowercase
|
|
369
|
+
const normalizedTags = tags.map(tag => tag.toLowerCase());
|
|
370
|
+
const originalLength = entity.tags.length;
|
|
371
|
+
// Capture existing tags (lowercase) BEFORE filtering to accurately track removals
|
|
372
|
+
const existingTagsLower = entity.tags.map(t => t.toLowerCase());
|
|
373
|
+
// Filter out the tags to remove
|
|
374
|
+
const newTags = entity.tags.filter(tag => !normalizedTags.includes(tag.toLowerCase()));
|
|
375
|
+
// A tag was removed if it existed in the original tags
|
|
376
|
+
const removedTags = normalizedTags.filter(tag => existingTagsLower.includes(tag));
|
|
377
|
+
// Update entity via storage if tags were removed
|
|
378
|
+
if (newTags.length < originalLength) {
|
|
379
|
+
await this.storage.updateEntity(entityName, { tags: newTags });
|
|
380
|
+
}
|
|
381
|
+
return { entityName, removedTags };
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Set importance level for an entity.
|
|
385
|
+
*
|
|
386
|
+
* @param entityName - Name of the entity
|
|
387
|
+
* @param importance - Importance level (0-10)
|
|
388
|
+
* @returns Result with entity name and importance
|
|
389
|
+
* @throws {EntityNotFoundError} If entity is not found
|
|
390
|
+
* @throws {Error} If importance is out of range
|
|
391
|
+
*/
|
|
392
|
+
async setImportance(entityName, importance) {
|
|
393
|
+
// Validate importance range (0-10)
|
|
394
|
+
if (importance < 0 || importance > 10) {
|
|
395
|
+
throw new Error(`Importance must be between 0 and 10, got ${importance}`);
|
|
396
|
+
}
|
|
397
|
+
// OPTIMIZED: Use O(1) NameIndex lookup instead of loadGraph() + O(n) find()
|
|
398
|
+
const entity = this.storage.getEntityByName(entityName);
|
|
399
|
+
if (!entity) {
|
|
400
|
+
throw new EntityNotFoundError(entityName);
|
|
401
|
+
}
|
|
402
|
+
// Use updateEntity for in-place update + append
|
|
403
|
+
await this.storage.updateEntity(entityName, { importance });
|
|
404
|
+
return { entityName, importance };
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Add tags to multiple entities in a single operation.
|
|
408
|
+
*
|
|
409
|
+
* OPTIMIZED: Uses Map for O(1) entity lookups instead of O(n) find() per entity.
|
|
410
|
+
*
|
|
411
|
+
* @param entityNames - Names of entities to tag
|
|
412
|
+
* @param tags - Tags to add to each entity
|
|
413
|
+
* @returns Array of results showing which tags were added to each entity
|
|
414
|
+
*/
|
|
415
|
+
async addTagsToMultipleEntities(entityNames, tags) {
|
|
416
|
+
const graph = await this.storage.getGraphForMutation();
|
|
417
|
+
const timestamp = new Date().toISOString();
|
|
418
|
+
const normalizedTags = tags.map(tag => tag.toLowerCase());
|
|
419
|
+
const results = [];
|
|
420
|
+
// OPTIMIZED: Build Map for O(1) lookups instead of O(n) find() per entity
|
|
421
|
+
const entityMap = new Map();
|
|
422
|
+
for (const e of graph.entities) {
|
|
423
|
+
entityMap.set(e.name, e);
|
|
424
|
+
}
|
|
425
|
+
for (const entityName of entityNames) {
|
|
426
|
+
const entity = entityMap.get(entityName);
|
|
427
|
+
if (!entity) {
|
|
428
|
+
continue; // Skip non-existent entities
|
|
429
|
+
}
|
|
430
|
+
// Initialize tags array if it doesn't exist
|
|
431
|
+
if (!entity.tags) {
|
|
432
|
+
entity.tags = [];
|
|
433
|
+
}
|
|
434
|
+
// Filter out duplicates
|
|
435
|
+
const newTags = normalizedTags.filter(tag => !entity.tags.includes(tag));
|
|
436
|
+
entity.tags.push(...newTags);
|
|
437
|
+
// Update lastModified timestamp if tags were added
|
|
438
|
+
if (newTags.length > 0) {
|
|
439
|
+
entity.lastModified = timestamp;
|
|
440
|
+
}
|
|
441
|
+
results.push({ entityName, addedTags: newTags });
|
|
442
|
+
}
|
|
443
|
+
await this.storage.saveGraph(graph);
|
|
444
|
+
return results;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Replace a tag with a new tag across all entities (rename tag).
|
|
448
|
+
*
|
|
449
|
+
* @param oldTag - Tag to replace
|
|
450
|
+
* @param newTag - New tag value
|
|
451
|
+
* @returns Result with affected entities and count
|
|
452
|
+
*/
|
|
453
|
+
async replaceTag(oldTag, newTag) {
|
|
454
|
+
const graph = await this.storage.getGraphForMutation();
|
|
455
|
+
const timestamp = new Date().toISOString();
|
|
456
|
+
const normalizedOldTag = oldTag.toLowerCase();
|
|
457
|
+
const normalizedNewTag = newTag.toLowerCase();
|
|
458
|
+
const affectedEntities = [];
|
|
459
|
+
for (const entity of graph.entities) {
|
|
460
|
+
if (!entity.tags || !entity.tags.includes(normalizedOldTag)) {
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
// Replace old tag with new tag
|
|
464
|
+
const index = entity.tags.indexOf(normalizedOldTag);
|
|
465
|
+
entity.tags[index] = normalizedNewTag;
|
|
466
|
+
entity.lastModified = timestamp;
|
|
467
|
+
affectedEntities.push(entity.name);
|
|
468
|
+
}
|
|
469
|
+
await this.storage.saveGraph(graph);
|
|
470
|
+
return { affectedEntities, count: affectedEntities.length };
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Merge two tags into one target tag across all entities.
|
|
474
|
+
*
|
|
475
|
+
* Combines tag1 and tag2 into targetTag. Any entity with either tag1 or tag2
|
|
476
|
+
* will have both removed and targetTag added (if not already present).
|
|
477
|
+
*
|
|
478
|
+
* @param tag1 - First tag to merge
|
|
479
|
+
* @param tag2 - Second tag to merge
|
|
480
|
+
* @param targetTag - Target tag to merge into
|
|
481
|
+
* @returns Object with affected entity names and count
|
|
482
|
+
*/
|
|
483
|
+
async mergeTags(tag1, tag2, targetTag) {
|
|
484
|
+
const graph = await this.storage.getGraphForMutation();
|
|
485
|
+
const timestamp = new Date().toISOString();
|
|
486
|
+
const normalizedTag1 = tag1.toLowerCase();
|
|
487
|
+
const normalizedTag2 = tag2.toLowerCase();
|
|
488
|
+
const normalizedTargetTag = targetTag.toLowerCase();
|
|
489
|
+
const affectedEntities = [];
|
|
490
|
+
for (const entity of graph.entities) {
|
|
491
|
+
if (!entity.tags) {
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
const hasTag1 = entity.tags.includes(normalizedTag1);
|
|
495
|
+
const hasTag2 = entity.tags.includes(normalizedTag2);
|
|
496
|
+
if (!hasTag1 && !hasTag2) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
// Remove both tags
|
|
500
|
+
entity.tags = entity.tags.filter(tag => tag !== normalizedTag1 && tag !== normalizedTag2);
|
|
501
|
+
// Add target tag if not already present
|
|
502
|
+
if (!entity.tags.includes(normalizedTargetTag)) {
|
|
503
|
+
entity.tags.push(normalizedTargetTag);
|
|
504
|
+
}
|
|
505
|
+
entity.lastModified = timestamp;
|
|
506
|
+
affectedEntities.push(entity.name);
|
|
507
|
+
}
|
|
508
|
+
await this.storage.saveGraph(graph);
|
|
509
|
+
return { affectedEntities, count: affectedEntities.length };
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
//# sourceMappingURL=EntityManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityManager.js","sourceRoot":"","sources":["../../src/core/EntityManager.ts"],"names":[],"mappings":"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"}
|