@remnic/coding-graph 9.6.24 → 9.6.26
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/README.md +16 -19
- package/dist/{chunk-ZLCF3XQK.js → chunk-ABDBWCXU.js} +75 -1
- package/dist/chunk-ABDBWCXU.js.map +1 -0
- package/dist/{chunk-7DI5P62Q.js → chunk-I4R6GAAA.js} +2 -2
- package/dist/cypher/query-parser.js +2 -2
- package/dist/graph-store.d.ts +20 -0
- package/dist/graph-store.js +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/graph-store.ts +99 -0
- package/src/lsp/resolution.ts +52 -11
- package/src/lsp-reconciliation.test.ts +145 -0
- package/dist/chunk-ZLCF3XQK.js.map +0 -1
- /package/dist/{chunk-7DI5P62Q.js.map → chunk-I4R6GAAA.js.map} +0 -0
package/README.md
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
engine: web-tree-sitter grammars, per-language symbol extractors, and the
|
|
5
5
|
neutral `FileIR` intermediate representation that the graph store consumes.
|
|
6
6
|
|
|
7
|
-
> Part of
|
|
8
|
-
> step 1 + step 2). The real backend lands in PR2 (#1551 step 3+).
|
|
7
|
+
> Part of Remnic's coding-knowledge layer (issue #1548).
|
|
9
8
|
|
|
10
9
|
## Install
|
|
11
10
|
|
|
@@ -15,23 +14,21 @@ npm install @remnic/coding-graph
|
|
|
15
14
|
pnpm add @remnic/coding-graph
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `TIER_1_LANGUAGES`
|
|
24
|
-
- `
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
will ship in PR2 via the `grammars/` directory listed in the package's
|
|
34
|
-
`files` manifest.
|
|
17
|
+
## What it provides
|
|
18
|
+
|
|
19
|
+
- `createCodingGraphEngine()` — returns a working engine backed by a
|
|
20
|
+
WASM tree-sitter parser. It parses source files into the neutral `FileIR`
|
|
21
|
+
(symbols plus import edges) for the 15 tier-1 languages.
|
|
22
|
+
- `TIER_1_LANGUAGES` — the supported tier-1 language list.
|
|
23
|
+
- `ENGINE_VERSION` / `CODING_GRAPH_ENGINE_VERSION` — the engine version
|
|
24
|
+
string. The single source of truth lives in `@remnic/core`; this package
|
|
25
|
+
re-exports it so every consumer stays in lockstep.
|
|
26
|
+
- `CodingGraphEngine` interface and the `CodingGraphError` tagged error class.
|
|
27
|
+
|
|
28
|
+
A per-file parse failure surfaces as a tagged `{ ok: false, code: "parse_failed" }`
|
|
29
|
+
result rather than a thrown exception, so one unparseable file never bricks a
|
|
30
|
+
whole index run. Grammar `.wasm` assets ship in the `grammars/` directory listed
|
|
31
|
+
in the package's `files` manifest.
|
|
35
32
|
|
|
36
33
|
## How `@remnic/core` loads this
|
|
37
34
|
|
|
@@ -207,6 +207,80 @@ var GraphStore = class _GraphStore {
|
|
|
207
207
|
}
|
|
208
208
|
return this.queue.schedule(() => this.runUpsertEdges(edges));
|
|
209
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Retire stale LSP-provenance edges for a file (issue #1895).
|
|
212
|
+
*
|
|
213
|
+
* The LSP resolution pass re-derives edges from the CURRENT source on each
|
|
214
|
+
* run. After writing the new `lsp` edges for a file, this method deletes
|
|
215
|
+
* prior `lsp`-provenance edges owned by that file's nodes whose
|
|
216
|
+
* `(src, dst, type)` key is NOT in the asserted set. This is the LSP
|
|
217
|
+
* layer's side of the provenance-lifecycle contract: each layer owns its
|
|
218
|
+
* own stale-edge retirement (#1894 established that reindex's heuristic
|
|
219
|
+
* scope never touches `lsp` rows).
|
|
220
|
+
*
|
|
221
|
+
* Heuristic, trace, and semantic edges are never touched.
|
|
222
|
+
*
|
|
223
|
+
* @returns the number of retired edges.
|
|
224
|
+
*/
|
|
225
|
+
reconcileLspEdges(filePath, assertedEdges) {
|
|
226
|
+
if (this.closed) return 0;
|
|
227
|
+
try {
|
|
228
|
+
const fileRow = expectRow(
|
|
229
|
+
this.db.prepare("SELECT id FROM files WHERE path = ?").get(filePath),
|
|
230
|
+
["id"]
|
|
231
|
+
);
|
|
232
|
+
if (!fileRow) return 0;
|
|
233
|
+
const nodes = expectRows(
|
|
234
|
+
this.db.prepare("SELECT id, qualified_name FROM nodes WHERE file_id = ?").all(fileRow.id),
|
|
235
|
+
["id", "qualified_name"]
|
|
236
|
+
);
|
|
237
|
+
if (nodes.length === 0) return 0;
|
|
238
|
+
const nameCount = /* @__PURE__ */ new Map();
|
|
239
|
+
for (const n of nodes) nameCount.set(n.qualified_name, (nameCount.get(n.qualified_name) ?? 0) + 1);
|
|
240
|
+
const srcMap = /* @__PURE__ */ new Map();
|
|
241
|
+
for (const n of nodes) {
|
|
242
|
+
if (nameCount.get(n.qualified_name) === 1) srcMap.set(n.qualified_name, n.id);
|
|
243
|
+
}
|
|
244
|
+
const nodeIds = nodes.map((n) => n.id);
|
|
245
|
+
const assertedKeys = /* @__PURE__ */ new Set();
|
|
246
|
+
for (const e of assertedEdges) {
|
|
247
|
+
const srcId = srcMap.get(e.srcQualifiedName);
|
|
248
|
+
if (!srcId) continue;
|
|
249
|
+
const dstId = resolveNodeId(e.dstQualifiedName, /* @__PURE__ */ new Map(), this.db);
|
|
250
|
+
if (!dstId) continue;
|
|
251
|
+
assertedKeys.add(`${srcId}\0${dstId}\0${e.type}`);
|
|
252
|
+
}
|
|
253
|
+
const placeholders = nodeIds.map(() => "?").join(", ");
|
|
254
|
+
const priorEdges = expectRows(
|
|
255
|
+
this.db.prepare(
|
|
256
|
+
`SELECT src, dst, type FROM edges
|
|
257
|
+
WHERE src IN (${placeholders}) AND provenance = 'lsp'`
|
|
258
|
+
).all(...nodeIds),
|
|
259
|
+
["src", "dst", "type"]
|
|
260
|
+
);
|
|
261
|
+
let deleted = 0;
|
|
262
|
+
const toDelete = [];
|
|
263
|
+
for (const e of priorEdges) {
|
|
264
|
+
const key = `${e.src}\0${e.dst}\0${e.type}`;
|
|
265
|
+
if (!assertedKeys.has(key)) toDelete.push([e.src, e.dst, e.type]);
|
|
266
|
+
}
|
|
267
|
+
if (toDelete.length > 0) {
|
|
268
|
+
const SQLITE_VARIABLE_LIMIT2 = 32766;
|
|
269
|
+
const PARAMS_PER_TUPLE = 3;
|
|
270
|
+
const MAX_TUPLES = Math.floor(SQLITE_VARIABLE_LIMIT2 / PARAMS_PER_TUPLE);
|
|
271
|
+
for (let i = 0; i < toDelete.length; i += MAX_TUPLES) {
|
|
272
|
+
const chunk = toDelete.slice(i, i + MAX_TUPLES);
|
|
273
|
+
const ph = chunk.map(() => "(?, ?, ?)").join(", ");
|
|
274
|
+
const r = this.db.prepare(`DELETE FROM edges WHERE (src, dst, type) IN (${ph})`).run(...chunk.flat());
|
|
275
|
+
deleted += r.changes;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return deleted;
|
|
279
|
+
} catch (error) {
|
|
280
|
+
logWriteFailure(error);
|
|
281
|
+
return 0;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
210
284
|
/** Wait for pending writes to drain — test seam. */
|
|
211
285
|
async drain() {
|
|
212
286
|
await this.queue.drain();
|
|
@@ -1899,4 +1973,4 @@ export {
|
|
|
1899
1973
|
GraphStore,
|
|
1900
1974
|
nodeIdFor
|
|
1901
1975
|
};
|
|
1902
|
-
//# sourceMappingURL=chunk-
|
|
1976
|
+
//# sourceMappingURL=chunk-ABDBWCXU.js.map
|