/** * Generic client-side cache with TTL support * Used for simple caching needs on the frontend **/ export class CacheService { private cache = new Map(); private readonly defaultTTL: number; constructor(defaultTTLMs: number = 5 * 60 * 1000) { this.defaultTTL = defaultTTLMs; } set(key: string, value: T, ttlMs?: number): void { const ttl = ttlMs ?? this.defaultTTL; this.cache.set(key, { value, expires: Date.now() + ttl, }); if (this.cache.size > 100) { this.cleanup(); } } get(key: string): U | null { const entry = this.cache.get(key); if (!entry) return null; if (Date.now() > entry.expires) { this.cache.delete(key); return null; } return entry.value as U; } has(key: string): boolean { return this.get(key) !== null; } delete(key: string): void { this.cache.delete(key); } invalidatePattern(pattern: string): void { for (const key of this.cache.keys()) { if (key.includes(pattern)) { this.cache.delete(key); } } } clear(): void { this.cache.clear(); } cleanup(): void { const now = Date.now(); for (const [key, entry] of this.cache.entries()) { if (now > entry.expires) { this.cache.delete(key); } } } }