cgb-builder 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 +21 -0
- package/README.md +369 -0
- package/dist/bundle/generator.d.ts +51 -0
- package/dist/bundle/generator.d.ts.map +1 -0
- package/dist/bundle/generator.js +291 -0
- package/dist/bundle/generator.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +388 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/graph/db.d.ts +43 -0
- package/dist/graph/db.d.ts.map +1 -0
- package/dist/graph/db.js +321 -0
- package/dist/graph/db.js.map +1 -0
- package/dist/graph/engine.d.ts +62 -0
- package/dist/graph/engine.d.ts.map +1 -0
- package/dist/graph/engine.js +246 -0
- package/dist/graph/engine.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +17 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +458 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parser/adapter.d.ts +10 -0
- package/dist/parser/adapter.d.ts.map +1 -0
- package/dist/parser/adapter.js +6 -0
- package/dist/parser/adapter.js.map +1 -0
- package/dist/parser/adapters/csharp.d.ts +24 -0
- package/dist/parser/adapters/csharp.d.ts.map +1 -0
- package/dist/parser/adapters/csharp.js +318 -0
- package/dist/parser/adapters/csharp.js.map +1 -0
- package/dist/parser/adapters/go.d.ts +21 -0
- package/dist/parser/adapters/go.d.ts.map +1 -0
- package/dist/parser/adapters/go.js +186 -0
- package/dist/parser/adapters/go.js.map +1 -0
- package/dist/parser/adapters/java.d.ts +22 -0
- package/dist/parser/adapters/java.d.ts.map +1 -0
- package/dist/parser/adapters/java.js +235 -0
- package/dist/parser/adapters/java.js.map +1 -0
- package/dist/parser/adapters/python.d.ts +19 -0
- package/dist/parser/adapters/python.d.ts.map +1 -0
- package/dist/parser/adapters/python.js +201 -0
- package/dist/parser/adapters/python.js.map +1 -0
- package/dist/parser/adapters/typescript.d.ts +24 -0
- package/dist/parser/adapters/typescript.d.ts.map +1 -0
- package/dist/parser/adapters/typescript.js +349 -0
- package/dist/parser/adapters/typescript.js.map +1 -0
- package/dist/parser/index.d.ts +42 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +191 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/tree-sitter-engine.d.ts +25 -0
- package/dist/parser/tree-sitter-engine.d.ts.map +1 -0
- package/dist/parser/tree-sitter-engine.js +107 -0
- package/dist/parser/tree-sitter-engine.js.map +1 -0
- package/dist/parser/utils.d.ts +19 -0
- package/dist/parser/utils.d.ts.map +1 -0
- package/dist/parser/utils.js +111 -0
- package/dist/parser/utils.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher/index.d.ts +36 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +139 -0
- package/dist/watcher/index.js.map +1 -0
- package/package.json +81 -0
package/dist/graph/db.js
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQLite-backed graph database using sql.js (pure WASM, no native compilation).
|
|
4
|
+
* Stores nodes, edges, and file metadata. Persists to a binary .db file on disk.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.GraphDb = void 0;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const sql_js_1 = __importDefault(require("sql.js"));
|
|
47
|
+
// ─── Schema ───────────────────────────────────────────────────────────────────
|
|
48
|
+
const SCHEMA = `
|
|
49
|
+
PRAGMA journal_mode=WAL;
|
|
50
|
+
PRAGMA foreign_keys=ON;
|
|
51
|
+
|
|
52
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
53
|
+
id TEXT PRIMARY KEY,
|
|
54
|
+
kind TEXT NOT NULL,
|
|
55
|
+
name TEXT NOT NULL,
|
|
56
|
+
file_path TEXT NOT NULL,
|
|
57
|
+
description TEXT NOT NULL DEFAULT '',
|
|
58
|
+
is_external INTEGER NOT NULL DEFAULT 0,
|
|
59
|
+
language TEXT,
|
|
60
|
+
meta TEXT NOT NULL DEFAULT '{}',
|
|
61
|
+
updated_at INTEGER NOT NULL
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
65
|
+
id TEXT PRIMARY KEY,
|
|
66
|
+
from_id TEXT NOT NULL,
|
|
67
|
+
to_id TEXT NOT NULL,
|
|
68
|
+
kind TEXT NOT NULL,
|
|
69
|
+
reason TEXT NOT NULL DEFAULT '',
|
|
70
|
+
updated_at INTEGER NOT NULL,
|
|
71
|
+
FOREIGN KEY (from_id) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
72
|
+
FOREIGN KEY (to_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
76
|
+
file_path TEXT PRIMARY KEY,
|
|
77
|
+
language TEXT NOT NULL,
|
|
78
|
+
content_hash TEXT NOT NULL,
|
|
79
|
+
mtime INTEGER NOT NULL,
|
|
80
|
+
node_count INTEGER NOT NULL DEFAULT 0,
|
|
81
|
+
edge_count INTEGER NOT NULL DEFAULT 0,
|
|
82
|
+
parsed_at INTEGER NOT NULL
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
-- Indexes for common query patterns
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file_path ON nodes(file_path);
|
|
87
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_edges_from_id ON edges(from_id);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_edges_to_id ON edges(to_id);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_edges_kind ON edges(kind);
|
|
91
|
+
`;
|
|
92
|
+
// ─── GraphDb class ────────────────────────────────────────────────────────────
|
|
93
|
+
class GraphDb {
|
|
94
|
+
db;
|
|
95
|
+
dbPath;
|
|
96
|
+
static sqlJs = null;
|
|
97
|
+
constructor(projectRoot) {
|
|
98
|
+
const cgbDir = path.join(projectRoot, '.cgb');
|
|
99
|
+
if (!fs.existsSync(cgbDir)) {
|
|
100
|
+
fs.mkdirSync(cgbDir, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
this.dbPath = path.join(cgbDir, 'graph.db');
|
|
103
|
+
}
|
|
104
|
+
/** Initialize the database (async because sql.js WASM loading is async) */
|
|
105
|
+
async init() {
|
|
106
|
+
if (!GraphDb.sqlJs) {
|
|
107
|
+
const wasmPath = require.resolve('sql.js/dist/sql-wasm.wasm');
|
|
108
|
+
GraphDb.sqlJs = await (0, sql_js_1.default)({ locateFile: () => wasmPath });
|
|
109
|
+
}
|
|
110
|
+
if (fs.existsSync(this.dbPath)) {
|
|
111
|
+
const fileBuffer = fs.readFileSync(this.dbPath);
|
|
112
|
+
this.db = new GraphDb.sqlJs.Database(fileBuffer);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.db = new GraphDb.sqlJs.Database();
|
|
116
|
+
}
|
|
117
|
+
this.db.run(SCHEMA);
|
|
118
|
+
this.persist();
|
|
119
|
+
}
|
|
120
|
+
/** Save the in-memory DB back to disk */
|
|
121
|
+
persist() {
|
|
122
|
+
const data = this.db.export();
|
|
123
|
+
fs.writeFileSync(this.dbPath, Buffer.from(data));
|
|
124
|
+
}
|
|
125
|
+
close() {
|
|
126
|
+
this.persist();
|
|
127
|
+
this.db.close();
|
|
128
|
+
}
|
|
129
|
+
// ─── Node Operations ───────────────────────────────────────────────────────
|
|
130
|
+
upsertNode(node) {
|
|
131
|
+
this.db.run(`INSERT INTO nodes (id, kind, name, file_path, description, is_external, language, meta, updated_at)
|
|
132
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
133
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
134
|
+
kind = excluded.kind,
|
|
135
|
+
name = excluded.name,
|
|
136
|
+
file_path = excluded.file_path,
|
|
137
|
+
description = excluded.description,
|
|
138
|
+
is_external = excluded.is_external,
|
|
139
|
+
language = excluded.language,
|
|
140
|
+
meta = excluded.meta,
|
|
141
|
+
updated_at = excluded.updated_at`, [
|
|
142
|
+
node.id,
|
|
143
|
+
node.kind,
|
|
144
|
+
node.name,
|
|
145
|
+
node.filePath,
|
|
146
|
+
node.description,
|
|
147
|
+
node.isExternal ? 1 : 0,
|
|
148
|
+
node.language ?? null,
|
|
149
|
+
node.meta,
|
|
150
|
+
node.updatedAt,
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
153
|
+
getNode(id) {
|
|
154
|
+
const rows = this.db.exec('SELECT * FROM nodes WHERE id = ?', [id]);
|
|
155
|
+
if (!rows.length || !rows[0].values.length)
|
|
156
|
+
return null;
|
|
157
|
+
return this.rowToNode(rows[0].columns, rows[0].values[0]);
|
|
158
|
+
}
|
|
159
|
+
getNodesByFile(filePath) {
|
|
160
|
+
const rows = this.db.exec('SELECT * FROM nodes WHERE file_path = ?', [filePath]);
|
|
161
|
+
if (!rows.length)
|
|
162
|
+
return [];
|
|
163
|
+
return rows[0].values.map((row) => this.rowToNode(rows[0].columns, row));
|
|
164
|
+
}
|
|
165
|
+
searchNodes(query) {
|
|
166
|
+
const like = `%${query}%`;
|
|
167
|
+
const rows = this.db.exec('SELECT * FROM nodes WHERE name LIKE ? OR description LIKE ? OR file_path LIKE ? LIMIT 50', [like, like, like]);
|
|
168
|
+
if (!rows.length)
|
|
169
|
+
return [];
|
|
170
|
+
return rows[0].values.map((row) => this.rowToNode(rows[0].columns, row));
|
|
171
|
+
}
|
|
172
|
+
deleteNodesByFile(filePath) {
|
|
173
|
+
this.db.run('DELETE FROM nodes WHERE file_path = ?', [filePath]);
|
|
174
|
+
}
|
|
175
|
+
// ─── Edge Operations ───────────────────────────────────────────────────────
|
|
176
|
+
upsertEdge(edge) {
|
|
177
|
+
this.db.run(`INSERT INTO edges (id, from_id, to_id, kind, reason, updated_at)
|
|
178
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
179
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
180
|
+
reason = excluded.reason,
|
|
181
|
+
updated_at = excluded.updated_at`, [edge.id, edge.fromId, edge.toId, edge.kind, edge.reason, edge.updatedAt]);
|
|
182
|
+
}
|
|
183
|
+
getEdgesFrom(nodeId) {
|
|
184
|
+
const rows = this.db.exec('SELECT * FROM edges WHERE from_id = ?', [nodeId]);
|
|
185
|
+
if (!rows.length)
|
|
186
|
+
return [];
|
|
187
|
+
return rows[0].values.map((row) => this.rowToEdge(rows[0].columns, row));
|
|
188
|
+
}
|
|
189
|
+
getEdgesTo(nodeId) {
|
|
190
|
+
const rows = this.db.exec('SELECT * FROM edges WHERE to_id = ?', [nodeId]);
|
|
191
|
+
if (!rows.length)
|
|
192
|
+
return [];
|
|
193
|
+
return rows[0].values.map((row) => this.rowToEdge(rows[0].columns, row));
|
|
194
|
+
}
|
|
195
|
+
getEdgesFromByKind(nodeId, kind) {
|
|
196
|
+
const rows = this.db.exec('SELECT * FROM edges WHERE from_id = ? AND kind = ?', [nodeId, kind]);
|
|
197
|
+
if (!rows.length)
|
|
198
|
+
return [];
|
|
199
|
+
return rows[0].values.map((row) => this.rowToEdge(rows[0].columns, row));
|
|
200
|
+
}
|
|
201
|
+
getEdgesToByKind(nodeId, kind) {
|
|
202
|
+
const rows = this.db.exec('SELECT * FROM edges WHERE to_id = ? AND kind = ?', [nodeId, kind]);
|
|
203
|
+
if (!rows.length)
|
|
204
|
+
return [];
|
|
205
|
+
return rows[0].values.map((row) => this.rowToEdge(rows[0].columns, row));
|
|
206
|
+
}
|
|
207
|
+
deleteEdgesByFile(filePath) {
|
|
208
|
+
// Edges are cascade-deleted when nodes are deleted, but we also remove
|
|
209
|
+
// outgoing edges from this file's nodes
|
|
210
|
+
const nodes = this.getNodesByFile(filePath);
|
|
211
|
+
for (const node of nodes) {
|
|
212
|
+
this.db.run('DELETE FROM edges WHERE from_id = ?', [node.id]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// ─── File Operations ───────────────────────────────────────────────────────
|
|
216
|
+
upsertFile(record) {
|
|
217
|
+
this.db.run(`INSERT INTO files (file_path, language, content_hash, mtime, node_count, edge_count, parsed_at)
|
|
218
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
219
|
+
ON CONFLICT(file_path) DO UPDATE SET
|
|
220
|
+
language = excluded.language,
|
|
221
|
+
content_hash = excluded.content_hash,
|
|
222
|
+
mtime = excluded.mtime,
|
|
223
|
+
node_count = excluded.node_count,
|
|
224
|
+
edge_count = excluded.edge_count,
|
|
225
|
+
parsed_at = excluded.parsed_at`, [
|
|
226
|
+
record.filePath,
|
|
227
|
+
record.language,
|
|
228
|
+
record.contentHash,
|
|
229
|
+
record.mtime,
|
|
230
|
+
record.nodeCount,
|
|
231
|
+
record.edgeCount,
|
|
232
|
+
record.parsedAt,
|
|
233
|
+
]);
|
|
234
|
+
}
|
|
235
|
+
getFile(filePath) {
|
|
236
|
+
const rows = this.db.exec('SELECT * FROM files WHERE file_path = ?', [filePath]);
|
|
237
|
+
if (!rows.length || !rows[0].values.length)
|
|
238
|
+
return null;
|
|
239
|
+
return this.rowToFile(rows[0].columns, rows[0].values[0]);
|
|
240
|
+
}
|
|
241
|
+
getAllFiles() {
|
|
242
|
+
const rows = this.db.exec('SELECT * FROM files ORDER BY file_path');
|
|
243
|
+
if (!rows.length)
|
|
244
|
+
return [];
|
|
245
|
+
return rows[0].values.map((row) => this.rowToFile(rows[0].columns, row));
|
|
246
|
+
}
|
|
247
|
+
deleteFile(filePath) {
|
|
248
|
+
this.deleteEdgesByFile(filePath);
|
|
249
|
+
this.deleteNodesByFile(filePath);
|
|
250
|
+
this.db.run('DELETE FROM files WHERE file_path = ?', [filePath]);
|
|
251
|
+
}
|
|
252
|
+
// ─── Stats ─────────────────────────────────────────────────────────────────
|
|
253
|
+
getStats() {
|
|
254
|
+
const nodeCount = this.db.exec('SELECT COUNT(*) FROM nodes')[0]?.values[0][0];
|
|
255
|
+
const edgeCount = this.db.exec('SELECT COUNT(*) FROM edges')[0]?.values[0][0];
|
|
256
|
+
const fileCount = this.db.exec('SELECT COUNT(*) FROM files')[0]?.values[0][0];
|
|
257
|
+
return { nodes: nodeCount ?? 0, edges: edgeCount ?? 0, files: fileCount ?? 0 };
|
|
258
|
+
}
|
|
259
|
+
getNodeCountByKind() {
|
|
260
|
+
const rows = this.db.exec('SELECT kind, COUNT(*) as cnt FROM nodes GROUP BY kind');
|
|
261
|
+
if (!rows.length)
|
|
262
|
+
return {};
|
|
263
|
+
return Object.fromEntries(rows[0].values.map(([kind, cnt]) => [kind, cnt]));
|
|
264
|
+
}
|
|
265
|
+
// ─── All Nodes/Edges (for traversal) ──────────────────────────────────────
|
|
266
|
+
getAllNodes() {
|
|
267
|
+
const rows = this.db.exec('SELECT * FROM nodes');
|
|
268
|
+
if (!rows.length)
|
|
269
|
+
return [];
|
|
270
|
+
return rows[0].values.map((row) => this.rowToNode(rows[0].columns, row));
|
|
271
|
+
}
|
|
272
|
+
getAllEdges() {
|
|
273
|
+
const rows = this.db.exec('SELECT * FROM edges');
|
|
274
|
+
if (!rows.length)
|
|
275
|
+
return [];
|
|
276
|
+
return rows[0].values.map((row) => this.rowToEdge(rows[0].columns, row));
|
|
277
|
+
}
|
|
278
|
+
// ─── Row Mappers ───────────────────────────────────────────────────────────
|
|
279
|
+
rowToNode(columns, row) {
|
|
280
|
+
const obj = {};
|
|
281
|
+
columns.forEach((col, i) => (obj[col] = row[i]));
|
|
282
|
+
return {
|
|
283
|
+
id: obj['id'],
|
|
284
|
+
kind: obj['kind'],
|
|
285
|
+
name: obj['name'],
|
|
286
|
+
filePath: obj['file_path'],
|
|
287
|
+
description: obj['description'] ?? '',
|
|
288
|
+
isExternal: obj['is_external'] === 1,
|
|
289
|
+
language: obj['language'] ?? null,
|
|
290
|
+
meta: obj['meta'] ?? '{}',
|
|
291
|
+
updatedAt: obj['updated_at'],
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
rowToEdge(columns, row) {
|
|
295
|
+
const obj = {};
|
|
296
|
+
columns.forEach((col, i) => (obj[col] = row[i]));
|
|
297
|
+
return {
|
|
298
|
+
id: obj['id'],
|
|
299
|
+
fromId: obj['from_id'],
|
|
300
|
+
toId: obj['to_id'],
|
|
301
|
+
kind: obj['kind'],
|
|
302
|
+
reason: obj['reason'] ?? '',
|
|
303
|
+
updatedAt: obj['updated_at'],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
rowToFile(columns, row) {
|
|
307
|
+
const obj = {};
|
|
308
|
+
columns.forEach((col, i) => (obj[col] = row[i]));
|
|
309
|
+
return {
|
|
310
|
+
filePath: obj['file_path'],
|
|
311
|
+
language: obj['language'],
|
|
312
|
+
contentHash: obj['content_hash'],
|
|
313
|
+
mtime: obj['mtime'],
|
|
314
|
+
nodeCount: obj['node_count'],
|
|
315
|
+
edgeCount: obj['edge_count'],
|
|
316
|
+
parsedAt: obj['parsed_at'],
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
exports.GraphDb = GraphDb;
|
|
321
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/graph/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph traversal engine.
|
|
3
|
+
* Provides deps, callers, callees, impact analysis, and shortest-path queries
|
|
4
|
+
* built on top of the GraphDb.
|
|
5
|
+
*/
|
|
6
|
+
import type { GraphDb } from './db.js';
|
|
7
|
+
import type { GraphNode, DepsResult, CallersResult, CalleesResult, ImpactResult, PathResult } from '../types.js';
|
|
8
|
+
export declare class GraphEngine {
|
|
9
|
+
private readonly db;
|
|
10
|
+
constructor(db: GraphDb);
|
|
11
|
+
/**
|
|
12
|
+
* Return all dependencies (imports) of a node.
|
|
13
|
+
* depth=1 → direct imports only; depth>1 → transitive.
|
|
14
|
+
*/
|
|
15
|
+
deps(nodeId: string, depth?: number): DepsResult | null;
|
|
16
|
+
/**
|
|
17
|
+
* Return all nodes that call a given function/method node.
|
|
18
|
+
*/
|
|
19
|
+
callers(nodeId: string): CallersResult | null;
|
|
20
|
+
/**
|
|
21
|
+
* Return all nodes called by a given function/method node.
|
|
22
|
+
*/
|
|
23
|
+
callees(nodeId: string): CalleesResult | null;
|
|
24
|
+
/**
|
|
25
|
+
* Impact analysis: find all nodes that would be affected if nodeId changed.
|
|
26
|
+
* Traverses the reverse import/dependency graph.
|
|
27
|
+
*/
|
|
28
|
+
impact(nodeId: string, maxDepth?: number): ImpactResult | null;
|
|
29
|
+
/**
|
|
30
|
+
* Find the shortest dependency path between two nodes using BFS.
|
|
31
|
+
*/
|
|
32
|
+
path(fromId: string, toId: string): PathResult | null;
|
|
33
|
+
/**
|
|
34
|
+
* Search for nodes by name, description, or file path.
|
|
35
|
+
*/
|
|
36
|
+
search(query: string): GraphNode[];
|
|
37
|
+
/**
|
|
38
|
+
* Find a node by its exact file path (returns the file node for that path).
|
|
39
|
+
*/
|
|
40
|
+
findByFile(filePath: string): GraphNode[];
|
|
41
|
+
/**
|
|
42
|
+
* Detect dependency cycles using DFS.
|
|
43
|
+
* Returns arrays of node IDs representing each cycle found.
|
|
44
|
+
*/
|
|
45
|
+
detectCycles(): string[][];
|
|
46
|
+
/**
|
|
47
|
+
* Find orphan nodes — nodes with no incoming or outgoing edges.
|
|
48
|
+
*/
|
|
49
|
+
orphans(): GraphNode[];
|
|
50
|
+
/**
|
|
51
|
+
* Layer analysis: return a compact summary of the architectural layers.
|
|
52
|
+
* Groups nodes by directory depth and kind to infer layering.
|
|
53
|
+
*/
|
|
54
|
+
layers(): Array<{
|
|
55
|
+
layer: string;
|
|
56
|
+
nodeCount: number;
|
|
57
|
+
kinds: Record<string, number>;
|
|
58
|
+
}>;
|
|
59
|
+
private directDeps;
|
|
60
|
+
private transitiveDeps;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/graph/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EACV,SAAS,EAET,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,UAAU,EACX,MAAM,aAAa,CAAC;AAErB,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAIxC;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,UAAU,GAAG,IAAI;IAUlD;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAe7C;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAe7C;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,YAAY,GAAG,IAAI;IAoC1D;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IA8BrD;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE;IAIlC;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAIzC;;;OAGG;IACH,YAAY,IAAI,MAAM,EAAE,EAAE;IAqC1B;;OAEG;IACH,OAAO,IAAI,SAAS,EAAE;IAatB;;;OAGG;IACH,MAAM,IAAI,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IA+BpF,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,cAAc;CAwBvB"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Graph traversal engine.
|
|
4
|
+
* Provides deps, callers, callees, impact analysis, and shortest-path queries
|
|
5
|
+
* built on top of the GraphDb.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.GraphEngine = void 0;
|
|
9
|
+
class GraphEngine {
|
|
10
|
+
db;
|
|
11
|
+
constructor(db) {
|
|
12
|
+
this.db = db;
|
|
13
|
+
}
|
|
14
|
+
// ─── Public queries ────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Return all dependencies (imports) of a node.
|
|
17
|
+
* depth=1 → direct imports only; depth>1 → transitive.
|
|
18
|
+
*/
|
|
19
|
+
deps(nodeId, depth = 3) {
|
|
20
|
+
const target = this.db.getNode(nodeId);
|
|
21
|
+
if (!target)
|
|
22
|
+
return null;
|
|
23
|
+
const direct = this.directDeps(nodeId);
|
|
24
|
+
const transitive = depth > 1 ? this.transitiveDeps(nodeId, depth) : [];
|
|
25
|
+
return { target, direct, transitive };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Return all nodes that call a given function/method node.
|
|
29
|
+
*/
|
|
30
|
+
callers(nodeId) {
|
|
31
|
+
const target = this.db.getNode(nodeId);
|
|
32
|
+
if (!target)
|
|
33
|
+
return null;
|
|
34
|
+
const callEdges = this.db.getEdgesToByKind(nodeId, 'calls');
|
|
35
|
+
const callers = callEdges
|
|
36
|
+
.map((edge) => {
|
|
37
|
+
const node = this.db.getNode(edge.fromId);
|
|
38
|
+
return node ? { node, reason: edge.reason } : null;
|
|
39
|
+
})
|
|
40
|
+
.filter((x) => x !== null);
|
|
41
|
+
return { target, callers };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Return all nodes called by a given function/method node.
|
|
45
|
+
*/
|
|
46
|
+
callees(nodeId) {
|
|
47
|
+
const target = this.db.getNode(nodeId);
|
|
48
|
+
if (!target)
|
|
49
|
+
return null;
|
|
50
|
+
const callEdges = this.db.getEdgesFromByKind(nodeId, 'calls');
|
|
51
|
+
const callees = callEdges
|
|
52
|
+
.map((edge) => {
|
|
53
|
+
const node = this.db.getNode(edge.toId);
|
|
54
|
+
return node ? { node, reason: edge.reason } : null;
|
|
55
|
+
})
|
|
56
|
+
.filter((x) => x !== null);
|
|
57
|
+
return { target, callees };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Impact analysis: find all nodes that would be affected if nodeId changed.
|
|
61
|
+
* Traverses the reverse import/dependency graph.
|
|
62
|
+
*/
|
|
63
|
+
impact(nodeId, maxDepth = 10) {
|
|
64
|
+
const target = this.db.getNode(nodeId);
|
|
65
|
+
if (!target)
|
|
66
|
+
return null;
|
|
67
|
+
const visited = new Map();
|
|
68
|
+
const queue = [
|
|
69
|
+
{ id: nodeId, depth: 0, path: [target] },
|
|
70
|
+
];
|
|
71
|
+
while (queue.length) {
|
|
72
|
+
const { id, depth, path } = queue.shift();
|
|
73
|
+
if (depth >= maxDepth)
|
|
74
|
+
continue;
|
|
75
|
+
// Find all nodes that import this node
|
|
76
|
+
const incomingImports = this.db.getEdgesToByKind(id, 'imports');
|
|
77
|
+
// Also find nodes that export symbols from this file (they re-export)
|
|
78
|
+
const incomingExports = this.db.getEdgesToByKind(id, 'exports');
|
|
79
|
+
for (const edge of [...incomingImports, ...incomingExports]) {
|
|
80
|
+
if (edge.fromId === nodeId)
|
|
81
|
+
continue; // skip self
|
|
82
|
+
if (visited.has(edge.fromId))
|
|
83
|
+
continue;
|
|
84
|
+
const node = this.db.getNode(edge.fromId);
|
|
85
|
+
if (!node)
|
|
86
|
+
continue;
|
|
87
|
+
visited.set(edge.fromId, { node, depth: depth + 1, path: [...path, node] });
|
|
88
|
+
queue.push({ id: edge.fromId, depth: depth + 1, path: [...path, node] });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
target,
|
|
93
|
+
affected: Array.from(visited.values()).sort((a, b) => a.depth - b.depth),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Find the shortest dependency path between two nodes using BFS.
|
|
98
|
+
*/
|
|
99
|
+
path(fromId, toId) {
|
|
100
|
+
const from = this.db.getNode(fromId);
|
|
101
|
+
const to = this.db.getNode(toId);
|
|
102
|
+
if (!from || !to)
|
|
103
|
+
return null;
|
|
104
|
+
// BFS
|
|
105
|
+
const visited = new Set([fromId]);
|
|
106
|
+
const queue = [
|
|
107
|
+
{ id: fromId, path: [from], edges: [] },
|
|
108
|
+
];
|
|
109
|
+
while (queue.length) {
|
|
110
|
+
const { id, path, edges } = queue.shift();
|
|
111
|
+
if (id === toId) {
|
|
112
|
+
return { from, to, path, edges };
|
|
113
|
+
}
|
|
114
|
+
const outEdges = this.db.getEdgesFrom(id);
|
|
115
|
+
for (const edge of outEdges) {
|
|
116
|
+
if (visited.has(edge.toId))
|
|
117
|
+
continue;
|
|
118
|
+
const next = this.db.getNode(edge.toId);
|
|
119
|
+
if (!next)
|
|
120
|
+
continue;
|
|
121
|
+
visited.add(edge.toId);
|
|
122
|
+
queue.push({ id: edge.toId, path: [...path, next], edges: [...edges, edge] });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null; // No path found
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Search for nodes by name, description, or file path.
|
|
129
|
+
*/
|
|
130
|
+
search(query) {
|
|
131
|
+
return this.db.searchNodes(query);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Find a node by its exact file path (returns the file node for that path).
|
|
135
|
+
*/
|
|
136
|
+
findByFile(filePath) {
|
|
137
|
+
return this.db.getNodesByFile(filePath);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Detect dependency cycles using DFS.
|
|
141
|
+
* Returns arrays of node IDs representing each cycle found.
|
|
142
|
+
*/
|
|
143
|
+
detectCycles() {
|
|
144
|
+
const cycles = [];
|
|
145
|
+
const visited = new Set();
|
|
146
|
+
const inStack = new Set();
|
|
147
|
+
const stack = [];
|
|
148
|
+
const dfs = (id) => {
|
|
149
|
+
visited.add(id);
|
|
150
|
+
inStack.add(id);
|
|
151
|
+
stack.push(id);
|
|
152
|
+
const outEdges = this.db.getEdgesFromByKind(id, 'imports');
|
|
153
|
+
for (const edge of outEdges) {
|
|
154
|
+
if (!visited.has(edge.toId)) {
|
|
155
|
+
dfs(edge.toId);
|
|
156
|
+
}
|
|
157
|
+
else if (inStack.has(edge.toId)) {
|
|
158
|
+
// Found a cycle
|
|
159
|
+
const cycleStart = stack.indexOf(edge.toId);
|
|
160
|
+
if (cycleStart !== -1) {
|
|
161
|
+
cycles.push([...stack.slice(cycleStart), edge.toId]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
stack.pop();
|
|
166
|
+
inStack.delete(id);
|
|
167
|
+
};
|
|
168
|
+
for (const node of this.db.getAllNodes()) {
|
|
169
|
+
if (!visited.has(node.id)) {
|
|
170
|
+
dfs(node.id);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return cycles;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Find orphan nodes — nodes with no incoming or outgoing edges.
|
|
177
|
+
*/
|
|
178
|
+
orphans() {
|
|
179
|
+
const allNodes = this.db.getAllNodes();
|
|
180
|
+
const allEdges = this.db.getAllEdges();
|
|
181
|
+
const connected = new Set();
|
|
182
|
+
for (const edge of allEdges) {
|
|
183
|
+
connected.add(edge.fromId);
|
|
184
|
+
connected.add(edge.toId);
|
|
185
|
+
}
|
|
186
|
+
return allNodes.filter((n) => !connected.has(n.id) && !n.isExternal);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Layer analysis: return a compact summary of the architectural layers.
|
|
190
|
+
* Groups nodes by directory depth and kind to infer layering.
|
|
191
|
+
*/
|
|
192
|
+
layers() {
|
|
193
|
+
const allNodes = this.db.getAllNodes().filter((n) => !n.isExternal && n.kind === 'file');
|
|
194
|
+
const layerMap = new Map();
|
|
195
|
+
for (const node of allNodes) {
|
|
196
|
+
// Use the top-level directory segment as the "layer"
|
|
197
|
+
const parts = node.filePath.replace(/\\/g, '/').split('/');
|
|
198
|
+
const srcIndex = parts.findIndex((p) => p === 'src');
|
|
199
|
+
const layer = srcIndex !== -1 && parts[srcIndex + 1]
|
|
200
|
+
? parts[srcIndex + 1]
|
|
201
|
+
: (parts[parts.length - 2] ?? 'root');
|
|
202
|
+
if (!layerMap.has(layer))
|
|
203
|
+
layerMap.set(layer, []);
|
|
204
|
+
layerMap.get(layer).push(node);
|
|
205
|
+
}
|
|
206
|
+
return Array.from(layerMap.entries())
|
|
207
|
+
.map(([layer, nodes]) => {
|
|
208
|
+
const allKindNodes = nodes.flatMap((n) => this.db.getNodesByFile(n.filePath));
|
|
209
|
+
const kinds = {};
|
|
210
|
+
for (const n of allKindNodes) {
|
|
211
|
+
kinds[n.kind] = (kinds[n.kind] ?? 0) + 1;
|
|
212
|
+
}
|
|
213
|
+
return { layer, nodeCount: nodes.length, kinds };
|
|
214
|
+
})
|
|
215
|
+
.sort((a, b) => b.nodeCount - a.nodeCount);
|
|
216
|
+
}
|
|
217
|
+
// ─── Private helpers ───────────────────────────────────────────────────────
|
|
218
|
+
directDeps(nodeId) {
|
|
219
|
+
const edges = this.db.getEdgesFromByKind(nodeId, 'imports');
|
|
220
|
+
return edges.map((e) => this.db.getNode(e.toId)).filter((n) => n !== null);
|
|
221
|
+
}
|
|
222
|
+
transitiveDeps(nodeId, maxDepth) {
|
|
223
|
+
const visited = new Set([nodeId]);
|
|
224
|
+
const queue = [{ id: nodeId, depth: 0 }];
|
|
225
|
+
const result = [];
|
|
226
|
+
while (queue.length) {
|
|
227
|
+
const { id, depth } = queue.shift();
|
|
228
|
+
if (depth >= maxDepth)
|
|
229
|
+
continue;
|
|
230
|
+
const edges = this.db.getEdgesFromByKind(id, 'imports');
|
|
231
|
+
for (const edge of edges) {
|
|
232
|
+
if (visited.has(edge.toId))
|
|
233
|
+
continue;
|
|
234
|
+
visited.add(edge.toId);
|
|
235
|
+
const node = this.db.getNode(edge.toId);
|
|
236
|
+
if (node) {
|
|
237
|
+
result.push(node);
|
|
238
|
+
queue.push({ id: edge.toId, depth: depth + 1 });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.GraphEngine = GraphEngine;
|
|
246
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/graph/engine.ts"],"names":[],"mappings":"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"}
|