@inerrata-corporation/errata 2.0.22-dev.4669 → 2.0.22-dev.4676

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.
@@ -16838,6 +16838,35 @@ var WM_CALIBRATION_KEYS = [
16838
16838
  var WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
16839
16839
  var wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
16840
16840
 
16841
+ // ../../packages/local-graph/src/exposure-attrs.ts
16842
+ var EXPOSURE_ATTRS = [
16843
+ "shownCount",
16844
+ "evictedCount",
16845
+ "firstShownAt",
16846
+ "firstEvictedAt",
16847
+ "firstShownAtSeq",
16848
+ "lastShownAtSeq",
16849
+ "lastEvictedAtSeq",
16850
+ "shownSinceTouch",
16851
+ "shownSinceTouchAt",
16852
+ "exposureLog",
16853
+ "exposureLogStart",
16854
+ "exposureLogSince",
16855
+ "exposureFirst",
16856
+ "exposureTrimmed"
16857
+ ];
16858
+ var EXPOSURE_SCOPE = "exposure";
16859
+ var EXPOSURE_KEYS = new Set(EXPOSURE_ATTRS);
16860
+ var isExposureAttr = (key) => EXPOSURE_KEYS.has(key);
16861
+ function pickExposure(attrs) {
16862
+ const out = {};
16863
+ for (const k of EXPOSURE_ATTRS) if (attrs[k] !== void 0) out[k] = attrs[k];
16864
+ return out;
16865
+ }
16866
+ function exposureDocSql(key) {
16867
+ return `coalesce((SELECT x.attrs_json FROM node_exposure x WHERE x.id = nodes.id AND json_type(x.attrs_json, '$.${key}') IS NOT NULL), attrs_json)`;
16868
+ }
16869
+
16841
16870
  // ../../packages/local-graph/src/history-cache-floor.ts
16842
16871
  var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
16843
16872
  function installHistoryCacheFloor(db) {
@@ -17122,25 +17151,6 @@ function textIndexReady(db) {
17122
17151
  return db.prepare("SELECT value FROM store_meta WHERE key = ?").get(TEXT_INDEX_KEY)?.["value"] === "installed";
17123
17152
  }
17124
17153
 
17125
- // ../../packages/local-graph/src/exposure-attrs.ts
17126
- var EXPOSURE_ATTRS = [
17127
- "shownCount",
17128
- "evictedCount",
17129
- "firstShownAt",
17130
- "firstEvictedAt",
17131
- "firstShownAtSeq",
17132
- "lastShownAtSeq",
17133
- "lastEvictedAtSeq",
17134
- "shownSinceTouch",
17135
- "shownSinceTouchAt",
17136
- "exposureLog",
17137
- "exposureLogStart",
17138
- "exposureLogSince",
17139
- "exposureFirst",
17140
- "exposureTrimmed"
17141
- ];
17142
- var EXPOSURE_SCOPE = "exposure";
17143
-
17144
17154
  // ../../packages/local-graph/src/change-feed.ts
17145
17155
  var CHANGE_FEED_KEY = "change-feed";
17146
17156
  var ANY_CHANGE = "*";
@@ -17204,6 +17214,16 @@ function readChangedNodeIds(db, sinceSeq, labels) {
17204
17214
  const rows = db.prepare(`SELECT DISTINCT id FROM change_log WHERE change_seq > ? AND kind = 'node' AND label IN (${labels.map(() => "?").join(",")})`).all(sinceSeq, ...labels);
17205
17215
  return rows.map((r) => r.id);
17206
17216
  }
17217
+ function readChangedAmong(db, sinceSeq, ids) {
17218
+ if (!changeLogCovers(db, sinceSeq)) return null;
17219
+ const out = [];
17220
+ for (let i = 0; i < ids.length; i += 500) {
17221
+ const chunk = ids.slice(i, i + 500);
17222
+ const rows = db.prepare(`SELECT DISTINCT id FROM change_log WHERE change_seq > ? AND kind = 'node' AND id IN (${chunk.map(() => "?").join(",")})`).all(sinceSeq, ...chunk);
17223
+ for (const r of rows) out.push(r.id);
17224
+ }
17225
+ return out;
17226
+ }
17207
17227
  function readLineageChangedFiles(db, sinceSeq) {
17208
17228
  if (!changeLogCovers(db, sinceSeq)) return null;
17209
17229
  const rows = db.prepare(LINEAGE_CHANGED_FILES_SQL).all({ s: sinceSeq });
@@ -17678,8 +17698,11 @@ function compileNodeWhere(q) {
17678
17698
  }
17679
17699
  return { where: conds.join(" AND "), params };
17680
17700
  }
17681
- function attrValueSql(p) {
17682
- return `CASE json_type(attrs_json, ${p}) WHEN 'integer' THEN CAST(json_extract(attrs_json, ${p}) AS REAL) ELSE json_extract(attrs_json, ${p}) END`;
17701
+ function attrValueSql(p, doc = "attrs_json") {
17702
+ return `CASE json_type(${doc}, ${p}) WHEN 'integer' THEN CAST(json_extract(${doc}, ${p}) AS REAL) ELSE json_extract(${doc}, ${p}) END`;
17703
+ }
17704
+ function attrDocSql(key) {
17705
+ return isExposureAttr(key) ? exposureDocSql(key) : "attrs_json";
17683
17706
  }
17684
17707
  function nodeSelectFrom(q) {
17685
17708
  if (q.indexedBy) return `nodes INDEXED BY ${selectIndex(q.indexedBy)}`;
@@ -17692,7 +17715,7 @@ function nodeSelectFrom(q) {
17692
17715
  function compileNodeSelect(q) {
17693
17716
  const { where, params } = compileNodeWhere(q);
17694
17717
  const attrs = q.attrs ?? [];
17695
- const attrCols = attrs.map((k, i) => `, ${attrValueSql(path(k))} AS a${i}, json_type(attrs_json, ${path(k)}) AS t${i}`).join("");
17718
+ const attrCols = attrs.map((k, i) => `, ${attrValueSql(path(k), attrDocSql(k))} AS a${i}, json_type(${attrDocSql(k)}, ${path(k)}) AS t${i}`).join("");
17696
17719
  let order;
17697
17720
  if (q.orderBy && "column" in q.orderBy) {
17698
17721
  order = `${column(q.orderBy.column)} ${q.orderBy.desc ? "DESC" : "ASC"}, rowid`;
@@ -17809,6 +17832,7 @@ function localEdgeViolation(fromLabel, type, toLabel) {
17809
17832
  }
17810
17833
  var SCHEMA_VERSION = 6;
17811
17834
  var SESSION_REPAIR_KEY = "session-evidence-v1";
17835
+ var EXPOSURE_SIDE_KEY = "exposure-side-rows-1";
17812
17836
  var SESSION_EVIDENCE_PREDICATE = SESSION_EVIDENCE_FIELDS.map((field) => `instr(attrs_json, '${JSON.stringify(field)}') > 0`).join(" OR ");
17813
17837
  var SCHEMA_SQL = `
17814
17838
  CREATE TABLE IF NOT EXISTS schema_version (
@@ -17872,8 +17896,13 @@ CREATE TABLE IF NOT EXISTS nodes (
17872
17896
  );
17873
17897
 
17874
17898
  CREATE INDEX IF NOT EXISTS nodes_label ON nodes(label);
17875
- CREATE INDEX IF NOT EXISTS nodes_memory_tier ON nodes(memory_tier);
17876
- CREATE INDEX IF NOT EXISTS nodes_page_rank ON nodes(page_rank DESC);
17899
+ -- Dropped: no query plans through them (every prepared statement across the
17900
+ -- local-graph, indexer, context-writer, generalizer and daemon suites was
17901
+ -- planned with and without them, 2026-10-21), and each write that touches
17902
+ -- memory_tier / page_rank (every node upsert, every rescore) paid to maintain
17903
+ -- them. nodes_live_page_rank serves the live page-rank orderings.
17904
+ DROP INDEX IF EXISTS nodes_memory_tier;
17905
+ DROP INDEX IF EXISTS nodes_page_rank;
17877
17906
 
17878
17907
  CREATE TABLE IF NOT EXISTS edges (
17879
17908
  id TEXT PRIMARY KEY,
@@ -17895,7 +17924,10 @@ CREATE TABLE IF NOT EXISTS edges (
17895
17924
  FOREIGN KEY (to_id) REFERENCES nodes(id) ON DELETE CASCADE
17896
17925
  );
17897
17926
 
17898
- CREATE INDEX IF NOT EXISTS edges_from ON edges(from_id, type);
17927
+ -- Dropped: a prefix of edges_triple (from_id, type, to_id), which every
17928
+ -- from-side lookup and foreign-key check already plans through; it cost 47 MB
17929
+ -- and an index write on every edge write.
17930
+ DROP INDEX IF EXISTS edges_from;
17899
17931
  CREATE INDEX IF NOT EXISTS edges_to ON edges(to_id, type);
17900
17932
  CREATE INDEX IF NOT EXISTS edges_type ON edges(type);
17901
17933
  CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
@@ -17917,6 +17949,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
17917
17949
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
17918
17950
  -- Problems; without it every live Problem was read to find them (56 MB).
17919
17951
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
17952
+ -- Render impressions, one row per node id (exposure-attrs.ts): a render bumps
17953
+ -- ~40 of these, which in the node row rewrote each whole row and its indexes.
17954
+ CREATE TABLE IF NOT EXISTS node_exposure (
17955
+ id TEXT PRIMARY KEY,
17956
+ attrs_json TEXT NOT NULL DEFAULT '{}'
17957
+ ) WITHOUT ROWID;
17920
17958
  -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
17921
17959
  -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
17922
17960
  -- several times a run, and a run follows most writes (2026-10-20).
@@ -18080,6 +18118,7 @@ var SqliteGraphStore = class {
18080
18118
  constructor(opts) {
18081
18119
  this.db = openDatabase(opts.path);
18082
18120
  this.db.exec("PRAGMA cache_size = -32768");
18121
+ this.db.exec("PRAGMA mmap_size = 2147483648");
18083
18122
  this.db.exec(SCHEMA_SQL);
18084
18123
  const versionRow = this.db.prepare("SELECT version FROM schema_version LIMIT 1").get();
18085
18124
  if (!versionRow) {
@@ -18143,7 +18182,10 @@ var SqliteGraphStore = class {
18143
18182
  last_reinforced_at_seq = excluded.last_reinforced_at_seq,
18144
18183
  attrs_json = excluded.attrs_json
18145
18184
  `),
18146
- getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
18185
+ getNode: this.db.prepare("SELECT nodes.*, (SELECT x.attrs_json FROM node_exposure x WHERE x.id = nodes.id) AS exposure_json FROM nodes WHERE id = ?"),
18186
+ exposureOf: this.db.prepare("SELECT attrs_json FROM node_exposure WHERE id = ?"),
18187
+ writeExposure: this.db.prepare("INSERT INTO node_exposure(id, attrs_json) VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET attrs_json = excluded.attrs_json"),
18188
+ lastUpdatedOf: this.db.prepare("SELECT last_updated_at AS t, attrs_json FROM nodes WHERE id = ?"),
18147
18189
  labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
18148
18190
  nodeContent: this.db.prepare(
18149
18191
  "SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
@@ -18307,6 +18349,7 @@ var SqliteGraphStore = class {
18307
18349
  "INSERT INTO store_meta (key, value) VALUES ('ingest_seq', :v) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
18308
18350
  )
18309
18351
  };
18352
+ this.moveExposureToSideRows();
18310
18353
  const seqRow = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
18311
18354
  this.ingestSeq = seqRow ? Number(seqRow.value) : 0;
18312
18355
  }
@@ -18367,21 +18410,35 @@ var SqliteGraphStore = class {
18367
18410
  `SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i) => `${wmCounterSql(k)} AS c${i}`).join(", ")}
18368
18411
  FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
18369
18412
  ).all();
18413
+ const exposed = this.db.prepare(
18414
+ `SELECT n.rowid AS rid, n.logical_id, n.version, n.valid_to, n.label, x.attrs_json AS exposure
18415
+ FROM node_exposure x JOIN nodes n ON n.id = x.id`
18416
+ ).all();
18370
18417
  const others = this.db.prepare(
18371
18418
  `SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
18372
18419
  SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
18373
- WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
18374
- EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
18420
+ WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}
18421
+ UNION SELECT n2.logical_id FROM node_exposure x2 JOIN nodes n2 ON n2.id = x2.id)
18422
+ EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}
18423
+ EXCEPT SELECT n3.rowid FROM node_exposure x3 JOIN nodes n3 ON n3.id = x3.id)`
18375
18424
  ).all();
18376
- const order = new Map(labels.map((l, i) => [l, i]));
18377
- return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
18425
+ const byRid = /* @__PURE__ */ new Map();
18426
+ for (const r of [...counted, ...others]) {
18378
18427
  const attrs = {};
18379
18428
  WM_CALIBRATION_KEYS.forEach((k, i) => {
18380
18429
  const v = r[`c${i}`];
18381
18430
  if (typeof v === "number") attrs[k] = v;
18382
18431
  });
18383
- return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
18384
- });
18432
+ byRid.set(r.rid, { row: r, attrs });
18433
+ }
18434
+ for (const r of exposed) {
18435
+ const side = JSON.parse(r.exposure);
18436
+ const entry = byRid.get(r.rid) ?? { row: r, attrs: {} };
18437
+ for (const k of WM_CALIBRATION_KEYS) if (typeof side[k] === "number" && Number.isFinite(side[k])) entry.attrs[k] = side[k];
18438
+ byRid.set(r.rid, entry);
18439
+ }
18440
+ const order = new Map(labels.map((l, i) => [l, i]));
18441
+ return [...byRid.values()].filter(({ row }) => order.has(row.label)).sort((a, b) => order.get(a.row.label) - order.get(b.row.label) || a.row.rid - b.row.rid).map(({ row, attrs }) => ({ logicalId: row.logical_id, version: Number(row.version), validTo: row.valid_to ?? null, attrs }));
18385
18442
  }
18386
18443
  liveCommentsAttachedTo(name) {
18387
18444
  return this.db.prepare(
@@ -18519,7 +18576,7 @@ var SqliteGraphStore = class {
18519
18576
  logical_id: node.logicalId ?? node.id,
18520
18577
  created_at_seq: node.createdAtSeq ?? null,
18521
18578
  last_reinforced_at_seq: node.lastReinforcedAtSeq ?? null,
18522
- attrs_json: JSON.stringify(node.attrs ?? {})
18579
+ attrs_json: this.nodeAttrsJson(node.id, node.attrs ?? {})
18523
18580
  });
18524
18581
  }
18525
18582
  /** mergeNode, unless the live row already holds this content. Content is what
@@ -18531,7 +18588,7 @@ var SqliteGraphStore = class {
18531
18588
  * whether it wrote. */
18532
18589
  mergeNodeIfChanged(node) {
18533
18590
  const row = this.stmts.nodeContent.get(node.id);
18534
- if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
18591
+ if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && !EXPOSURE_ATTRS.some((k) => node.attrs?.[k] !== void 0) && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
18535
18592
  this.mergeNode(node);
18536
18593
  return true;
18537
18594
  }
@@ -18558,7 +18615,37 @@ var SqliteGraphStore = class {
18558
18615
  logical_id: patch.logicalId ?? null,
18559
18616
  created_at_seq: patch.createdAtSeq ?? null,
18560
18617
  last_reinforced_at_seq: patch.lastReinforcedAtSeq ?? null,
18561
- attrs_json: patch.attrs ? JSON.stringify(patch.attrs) : null
18618
+ attrs_json: patch.attrs ? this.nodeAttrsJson(id, patch.attrs) : null
18619
+ });
18620
+ }
18621
+ /**
18622
+ * The node-row attrs of a write, after handing any exposure keys to the side
18623
+ * row (exposure-attrs.ts). `getNode` returns exposure merged into attrs, so a
18624
+ * read-modify-write carries it; kept in the row it would re-bloat the row and
18625
+ * drift from the side row. Unchanged exposure costs no write.
18626
+ */
18627
+ nodeAttrsJson(id, attrs) {
18628
+ if (!EXPOSURE_ATTRS.some((k) => attrs[k] !== void 0)) return JSON.stringify(attrs);
18629
+ const current = this.stmts.exposureOf.get(id);
18630
+ const next = JSON.stringify({ ...current ? JSON.parse(current.attrs_json) : {}, ...pickExposure(attrs) });
18631
+ if (current?.attrs_json !== next) this.stmts.writeExposure.run(id, next);
18632
+ const rest = { ...attrs };
18633
+ for (const k of EXPOSURE_ATTRS) delete rest[k];
18634
+ return JSON.stringify(rest);
18635
+ }
18636
+ /** One-time: exposure keys written to node rows before the side table existed
18637
+ * move to it. Only rows carrying a counter can carry exposure, and those are
18638
+ * what nodes_wm_counted holds, so this reads the index, not the table. */
18639
+ moveExposureToSideRows() {
18640
+ if (this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(EXPOSURE_SIDE_KEY)) return;
18641
+ const rows = this.db.prepare(`SELECT id, attrs_json FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`).all();
18642
+ const move = this.db.prepare("UPDATE nodes SET attrs_json = ? WHERE id = ?");
18643
+ this.db.transaction(() => {
18644
+ for (const r of rows) {
18645
+ const stripped = this.nodeAttrsJson(r.id, JSON.parse(r.attrs_json));
18646
+ if (stripped !== r.attrs_json) move.run(stripped, r.id);
18647
+ }
18648
+ this.db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, 'done')").run(EXPOSURE_SIDE_KEY);
18562
18649
  });
18563
18650
  }
18564
18651
  /** Fast single-column writes for the nightly pass (avoid the 18-column COALESCE
@@ -18721,7 +18808,27 @@ var SqliteGraphStore = class {
18721
18808
  }
18722
18809
  getNode(id) {
18723
18810
  const row = this.stmts.getNode.get(id);
18724
- return row ? rowToNode(row) : null;
18811
+ if (!row) return null;
18812
+ const node = rowToNode(row);
18813
+ if (row.exposure_json) Object.assign(node.attrs, JSON.parse(row.exposure_json));
18814
+ return node;
18815
+ }
18816
+ /** A node's render exposure: the side row's keys over the node row's own
18817
+ * (exposure-attrs.ts), plus the node's `lastUpdatedAt` (the "shown since
18818
+ * touch" counter is relative to it) — without reading the node's attrs. */
18819
+ exposureOf(id) {
18820
+ const row = this.stmts.lastUpdatedOf.get(id);
18821
+ if (!row) return null;
18822
+ const side = this.stmts.exposureOf.get(id);
18823
+ return {
18824
+ attrs: { ...pickExposure(JSON.parse(row.attrs_json)), ...side ? JSON.parse(side.attrs_json) : {} },
18825
+ lastUpdatedAt: row.t
18826
+ };
18827
+ }
18828
+ /** Replace a node's exposure (only EXPOSURE_ATTRS keys belong here). Touches
18829
+ * neither the node row nor its indexes, nor the change feed. */
18830
+ writeExposure(id, attrs) {
18831
+ this.stmts.writeExposure.run(id, JSON.stringify(attrs));
18725
18832
  }
18726
18833
  nodeLabels(ids) {
18727
18834
  const width = NODE_LABELS_CHUNK;
@@ -18772,7 +18879,7 @@ var SqliteGraphStore = class {
18772
18879
  findNodeStampsByLabel(label, attrKey) {
18773
18880
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
18774
18881
  const rows = this.db.prepare(
18775
- `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
18882
+ `SELECT id, created_at, created_at_seq, json_type(${attrDocSql(attrKey)}, '$.${attrKey}') IS NOT NULL AS has,
18776
18883
  COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
18777
18884
  FROM nodes WHERE label = ? AND valid_to IS NULL`
18778
18885
  ).all(label);
@@ -18789,7 +18896,7 @@ var SqliteGraphStore = class {
18789
18896
  const keys = [...new Set(attrKeys)];
18790
18897
  const rows = this.db.prepare(
18791
18898
  `SELECT id, created_at, created_at_seq,
18792
- ${keys.map((k, i) => `json_type(attrs_json, '$.${k}') IS NOT NULL AS h${i}`).join(", ")}${keys.length ? "," : ""}
18899
+ ${keys.map((k, i) => `json_type(${attrDocSql(k)}, '$.${k}') IS NOT NULL AS h${i}`).join(", ")}${keys.length ? "," : ""}
18793
18900
  COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
18794
18901
  FROM nodes WHERE label = ? AND valid_to IS NULL`
18795
18902
  ).all(label);
@@ -19049,6 +19156,9 @@ var SqliteGraphStore = class {
19049
19156
  changedNodeIds(sinceSeq, labels) {
19050
19157
  return readChangedNodeIds(this.db, sinceSeq, labels);
19051
19158
  }
19159
+ changedAmong(sinceSeq, ids) {
19160
+ return readChangedAmong(this.db, sinceSeq, ids);
19161
+ }
19052
19162
  pruneChangeLog() {
19053
19163
  return pruneChangeLog(this.db);
19054
19164
  }