x402-toolpick / tree / src/store.js ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
// 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