import crypto from 'crypto' import type { PDFReport } from './types' interface CacheEntry { pdfBuffer: Buffer hash: string expiresAt: number createdAt: number hits: number } export class PDFCacheManager { private cache: Map = new Map() private readonly TTL_MS = 5 * 60 * 1000 private cleanupInterval: NodeJS.Timeout | null = null constructor() { this.startCleanup() } private startCleanup(): void { this.cleanupInterval = setInterval(() => { const now = Date.now() let removed = 0 for (const [key, entry] of this.cache.entries()) { if (now > entry.expiresAt) { this.cache.delete(key) removed++ } } if (removed > 0) { console.log(`[PDFCache] Removed ${removed} expired entries`) } }, 60000) if (this.cleanupInterval.unref) { this.cleanupInterval.unref() } } get(cacheKey: string): CacheEntry | null { const entry = this.cache.get(cacheKey) if (!entry) return null if (Date.now() > entry.expiresAt) { this.cache.delete(cacheKey) return null } entry.hits++ return entry } set(cacheKey: string, pdfBuffer: Buffer): void { const hash = crypto.createHash('sha256').update(pdfBuffer).digest('hex') const now = Date.now() this.cache.set(cacheKey, { pdfBuffer, hash, expiresAt: now + this.TTL_MS, createdAt: now, hits: 0, }) console.log(`[PDFCache] Cached PDF: ${cacheKey} (${pdfBuffer.length} bytes)`) } generateKey(asn: number, format: string, date: string): string { return crypto .createHash('md5') .update(`${asn}:${format}:${date}`) .digest('hex') } getStats(): { size: number; entries: number; totalMemory: number } { let totalMemory = 0 for (const entry of this.cache.values()) { totalMemory += entry.pdfBuffer.length } return { size: this.cache.size, entries: this.cache.size, totalMemory, } } clear(): void { this.cache.clear() console.log('[PDFCache] Cache cleared') } destroy(): void { if (this.cleanupInterval) { clearInterval(this.cleanupInterval) } this.clear() } }