interface CacheEntry { data: T; expiresAt: number; } class MailCache { private cache = new Map>(); private readonly maxEntries = 1000; constructor() { setInterval(() => this.sweep(), 60_000); } get(key: string): T | null { const entry = this.cache.get(key); if (!entry) return null; if (Date.now() > entry.expiresAt) { this.cache.delete(key); return null; } return entry.data as T; } set(key: string, data: T, ttlMs: number) { if (this.cache.size >= this.maxEntries) this.sweep(); this.cache.set(key, { data, expiresAt: Date.now() + ttlMs }); } invalidateByPrefix(prefix: string) { for (const key of this.cache.keys()) { if (key.startsWith(prefix)) this.cache.delete(key); } } private sweep() { const now = Date.now(); for (const [key, entry] of this.cache.entries()) { if (now > entry.expiresAt) this.cache.delete(key); } } } export const mailCache = new MailCache();