// Index store adapter: wraps the IndexStore Durable Object (production) or an in-memory index (tests, local node).
import { withDeadline } from './deadline.js';
import { buildIndex } from './engine.js';
import { queryIndex } from './query.js';
/** `stubOrFn` may be a function returning a fresh stub (DO stubs are bound to the request that created them). */
export function makeStore(stubOrFn, { readMs = 8000 } = {}) {
return {
async query(tier, v, now) {
const stub = typeof stubOrFn === 'function' ? stubOrFn() : stubOrFn;
return withDeadline(stub.query(tier, v, now), readMs, 'index store');
},
async status() { const stub = typeof stubOrFn === 'function' ? stubOrFn() : stubOrFn; return withDeadline(stub.status(), readMs, 'index store'); },
};
}
/** In-memory stub with the IndexStore interface. index: { at, rows, counts, sources_failed } or null. */
export function memoryStub(index = null, { fetchImpl } = {}) {
const s = { index, refreshes: 0 };
return {
state: s,
async query(tier, v, now = Date.now()) {
if (!s.index && fetchImpl) { try { s.index = await buildIndex({ fetchImpl, now }); s.refreshes++; } catch { /* stays null */ } }
if (!s.index) return { info: null };
const info = { gen: 1, at: s.index.at, counts: s.index.counts, sources_failed: s.index.sources_failed || [] };
return { info, result: queryIndex(s.index.rows, tier, v, Math.floor(now / 1000)) };
},
async status() { return { index: s.index ? { at: s.index.at, counts: s.index.counts } : null }; },
};
}
agentgate-source: code mirror on Cloudflare Pages. All repos