import { MemoryCache } from "@suaveplan/cache"; import { describe, expect, it } from "@suaveplan/testing/runner"; import { cachedStorage } from "../../src/factory/factory.js"; import { FakeStorage } from "../setup/fake-storage.js"; /** * Integration: a long-lived cache instance survives the * `CachedStorage` wrapper being dropped and re-instantiated. We * stand-in for a file-backed cache with a shared `MemoryCache` * instance: the cache outlives the wrapper, and the second wrapper * (constructed after the first is dropped) observes a hit on the first * read — same behaviour any persistent backend (file, OPFS, redis) * would exhibit. */ describe("integration: cache survives wrapper re-instantiation", () => { it("populates, drops the wrapper, and the next wrapper observes a hit", { timeout: 30000, }, async () => { const inner = new FakeStorage(); const sharedCache = new MemoryCache(); inner.seed("v.bin", new Uint8Array([9, 9, 9])); // First wrapper populates the shared cache and is then dropped. const first = cachedStorage(inner, { cache: sharedCache, namespace: "shared", }); await first.get("v.bin"); expect(first.getCacheStats().populations).toBe(1); // Drop the reference. The shared cache persists. // (No explicit teardown needed — `MemoryCache` has no resource handle.) // New wrapper over the same cache + same inner. Inner.getCalls is now 1. // Seed the inner with a different value to prove the cached bytes // win on the next read. inner.seed("v.bin", new Uint8Array([1, 2, 3])); const second = cachedStorage(inner, { cache: sharedCache, namespace: "shared", }); const out = await second.get("v.bin"); expect(out).toEqual(new Uint8Array([9, 9, 9])); // served from cache expect(inner.getCalls.length).toBe(1); // unchanged after the second read expect(second.getCacheStats().hits).toBe(1); }); });