@claude-flow/memory 3.2.5 → 3.3.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 (37) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/learning-bridge.d.ts +24 -1
  6. package/dist/learning-bridge.d.ts.map +1 -1
  7. package/dist/learning-bridge.js +47 -1
  8. package/dist/learning-bridge.js.map +1 -1
  9. package/dist/learning-bridge.test.js +122 -0
  10. package/dist/learning-bridge.test.js.map +1 -1
  11. package/dist/memory-graph.d.ts +6 -3
  12. package/dist/memory-graph.d.ts.map +1 -1
  13. package/dist/memory-graph.js +35 -42
  14. package/dist/memory-graph.js.map +1 -1
  15. package/dist/memory-graph.test.js +1 -1
  16. package/dist/memory-graph.test.js.map +1 -1
  17. package/dist/pagerank.d.ts +30 -0
  18. package/dist/pagerank.d.ts.map +1 -0
  19. package/dist/pagerank.js +123 -0
  20. package/dist/pagerank.js.map +1 -0
  21. package/dist/pagerank.test.d.ts +2 -0
  22. package/dist/pagerank.test.d.ts.map +1 -0
  23. package/dist/pagerank.test.js +130 -0
  24. package/dist/pagerank.test.js.map +1 -0
  25. package/dist/tiered-memory-inventory.d.ts +108 -0
  26. package/dist/tiered-memory-inventory.d.ts.map +1 -0
  27. package/dist/tiered-memory-inventory.js +228 -0
  28. package/dist/tiered-memory-inventory.js.map +1 -0
  29. package/dist/tiered-memory-inventory.test.d.ts +10 -0
  30. package/dist/tiered-memory-inventory.test.d.ts.map +1 -0
  31. package/dist/tiered-memory-inventory.test.js +323 -0
  32. package/dist/tiered-memory-inventory.test.js.map +1 -0
  33. package/dist/tiered-memory.d.ts +26 -0
  34. package/dist/tiered-memory.d.ts.map +1 -1
  35. package/dist/tiered-memory.js +27 -0
  36. package/dist/tiered-memory.js.map +1 -1
  37. package/package.json +3 -2
@@ -0,0 +1,123 @@
1
+ /**
2
+ * PageRank by power iteration over a dense-index graph.
3
+ *
4
+ * Uses `@ruvnet/sublinear-core` when it is installed (optional dependency,
5
+ * loaded lazily and synchronously through `createRequire`) and otherwise an
6
+ * in-tree implementation with the same semantics:
7
+ *
8
+ * - `damping` is the probability of following an out-edge;
9
+ * - the mass of nodes without out-edges is redistributed by the teleport
10
+ * vector, so scores always sum to 1;
11
+ * - iteration stops when the L1 change between iterates is <= `tolerance`.
12
+ *
13
+ * @module v3/memory/pagerank
14
+ */
15
+ import { createRequire } from 'node:module';
16
+ let core;
17
+ function loadCore() {
18
+ if (core === undefined) {
19
+ try {
20
+ const mod = createRequire(import.meta.url)('@ruvnet/sublinear-core');
21
+ core = typeof mod?.pageRank === 'function'
22
+ && typeof mod.personalizedPageRank === 'function'
23
+ && typeof mod.graphFromEdges === 'function'
24
+ ? mod
25
+ : null;
26
+ }
27
+ catch {
28
+ core = null;
29
+ }
30
+ }
31
+ return core;
32
+ }
33
+ /**
34
+ * Test hook: `null` forces the in-tree implementation, `undefined` restores
35
+ * lazy loading, an object substitutes the module.
36
+ */
37
+ export function _setSublinearCoreForTests(mod) {
38
+ core = mod;
39
+ }
40
+ /** Drop self-references, out-of-range endpoints and non-positive or non-finite weights. */
41
+ function sanitize(n, edges) {
42
+ const clean = [];
43
+ for (const [s, t, rawW] of edges) {
44
+ const w = rawW ?? 1;
45
+ if (!Number.isInteger(s) || !Number.isInteger(t) || s < 0 || t < 0 || s >= n || t >= n)
46
+ continue;
47
+ if (!Number.isFinite(w) || w <= 0)
48
+ continue;
49
+ clean.push([s, t, w]);
50
+ }
51
+ return clean;
52
+ }
53
+ function teleportVector(n, teleport) {
54
+ if (!teleport)
55
+ return null;
56
+ const v = new Map();
57
+ let total = 0;
58
+ for (const [i, w] of teleport) {
59
+ if (Number.isInteger(i) && i >= 0 && i < n && Number.isFinite(w) && w > 0) {
60
+ v.set(i, (v.get(i) ?? 0) + w);
61
+ total += w;
62
+ }
63
+ }
64
+ if (total === 0)
65
+ return null;
66
+ for (const [i, w] of v)
67
+ v.set(i, w / total);
68
+ return v;
69
+ }
70
+ /** In-tree power iteration. Exported for tests. */
71
+ export function pageRankInTree(n, edges, damping, tolerance, maxIterations, teleport) {
72
+ const v = new Float64Array(n);
73
+ if (teleport)
74
+ for (const [i, w] of teleport)
75
+ v[i] = w;
76
+ else
77
+ v.fill(1 / n);
78
+ const outWeight = new Float64Array(n);
79
+ for (const [s, , w] of edges)
80
+ outWeight[s] += w;
81
+ let x = Float64Array.from(v);
82
+ let delta = Infinity;
83
+ let iterations = 0;
84
+ while (iterations < maxIterations) {
85
+ let dangling = 0;
86
+ for (let i = 0; i < n; i++)
87
+ if (outWeight[i] === 0)
88
+ dangling += x[i];
89
+ const y = new Float64Array(n);
90
+ for (const [s, t, w] of edges)
91
+ y[t] += (damping * x[s] * w) / outWeight[s];
92
+ const restart = 1 - damping + damping * dangling;
93
+ delta = 0;
94
+ for (let i = 0; i < n; i++) {
95
+ y[i] += restart * v[i];
96
+ delta += Math.abs(y[i] - x[i]);
97
+ }
98
+ x = y;
99
+ iterations++;
100
+ if (delta <= tolerance)
101
+ break;
102
+ }
103
+ return { scores: x, iterations, delta, converged: delta <= tolerance };
104
+ }
105
+ /** PageRank (or personalized PageRank when `teleport` is given) over nodes 0..n-1. */
106
+ export function computePageRankScores(n, edges, options = {}) {
107
+ const damping = options.damping ?? 0.85;
108
+ const tolerance = options.tolerance ?? 1e-10;
109
+ const maxIterations = options.maxIterations ?? 100;
110
+ if (n === 0)
111
+ return { scores: new Float64Array(0), iterations: 0, delta: 0, converged: true, backend: 'in-tree' };
112
+ const clean = sanitize(n, edges);
113
+ const teleport = teleportVector(n, options.teleport);
114
+ const lib = loadCore();
115
+ if (lib) {
116
+ const graph = lib.graphFromEdges(clean, { n });
117
+ const opts = { damping, tolerance, maxIterations };
118
+ const r = teleport ? lib.personalizedPageRank(graph, teleport, opts) : lib.pageRank(graph, opts);
119
+ return { scores: r.scores, iterations: r.iterations, delta: r.delta, converged: r.converged, backend: 'sublinear-core' };
120
+ }
121
+ return { ...pageRankInTree(n, clean, damping, tolerance, maxIterations, teleport), backend: 'in-tree' };
122
+ }
123
+ //# sourceMappingURL=pagerank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagerank.js","sourceRoot":"","sources":["../src/pagerank.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pagerank.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagerank.test.d.ts","sourceRoot":"","sources":["../src/pagerank.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * PageRank backends: @ruvnet/sublinear-core (optional) and the in-tree
3
+ * fallback must agree with a straightforward power-iteration reference,
4
+ * conserve probability mass, and the fallback must be used when the package
5
+ * is absent.
6
+ */
7
+ import { describe, it, expect, afterEach } from 'vitest';
8
+ import { createRequire } from 'node:module';
9
+ import { computePageRankScores, _setSublinearCoreForTests } from './pagerank.js';
10
+ import { MemoryGraph } from './memory-graph.js';
11
+ /** Deterministic LCG so the graphs are reproducible. */
12
+ function rng(seed) {
13
+ let s = seed >>> 0;
14
+ return () => ((s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32);
15
+ }
16
+ function randomGraph(n, avgOut, seed) {
17
+ const r = rng(seed);
18
+ const edges = [];
19
+ for (let s = 0; s < n; s++) {
20
+ // ~10% dangling nodes
21
+ if (r() < 0.1)
22
+ continue;
23
+ const k = 1 + Math.floor(r() * 2 * avgOut);
24
+ for (let j = 0; j < k; j++) {
25
+ const t = Math.floor(r() * n);
26
+ if (t !== s)
27
+ edges.push([s, t]);
28
+ }
29
+ }
30
+ return edges;
31
+ }
32
+ /** Reference: dense power iteration run to 1e-15, written independently of pagerank.ts. */
33
+ function reference(n, edges, d, teleport) {
34
+ const v = new Array(n).fill(teleport ? 0 : 1 / n);
35
+ if (teleport) {
36
+ let tot = 0;
37
+ for (const w of teleport.values())
38
+ tot += w;
39
+ for (const [i, w] of teleport)
40
+ v[i] = w / tot;
41
+ }
42
+ const out = new Array(n).fill(0);
43
+ for (const [s] of edges)
44
+ out[s]++;
45
+ let x = v.slice();
46
+ for (let it = 0; it < 10_000; it++) {
47
+ const dangling = x.reduce((acc, xi, i) => (out[i] === 0 ? acc + xi : acc), 0);
48
+ const y = v.map((vi) => (1 - d) * vi + d * dangling * vi);
49
+ for (const [s, t] of edges)
50
+ y[t] += (d * x[s]) / out[s];
51
+ const delta = y.reduce((acc, yi, i) => acc + Math.abs(yi - x[i]), 0);
52
+ x = y;
53
+ if (delta < 1e-15)
54
+ break;
55
+ }
56
+ return x;
57
+ }
58
+ const sum = (a) => Array.from(a).reduce((s, x) => s + x, 0);
59
+ const maxErr = (a, b) => Math.max(...b.map((bi, i) => Math.abs(a[i] - bi)));
60
+ afterEach(() => _setSublinearCoreForTests(undefined));
61
+ // @ruvnet/sublinear-core is an optional dependency: the repo-root test run
62
+ // (npm workspaces) does not install it, so its cases are skipped there.
63
+ const HAS_CORE = (() => { try {
64
+ createRequire(import.meta.url).resolve('@ruvnet/sublinear-core');
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ } })();
70
+ const BACKENDS = [['sublinear-core', undefined], ['in-tree', null]].filter(([b]) => HAS_CORE || b === 'in-tree');
71
+ describe.each(BACKENDS)('computePageRankScores (%s)', (backend, hook) => {
72
+ it('uses the expected backend', () => {
73
+ _setSublinearCoreForTests(hook);
74
+ const run = computePageRankScores(3, [[0, 1], [1, 2]]);
75
+ expect(run.backend).toBe(backend);
76
+ });
77
+ it('sums to 1 and matches power iteration within 1e-9 (n=2000, dangling nodes)', () => {
78
+ _setSublinearCoreForTests(hook);
79
+ const n = 2000;
80
+ const edges = randomGraph(n, 4, 7);
81
+ const run = computePageRankScores(n, edges, { damping: 0.85 });
82
+ expect(run.converged).toBe(true);
83
+ expect(sum(run.scores)).toBeCloseTo(1, 12);
84
+ expect(maxErr(run.scores, reference(n, edges, 0.85))).toBeLessThan(1e-9);
85
+ });
86
+ it('personalized: sums to 1, teleports only to seeds, matches reference', () => {
87
+ _setSublinearCoreForTests(hook);
88
+ const n = 500;
89
+ const edges = randomGraph(n, 3, 11);
90
+ const seeds = new Map([[3, 2], [42, 1]]);
91
+ const run = computePageRankScores(n, edges, { teleport: seeds });
92
+ expect(sum(run.scores)).toBeCloseTo(1, 12);
93
+ expect(maxErr(run.scores, reference(n, edges, 0.85, seeds))).toBeLessThan(1e-9);
94
+ });
95
+ it('ignores invalid teleport entries and falls back to uniform when none remain', () => {
96
+ _setSublinearCoreForTests(hook);
97
+ const edges = [[0, 1], [1, 2], [2, 0], [2, 3]];
98
+ const uniform = computePageRankScores(4, edges);
99
+ const bogus = computePageRankScores(4, edges, { teleport: new Map([[99, 1], [1, -5]]) });
100
+ expect(maxErr(bogus.scores, Array.from(uniform.scores))).toBeLessThan(1e-12);
101
+ });
102
+ });
103
+ describe('MemoryGraph.computePageRank', () => {
104
+ const entry = (id, refs = []) => ({
105
+ id, key: id, content: id, type: 'semantic', namespace: 'default', tags: [], metadata: {},
106
+ accessLevel: 'private', createdAt: 0, updatedAt: 0, version: 1, references: refs,
107
+ accessCount: 0, lastAccessedAt: 0,
108
+ });
109
+ it.each(BACKENDS)('matches power iteration within 1e-9 and sums to 1 (%s)', (backend, hook) => {
110
+ _setSublinearCoreForTests(hook);
111
+ const n = 1000;
112
+ const edges = randomGraph(n, 3, 5);
113
+ const g = new MemoryGraph({ maxNodes: n });
114
+ for (let i = 0; i < n; i++)
115
+ g.addNode(entry(`n${i}`));
116
+ for (const [s, t] of edges)
117
+ g.addEdge(`n${s}`, `n${t}`, 'reference');
118
+ let event = {};
119
+ g.on('pagerank:computed', (e) => { event = e; });
120
+ const ranks = g.computePageRank();
121
+ expect(event.backend).toBe(backend);
122
+ // MemoryGraph de-duplicates parallel edges; mirror that in the reference.
123
+ const unique = [...new Set(edges.map(([s, t]) => `${s},${t}`))].map((k) => k.split(',').map(Number));
124
+ const ref = reference(n, unique, 0.85);
125
+ const got = Array.from({ length: n }, (_, i) => ranks.get(`n${i}`));
126
+ expect(sum(got)).toBeCloseTo(1, 12);
127
+ expect(maxErr(got, ref)).toBeLessThan(1e-9);
128
+ });
129
+ });
130
+ //# sourceMappingURL=pagerank.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagerank.test.js","sourceRoot":"","sources":["../src/pagerank.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,wDAAwD;AACxD,SAAS,GAAG,CAAC,IAAY;IACvB,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IACnB,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,WAAW,CAAC,CAAS,EAAE,MAAc,EAAE,IAAY;IAC1D,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,sBAAsB;QACtB,IAAI,CAAC,EAAE,GAAG,GAAG;YAAE,SAAS;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,2FAA2F;AAC3F,SAAS,SAAS,CAAC,CAAS,EAAE,KAA8B,EAAE,CAAS,EAAE,QAA8B;IACrG,MAAM,CAAC,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE;YAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ;YAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAChD,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;IAClB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,GAAG,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK;YAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC,GAAG,CAAC,CAAC;QACN,IAAI,KAAK,GAAG,KAAK;YAAE,MAAM;IAC3B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,GAAG,GAAG,CAAC,CAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/E,MAAM,MAAM,GAAG,CAAC,CAAoB,EAAE,CAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AAEzG,SAAS,CAAC,GAAG,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC,CAAC;AAEtD,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAAC,OAAO,IAAI,CAAC;AAAC,CAAC;AAAC,MAAM,CAAC;IAAC,OAAO,KAAK,CAAC;AAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9I,MAAM,QAAQ,GAAI,CAAC,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;AAE5H,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,4BAA4B,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtE,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,GAAG,CAAC;QACd,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,KAAK,GAA4B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,qBAAqB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,OAAiB,EAAE,EAAe,EAAE,CAAC,CAAC;QAC/D,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;QACxF,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI;QAChF,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC;KAClC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,wDAAwD,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QAC5F,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK;YAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAErE,IAAI,KAAK,GAAyB,EAAE,CAAC;QACrC,CAAC,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,0EAA0E;QAC1E,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAqB,CAAC,CAAC;QACzH,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Persisted inventory and exact-ID reads for {@link TieredMemoryStore} (#4712).
3
+ *
4
+ * `recall()` scores the hydrated in-memory maps, which hold at most 5,000
5
+ * active entries per tier plus a 5,000-entry archive and collapse same-key
6
+ * rows. They cannot answer "what is stored?". These helpers read the durable
7
+ * `tiered_memory` table instead, so every persisted row — including history
8
+ * beyond the hydration caps — is reachable.
9
+ *
10
+ * Status of a row, by fixed precedence (one definition, used for both the
11
+ * list filter and the label returned to callers):
12
+ * 1. `superseded` — `superseded_by` is set (invalidated by a newer fact)
13
+ * 2. `archived` — `archived = 1` without a superseding id
14
+ * 3. `expired` — outside its validity window per {@link isTemporallyValid};
15
+ * this includes not-yet-valid (future `validFrom`) rows,
16
+ * matching `recall()`'s `includeExpired` semantics
17
+ * 4. `active` — everything else
18
+ *
19
+ * Each call captures one evaluation instant, so temporal classification is
20
+ * consistent within a call. Reads are live, not a snapshot: rows written
21
+ * between page requests may or may not appear.
22
+ *
23
+ * Ordering is `ts DESC, id DESC` (newest first, id breaks ties), paginated
24
+ * by keyset, so it is stable across calls.
25
+ *
26
+ * @module @claude-flow/memory/tiered-memory-inventory
27
+ */
28
+ import type { TieredMemoryDb, TieredMemoryEntry, TieredMemoryRow } from './tiered-memory.js';
29
+ /** Status of a persisted tiered-memory row. */
30
+ export type TieredEntryStatus = 'active' | 'expired' | 'superseded' | 'archived';
31
+ /** Status filter accepted by `listEntries`. */
32
+ export type TieredStatusFilter = TieredEntryStatus | 'all';
33
+ export declare const TIERED_STATUS_FILTERS: readonly TieredStatusFilter[];
34
+ export declare const TIERED_LIST_DEFAULT_LIMIT = 100;
35
+ export declare const TIERED_LIST_MAX_LIMIT = 1000;
36
+ /** Upper bound on characters accepted for a cursor or an id. */
37
+ export declare const TIERED_CURSOR_MAX_LENGTH = 2048;
38
+ export declare const TIERED_ID_MAX_LENGTH = 1000;
39
+ /** Options accepted by `listEntries`. */
40
+ export interface TieredListOptions {
41
+ /** Only rows in this tier (working, episodic, semantic). */
42
+ tier?: string;
43
+ /** Status filter (default `active`). */
44
+ status?: TieredStatusFilter;
45
+ /** Page size, clamped to 1..1000 (default 100). */
46
+ limit?: number;
47
+ /** Opaque cursor from a previous page's `nextCursor`. */
48
+ cursor?: string;
49
+ }
50
+ /** Options accepted by `getEntry`. */
51
+ export interface TieredGetOptions {
52
+ /** Return superseded / archived / expired rows too (default false). */
53
+ includeInactive?: boolean;
54
+ }
55
+ /** A persisted entry with its derived status. */
56
+ export interface TieredInventoryEntry extends TieredMemoryEntry {
57
+ status: TieredEntryStatus;
58
+ /** Raw `archived` column — kept separate from temporal validity. */
59
+ archived: boolean;
60
+ }
61
+ /** One page of `listEntries`. */
62
+ export interface TieredListResult {
63
+ entries: TieredInventoryEntry[];
64
+ /**
65
+ * Cursor for the next page, or null when there is nothing after this page.
66
+ * A short (even empty) page with a non-null cursor means the per-call scan
67
+ * budget ran out before the page filled; keep paging.
68
+ */
69
+ nextCursor: string | null;
70
+ /**
71
+ * Exact row count for the tier/status filter when it is SQL-expressible
72
+ * (`all`, `superseded`, `archived`). Omitted for `active` / `expired`,
73
+ * which need a full JS temporal scan to count.
74
+ */
75
+ totalEstimate?: number;
76
+ /** The single instant used to classify temporal validity for this call. */
77
+ evaluatedAt: string;
78
+ }
79
+ export type TieredInventoryErrorCode = 'unsupported' | 'invalid-cursor' | 'invalid-argument';
80
+ /** Base error for inventory reads. */
81
+ export declare class TieredMemoryInventoryError extends Error {
82
+ readonly code: TieredInventoryErrorCode;
83
+ constructor(message: string, code: TieredInventoryErrorCode);
84
+ }
85
+ /** Thrown when the store has no SQLite handle, so the full inventory cannot be read. */
86
+ export declare class TieredMemoryUnsupportedError extends TieredMemoryInventoryError {
87
+ constructor(operation: string);
88
+ }
89
+ /** Thrown for a cursor that is malformed, altered, or issued for a different filter. */
90
+ export declare class TieredMemoryCursorError extends TieredMemoryInventoryError {
91
+ constructor(reason: string);
92
+ }
93
+ /** Collaborators supplied by the store, so this module holds no runtime import of it. */
94
+ export interface TieredInventoryDeps {
95
+ decode(row: TieredMemoryRow): TieredMemoryEntry;
96
+ isValid(entry: Pick<TieredMemoryEntry, 'validFrom' | 'validUntil'>, nowMs: number): boolean;
97
+ validTiers: readonly string[];
98
+ }
99
+ /** Status of a row at `nowMs`, by the precedence documented on this module. */
100
+ export declare function deriveTieredStatus(row: TieredMemoryRow, entry: TieredMemoryEntry, nowMs: number, isValid: TieredInventoryDeps['isValid']): TieredEntryStatus;
101
+ /**
102
+ * One page of persisted entries, newest first. Reads only; never writes.
103
+ * SQL errors propagate so a failed read is never mistaken for an empty one.
104
+ */
105
+ export declare function listPersistedEntries(db: TieredMemoryDb, options: TieredListOptions | undefined, deps: TieredInventoryDeps): TieredListResult;
106
+ /** Exact read by stable id. Null when missing, or inactive without `includeInactive`. */
107
+ export declare function getPersistedEntry(db: TieredMemoryDb, id: unknown, options: TieredGetOptions | undefined, deps: TieredInventoryDeps): TieredInventoryEntry | null;
108
+ //# sourceMappingURL=tiered-memory-inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiered-memory-inventory.d.ts","sourceRoot":"","sources":["../src/tiered-memory-inventory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Persisted inventory and exact-ID reads for {@link TieredMemoryStore} (#4712).
3
+ *
4
+ * `recall()` scores the hydrated in-memory maps, which hold at most 5,000
5
+ * active entries per tier plus a 5,000-entry archive and collapse same-key
6
+ * rows. They cannot answer "what is stored?". These helpers read the durable
7
+ * `tiered_memory` table instead, so every persisted row — including history
8
+ * beyond the hydration caps — is reachable.
9
+ *
10
+ * Status of a row, by fixed precedence (one definition, used for both the
11
+ * list filter and the label returned to callers):
12
+ * 1. `superseded` — `superseded_by` is set (invalidated by a newer fact)
13
+ * 2. `archived` — `archived = 1` without a superseding id
14
+ * 3. `expired` — outside its validity window per {@link isTemporallyValid};
15
+ * this includes not-yet-valid (future `validFrom`) rows,
16
+ * matching `recall()`'s `includeExpired` semantics
17
+ * 4. `active` — everything else
18
+ *
19
+ * Each call captures one evaluation instant, so temporal classification is
20
+ * consistent within a call. Reads are live, not a snapshot: rows written
21
+ * between page requests may or may not appear.
22
+ *
23
+ * Ordering is `ts DESC, id DESC` (newest first, id breaks ties), paginated
24
+ * by keyset, so it is stable across calls.
25
+ *
26
+ * @module @claude-flow/memory/tiered-memory-inventory
27
+ */
28
+ export const TIERED_STATUS_FILTERS = [
29
+ 'active', 'expired', 'superseded', 'archived', 'all',
30
+ ];
31
+ export const TIERED_LIST_DEFAULT_LIMIT = 100;
32
+ export const TIERED_LIST_MAX_LIMIT = 1000;
33
+ /** Upper bound on characters accepted for a cursor or an id. */
34
+ export const TIERED_CURSOR_MAX_LENGTH = 2048;
35
+ export const TIERED_ID_MAX_LENGTH = 1000;
36
+ /** Rows read from SQLite per batch while filtering. */
37
+ const SCAN_BATCH = 500;
38
+ /** Rows examined by one listEntries call before it returns a partial page. */
39
+ const MAX_SCAN_PER_CALL = 50_000;
40
+ /** Base error for inventory reads. */
41
+ export class TieredMemoryInventoryError extends Error {
42
+ code;
43
+ constructor(message, code) {
44
+ super(message);
45
+ this.code = code;
46
+ this.name = 'TieredMemoryInventoryError';
47
+ }
48
+ }
49
+ /** Thrown when the store has no SQLite handle, so the full inventory cannot be read. */
50
+ export class TieredMemoryUnsupportedError extends TieredMemoryInventoryError {
51
+ constructor(operation) {
52
+ super(`unsupported: volatile store — ${operation} reads the persisted tiered_memory table, ` +
53
+ 'and this TieredMemoryStore has no SQLite handle. Refusing rather than returning a partial in-memory view.', 'unsupported');
54
+ this.name = 'TieredMemoryUnsupportedError';
55
+ }
56
+ }
57
+ /** Thrown for a cursor that is malformed, altered, or issued for a different filter. */
58
+ export class TieredMemoryCursorError extends TieredMemoryInventoryError {
59
+ constructor(reason) {
60
+ super(`invalid cursor: ${reason}. Restart pagination without a cursor.`, 'invalid-cursor');
61
+ this.name = 'TieredMemoryCursorError';
62
+ }
63
+ }
64
+ /** Status of a row at `nowMs`, by the precedence documented on this module. */
65
+ export function deriveTieredStatus(row, entry, nowMs, isValid) {
66
+ if (row.superseded_by)
67
+ return 'superseded';
68
+ if (Number(row.archived) !== 0)
69
+ return 'archived';
70
+ if (!isValid(entry, nowMs))
71
+ return 'expired';
72
+ return 'active';
73
+ }
74
+ function encodeCursor(p) {
75
+ const canonical = JSON.stringify({ v: p.v, ts: p.ts, id: p.id, tier: p.tier, status: p.status });
76
+ return Buffer.from(canonical, 'utf8').toString('base64url');
77
+ }
78
+ function decodeCursor(cursor, tier, status) {
79
+ if (typeof cursor !== 'string' || cursor.length === 0)
80
+ throw new TieredMemoryCursorError('must be a non-empty string');
81
+ if (cursor.length > TIERED_CURSOR_MAX_LENGTH)
82
+ throw new TieredMemoryCursorError('too long');
83
+ if (!/^[A-Za-z0-9_-]+$/.test(cursor))
84
+ throw new TieredMemoryCursorError('not base64url');
85
+ let parsed;
86
+ try {
87
+ parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
88
+ }
89
+ catch {
90
+ throw new TieredMemoryCursorError('not decodable');
91
+ }
92
+ const p = parsed;
93
+ if (!p || typeof p !== 'object' || Array.isArray(p))
94
+ throw new TieredMemoryCursorError('not an object');
95
+ if (p.v !== 1)
96
+ throw new TieredMemoryCursorError('unknown version');
97
+ if (typeof p.ts !== 'number' || !Number.isSafeInteger(p.ts))
98
+ throw new TieredMemoryCursorError('bad position');
99
+ if (typeof p.id !== 'string' || p.id.length === 0 || p.id.length > TIERED_ID_MAX_LENGTH) {
100
+ throw new TieredMemoryCursorError('bad position');
101
+ }
102
+ if (!(p.tier === null || typeof p.tier === 'string'))
103
+ throw new TieredMemoryCursorError('bad filter');
104
+ if (!TIERED_STATUS_FILTERS.includes(p.status))
105
+ throw new TieredMemoryCursorError('bad filter');
106
+ const payload = { v: 1, ts: p.ts, id: p.id, tier: p.tier, status: p.status };
107
+ // Only cursors this module minted round-trip byte-for-byte.
108
+ if (encodeCursor(payload) !== cursor)
109
+ throw new TieredMemoryCursorError('not canonical (altered)');
110
+ if (payload.tier !== tier || payload.status !== status) {
111
+ throw new TieredMemoryCursorError('issued for a different tier/status filter');
112
+ }
113
+ return payload;
114
+ }
115
+ function invalid(message) {
116
+ return new TieredMemoryInventoryError(message, 'invalid-argument');
117
+ }
118
+ function normalizeLimit(limit) {
119
+ if (limit === undefined || limit === null)
120
+ return TIERED_LIST_DEFAULT_LIMIT;
121
+ if (typeof limit !== 'number' || !Number.isFinite(limit))
122
+ throw invalid('limit must be a finite number');
123
+ return Math.min(TIERED_LIST_MAX_LIMIT, Math.max(1, Math.floor(limit)));
124
+ }
125
+ /** SQL prefilter for a status. The JS status check below stays authoritative. */
126
+ function statusClause(status) {
127
+ switch (status) {
128
+ case 'superseded': return "COALESCE(superseded_by, '') <> ''";
129
+ case 'archived': return "COALESCE(superseded_by, '') = '' AND archived <> 0";
130
+ case 'active':
131
+ case 'expired': return "COALESCE(superseded_by, '') = '' AND archived = 0";
132
+ default: return null;
133
+ }
134
+ }
135
+ /**
136
+ * One page of persisted entries, newest first. Reads only; never writes.
137
+ * SQL errors propagate so a failed read is never mistaken for an empty one.
138
+ */
139
+ export function listPersistedEntries(db, options, deps) {
140
+ const opts = options ?? {};
141
+ if (opts.tier !== undefined && opts.tier !== null && !deps.validTiers.includes(opts.tier)) {
142
+ throw invalid(`tier must be one of ${deps.validTiers.join(', ')}`);
143
+ }
144
+ const tier = opts.tier ?? null;
145
+ const status = opts.status ?? 'active';
146
+ if (!TIERED_STATUS_FILTERS.includes(status))
147
+ throw invalid(`status must be one of ${TIERED_STATUS_FILTERS.join(', ')}`);
148
+ const limit = normalizeLimit(opts.limit);
149
+ let position = opts.cursor !== undefined && opts.cursor !== null ? decodeCursor(opts.cursor, tier, status) : null;
150
+ const nowMs = Date.now();
151
+ const filters = [];
152
+ const filterParams = [];
153
+ if (tier) {
154
+ filters.push('tier = ?');
155
+ filterParams.push(tier);
156
+ }
157
+ const sc = statusClause(status);
158
+ if (sc)
159
+ filters.push(sc);
160
+ const page = [];
161
+ let lastScanned = null;
162
+ let scanned = 0;
163
+ let exhausted = false;
164
+ let overflow = false;
165
+ while (!overflow && scanned < MAX_SCAN_PER_CALL) {
166
+ const where = [...filters];
167
+ const params = [...filterParams];
168
+ if (position) {
169
+ where.push('(ts < ? OR (ts = ? AND id < ?))');
170
+ params.push(position.ts, position.ts, position.id);
171
+ }
172
+ const batch = Math.min(SCAN_BATCH, MAX_SCAN_PER_CALL - scanned);
173
+ const sql = `SELECT * FROM tiered_memory${where.length ? ` WHERE ${where.join(' AND ')}` : ''} ` +
174
+ 'ORDER BY ts DESC, id DESC LIMIT ?';
175
+ const rows = db.prepare(sql).all(...params, batch);
176
+ for (const row of rows) {
177
+ scanned++;
178
+ lastScanned = row;
179
+ const entry = deps.decode(row);
180
+ const rowStatus = deriveTieredStatus(row, entry, nowMs, deps.isValid);
181
+ if (status !== 'all' && rowStatus !== status)
182
+ continue;
183
+ if (page.length === limit) {
184
+ overflow = true;
185
+ break;
186
+ } // one more match exists
187
+ page.push({ row, item: { ...entry, status: rowStatus, archived: Number(row.archived) !== 0 } });
188
+ }
189
+ if (overflow)
190
+ break;
191
+ if (rows.length < batch) {
192
+ exhausted = true;
193
+ break;
194
+ }
195
+ position = { v: 1, ts: Number(lastScanned.ts), id: lastScanned.id, tier, status };
196
+ }
197
+ let next = null;
198
+ if (overflow)
199
+ next = page[page.length - 1].row; // resume right after the last emitted row
200
+ else if (!exhausted && lastScanned)
201
+ next = lastScanned; // scan budget hit: skip what was examined
202
+ const result = {
203
+ entries: page.map(p => p.item),
204
+ nextCursor: next ? encodeCursor({ v: 1, ts: Number(next.ts), id: next.id, tier, status }) : null,
205
+ evaluatedAt: new Date(nowMs).toISOString(),
206
+ };
207
+ if (status === 'all' || status === 'superseded' || status === 'archived') {
208
+ const countSql = `SELECT COUNT(*) AS n FROM tiered_memory${filters.length ? ` WHERE ${filters.join(' AND ')}` : ''}`;
209
+ const row = db.prepare(countSql).get(...filterParams);
210
+ result.totalEstimate = Number(row?.n ?? 0);
211
+ }
212
+ return result;
213
+ }
214
+ /** Exact read by stable id. Null when missing, or inactive without `includeInactive`. */
215
+ export function getPersistedEntry(db, id, options, deps) {
216
+ if (typeof id !== 'string' || id.length === 0 || id.length > TIERED_ID_MAX_LENGTH) {
217
+ throw invalid(`id must be a non-empty string of at most ${TIERED_ID_MAX_LENGTH} characters`);
218
+ }
219
+ const row = db.prepare('SELECT * FROM tiered_memory WHERE id = ?').get(id);
220
+ if (!row)
221
+ return null;
222
+ const entry = deps.decode(row);
223
+ const status = deriveTieredStatus(row, entry, Date.now(), deps.isValid);
224
+ if (status !== 'active' && options?.includeInactive !== true)
225
+ return null;
226
+ return { ...entry, status, archived: Number(row.archived) !== 0 };
227
+ }
228
+ //# sourceMappingURL=tiered-memory-inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiered-memory-inventory.js","sourceRoot":"","sources":["../src/tiered-memory-inventory.ts"],"names":[],"mappings":"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"}