# `cache/lru.ts` ## Purpose `LruHibpCache` is the default cache for `HibpClient`. It holds up to `LRU_DEFAULT_CAPACITY` entries (10 000) with `LRU_DEFAULT_TTL_MS` (24 h) expiry, keyed by the uppercase 5-hex SHA-1 prefix. The TTL clock is the injectable `Clock` from `@suaveplan/types` so tests can advance virtual time without timers. Eviction policy is least-recently-used at capacity plus eager TTL eviction on read. ## Features - O(1) `get`/`set`/`delete` over a `Map>` with recency tracked by insertion order — re-inserting on read bumps the key to the tail. - TTL eviction at access time: stale entries are dropped and reported as cache misses; no background timer is required. - Constructor-time overrides for `capacity`, `ttlMs`, and `clock` so the same class powers production caches, deterministic tests, and experimental tunings. - Key normalisation to uppercase hex on every operation — case-insensitive reads and writes share the same slot. ## Usage: Basic Example ```ts import { LruHibpCache } from "@suaveplan/hibp"; const cache = new LruHibpCache<{ pwned: boolean; count: number }>(); cache.set("F3BBB", { pwned: true, count: 1 }); cache.get("f3bbb"); // case-insensitive hit ``` ## Usage: Advanced Example ```ts import { LruHibpCache } from "@suaveplan/hibp"; let now = 0; const cache = new LruHibpCache({ capacity: 50, ttlMs: 5_000, clock: () => now, }); cache.set("A", 1); now = 4_999; cache.get("A"); // 1 now = 5_001; cache.get("A"); // undefined (TTL-evicted) ``` ## API Reference - `new LruHibpCache(options?)` — `capacity`, `ttlMs`, `clock`. - `LRU_DEFAULT_CAPACITY = 10_000`. - `LRU_DEFAULT_TTL_MS = 24 * 60 * 60 * 1000`. ## Implementation Notes Insertion-order tracking via JavaScript `Map` is the canonical O(1) LRU implementation in pure JS. The class avoids `setInterval`-based eviction because that would require timer cleanup on disposal and add jitter to TTL behaviour; on-read TTL is cheap and deterministic. The capacity loop guards against `capacity: 0` by evicting immediately after the insert.