// Caching Strategy for Improved Performance // Implements in-memory caching with TTL interface CacheEntry { value: T; expiresAt: number; } class Cache { private store: Map> = new Map(); private cleanupInterval: NodeJS.Timeout | null = null; constructor() { // Cleanup expired entries every 5 minutes this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000); } set(key: string, value: T, ttlSeconds: number = 300): void { const expiresAt = Date.now() + (ttlSeconds * 1000); this.store.set(key, { value, expiresAt }); } get(key: string): T | null { const entry = this.store.get(key); if (!entry) return null; // Check if expired if (Date.now() > entry.expiresAt) { this.store.delete(key); return null; } return entry.value as T; } has(key: string): boolean { const entry = this.store.get(key); if (!entry) return false; if (Date.now() > entry.expiresAt) { this.store.delete(key); return false; } return true; } delete(key: string): void { this.store.delete(key); } clear(): void { this.store.clear(); } private cleanup(): void { const now = Date.now(); for (const [key, entry] of this.store.entries()) { if (now > entry.expiresAt) { this.store.delete(key); } } } destroy(): void { if (this.cleanupInterval) { clearInterval(this.cleanupInterval); this.cleanupInterval = null; } this.clear(); } } // Global cache instance export const cache = new Cache(); // Helper function for cache-aside pattern export async function getCached( key: string, fetcher: () => Promise, ttlSeconds: number = 300 ): Promise { // Try to get from cache const cached = cache.get(key); if (cached !== null) { return cached; } // Fetch fresh data const data = await fetcher(); // Store in cache cache.set(key, data, ttlSeconds); return data; } // Cache key generators for common patterns export const cacheKeys = { user: (userId: string) => `user:${userId}`, businesses: (userId: string) => `businesses:${userId}`, templates: (userId: string) => `templates:${userId}`, stats: (userId: string) => `stats:${userId}`, analytics: (userId: string, period: string) => `analytics:${userId}:${period}`, };