@inerrata-corporation/errata 2.0.17-dev.3421 → 2.0.17-dev.3433
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/consolidate-worker.mjs +65 -19
- package/errata.mjs +916 -518
- package/package.json +1 -1
- package/pass-worker.mjs +65 -42
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -16283,13 +16283,13 @@ function loadNodeSqlite() {
|
|
|
16283
16283
|
process.emitWarning = original;
|
|
16284
16284
|
}
|
|
16285
16285
|
}
|
|
16286
|
-
function openDatabase(path) {
|
|
16287
|
-
const db = new DatabaseSync(path);
|
|
16286
|
+
function openDatabase(path, opts) {
|
|
16287
|
+
const db = opts ? new DatabaseSync(path, opts) : new DatabaseSync(path);
|
|
16288
16288
|
try {
|
|
16289
16289
|
db.exec("PRAGMA foreign_keys = ON");
|
|
16290
16290
|
} catch {
|
|
16291
16291
|
}
|
|
16292
|
-
if (path !== ":memory:") {
|
|
16292
|
+
if (path !== ":memory:" && !opts?.readOnly) {
|
|
16293
16293
|
try {
|
|
16294
16294
|
db.exec("PRAGMA journal_mode = WAL");
|
|
16295
16295
|
db.exec("PRAGMA synchronous = NORMAL");
|
|
@@ -25171,8 +25171,9 @@ init_src2();
|
|
|
25171
25171
|
init_src();
|
|
25172
25172
|
|
|
25173
25173
|
// ../../packages/local-graph/src/history-cache-floor.ts
|
|
25174
|
+
var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
|
|
25174
25175
|
function installHistoryCacheFloor(db) {
|
|
25175
|
-
const key =
|
|
25176
|
+
const key = HISTORY_CACHE_FLOOR_KEY;
|
|
25176
25177
|
if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key)) return;
|
|
25177
25178
|
db.transaction(() => {
|
|
25178
25179
|
db.exec("DROP TRIGGER IF EXISTS history_cache_nodes_insert; DROP TRIGGER IF EXISTS history_cache_nodes_update;");
|
|
@@ -25334,6 +25335,7 @@ function localEdgeViolation(fromLabel, type, toLabel) {
|
|
|
25334
25335
|
return verdict.ok ? null : verdict.reason ?? "edge rule violation";
|
|
25335
25336
|
}
|
|
25336
25337
|
var SCHEMA_VERSION = 6;
|
|
25338
|
+
var SESSION_REPAIR_KEY = "session-evidence-v1";
|
|
25337
25339
|
var SESSION_EVIDENCE_PREDICATE = SESSION_EVIDENCE_FIELDS.map((field) => `instr(attrs_json, '${JSON.stringify(field)}') > 0`).join(" OR ");
|
|
25338
25340
|
var SCHEMA_SQL = `
|
|
25339
25341
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
@@ -25545,10 +25547,10 @@ var SqliteGraphStore = class {
|
|
|
25545
25547
|
}
|
|
25546
25548
|
this.db.exec(TEMPORAL_INDEX_SQL);
|
|
25547
25549
|
installHistoryCacheFloor(this.db);
|
|
25548
|
-
if (!this.db.prepare("SELECT value FROM store_meta WHERE key =
|
|
25550
|
+
if (!this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(SESSION_REPAIR_KEY)) {
|
|
25549
25551
|
this.db.transaction(() => {
|
|
25550
25552
|
this.repairSessionAliases();
|
|
25551
|
-
this.db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES (
|
|
25553
|
+
this.db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES (?, 'done')").run(SESSION_REPAIR_KEY);
|
|
25552
25554
|
});
|
|
25553
25555
|
}
|
|
25554
25556
|
this.stmts = {
|
|
@@ -25743,6 +25745,34 @@ var SqliteGraphStore = class {
|
|
|
25743
25745
|
const seqRow = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
|
|
25744
25746
|
this.ingestSeq = seqRow ? Number(seqRow.value) : 0;
|
|
25745
25747
|
}
|
|
25748
|
+
strandedSymbols() {
|
|
25749
|
+
return this.db.prepare(`
|
|
25750
|
+
SELECT f.id AS fileId, e.to_id AS symbolId
|
|
25751
|
+
-- Start from the small File population. An unconstrained JOIN lets
|
|
25752
|
+
-- SQLite start at edges_live and visit every live edge in the graph.
|
|
25753
|
+
FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
|
|
25754
|
+
LEFT JOIN nodes t ON t.id = e.to_id
|
|
25755
|
+
WHERE f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
|
|
25756
|
+
AND e.type IN ('DEFINES', 'CONTAINS')
|
|
25757
|
+
AND (t.id IS NULL OR t.valid_to IS NOT NULL)
|
|
25758
|
+
`).all();
|
|
25759
|
+
}
|
|
25760
|
+
fileIndexStates(ids) {
|
|
25761
|
+
if (ids.length === 0) return [];
|
|
25762
|
+
if (ids.length > 500) throw new RangeError("fileIndexStates accepts at most 500 ids per read");
|
|
25763
|
+
const rows = this.db.prepare(`
|
|
25764
|
+
SELECT f.id, f.last_updated_at AS lastUpdatedAt, f.valid_to AS validTo,
|
|
25765
|
+
CASE WHEN count(e.id) = 0 THEN
|
|
25766
|
+
(json_type(f.attrs_json, '$.symbolCount') IN ('integer','real') AND json_extract(f.attrs_json, '$.symbolCount') = 0)
|
|
25767
|
+
OR json_type(f.attrs_json, '$.indexSkipped') = 'text'
|
|
25768
|
+
ELSE max(CASE WHEN t.id IS NULL OR t.valid_to IS NOT NULL THEN 1 ELSE 0 END) = 0 END AS complete
|
|
25769
|
+
FROM nodes f
|
|
25770
|
+
LEFT JOIN edges e ON e.from_id = f.id AND e.valid_to IS NULL AND e.type IN ('DEFINES','CONTAINS')
|
|
25771
|
+
LEFT JOIN nodes t ON t.id = e.to_id
|
|
25772
|
+
WHERE f.id IN (${ids.map(() => "?").join(",")}) GROUP BY f.id
|
|
25773
|
+
`).all(...ids);
|
|
25774
|
+
return rows.map((row) => ({ ...row, complete: row.complete === 1 }));
|
|
25775
|
+
}
|
|
25746
25776
|
/** Forward-migrate the on-disk schema to the current SCHEMA_VERSION. */
|
|
25747
25777
|
migrate(from) {
|
|
25748
25778
|
this.db.transaction(() => {
|
|
@@ -28833,11 +28863,13 @@ function buildSnapshot(opts) {
|
|
|
28833
28863
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
28834
28864
|
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
28835
28865
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
28836
|
-
const
|
|
28866
|
+
const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
|
|
28837
28867
|
node: p,
|
|
28838
28868
|
anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
|
|
28839
28869
|
}));
|
|
28840
|
-
const
|
|
28870
|
+
const recent = openPool.slice(0, RECENT_OPEN);
|
|
28871
|
+
const constraintPool = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
|
|
28872
|
+
const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
|
|
28841
28873
|
const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
|
|
28842
28874
|
(open) => opts.store.outEdges(open.id, ["REGRESSION_OF"]).flatMap((e) => {
|
|
28843
28875
|
const closed = opts.store.getNode(e.to);
|
|
@@ -28850,11 +28882,12 @@ function buildSnapshot(opts) {
|
|
|
28850
28882
|
})
|
|
28851
28883
|
).sort((a, b) => Number(b.closed.attrs["recurredAt"] ?? 0) - Number(a.closed.attrs["recurredAt"] ?? 0)).slice(0, 2);
|
|
28852
28884
|
const regressionClosedIds = new Set(regressions.map((r) => r.closed.id));
|
|
28853
|
-
const
|
|
28885
|
+
const resolvedPool = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).filter((p) => !regressionClosedIds.has(p.id)).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, RECENT_RESOLVED * SCOPE_POOL_FACTOR).map((p) => {
|
|
28854
28886
|
const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
|
|
28855
28887
|
const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
|
|
28856
28888
|
return { node: p, ...solution ? { solution } : {} };
|
|
28857
28889
|
});
|
|
28890
|
+
const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
|
|
28858
28891
|
const motifs = [
|
|
28859
28892
|
...opts.store.findNodesByLabel("Pattern"),
|
|
28860
28893
|
...opts.store.findNodesByLabel("Technique"),
|
|
@@ -28932,9 +28965,14 @@ function buildSnapshot(opts) {
|
|
|
28932
28965
|
pendingEnrichment,
|
|
28933
28966
|
skills: opts.skills ?? [],
|
|
28934
28967
|
needsRevisit,
|
|
28968
|
+
scopePool: { open: openPool, resolved: resolvedPool, constraints: constraintPool },
|
|
28935
28969
|
generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
28936
28970
|
};
|
|
28937
28971
|
}
|
|
28972
|
+
var RECENT_OPEN = 8;
|
|
28973
|
+
var RECENT_RESOLVED = 4;
|
|
28974
|
+
var RECENT_CONSTRAINTS = 3;
|
|
28975
|
+
var SCOPE_POOL_FACTOR = 3;
|
|
28938
28976
|
function sliceForFile(store2, relPath, atCommit) {
|
|
28939
28977
|
const candidates = store2.findNodesByLabel("File");
|
|
28940
28978
|
const file2 = candidates.find((n) => n.description === relPath);
|
|
@@ -29110,48 +29148,30 @@ function listSourceFiles(root) {
|
|
|
29110
29148
|
return gitSourceFiles(root) ?? walkSource(root);
|
|
29111
29149
|
}
|
|
29112
29150
|
var SCAN_YIELD_EVERY = 100;
|
|
29113
|
-
var LIVENESS_CHUNK = 4e3;
|
|
29114
29151
|
async function findStaleFiles(store2, rootPath, workspaceId) {
|
|
29115
29152
|
const stale = [];
|
|
29116
|
-
|
|
29117
|
-
const
|
|
29153
|
+
let pending = [];
|
|
29154
|
+
const check2 = () => {
|
|
29155
|
+
const states = new Map(store2.fileIndexStates(pending.map((f) => f.id)).map((s) => [s.id, s]));
|
|
29156
|
+
for (const f of pending) {
|
|
29157
|
+
const state = states.get(f.id);
|
|
29158
|
+
if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
|
|
29159
|
+
}
|
|
29160
|
+
pending = [];
|
|
29161
|
+
};
|
|
29118
29162
|
let scanned = 0;
|
|
29119
29163
|
for (const abs of listSourceFiles(rootPath)) {
|
|
29120
|
-
if (++scanned % SCAN_YIELD_EVERY === 0) await new Promise((r) => setImmediate(r));
|
|
29121
|
-
let mtimeMs;
|
|
29122
29164
|
try {
|
|
29123
|
-
|
|
29165
|
+
const rel = relative2(rootPath, abs).split(sep2).join("/");
|
|
29166
|
+
pending.push({ abs, id: fileNodeId(workspaceId, rel), mtimeMs: statSync3(abs).mtimeMs });
|
|
29124
29167
|
} catch {
|
|
29125
|
-
continue;
|
|
29126
29168
|
}
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
stale.push(abs);
|
|
29131
|
-
} else if ((fnode.validTo ?? null) !== null) {
|
|
29132
|
-
stale.push(abs);
|
|
29133
|
-
} else if (fnode.lastUpdatedAt < mtimeMs) {
|
|
29134
|
-
stale.push(abs);
|
|
29135
|
-
} else {
|
|
29136
|
-
const edges = store2.outEdges(fnode.id, ["DEFINES", "CONTAINS"]);
|
|
29137
|
-
if (edges.length === 0) {
|
|
29138
|
-
const converged = fnode.attrs["symbolCount"] === 0 || typeof fnode.attrs["indexSkipped"] === "string";
|
|
29139
|
-
if (!converged) stale.push(abs);
|
|
29140
|
-
} else {
|
|
29141
|
-
const targets = edges.map((e) => e.to);
|
|
29142
|
-
pending.push({ abs, targets });
|
|
29143
|
-
allTargets.push(...targets);
|
|
29144
|
-
}
|
|
29169
|
+
if (++scanned % SCAN_YIELD_EVERY === 0) {
|
|
29170
|
+
check2();
|
|
29171
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
29145
29172
|
}
|
|
29146
29173
|
}
|
|
29147
|
-
|
|
29148
|
-
for (let i2 = 0; i2 < allTargets.length; i2 += LIVENESS_CHUNK) {
|
|
29149
|
-
for (const id of store2.liveNodeIds(allTargets.slice(i2, i2 + LIVENESS_CHUNK))) live.add(id);
|
|
29150
|
-
if (i2 + LIVENESS_CHUNK < allTargets.length) await new Promise((r) => setImmediate(r));
|
|
29151
|
-
}
|
|
29152
|
-
for (const { abs, targets } of pending) {
|
|
29153
|
-
if (targets.some((id) => !live.has(id))) stale.push(abs);
|
|
29154
|
-
}
|
|
29174
|
+
check2();
|
|
29155
29175
|
return stale;
|
|
29156
29176
|
}
|
|
29157
29177
|
async function reconcileStaleFiles(store2, rootPath, workspaceId) {
|
|
@@ -29566,6 +29586,9 @@ port.on("message", (msg) => {
|
|
|
29566
29586
|
});
|
|
29567
29587
|
function runPass(msg) {
|
|
29568
29588
|
switch (msg.kind) {
|
|
29589
|
+
case "prepareStore":
|
|
29590
|
+
return void 0;
|
|
29591
|
+
// opening the connection above completed all preparation
|
|
29569
29592
|
case "semanticMaintenance":
|
|
29570
29593
|
return runWorkspaceMaintenance(store, init2.workspaceId);
|
|
29571
29594
|
case "liveness":
|