/** Мини-кэш с TTL и вытеснением по LRU (Map сохраняет порядок вставки). */ export class TtlCache { private readonly map = new Map() constructor( private readonly opts: { max: number ttlMs: number now?: () => number }, ) {} private now(): number { return (this.opts.now ?? Date.now)() } get(key: K): V | undefined { const hit = this.map.get(key) if (!hit) return undefined if (hit.expires <= this.now()) { this.map.delete(key) return undefined } // освежаем позицию для LRU this.map.delete(key) this.map.set(key, hit) return hit.value } set(key: K, value: V): void { this.map.delete(key) this.map.set(key, { value, expires: this.now() + this.opts.ttlMs }) while (this.map.size > this.opts.max) { const oldest = this.map.keys().next() if (oldest.done) break this.map.delete(oldest.value) } } delete(key: K): void { this.map.delete(key) } clear(): void { this.map.clear() } get size(): number { return this.map.size } }