interface CleanupTask { name: string; cleanup: () => void | Promise; interval?: number; } class CleanupManager { private static instance: CleanupManager; private tasks: Map = new Map(); private intervals: Map = new Map(); private constructor() { // Register default cleanup tasks this.registerDefaultTasks(); } static getInstance(): CleanupManager { if (!CleanupManager.instance) { CleanupManager.instance = new CleanupManager(); } return CleanupManager.instance; } private registerDefaultTasks() { // Clean up old temporary files this.registerTask({ name: 'temp-files-cleanup', cleanup: async () => { console.log('[Cleanup] Running temporary files cleanup...'); // Implementation would go here }, interval: 3600000 // Every hour }); // Clean up expired cache entries this.registerTask({ name: 'cache-cleanup', cleanup: async () => { console.log('[Cleanup] Running cache cleanup...'); // Implementation would go here }, interval: 1800000 // Every 30 minutes }); } registerTask(task: CleanupTask) { this.tasks.set(task.name, task); if (task.interval) { // Clear existing interval if any const existingInterval = this.intervals.get(task.name); if (existingInterval) { clearInterval(existingInterval); } // Set up new interval const interval = setInterval(async () => { try { await task.cleanup(); } catch (error) { console.error(`[Cleanup] Task '${task.name}' failed:`, error); } }, task.interval); this.intervals.set(task.name, interval); } } async runTask(taskName: string) { const task = this.tasks.get(taskName); if (!task) { throw new Error(`Cleanup task '${taskName}' not found`); } try { await task.cleanup(); console.log(`[Cleanup] Task '${taskName}' completed successfully`); } catch (error) { console.error(`[Cleanup] Task '${taskName}' failed:`, error); throw error; } } async runAllTasks() { console.log('[Cleanup] Running all cleanup tasks...'); const results: { task: string; success: boolean; error?: any }[] = []; for (const [name, task] of this.tasks) { try { await task.cleanup(); results.push({ task: name, success: true }); } catch (error) { results.push({ task: name, success: false, error }); } } return results; } stopAllIntervals() { for (const [name, interval] of this.intervals) { clearInterval(interval); console.log(`[Cleanup] Stopped interval for task '${name}'`); } this.intervals.clear(); } } export const cleanupManager = CleanupManager.getInstance(); // Utility functions for common cleanup operations export const cleanupUtils = { // Clean up old files in a directory async cleanupOldFiles(directory: string, maxAgeMs: number) { // Implementation would check file ages and remove old ones console.log(`[Cleanup] Would clean files older than ${maxAgeMs}ms in ${directory}`); }, // Clean up unused stream handles cleanupStreams(streams: any[]) { streams.forEach(stream => { if (stream && typeof stream.destroy === 'function') { stream.destroy(); } }); }, // Clean up IMAP connections cleanupIMAPConnections(connections: any[]) { connections.forEach(conn => { try { if (conn && typeof conn.end === 'function') { conn.end(); } } catch (error) { console.error('[Cleanup] Failed to close IMAP connection:', error); } }); }, // Memory-efficient array processing async processInBatches( items: T[], batchSize: number, processor: (batch: T[]) => Promise ): Promise { const results: R[] = []; for (let i = 0; i < items.length; i += batchSize) { const batch = items.slice(i, i + batchSize); const batchResults = await processor(batch); results.push(...batchResults); // Allow garbage collection between batches await new Promise(resolve => setImmediate(resolve)); } return results; } };