@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.
- package/LICENSE +22 -0
- package/README.md +2000 -194
- package/dist/__tests__/file-path.test.js +7 -11
- package/dist/__tests__/knowledge-graph.test.js +3 -8
- package/dist/core/EntityManager.d.ts +266 -0
- package/dist/core/EntityManager.d.ts.map +1 -0
- package/dist/core/EntityManager.js +85 -133
- package/dist/core/GraphEventEmitter.d.ts +202 -0
- package/dist/core/GraphEventEmitter.d.ts.map +1 -0
- package/dist/core/GraphEventEmitter.js +346 -0
- package/dist/core/GraphStorage.d.ts +395 -0
- package/dist/core/GraphStorage.d.ts.map +1 -0
- package/dist/core/GraphStorage.js +643 -31
- package/dist/core/GraphTraversal.d.ts +141 -0
- package/dist/core/GraphTraversal.d.ts.map +1 -0
- package/dist/core/GraphTraversal.js +573 -0
- package/dist/core/HierarchyManager.d.ts +111 -0
- package/dist/core/HierarchyManager.d.ts.map +1 -0
- package/dist/{features → core}/HierarchyManager.js +14 -9
- package/dist/core/ManagerContext.d.ts +72 -0
- package/dist/core/ManagerContext.d.ts.map +1 -0
- package/dist/core/ManagerContext.js +118 -0
- package/dist/core/ObservationManager.d.ts +85 -0
- package/dist/core/ObservationManager.d.ts.map +1 -0
- package/dist/core/ObservationManager.js +51 -57
- package/dist/core/RelationManager.d.ts +131 -0
- package/dist/core/RelationManager.d.ts.map +1 -0
- package/dist/core/RelationManager.js +31 -7
- package/dist/core/SQLiteStorage.d.ts +354 -0
- package/dist/core/SQLiteStorage.d.ts.map +1 -0
- package/dist/core/SQLiteStorage.js +917 -0
- package/dist/core/StorageFactory.d.ts +45 -0
- package/dist/core/StorageFactory.d.ts.map +1 -0
- package/dist/core/StorageFactory.js +64 -0
- package/dist/core/TransactionManager.d.ts +464 -0
- package/dist/core/TransactionManager.d.ts.map +1 -0
- package/dist/core/TransactionManager.js +490 -13
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -2
- package/dist/features/AnalyticsManager.d.ts +44 -0
- package/dist/features/AnalyticsManager.d.ts.map +1 -0
- package/dist/features/AnalyticsManager.js +3 -2
- package/dist/features/ArchiveManager.d.ts +133 -0
- package/dist/features/ArchiveManager.d.ts.map +1 -0
- package/dist/features/ArchiveManager.js +221 -14
- package/dist/features/CompressionManager.d.ts +117 -0
- package/dist/features/CompressionManager.d.ts.map +1 -0
- package/dist/features/CompressionManager.js +189 -20
- package/dist/features/IOManager.d.ts +225 -0
- package/dist/features/IOManager.d.ts.map +1 -0
- package/dist/features/IOManager.js +1041 -0
- package/dist/features/StreamingExporter.d.ts +123 -0
- package/dist/features/StreamingExporter.d.ts.map +1 -0
- package/dist/features/StreamingExporter.js +203 -0
- package/dist/features/TagManager.d.ts +147 -0
- package/dist/features/TagManager.d.ts.map +1 -0
- package/dist/features/index.d.ts +12 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +5 -6
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -10
- package/dist/memory.jsonl +1 -26
- package/dist/search/BasicSearch.d.ts +51 -0
- package/dist/search/BasicSearch.d.ts.map +1 -0
- package/dist/search/BasicSearch.js +9 -3
- package/dist/search/BooleanSearch.d.ts +98 -0
- package/dist/search/BooleanSearch.d.ts.map +1 -0
- package/dist/search/BooleanSearch.js +156 -9
- package/dist/search/EmbeddingService.d.ts +178 -0
- package/dist/search/EmbeddingService.d.ts.map +1 -0
- package/dist/search/EmbeddingService.js +358 -0
- package/dist/search/FuzzySearch.d.ts +118 -0
- package/dist/search/FuzzySearch.d.ts.map +1 -0
- package/dist/search/FuzzySearch.js +241 -25
- package/dist/search/QueryCostEstimator.d.ts +111 -0
- package/dist/search/QueryCostEstimator.d.ts.map +1 -0
- package/dist/search/QueryCostEstimator.js +355 -0
- package/dist/search/RankedSearch.d.ts +71 -0
- package/dist/search/RankedSearch.d.ts.map +1 -0
- package/dist/search/RankedSearch.js +54 -6
- package/dist/search/SavedSearchManager.d.ts +79 -0
- package/dist/search/SavedSearchManager.d.ts.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 +2 -4
- package/dist/search/SearchManager.d.ts +326 -0
- package/dist/search/SearchManager.d.ts.map +1 -0
- package/dist/search/SearchManager.js +148 -0
- package/dist/search/SearchSuggestions.d.ts +27 -0
- package/dist/search/SearchSuggestions.d.ts.map +1 -0
- package/dist/search/SearchSuggestions.js +1 -1
- package/dist/search/SemanticSearch.d.ts +149 -0
- package/dist/search/SemanticSearch.d.ts.map +1 -0
- package/dist/search/SemanticSearch.js +323 -0
- package/dist/search/TFIDFEventSync.d.ts +85 -0
- package/dist/search/TFIDFEventSync.d.ts.map +1 -0
- package/dist/search/TFIDFEventSync.js +133 -0
- package/dist/search/TFIDFIndexManager.d.ts +151 -0
- package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
- package/dist/search/TFIDFIndexManager.js +232 -17
- package/dist/search/VectorStore.d.ts +235 -0
- package/dist/search/VectorStore.d.ts.map +1 -0
- package/dist/search/VectorStore.js +311 -0
- package/dist/search/index.d.ts +21 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +12 -0
- package/dist/server/MCPServer.d.ts +21 -0
- package/dist/server/MCPServer.d.ts.map +1 -0
- package/dist/server/MCPServer.js +4 -4
- package/dist/server/responseCompressor.d.ts +94 -0
- package/dist/server/responseCompressor.d.ts.map +1 -0
- package/dist/server/responseCompressor.js +127 -0
- package/dist/server/toolDefinitions.d.ts +27 -0
- package/dist/server/toolDefinitions.d.ts.map +1 -0
- package/dist/server/toolDefinitions.js +188 -17
- package/dist/server/toolHandlers.d.ts +41 -0
- package/dist/server/toolHandlers.d.ts.map +1 -0
- package/dist/server/toolHandlers.js +467 -75
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -1
- package/dist/types/types.d.ts +1654 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +9 -0
- package/dist/utils/compressedCache.d.ts +192 -0
- package/dist/utils/compressedCache.d.ts.map +1 -0
- package/dist/utils/compressedCache.js +309 -0
- package/dist/utils/compressionUtil.d.ts +214 -0
- package/dist/utils/compressionUtil.d.ts.map +1 -0
- package/dist/utils/compressionUtil.js +247 -0
- package/dist/utils/constants.d.ts +245 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +124 -0
- package/dist/utils/entityUtils.d.ts +321 -0
- package/dist/utils/entityUtils.d.ts.map +1 -0
- package/dist/utils/entityUtils.js +434 -4
- package/dist/utils/errors.d.ts +95 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +24 -0
- package/dist/utils/formatters.d.ts +145 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/{paginationUtils.js → formatters.js} +54 -3
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +69 -31
- package/dist/utils/indexes.d.ts +270 -0
- package/dist/utils/indexes.d.ts.map +1 -0
- package/dist/utils/indexes.js +526 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.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 +175 -0
- package/dist/utils/parallelUtils.d.ts +72 -0
- package/dist/utils/parallelUtils.d.ts.map +1 -0
- package/dist/utils/parallelUtils.js +169 -0
- package/dist/utils/schemas.d.ts +374 -0
- package/dist/utils/schemas.d.ts.map +1 -0
- package/dist/utils/schemas.js +302 -2
- package/dist/utils/searchAlgorithms.d.ts +99 -0
- package/dist/utils/searchAlgorithms.d.ts.map +1 -0
- package/dist/utils/searchAlgorithms.js +167 -0
- package/dist/utils/searchCache.d.ts +108 -0
- package/dist/utils/searchCache.d.ts.map +1 -0
- package/dist/utils/taskScheduler.d.ts +290 -0
- package/dist/utils/taskScheduler.d.ts.map +1 -0
- package/dist/utils/taskScheduler.js +466 -0
- package/dist/workers/index.d.ts +12 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +9 -0
- package/dist/workers/levenshteinWorker.d.ts +60 -0
- package/dist/workers/levenshteinWorker.d.ts.map +1 -0
- package/dist/workers/levenshteinWorker.js +98 -0
- package/package.json +17 -4
- package/dist/__tests__/edge-cases/edge-cases.test.js +0 -406
- package/dist/__tests__/integration/workflows.test.js +0 -449
- package/dist/__tests__/performance/benchmarks.test.js +0 -413
- package/dist/__tests__/unit/core/EntityManager.test.js +0 -334
- package/dist/__tests__/unit/core/GraphStorage.test.js +0 -205
- package/dist/__tests__/unit/core/RelationManager.test.js +0 -274
- package/dist/__tests__/unit/features/CompressionManager.test.js +0 -350
- package/dist/__tests__/unit/search/BasicSearch.test.js +0 -311
- package/dist/__tests__/unit/search/BooleanSearch.test.js +0 -432
- package/dist/__tests__/unit/search/FuzzySearch.test.js +0 -448
- package/dist/__tests__/unit/search/RankedSearch.test.js +0 -379
- package/dist/__tests__/unit/utils/levenshtein.test.js +0 -77
- package/dist/core/KnowledgeGraphManager.js +0 -423
- package/dist/features/BackupManager.js +0 -311
- package/dist/features/ExportManager.js +0 -305
- package/dist/features/ImportExportManager.js +0 -50
- package/dist/features/ImportManager.js +0 -328
- package/dist/memory-saved-searches.jsonl +0 -0
- package/dist/memory-tag-aliases.jsonl +0 -0
- package/dist/types/analytics.types.js +0 -6
- package/dist/types/entity.types.js +0 -7
- package/dist/types/import-export.types.js +0 -7
- package/dist/types/search.types.js +0 -7
- package/dist/types/tag.types.js +0 -6
- package/dist/utils/dateUtils.js +0 -89
- package/dist/utils/filterUtils.js +0 -155
- package/dist/utils/levenshtein.js +0 -62
- package/dist/utils/pathUtils.js +0 -115
- package/dist/utils/responseFormatter.js +0 -55
- package/dist/utils/tagUtils.js +0 -107
- package/dist/utils/tfidf.js +0 -90
- package/dist/utils/validationHelper.js +0 -99
- package/dist/utils/validationUtils.js +0 -109
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Traversal
|
|
3
|
+
*
|
|
4
|
+
* Phase 4 Sprints 6-8: Graph traversal algorithms for knowledge graph analysis.
|
|
5
|
+
* Includes BFS, DFS, shortest path, all paths, connected components, and centrality.
|
|
6
|
+
*
|
|
7
|
+
* @module core/GraphTraversal
|
|
8
|
+
*/
|
|
9
|
+
import { checkCancellation } from '../utils/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Phase 4 Sprint 6: Default traversal options.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_OPTIONS = {
|
|
14
|
+
direction: 'both',
|
|
15
|
+
maxDepth: Infinity,
|
|
16
|
+
relationTypes: [],
|
|
17
|
+
entityTypes: [],
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Graph traversal algorithms for knowledge graph analysis.
|
|
21
|
+
*
|
|
22
|
+
* Provides BFS, DFS, shortest path finding, connected component detection,
|
|
23
|
+
* and centrality metrics for analyzing graph structure.
|
|
24
|
+
*/
|
|
25
|
+
export class GraphTraversal {
|
|
26
|
+
storage;
|
|
27
|
+
constructor(storage) {
|
|
28
|
+
this.storage = storage;
|
|
29
|
+
}
|
|
30
|
+
// ==================== Sprint 6: BFS and DFS Traversal ====================
|
|
31
|
+
/**
|
|
32
|
+
* Get neighbors of a node based on traversal direction and filters.
|
|
33
|
+
*
|
|
34
|
+
* @param entityName - Entity to get neighbors for
|
|
35
|
+
* @param options - Traversal options
|
|
36
|
+
* @returns Array of neighbor entity names with their relations
|
|
37
|
+
*/
|
|
38
|
+
getNeighborsWithRelations(entityName, options = {}) {
|
|
39
|
+
// Filter out undefined values before merging with defaults
|
|
40
|
+
const definedOptions = Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined));
|
|
41
|
+
const opts = { ...DEFAULT_OPTIONS, ...definedOptions };
|
|
42
|
+
const neighbors = [];
|
|
43
|
+
// Get relations based on direction
|
|
44
|
+
let relations = [];
|
|
45
|
+
if (opts.direction === 'outgoing' || opts.direction === 'both') {
|
|
46
|
+
relations = relations.concat(this.storage.getRelationsFrom(entityName));
|
|
47
|
+
}
|
|
48
|
+
if (opts.direction === 'incoming' || opts.direction === 'both') {
|
|
49
|
+
relations = relations.concat(this.storage.getRelationsTo(entityName));
|
|
50
|
+
}
|
|
51
|
+
// Filter by relation types if specified
|
|
52
|
+
if (opts.relationTypes && opts.relationTypes.length > 0) {
|
|
53
|
+
const typeSet = new Set(opts.relationTypes.map(t => t.toLowerCase()));
|
|
54
|
+
relations = relations.filter(r => typeSet.has(r.relationType.toLowerCase()));
|
|
55
|
+
}
|
|
56
|
+
// Process relations to get neighbors
|
|
57
|
+
for (const relation of relations) {
|
|
58
|
+
const neighbor = relation.from === entityName ? relation.to : relation.from;
|
|
59
|
+
// Skip self-loops
|
|
60
|
+
if (neighbor === entityName)
|
|
61
|
+
continue;
|
|
62
|
+
// Filter by entity types if specified
|
|
63
|
+
if (opts.entityTypes && opts.entityTypes.length > 0) {
|
|
64
|
+
const entity = this.storage.getEntityByName(neighbor);
|
|
65
|
+
if (!entity)
|
|
66
|
+
continue;
|
|
67
|
+
const typeSet = new Set(opts.entityTypes.map(t => t.toLowerCase()));
|
|
68
|
+
if (!typeSet.has(entity.entityType.toLowerCase()))
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
neighbors.push({ neighbor, relation });
|
|
72
|
+
}
|
|
73
|
+
return neighbors;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Breadth-First Search traversal starting from a given entity.
|
|
77
|
+
*
|
|
78
|
+
* @param startEntity - Entity name to start traversal from
|
|
79
|
+
* @param options - Traversal options
|
|
80
|
+
* @returns Traversal result with visited nodes, depths, and parent pointers
|
|
81
|
+
*/
|
|
82
|
+
bfs(startEntity, options = {}) {
|
|
83
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
84
|
+
// Validate start entity exists
|
|
85
|
+
if (!this.storage.hasEntity(startEntity)) {
|
|
86
|
+
return { nodes: [], depths: new Map(), parents: new Map() };
|
|
87
|
+
}
|
|
88
|
+
const visited = new Set();
|
|
89
|
+
const queue = [{ node: startEntity, depth: 0 }];
|
|
90
|
+
const nodes = [];
|
|
91
|
+
const depths = new Map();
|
|
92
|
+
const parents = new Map();
|
|
93
|
+
visited.add(startEntity);
|
|
94
|
+
parents.set(startEntity, null);
|
|
95
|
+
while (queue.length > 0) {
|
|
96
|
+
const { node, depth } = queue.shift();
|
|
97
|
+
// Respect maxDepth limit
|
|
98
|
+
if (depth > opts.maxDepth)
|
|
99
|
+
continue;
|
|
100
|
+
nodes.push(node);
|
|
101
|
+
depths.set(node, depth);
|
|
102
|
+
// Get neighbors and add unvisited ones to queue
|
|
103
|
+
const neighbors = this.getNeighborsWithRelations(node, opts);
|
|
104
|
+
for (const { neighbor } of neighbors) {
|
|
105
|
+
if (!visited.has(neighbor)) {
|
|
106
|
+
visited.add(neighbor);
|
|
107
|
+
queue.push({ node: neighbor, depth: depth + 1 });
|
|
108
|
+
parents.set(neighbor, node);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { nodes, depths, parents };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Depth-First Search traversal starting from a given entity.
|
|
116
|
+
*
|
|
117
|
+
* @param startEntity - Entity name to start traversal from
|
|
118
|
+
* @param options - Traversal options
|
|
119
|
+
* @returns Traversal result with visited nodes, depths, and parent pointers
|
|
120
|
+
*/
|
|
121
|
+
dfs(startEntity, options = {}) {
|
|
122
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
123
|
+
// Validate start entity exists
|
|
124
|
+
if (!this.storage.hasEntity(startEntity)) {
|
|
125
|
+
return { nodes: [], depths: new Map(), parents: new Map() };
|
|
126
|
+
}
|
|
127
|
+
const visited = new Set();
|
|
128
|
+
const stack = [{ node: startEntity, depth: 0 }];
|
|
129
|
+
const nodes = [];
|
|
130
|
+
const depths = new Map();
|
|
131
|
+
const parents = new Map();
|
|
132
|
+
parents.set(startEntity, null);
|
|
133
|
+
while (stack.length > 0) {
|
|
134
|
+
const { node, depth } = stack.pop();
|
|
135
|
+
// Skip if already visited
|
|
136
|
+
if (visited.has(node))
|
|
137
|
+
continue;
|
|
138
|
+
// Respect maxDepth limit
|
|
139
|
+
if (depth > opts.maxDepth)
|
|
140
|
+
continue;
|
|
141
|
+
visited.add(node);
|
|
142
|
+
nodes.push(node);
|
|
143
|
+
depths.set(node, depth);
|
|
144
|
+
// Get neighbors and add unvisited ones to stack
|
|
145
|
+
const neighbors = this.getNeighborsWithRelations(node, opts);
|
|
146
|
+
for (const { neighbor } of neighbors) {
|
|
147
|
+
if (!visited.has(neighbor)) {
|
|
148
|
+
stack.push({ node: neighbor, depth: depth + 1 });
|
|
149
|
+
if (!parents.has(neighbor)) {
|
|
150
|
+
parents.set(neighbor, node);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return { nodes, depths, parents };
|
|
156
|
+
}
|
|
157
|
+
// ==================== Sprint 7: Path Finding Algorithms ====================
|
|
158
|
+
/**
|
|
159
|
+
* Find the shortest path between two entities using BFS.
|
|
160
|
+
*
|
|
161
|
+
* @param source - Source entity name
|
|
162
|
+
* @param target - Target entity name
|
|
163
|
+
* @param options - Traversal options
|
|
164
|
+
* @returns PathResult if path exists, null otherwise
|
|
165
|
+
*/
|
|
166
|
+
async findShortestPath(source, target, options = {}) {
|
|
167
|
+
// Ensure graph is loaded to populate indexes
|
|
168
|
+
await this.storage.loadGraph();
|
|
169
|
+
// Validate entities exist
|
|
170
|
+
if (!this.storage.hasEntity(source) || !this.storage.hasEntity(target)) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
// Same source and target
|
|
174
|
+
if (source === target) {
|
|
175
|
+
return { path: [source], length: 0, relations: [] };
|
|
176
|
+
}
|
|
177
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
178
|
+
const visited = new Set();
|
|
179
|
+
const queue = [source];
|
|
180
|
+
const parents = new Map();
|
|
181
|
+
visited.add(source);
|
|
182
|
+
parents.set(source, null);
|
|
183
|
+
while (queue.length > 0) {
|
|
184
|
+
const current = queue.shift();
|
|
185
|
+
// Found target, reconstruct path
|
|
186
|
+
if (current === target) {
|
|
187
|
+
return this.reconstructPath(source, target, parents);
|
|
188
|
+
}
|
|
189
|
+
// Get neighbors
|
|
190
|
+
const neighbors = this.getNeighborsWithRelations(current, opts);
|
|
191
|
+
for (const { neighbor, relation } of neighbors) {
|
|
192
|
+
if (!visited.has(neighbor)) {
|
|
193
|
+
visited.add(neighbor);
|
|
194
|
+
queue.push(neighbor);
|
|
195
|
+
parents.set(neighbor, { parent: current, relation });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// No path found
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Reconstruct path from parent pointers.
|
|
204
|
+
*/
|
|
205
|
+
reconstructPath(_source, target, parents) {
|
|
206
|
+
const path = [];
|
|
207
|
+
const relations = [];
|
|
208
|
+
let current = target;
|
|
209
|
+
while (current !== null) {
|
|
210
|
+
path.unshift(current);
|
|
211
|
+
const parentInfo = parents.get(current);
|
|
212
|
+
if (parentInfo) {
|
|
213
|
+
relations.unshift(parentInfo.relation);
|
|
214
|
+
current = parentInfo.parent;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
current = null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
path,
|
|
222
|
+
length: path.length - 1,
|
|
223
|
+
relations,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Find all paths between two entities up to a maximum depth.
|
|
228
|
+
*
|
|
229
|
+
* Phase 9B: Supports cancellation via AbortSignal in options.
|
|
230
|
+
*
|
|
231
|
+
* @param source - Source entity name
|
|
232
|
+
* @param target - Target entity name
|
|
233
|
+
* @param maxDepth - Maximum path length (default: 5)
|
|
234
|
+
* @param options - Traversal options (includes signal for cancellation)
|
|
235
|
+
* @returns Array of PathResult objects for all found paths
|
|
236
|
+
* @throws {OperationCancelledError} If operation is cancelled via signal (Phase 9B)
|
|
237
|
+
*/
|
|
238
|
+
async findAllPaths(source, target, maxDepth = 5, options = {}) {
|
|
239
|
+
// Check for early cancellation
|
|
240
|
+
const { signal, ...traversalOptions } = options;
|
|
241
|
+
checkCancellation(signal, 'findAllPaths');
|
|
242
|
+
// Ensure graph is loaded to populate indexes
|
|
243
|
+
await this.storage.loadGraph();
|
|
244
|
+
// Check for cancellation after load
|
|
245
|
+
checkCancellation(signal, 'findAllPaths');
|
|
246
|
+
// Validate entities exist
|
|
247
|
+
if (!this.storage.hasEntity(source) || !this.storage.hasEntity(target)) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
const opts = { ...DEFAULT_OPTIONS, ...traversalOptions };
|
|
251
|
+
const allPaths = [];
|
|
252
|
+
const currentPath = [source];
|
|
253
|
+
const currentRelations = [];
|
|
254
|
+
const visited = new Set([source]);
|
|
255
|
+
// Track iterations for periodic cancellation checks
|
|
256
|
+
let iterationCount = 0;
|
|
257
|
+
const CANCELLATION_CHECK_INTERVAL = 100;
|
|
258
|
+
const dfsAllPaths = (current, depth) => {
|
|
259
|
+
// Periodic cancellation check
|
|
260
|
+
iterationCount++;
|
|
261
|
+
if (iterationCount % CANCELLATION_CHECK_INTERVAL === 0) {
|
|
262
|
+
checkCancellation(signal, 'findAllPaths');
|
|
263
|
+
}
|
|
264
|
+
if (depth > maxDepth)
|
|
265
|
+
return;
|
|
266
|
+
if (current === target && depth > 0) {
|
|
267
|
+
allPaths.push({
|
|
268
|
+
path: [...currentPath],
|
|
269
|
+
length: currentPath.length - 1,
|
|
270
|
+
relations: [...currentRelations],
|
|
271
|
+
});
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const neighbors = this.getNeighborsWithRelations(current, opts);
|
|
275
|
+
for (const { neighbor, relation } of neighbors) {
|
|
276
|
+
if (!visited.has(neighbor)) {
|
|
277
|
+
visited.add(neighbor);
|
|
278
|
+
currentPath.push(neighbor);
|
|
279
|
+
currentRelations.push(relation);
|
|
280
|
+
dfsAllPaths(neighbor, depth + 1);
|
|
281
|
+
currentPath.pop();
|
|
282
|
+
currentRelations.pop();
|
|
283
|
+
visited.delete(neighbor);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
dfsAllPaths(source, 0);
|
|
288
|
+
return allPaths;
|
|
289
|
+
}
|
|
290
|
+
// ==================== Sprint 8: Connected Components ====================
|
|
291
|
+
/**
|
|
292
|
+
* Find all connected components in the graph.
|
|
293
|
+
*
|
|
294
|
+
* Uses BFS to find all weakly connected components (treating the graph as undirected).
|
|
295
|
+
*
|
|
296
|
+
* @returns ConnectedComponentsResult with all components
|
|
297
|
+
*/
|
|
298
|
+
async findConnectedComponents() {
|
|
299
|
+
const graph = await this.storage.loadGraph();
|
|
300
|
+
const visited = new Set();
|
|
301
|
+
const components = [];
|
|
302
|
+
for (const entity of graph.entities) {
|
|
303
|
+
if (!visited.has(entity.name)) {
|
|
304
|
+
// BFS to find all nodes in this component
|
|
305
|
+
const component = [];
|
|
306
|
+
const queue = [entity.name];
|
|
307
|
+
visited.add(entity.name);
|
|
308
|
+
while (queue.length > 0) {
|
|
309
|
+
const current = queue.shift();
|
|
310
|
+
component.push(current);
|
|
311
|
+
// Get all neighbors (both directions for weakly connected)
|
|
312
|
+
const neighbors = this.getNeighborsWithRelations(current, { direction: 'both' });
|
|
313
|
+
for (const { neighbor } of neighbors) {
|
|
314
|
+
if (!visited.has(neighbor)) {
|
|
315
|
+
visited.add(neighbor);
|
|
316
|
+
queue.push(neighbor);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
components.push(component);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Sort components by size (largest first)
|
|
324
|
+
components.sort((a, b) => b.length - a.length);
|
|
325
|
+
return {
|
|
326
|
+
components,
|
|
327
|
+
count: components.length,
|
|
328
|
+
largestComponentSize: components.length > 0 ? components[0].length : 0,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
// ==================== Sprint 8: Centrality Algorithms ====================
|
|
332
|
+
/**
|
|
333
|
+
* Calculate degree centrality for all entities.
|
|
334
|
+
*
|
|
335
|
+
* Degree centrality is the number of connections an entity has,
|
|
336
|
+
* normalized by the maximum possible connections.
|
|
337
|
+
*
|
|
338
|
+
* @param direction - Direction to count: 'in', 'out', or 'both' (default)
|
|
339
|
+
* @param topN - Number of top entities to return (default: 10)
|
|
340
|
+
* @returns CentralityResult with scores and top entities
|
|
341
|
+
*/
|
|
342
|
+
async calculateDegreeCentrality(direction = 'both', topN = 10) {
|
|
343
|
+
const graph = await this.storage.loadGraph();
|
|
344
|
+
const scores = new Map();
|
|
345
|
+
const n = graph.entities.length;
|
|
346
|
+
// Calculate degree for each entity
|
|
347
|
+
for (const entity of graph.entities) {
|
|
348
|
+
let degree = 0;
|
|
349
|
+
if (direction === 'in' || direction === 'both') {
|
|
350
|
+
degree += this.storage.getRelationsTo(entity.name).length;
|
|
351
|
+
}
|
|
352
|
+
if (direction === 'out' || direction === 'both') {
|
|
353
|
+
degree += this.storage.getRelationsFrom(entity.name).length;
|
|
354
|
+
}
|
|
355
|
+
// Normalize by maximum possible degree
|
|
356
|
+
const normalizedDegree = n > 1 ? degree / (n - 1) : 0;
|
|
357
|
+
scores.set(entity.name, normalizedDegree);
|
|
358
|
+
}
|
|
359
|
+
// Get top N entities
|
|
360
|
+
const topEntities = this.getTopEntities(scores, topN);
|
|
361
|
+
return {
|
|
362
|
+
scores,
|
|
363
|
+
topEntities,
|
|
364
|
+
algorithm: 'degree',
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Calculate betweenness centrality for all entities.
|
|
369
|
+
*
|
|
370
|
+
* Betweenness centrality measures how often a node appears on shortest paths
|
|
371
|
+
* between other nodes. Uses Brandes' algorithm for efficiency.
|
|
372
|
+
*
|
|
373
|
+
* @param options - Configuration options
|
|
374
|
+
* @param options.topN - Number of top entities to return (default: 10)
|
|
375
|
+
* @param options.chunkSize - Yield control every N vertices (default: 50)
|
|
376
|
+
* @param options.onProgress - Progress callback (0.0 to 1.0)
|
|
377
|
+
* @param options.approximate - Use approximation for faster results (default: false)
|
|
378
|
+
* @param options.sampleRate - Sample rate for approximation (default: 0.2)
|
|
379
|
+
* @returns CentralityResult with scores and top entities
|
|
380
|
+
*/
|
|
381
|
+
async calculateBetweennessCentrality(options = {}) {
|
|
382
|
+
const { topN = 10, chunkSize = 50, onProgress, approximate = false, sampleRate = 0.2 } = options;
|
|
383
|
+
const graph = await this.storage.loadGraph();
|
|
384
|
+
const scores = new Map();
|
|
385
|
+
// Initialize scores
|
|
386
|
+
for (const entity of graph.entities) {
|
|
387
|
+
scores.set(entity.name, 0);
|
|
388
|
+
}
|
|
389
|
+
// Determine which sources to process (full or sampled)
|
|
390
|
+
let sourcesToProcess = graph.entities;
|
|
391
|
+
if (approximate && graph.entities.length > 100) {
|
|
392
|
+
const sampleSize = Math.max(10, Math.floor(graph.entities.length * sampleRate));
|
|
393
|
+
sourcesToProcess = this.sampleEntities(graph.entities, sampleSize);
|
|
394
|
+
}
|
|
395
|
+
// Brandes' algorithm with chunked processing
|
|
396
|
+
let processed = 0;
|
|
397
|
+
for (const source of sourcesToProcess) {
|
|
398
|
+
const stack = [];
|
|
399
|
+
const predecessors = new Map();
|
|
400
|
+
const sigma = new Map(); // Number of shortest paths
|
|
401
|
+
const distance = new Map(); // Distance from source
|
|
402
|
+
const delta = new Map(); // Dependency
|
|
403
|
+
// Initialize
|
|
404
|
+
for (const entity of graph.entities) {
|
|
405
|
+
predecessors.set(entity.name, []);
|
|
406
|
+
sigma.set(entity.name, 0);
|
|
407
|
+
distance.set(entity.name, -1);
|
|
408
|
+
delta.set(entity.name, 0);
|
|
409
|
+
}
|
|
410
|
+
sigma.set(source.name, 1);
|
|
411
|
+
distance.set(source.name, 0);
|
|
412
|
+
// BFS
|
|
413
|
+
const queue = [source.name];
|
|
414
|
+
while (queue.length > 0) {
|
|
415
|
+
const v = queue.shift();
|
|
416
|
+
stack.push(v);
|
|
417
|
+
const neighbors = this.getNeighborsWithRelations(v, { direction: 'both' });
|
|
418
|
+
for (const { neighbor: w } of neighbors) {
|
|
419
|
+
// First time w is discovered
|
|
420
|
+
if (distance.get(w) === -1) {
|
|
421
|
+
distance.set(w, distance.get(v) + 1);
|
|
422
|
+
queue.push(w);
|
|
423
|
+
}
|
|
424
|
+
// w is on a shortest path from source via v
|
|
425
|
+
if (distance.get(w) === distance.get(v) + 1) {
|
|
426
|
+
sigma.set(w, sigma.get(w) + sigma.get(v));
|
|
427
|
+
predecessors.get(w).push(v);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Accumulation
|
|
432
|
+
while (stack.length > 0) {
|
|
433
|
+
const w = stack.pop();
|
|
434
|
+
for (const v of predecessors.get(w)) {
|
|
435
|
+
const contribution = (sigma.get(v) / sigma.get(w)) * (1 + delta.get(w));
|
|
436
|
+
delta.set(v, delta.get(v) + contribution);
|
|
437
|
+
}
|
|
438
|
+
if (w !== source.name) {
|
|
439
|
+
scores.set(w, scores.get(w) + delta.get(w));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// Yield control periodically to prevent blocking event loop
|
|
443
|
+
processed++;
|
|
444
|
+
if (processed % chunkSize === 0) {
|
|
445
|
+
// Yield control to allow event loop to process other events
|
|
446
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
447
|
+
// Report progress
|
|
448
|
+
if (onProgress) {
|
|
449
|
+
onProgress(processed / sourcesToProcess.length);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// Final progress update
|
|
454
|
+
if (onProgress) {
|
|
455
|
+
onProgress(1);
|
|
456
|
+
}
|
|
457
|
+
// Scale scores if using approximation
|
|
458
|
+
if (approximate && sampleRate < 1.0) {
|
|
459
|
+
const scaleFactor = 1 / sampleRate;
|
|
460
|
+
for (const [entity, score] of scores) {
|
|
461
|
+
scores.set(entity, score * scaleFactor);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// Normalize scores
|
|
465
|
+
const n = graph.entities.length;
|
|
466
|
+
const normalization = n > 2 ? 2 / ((n - 1) * (n - 2)) : 1;
|
|
467
|
+
for (const [name, score] of scores) {
|
|
468
|
+
scores.set(name, score * normalization);
|
|
469
|
+
}
|
|
470
|
+
const topEntities = this.getTopEntities(scores, topN);
|
|
471
|
+
return {
|
|
472
|
+
scores,
|
|
473
|
+
topEntities,
|
|
474
|
+
algorithm: 'betweenness',
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Sample entities randomly for approximation algorithms.
|
|
479
|
+
*
|
|
480
|
+
* @param entities - Array of entities to sample from
|
|
481
|
+
* @param sampleSize - Number of entities to sample
|
|
482
|
+
* @returns Array of sampled entities
|
|
483
|
+
*/
|
|
484
|
+
sampleEntities(entities, sampleSize) {
|
|
485
|
+
const shuffled = [...entities];
|
|
486
|
+
// Fisher-Yates shuffle
|
|
487
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
488
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
489
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
490
|
+
}
|
|
491
|
+
return shuffled.slice(0, sampleSize);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Calculate PageRank centrality for all entities.
|
|
495
|
+
*
|
|
496
|
+
* PageRank measures importance based on incoming connections from
|
|
497
|
+
* other important nodes. Uses iterative power method.
|
|
498
|
+
*
|
|
499
|
+
* @param dampingFactor - Damping factor (default: 0.85)
|
|
500
|
+
* @param maxIterations - Maximum iterations (default: 100)
|
|
501
|
+
* @param tolerance - Convergence tolerance (default: 1e-6)
|
|
502
|
+
* @param topN - Number of top entities to return (default: 10)
|
|
503
|
+
* @returns CentralityResult with scores and top entities
|
|
504
|
+
*/
|
|
505
|
+
async calculatePageRank(dampingFactor = 0.85, maxIterations = 100, tolerance = 1e-6, topN = 10) {
|
|
506
|
+
const graph = await this.storage.loadGraph();
|
|
507
|
+
const n = graph.entities.length;
|
|
508
|
+
if (n === 0) {
|
|
509
|
+
return { scores: new Map(), topEntities: [], algorithm: 'pagerank' };
|
|
510
|
+
}
|
|
511
|
+
// Initialize PageRank scores
|
|
512
|
+
const scores = new Map();
|
|
513
|
+
const initialScore = 1 / n;
|
|
514
|
+
for (const entity of graph.entities) {
|
|
515
|
+
scores.set(entity.name, initialScore);
|
|
516
|
+
}
|
|
517
|
+
// Build outgoing links map
|
|
518
|
+
const outLinks = new Map();
|
|
519
|
+
for (const entity of graph.entities) {
|
|
520
|
+
const outgoing = this.storage.getRelationsFrom(entity.name);
|
|
521
|
+
outLinks.set(entity.name, outgoing.map(r => r.to));
|
|
522
|
+
}
|
|
523
|
+
// Power iteration
|
|
524
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
525
|
+
const newScores = new Map();
|
|
526
|
+
let totalDiff = 0;
|
|
527
|
+
// Calculate dangling node contribution (nodes with no outgoing links)
|
|
528
|
+
let danglingSum = 0;
|
|
529
|
+
for (const entity of graph.entities) {
|
|
530
|
+
if (outLinks.get(entity.name).length === 0) {
|
|
531
|
+
danglingSum += scores.get(entity.name);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const danglingContribution = (dampingFactor * danglingSum) / n;
|
|
535
|
+
// Calculate new scores
|
|
536
|
+
for (const entity of graph.entities) {
|
|
537
|
+
let incomingScore = 0;
|
|
538
|
+
const incoming = this.storage.getRelationsTo(entity.name);
|
|
539
|
+
for (const relation of incoming) {
|
|
540
|
+
const source = relation.from;
|
|
541
|
+
const sourceOutCount = outLinks.get(source)?.length || 1;
|
|
542
|
+
incomingScore += scores.get(source) / sourceOutCount;
|
|
543
|
+
}
|
|
544
|
+
const newScore = (1 - dampingFactor) / n + dampingFactor * incomingScore + danglingContribution;
|
|
545
|
+
newScores.set(entity.name, newScore);
|
|
546
|
+
totalDiff += Math.abs(newScore - scores.get(entity.name));
|
|
547
|
+
}
|
|
548
|
+
// Update scores
|
|
549
|
+
for (const [name, score] of newScores) {
|
|
550
|
+
scores.set(name, score);
|
|
551
|
+
}
|
|
552
|
+
// Check convergence
|
|
553
|
+
if (totalDiff < tolerance) {
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
const topEntities = this.getTopEntities(scores, topN);
|
|
558
|
+
return {
|
|
559
|
+
scores,
|
|
560
|
+
topEntities,
|
|
561
|
+
algorithm: 'pagerank',
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Get top N entities from a scores map.
|
|
566
|
+
*/
|
|
567
|
+
getTopEntities(scores, topN) {
|
|
568
|
+
return Array.from(scores.entries())
|
|
569
|
+
.sort((a, b) => b[1] - a[1])
|
|
570
|
+
.slice(0, topN)
|
|
571
|
+
.map(([name, score]) => ({ name, score }));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchy Manager
|
|
3
|
+
*
|
|
4
|
+
* Handles entity hierarchy operations (parent-child relationships).
|
|
5
|
+
* Extracted from EntityManager (Phase 4: Consolidate God Objects).
|
|
6
|
+
*
|
|
7
|
+
* @module core/HierarchyManager
|
|
8
|
+
*/
|
|
9
|
+
import type { Entity, KnowledgeGraph } from '../types/index.js';
|
|
10
|
+
import type { GraphStorage } from './GraphStorage.js';
|
|
11
|
+
/**
|
|
12
|
+
* Manages hierarchical relationships between entities.
|
|
13
|
+
*/
|
|
14
|
+
export declare class HierarchyManager {
|
|
15
|
+
private storage;
|
|
16
|
+
constructor(storage: GraphStorage);
|
|
17
|
+
/**
|
|
18
|
+
* Set the parent of an entity.
|
|
19
|
+
*
|
|
20
|
+
* Validates:
|
|
21
|
+
* - Entity and parent exist
|
|
22
|
+
* - Setting parent won't create a cycle
|
|
23
|
+
*
|
|
24
|
+
* @param entityName - Entity to set parent for
|
|
25
|
+
* @param parentName - Parent entity name (null to remove parent)
|
|
26
|
+
* @returns Updated entity
|
|
27
|
+
* @throws {EntityNotFoundError} If entity or parent not found
|
|
28
|
+
* @throws {CycleDetectedError} If setting parent would create a cycle
|
|
29
|
+
*/
|
|
30
|
+
setEntityParent(entityName: string, parentName: string | null): Promise<Entity>;
|
|
31
|
+
/**
|
|
32
|
+
* Check if setting a parent would create a cycle in the hierarchy.
|
|
33
|
+
*
|
|
34
|
+
* @param graph - Knowledge graph
|
|
35
|
+
* @param entityName - Entity to set parent for
|
|
36
|
+
* @param parentName - Proposed parent
|
|
37
|
+
* @returns True if cycle would be created
|
|
38
|
+
*/
|
|
39
|
+
private wouldCreateCycle;
|
|
40
|
+
/**
|
|
41
|
+
* Get the immediate children of an entity.
|
|
42
|
+
*
|
|
43
|
+
* @param entityName - Parent entity name
|
|
44
|
+
* @returns Array of child entities
|
|
45
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
46
|
+
*/
|
|
47
|
+
getChildren(entityName: string): Promise<Entity[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Get the parent of an entity.
|
|
50
|
+
*
|
|
51
|
+
* @param entityName - Entity name
|
|
52
|
+
* @returns Parent entity or null if no parent
|
|
53
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
54
|
+
*/
|
|
55
|
+
getParent(entityName: string): Promise<Entity | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Get all ancestors of an entity (parent, grandparent, etc.).
|
|
58
|
+
*
|
|
59
|
+
* @param entityName - Entity name
|
|
60
|
+
* @returns Array of ancestor entities (ordered from immediate parent to root)
|
|
61
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
62
|
+
*/
|
|
63
|
+
getAncestors(entityName: string): Promise<Entity[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Get all descendants of an entity (children, grandchildren, etc.).
|
|
66
|
+
*
|
|
67
|
+
* Uses breadth-first traversal.
|
|
68
|
+
*
|
|
69
|
+
* @param entityName - Entity name
|
|
70
|
+
* @returns Array of descendant entities
|
|
71
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
72
|
+
*/
|
|
73
|
+
getDescendants(entityName: string): Promise<Entity[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Get the entire subtree rooted at an entity (entity + all descendants).
|
|
76
|
+
*
|
|
77
|
+
* Includes relations between entities in the subtree.
|
|
78
|
+
*
|
|
79
|
+
* @param entityName - Root entity name
|
|
80
|
+
* @returns Knowledge graph containing subtree
|
|
81
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
82
|
+
*/
|
|
83
|
+
getSubtree(entityName: string): Promise<KnowledgeGraph>;
|
|
84
|
+
/**
|
|
85
|
+
* Get root entities (entities with no parent).
|
|
86
|
+
*
|
|
87
|
+
* @returns Array of root entities
|
|
88
|
+
*/
|
|
89
|
+
getRootEntities(): Promise<Entity[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Get the depth of an entity in the hierarchy.
|
|
92
|
+
*
|
|
93
|
+
* Root entities have depth 0, their children depth 1, etc.
|
|
94
|
+
*
|
|
95
|
+
* @param entityName - Entity name
|
|
96
|
+
* @returns Depth (number of ancestors)
|
|
97
|
+
* @throws {EntityNotFoundError} If entity not found
|
|
98
|
+
*/
|
|
99
|
+
getEntityDepth(entityName: string): Promise<number>;
|
|
100
|
+
/**
|
|
101
|
+
* Move an entity to a new parent (maintaining its descendants).
|
|
102
|
+
*
|
|
103
|
+
* Alias for setEntityParent.
|
|
104
|
+
*
|
|
105
|
+
* @param entityName - Entity to move
|
|
106
|
+
* @param newParentName - New parent name (null to make root)
|
|
107
|
+
* @returns Updated entity
|
|
108
|
+
*/
|
|
109
|
+
moveEntity(entityName: string, newParentName: string | null): Promise<Entity>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=HierarchyManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HierarchyManager.d.ts","sourceRoot":"","sources":["../../src/core/HierarchyManager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAA0B,MAAM,mBAAmB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAEzC;;;;;;;;;;;;OAYG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCrF;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;;;;;OAMG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWxD;;;;;;OAMG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgB3D;;;;;;OAMG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBzD;;;;;;;;OAQG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwB3D;;;;;;;;OAQG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuB7D;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAK1C;;;;;;;;OAQG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKzD;;;;;;;;OAQG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CAGpF"}
|