dbgraph 0.1.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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +347 -0
  3. package/dist/bin/dbgraph.d.ts +8 -0
  4. package/dist/bin/dbgraph.d.ts.map +1 -0
  5. package/dist/bin/dbgraph.js +382 -0
  6. package/dist/bin/dbgraph.js.map +1 -0
  7. package/dist/config.d.ts +25 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +158 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/context/formatter.d.ts +94 -0
  12. package/dist/context/formatter.d.ts.map +1 -0
  13. package/dist/context/formatter.js +288 -0
  14. package/dist/context/formatter.js.map +1 -0
  15. package/dist/context/index.d.ts +77 -0
  16. package/dist/context/index.d.ts.map +1 -0
  17. package/dist/context/index.js +458 -0
  18. package/dist/context/index.js.map +1 -0
  19. package/dist/db/index.d.ts +26 -0
  20. package/dist/db/index.d.ts.map +1 -0
  21. package/dist/db/index.js +127 -0
  22. package/dist/db/index.js.map +1 -0
  23. package/dist/db/migrations.d.ts +8 -0
  24. package/dist/db/migrations.d.ts.map +1 -0
  25. package/dist/db/migrations.js +39 -0
  26. package/dist/db/migrations.js.map +1 -0
  27. package/dist/db/queries.d.ts +46 -0
  28. package/dist/db/queries.d.ts.map +1 -0
  29. package/dist/db/queries.js +436 -0
  30. package/dist/db/queries.js.map +1 -0
  31. package/dist/db/schema.sql +113 -0
  32. package/dist/db/sqlite-adapter.d.ts +30 -0
  33. package/dist/db/sqlite-adapter.d.ts.map +1 -0
  34. package/dist/db/sqlite-adapter.js +78 -0
  35. package/dist/db/sqlite-adapter.js.map +1 -0
  36. package/dist/directory.d.ts +37 -0
  37. package/dist/directory.d.ts.map +1 -0
  38. package/dist/directory.js +160 -0
  39. package/dist/directory.js.map +1 -0
  40. package/dist/errors.d.ts +46 -0
  41. package/dist/errors.d.ts.map +1 -0
  42. package/dist/errors.js +90 -0
  43. package/dist/errors.js.map +1 -0
  44. package/dist/graph/traversal.d.ts +157 -0
  45. package/dist/graph/traversal.d.ts.map +1 -0
  46. package/dist/graph/traversal.js +531 -0
  47. package/dist/graph/traversal.js.map +1 -0
  48. package/dist/index.d.ts +183 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +435 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/introspect/base.d.ts +62 -0
  53. package/dist/introspect/base.d.ts.map +1 -0
  54. package/dist/introspect/base.js +107 -0
  55. package/dist/introspect/base.js.map +1 -0
  56. package/dist/introspect/connection.d.ts +30 -0
  57. package/dist/introspect/connection.d.ts.map +1 -0
  58. package/dist/introspect/connection.js +232 -0
  59. package/dist/introspect/connection.js.map +1 -0
  60. package/dist/introspect/index.d.ts +23 -0
  61. package/dist/introspect/index.d.ts.map +1 -0
  62. package/dist/introspect/index.js +46 -0
  63. package/dist/introspect/index.js.map +1 -0
  64. package/dist/introspect/mysql.d.ts +64 -0
  65. package/dist/introspect/mysql.d.ts.map +1 -0
  66. package/dist/introspect/mysql.js +360 -0
  67. package/dist/introspect/mysql.js.map +1 -0
  68. package/dist/introspect/postgres.d.ts +55 -0
  69. package/dist/introspect/postgres.d.ts.map +1 -0
  70. package/dist/introspect/postgres.js +372 -0
  71. package/dist/introspect/postgres.js.map +1 -0
  72. package/dist/introspect/sqlite.d.ts +33 -0
  73. package/dist/introspect/sqlite.d.ts.map +1 -0
  74. package/dist/introspect/sqlite.js +207 -0
  75. package/dist/introspect/sqlite.js.map +1 -0
  76. package/dist/mcp/engine.d.ts +92 -0
  77. package/dist/mcp/engine.d.ts.map +1 -0
  78. package/dist/mcp/engine.js +261 -0
  79. package/dist/mcp/engine.js.map +1 -0
  80. package/dist/mcp/index.d.ts +33 -0
  81. package/dist/mcp/index.d.ts.map +1 -0
  82. package/dist/mcp/index.js +119 -0
  83. package/dist/mcp/index.js.map +1 -0
  84. package/dist/mcp/server-instructions.d.ts +9 -0
  85. package/dist/mcp/server-instructions.d.ts.map +1 -0
  86. package/dist/mcp/server-instructions.js +71 -0
  87. package/dist/mcp/server-instructions.js.map +1 -0
  88. package/dist/mcp/session.d.ts +35 -0
  89. package/dist/mcp/session.d.ts.map +1 -0
  90. package/dist/mcp/session.js +140 -0
  91. package/dist/mcp/session.js.map +1 -0
  92. package/dist/mcp/tools.d.ts +99 -0
  93. package/dist/mcp/tools.d.ts.map +1 -0
  94. package/dist/mcp/tools.js +499 -0
  95. package/dist/mcp/tools.js.map +1 -0
  96. package/dist/mcp/transport.d.ts +78 -0
  97. package/dist/mcp/transport.d.ts.map +1 -0
  98. package/dist/mcp/transport.js +182 -0
  99. package/dist/mcp/transport.js.map +1 -0
  100. package/dist/search/query-parser.d.ts +66 -0
  101. package/dist/search/query-parser.d.ts.map +1 -0
  102. package/dist/search/query-parser.js +163 -0
  103. package/dist/search/query-parser.js.map +1 -0
  104. package/dist/search/query-utils.d.ts +78 -0
  105. package/dist/search/query-utils.d.ts.map +1 -0
  106. package/dist/search/query-utils.js +203 -0
  107. package/dist/search/query-utils.js.map +1 -0
  108. package/dist/types.d.ts +279 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/types.js +47 -0
  111. package/dist/types.js.map +1 -0
  112. package/dist/utils.d.ts +40 -0
  113. package/dist/utils.d.ts.map +1 -0
  114. package/dist/utils.js +190 -0
  115. package/dist/utils.js.map +1 -0
  116. package/package.json +54 -0
@@ -0,0 +1,531 @@
1
+ "use strict";
2
+ /**
3
+ * Graph Traversal Algorithms
4
+ *
5
+ * BFS and DFS traversal for the database schema knowledge graph.
6
+ * Operates on nodes/edges stored in SQLite via QueryBuilder.
7
+ *
8
+ * All traversal methods use batch node lookups (getNodesByIds) to avoid
9
+ * N+1 query patterns and maintain performance on large schemas.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.GraphTraverser = void 0;
13
+ /**
14
+ * Default traversal options
15
+ */
16
+ const DEFAULT_OPTIONS = {
17
+ maxDepth: Infinity,
18
+ edgeKinds: [],
19
+ nodeKinds: [],
20
+ direction: 'outgoing',
21
+ limit: 1000,
22
+ includeStart: true,
23
+ };
24
+ /**
25
+ * Graph traverser for BFS and DFS traversal of the database schema graph.
26
+ *
27
+ * Provides methods to navigate the graph structure — containment hierarchies,
28
+ * foreign-key references, and impact analysis — all with batched queries.
29
+ */
30
+ class GraphTraverser {
31
+ queries;
32
+ constructor(queries) {
33
+ this.queries = queries;
34
+ }
35
+ // ===========================================================================
36
+ // Core Traversal
37
+ // ===========================================================================
38
+ /**
39
+ * Traverse the graph using breadth-first search.
40
+ *
41
+ * Structural edges (`contains`) are visited before reference edges so that
42
+ * BFS discovers internal structure first before fanning out.
43
+ *
44
+ * @param startId - Starting node ID
45
+ * @param options - Traversal options
46
+ * @returns Subgraph containing traversed nodes and edges
47
+ */
48
+ traverseBFS(startId, options = {}) {
49
+ const opts = { ...DEFAULT_OPTIONS, ...options };
50
+ const startNode = this.queries.getNodeById(startId);
51
+ if (!startNode) {
52
+ return { nodes: new Map(), edges: [], roots: [] };
53
+ }
54
+ const nodes = new Map();
55
+ const edges = [];
56
+ const visited = new Set();
57
+ const queue = [{ node: startNode, edge: null, depth: 0 }];
58
+ if (opts.includeStart) {
59
+ nodes.set(startNode.id, startNode);
60
+ }
61
+ while (queue.length > 0 && nodes.size < opts.limit) {
62
+ const step = queue.shift();
63
+ const { node, edge, depth } = step;
64
+ if (visited.has(node.id)) {
65
+ continue;
66
+ }
67
+ visited.add(node.id);
68
+ // Add edge to result
69
+ if (edge) {
70
+ edges.push(edge);
71
+ }
72
+ // Check depth limit
73
+ if (depth >= opts.maxDepth) {
74
+ continue;
75
+ }
76
+ // Get adjacent edges, prioritizing containment edges
77
+ const adjacentEdges = this.getAdjacentEdges(node.id, opts.direction, opts.edgeKinds);
78
+ adjacentEdges.sort((a, b) => {
79
+ const priority = (e) => e.kind === 'contains' ? 0 : 1;
80
+ return priority(a) - priority(b);
81
+ });
82
+ // Batch-fetch the unvisited neighbors in one query
83
+ const wantIds = adjacentEdges
84
+ .map((e) => (e.source === node.id ? e.target : e.source))
85
+ .filter((id) => !visited.has(id));
86
+ const neighborNodes = wantIds.length > 0 ? this.queries.getNodesByIds(wantIds) : new Map();
87
+ for (const adjEdge of adjacentEdges) {
88
+ const nextNodeId = adjEdge.source === node.id ? adjEdge.target : adjEdge.source;
89
+ if (visited.has(nextNodeId))
90
+ continue;
91
+ const nextNode = neighborNodes.get(nextNodeId);
92
+ if (!nextNode)
93
+ continue;
94
+ if (opts.nodeKinds && opts.nodeKinds.length > 0 && !opts.nodeKinds.includes(nextNode.kind)) {
95
+ continue;
96
+ }
97
+ nodes.set(nextNode.id, nextNode);
98
+ queue.push({ node: nextNode, edge: adjEdge, depth: depth + 1 });
99
+ }
100
+ }
101
+ return {
102
+ nodes,
103
+ edges,
104
+ roots: [startId],
105
+ };
106
+ }
107
+ /**
108
+ * Traverse the graph using depth-first search.
109
+ *
110
+ * @param startId - Starting node ID
111
+ * @param options - Traversal options
112
+ * @returns Subgraph containing traversed nodes and edges
113
+ */
114
+ traverseDFS(startId, options = {}) {
115
+ const opts = { ...DEFAULT_OPTIONS, ...options };
116
+ const startNode = this.queries.getNodeById(startId);
117
+ if (!startNode) {
118
+ return { nodes: new Map(), edges: [], roots: [] };
119
+ }
120
+ const nodes = new Map();
121
+ const edges = [];
122
+ const visited = new Set();
123
+ if (opts.includeStart) {
124
+ nodes.set(startNode.id, startNode);
125
+ }
126
+ this.dfsRecursive(startNode, 0, opts, nodes, edges, visited);
127
+ return {
128
+ nodes,
129
+ edges,
130
+ roots: [startId],
131
+ };
132
+ }
133
+ /**
134
+ * Recursive DFS helper with batch neighbor fetching.
135
+ */
136
+ dfsRecursive(node, depth, opts, nodes, edges, visited) {
137
+ if (visited.has(node.id) || nodes.size >= opts.limit || depth >= opts.maxDepth) {
138
+ return;
139
+ }
140
+ visited.add(node.id);
141
+ // Get adjacent edges
142
+ const adjacentEdges = this.getAdjacentEdges(node.id, opts.direction, opts.edgeKinds);
143
+ // Batch-fetch unvisited neighbors
144
+ const wantIds = adjacentEdges
145
+ .map((e) => (e.source === node.id ? e.target : e.source))
146
+ .filter((id) => !visited.has(id));
147
+ const neighborNodes = wantIds.length > 0 ? this.queries.getNodesByIds(wantIds) : new Map();
148
+ for (const adjEdge of adjacentEdges) {
149
+ const nextNodeId = adjEdge.source === node.id ? adjEdge.target : adjEdge.source;
150
+ if (visited.has(nextNodeId))
151
+ continue;
152
+ const nextNode = neighborNodes.get(nextNodeId);
153
+ if (!nextNode)
154
+ continue;
155
+ // Apply node kind filter
156
+ if (opts.nodeKinds && opts.nodeKinds.length > 0 && !opts.nodeKinds.includes(nextNode.kind)) {
157
+ continue;
158
+ }
159
+ nodes.set(nextNode.id, nextNode);
160
+ edges.push(adjEdge);
161
+ this.dfsRecursive(nextNode, depth + 1, opts, nodes, edges, visited);
162
+ }
163
+ }
164
+ /**
165
+ * Get adjacent edges based on direction.
166
+ */
167
+ getAdjacentEdges(nodeId, direction, edgeKinds) {
168
+ const kinds = edgeKinds && edgeKinds.length > 0 ? edgeKinds : undefined;
169
+ if (direction === 'outgoing') {
170
+ return this.queries.getOutgoingEdges(nodeId, kinds);
171
+ }
172
+ else if (direction === 'incoming') {
173
+ return this.queries.getIncomingEdges(nodeId, kinds);
174
+ }
175
+ else {
176
+ const outgoing = this.queries.getOutgoingEdges(nodeId, kinds);
177
+ const incoming = this.queries.getIncomingEdges(nodeId, kinds);
178
+ return [...outgoing, ...incoming];
179
+ }
180
+ }
181
+ // ===========================================================================
182
+ // Reference Analysis
183
+ // ===========================================================================
184
+ /**
185
+ * Find all nodes that reference a given node (e.g., tables with foreign keys
186
+ * pointing to this table, or views referencing this table).
187
+ *
188
+ * Follows `references` edges incoming to the target.
189
+ *
190
+ * @param nodeId - ID of the node being referenced
191
+ * @param maxDepth - Maximum depth to traverse (default: 1)
192
+ * @returns Array of { caller node, edge } pairs
193
+ */
194
+ getCallers(nodeId, maxDepth = 1) {
195
+ const result = [];
196
+ const visited = new Set();
197
+ this.getCallersRecursive(nodeId, maxDepth, 0, result, visited);
198
+ return result;
199
+ }
200
+ getCallersRecursive(nodeId, maxDepth, currentDepth, result, visited) {
201
+ if (currentDepth >= maxDepth || visited.has(nodeId)) {
202
+ return;
203
+ }
204
+ visited.add(nodeId);
205
+ const incomingEdges = this.queries.getIncomingEdges(nodeId, ['references', 'foreign_key', 'depends_on', 'imports']);
206
+ if (incomingEdges.length === 0)
207
+ return;
208
+ // Batch-fetch all source nodes in one round-trip
209
+ const sourceIds = incomingEdges.map((e) => e.source);
210
+ const callerNodes = this.queries.getNodesByIds(sourceIds);
211
+ for (const edge of incomingEdges) {
212
+ const callerNode = callerNodes.get(edge.source);
213
+ if (callerNode && !visited.has(callerNode.id)) {
214
+ result.push({ node: callerNode, edge });
215
+ this.getCallersRecursive(callerNode.id, maxDepth, currentDepth + 1, result, visited);
216
+ }
217
+ }
218
+ }
219
+ /**
220
+ * Find all nodes referenced by a given node (e.g., tables this foreign key
221
+ * points to, tables this view depends on).
222
+ *
223
+ * Follows `references` edges outgoing from the source.
224
+ *
225
+ * @param nodeId - ID of the source node
226
+ * @param maxDepth - Maximum depth to traverse (default: 1)
227
+ * @returns Array of { callee node, edge } pairs
228
+ */
229
+ getCallees(nodeId, maxDepth = 1) {
230
+ const result = [];
231
+ const visited = new Set();
232
+ this.getCalleesRecursive(nodeId, maxDepth, 0, result, visited);
233
+ return result;
234
+ }
235
+ getCalleesRecursive(nodeId, maxDepth, currentDepth, result, visited) {
236
+ if (currentDepth >= maxDepth || visited.has(nodeId)) {
237
+ return;
238
+ }
239
+ visited.add(nodeId);
240
+ const outgoingEdges = this.queries.getOutgoingEdges(nodeId, ['references', 'foreign_key', 'depends_on', 'imports']);
241
+ if (outgoingEdges.length === 0)
242
+ return;
243
+ // Batch-fetch all target nodes
244
+ const targetIds = outgoingEdges.map((e) => e.target);
245
+ const calleeNodes = this.queries.getNodesByIds(targetIds);
246
+ for (const edge of outgoingEdges) {
247
+ const calleeNode = calleeNodes.get(edge.target);
248
+ if (calleeNode && !visited.has(calleeNode.id)) {
249
+ result.push({ node: calleeNode, edge });
250
+ this.getCalleesRecursive(calleeNode.id, maxDepth, currentDepth + 1, result, visited);
251
+ }
252
+ }
253
+ }
254
+ // ===========================================================================
255
+ // Usage & Impact
256
+ // ===========================================================================
257
+ /**
258
+ * Find all usages of a node — all incoming edges regardless of kind.
259
+ *
260
+ * This returns every node that has any edge pointing to the given node,
261
+ * including foreign key references, dependencies, and structural containment.
262
+ *
263
+ * @param nodeId - ID of the node being examined
264
+ * @returns Array of { using node, edge } pairs
265
+ */
266
+ findUsages(nodeId) {
267
+ const result = [];
268
+ const incomingEdges = this.queries.getIncomingEdges(nodeId);
269
+ if (incomingEdges.length === 0)
270
+ return result;
271
+ // Batch-fetch all source nodes
272
+ const sources = this.queries.getNodesByIds(incomingEdges.map((e) => e.source));
273
+ for (const edge of incomingEdges) {
274
+ const sourceNode = sources.get(edge.source);
275
+ if (sourceNode)
276
+ result.push({ node: sourceNode, edge });
277
+ }
278
+ return result;
279
+ }
280
+ /**
281
+ * Compute the impact radius of a node — all nodes that could be affected
282
+ * if this schema object changes.
283
+ *
284
+ * Traverses incoming edges (dependents), including following `contains`
285
+ * edges into container children (e.g., a column change impacts the table's
286
+ * foreign-key dependents).
287
+ *
288
+ * @param nodeId - ID of the node being changed
289
+ * @param maxDepth - Maximum depth to traverse (default: 3)
290
+ * @returns Subgraph containing potentially impacted nodes
291
+ */
292
+ getImpactRadius(nodeId, maxDepth = 3) {
293
+ const focalNode = this.queries.getNodeById(nodeId);
294
+ if (!focalNode) {
295
+ return { nodes: new Map(), edges: [], roots: [] };
296
+ }
297
+ const nodes = new Map();
298
+ const edges = [];
299
+ const visited = new Set();
300
+ nodes.set(focalNode.id, focalNode);
301
+ this.getImpactRecursive(nodeId, maxDepth, 0, nodes, edges, visited);
302
+ return {
303
+ nodes,
304
+ edges,
305
+ roots: [nodeId],
306
+ };
307
+ }
308
+ /**
309
+ * Recursive impact traversal — follows incoming edges and also descends
310
+ * into container children (e.g., table → columns → FK references).
311
+ */
312
+ getImpactRecursive(nodeId, maxDepth, currentDepth, nodes, edges, visited) {
313
+ if (currentDepth >= maxDepth || visited.has(nodeId)) {
314
+ return;
315
+ }
316
+ visited.add(nodeId);
317
+ // For container nodes (tables, views, schemas), also traverse into their
318
+ // children so that dependents of contained members are discovered
319
+ const focalNode = this.queries.getNodeById(nodeId);
320
+ if (focalNode) {
321
+ const containerKinds = new Set(['table', 'view', 'schema', 'database']);
322
+ if (containerKinds.has(focalNode.kind)) {
323
+ const containsEdges = this.queries.getOutgoingEdges(nodeId, ['contains']);
324
+ if (containsEdges.length > 0) {
325
+ const children = this.queries.getNodesByIds(containsEdges.map((e) => e.target));
326
+ for (const edge of containsEdges) {
327
+ const childNode = children.get(edge.target);
328
+ if (childNode && !visited.has(childNode.id)) {
329
+ nodes.set(childNode.id, childNode);
330
+ edges.push(edge);
331
+ // Recurse into children at the same depth
332
+ this.getImpactRecursive(childNode.id, maxDepth, currentDepth, nodes, edges, visited);
333
+ }
334
+ }
335
+ }
336
+ }
337
+ }
338
+ // Get all incoming edges (things that depend on this node)
339
+ const incomingEdges = this.queries.getIncomingEdges(nodeId);
340
+ if (incomingEdges.length === 0)
341
+ return;
342
+ const sources = this.queries.getNodesByIds(incomingEdges.map((e) => e.source));
343
+ for (const edge of incomingEdges) {
344
+ const sourceNode = sources.get(edge.source);
345
+ if (sourceNode && !nodes.has(sourceNode.id)) {
346
+ nodes.set(sourceNode.id, sourceNode);
347
+ edges.push(edge);
348
+ this.getImpactRecursive(sourceNode.id, maxDepth, currentDepth + 1, nodes, edges, visited);
349
+ }
350
+ }
351
+ }
352
+ // ===========================================================================
353
+ // Path Finding
354
+ // ===========================================================================
355
+ /**
356
+ * Find the shortest path between two nodes using bidirectional BFS.
357
+ *
358
+ * Each step follows outgoing edges from the direction being expanded.
359
+ * Returns the path as an ordered array of { node, edge } steps, where
360
+ * the first entry's `edge` is null (the start node has no incoming edge).
361
+ *
362
+ * @param fromId - Starting node ID
363
+ * @param toId - Target node ID
364
+ * @param edgeKinds - Edge types to consider (all if empty array)
365
+ * @returns Ordered path, or null if no path exists
366
+ */
367
+ findPath(fromId, toId, edgeKinds = []) {
368
+ const fromNode = this.queries.getNodeById(fromId);
369
+ const toNode = this.queries.getNodeById(toId);
370
+ if (!fromNode || !toNode) {
371
+ return null;
372
+ }
373
+ // Short-circuit: same node
374
+ if (fromId === toId) {
375
+ return [{ node: fromNode, edge: null }];
376
+ }
377
+ // Bidirectional BFS
378
+ const kinds = edgeKinds.length > 0 ? edgeKinds : undefined;
379
+ const forwardVisited = new Map();
380
+ const backwardVisited = new Map();
381
+ forwardVisited.set(fromId, [{ node: fromNode, edge: null }]);
382
+ backwardVisited.set(toId, [{ node: toNode, edge: null }]);
383
+ const forwardQueue = [fromId];
384
+ const backwardQueue = [toId];
385
+ while (forwardQueue.length > 0 && backwardQueue.length > 0) {
386
+ // Expand forward frontier
387
+ const meetPoint = this.expandPathFrontier(forwardQueue, forwardVisited, backwardVisited, 'outgoing', kinds);
388
+ if (meetPoint !== null) {
389
+ return this.mergePaths(forwardVisited, backwardVisited, meetPoint);
390
+ }
391
+ // Expand backward frontier
392
+ const meetPoint2 = this.expandPathFrontier(backwardQueue, backwardVisited, forwardVisited, 'incoming', kinds);
393
+ if (meetPoint2 !== null) {
394
+ return this.mergePaths(backwardVisited, forwardVisited, meetPoint2);
395
+ }
396
+ }
397
+ return null; // No path found
398
+ }
399
+ /**
400
+ * Expand one frontier of the bidirectional BFS by one layer.
401
+ *
402
+ * Returns the meeting node ID if frontiers intersect, or null otherwise.
403
+ */
404
+ expandPathFrontier(queue, currentVisited, otherVisited, direction, edgeKinds) {
405
+ const batch = [];
406
+ // Drain current queue into a batch so new pushes don't re-process
407
+ while (queue.length > 0) {
408
+ batch.push(queue.shift());
409
+ }
410
+ // Collect all edges and targets for the batch
411
+ const adjacencyMap = new Map();
412
+ for (const nodeId of batch) {
413
+ const edges = direction === 'outgoing'
414
+ ? this.queries.getOutgoingEdges(nodeId, edgeKinds)
415
+ : this.queries.getIncomingEdges(nodeId, edgeKinds);
416
+ for (const edge of edges) {
417
+ const nextId = direction === 'outgoing' ? edge.target : edge.source;
418
+ if (!adjacencyMap.has(nodeId))
419
+ adjacencyMap.set(nodeId, []);
420
+ adjacencyMap.get(nodeId).push({ nextId, edge });
421
+ }
422
+ }
423
+ // Collect all candidate next IDs for batch fetch
424
+ const allCandidateIds = new Set();
425
+ for (const entries of adjacencyMap.values()) {
426
+ for (const { nextId } of entries) {
427
+ allCandidateIds.add(nextId);
428
+ }
429
+ }
430
+ // Filter to unvisited and batch-fetch
431
+ const wantIds = [...allCandidateIds].filter((id) => !currentVisited.has(id));
432
+ const fetchedNodes = wantIds.length > 0 ? this.queries.getNodesByIds(wantIds) : new Map();
433
+ for (const nodeId of batch) {
434
+ const entries = adjacencyMap.get(nodeId);
435
+ if (!entries)
436
+ continue;
437
+ const currentPath = currentVisited.get(nodeId);
438
+ for (const { nextId, edge } of entries) {
439
+ if (currentVisited.has(nextId))
440
+ continue;
441
+ const nextNode = fetchedNodes.get(nextId);
442
+ if (!nextNode)
443
+ continue;
444
+ const newPath = [...currentPath, { node: nextNode, edge }];
445
+ currentVisited.set(nextId, newPath);
446
+ queue.push(nextId);
447
+ // Check for intersection
448
+ if (otherVisited.has(nextId)) {
449
+ return nextId;
450
+ }
451
+ }
452
+ }
453
+ return null;
454
+ }
455
+ /**
456
+ * Merge forward and backward path fragments at the meeting node.
457
+ */
458
+ mergePaths(forward, backward, meetPoint) {
459
+ const forwardPath = forward.get(meetPoint);
460
+ const backwardPath = backward.get(meetPoint);
461
+ // Backward path is stored from meet → target; reverse and drop the
462
+ // duplicate meet-point node (keep only the forward copy's edge = null head)
463
+ const reversedBackward = backwardPath.slice(1).reverse();
464
+ return [...forwardPath, ...reversedBackward];
465
+ }
466
+ // ===========================================================================
467
+ // Hierarchy
468
+ // ===========================================================================
469
+ /**
470
+ * Walk up the containment hierarchy from a node to its ancestors.
471
+ *
472
+ * Follows `contains` edges in reverse (incoming edges of kind `contains`),
473
+ * which represent "parent → child" — so the incoming edge on this node
474
+ * points to its parent.
475
+ *
476
+ * @param nodeId - ID of the node to start from
477
+ * @returns Array of ancestor nodes from immediate parent to root
478
+ */
479
+ getAncestors(nodeId) {
480
+ const ancestors = [];
481
+ const visited = new Set();
482
+ let currentId = nodeId;
483
+ while (true) {
484
+ if (visited.has(currentId)) {
485
+ break;
486
+ }
487
+ visited.add(currentId);
488
+ // Look for 'contains' edges pointing to this node (it's a child)
489
+ const containingEdges = this.queries.getIncomingEdges(currentId, ['contains']);
490
+ const firstEdge = containingEdges[0];
491
+ if (!firstEdge) {
492
+ break;
493
+ }
494
+ // A node typically has at most one containing parent
495
+ const parentNode = this.queries.getNodeById(firstEdge.source);
496
+ if (parentNode) {
497
+ ancestors.push(parentNode);
498
+ currentId = parentNode.id;
499
+ }
500
+ else {
501
+ break;
502
+ }
503
+ }
504
+ return ancestors;
505
+ }
506
+ /**
507
+ * Get immediate children of a node via `contains` outgoing edges.
508
+ *
509
+ * For a table, these would be its columns, indexes, constraints, etc.
510
+ * For a schema, these would be its tables and views.
511
+ *
512
+ * @param nodeId - ID of the parent node
513
+ * @returns Array of child nodes
514
+ */
515
+ getChildren(nodeId) {
516
+ const containsEdges = this.queries.getOutgoingEdges(nodeId, ['contains']);
517
+ if (containsEdges.length === 0)
518
+ return [];
519
+ // Batch-fetch all children
520
+ const childNodes = this.queries.getNodesByIds(containsEdges.map((e) => e.target));
521
+ const children = [];
522
+ for (const edge of containsEdges) {
523
+ const childNode = childNodes.get(edge.target);
524
+ if (childNode)
525
+ children.push(childNode);
526
+ }
527
+ return children;
528
+ }
529
+ }
530
+ exports.GraphTraverser = GraphTraverser;
531
+ //# sourceMappingURL=traversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversal.js","sourceRoot":"","sources":["../../src/graph/traversal.ts"],"names":[],"mappings":"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"}