/** Minimal in-process TTL cache (single node, no eviction pressure expected). */ export class TtlCache { private store = new Map(); constructor(private readonly ttlMs: number) {} get(key: string): V | undefined { const hit = this.store.get(key); if (!hit) return undefined; if (hit.expires < Date.now()) { this.store.delete(key); return undefined; } return hit.value; } set(key: string, value: V): V { this.store.set(key, { value, expires: Date.now() + this.ttlMs }); return value; } async getOrLoad(key: string, load: () => Promise): Promise { const hit = this.get(key); if (hit !== undefined) return hit; return this.set(key, await load()); } clear(): void { this.store.clear(); } }