UNPKG

ai-debug-local-mcp

Version:

🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

99 lines 3.36 kB
/** * AbortSignal Memory Leak Manager * Critical fix for EventTarget memory leak: 11 abort listeners detected * Centralized AbortController management with proper cleanup */ export class AbortSignalManager { static activeControllers = new Set(); static listenerCount = 0; /** * Create a tracked AbortController with automatic cleanup */ static createController() { const controller = new AbortController(); this.activeControllers.add(controller); // Set up automatic cleanup when aborted controller.signal.addEventListener('abort', () => { this.activeControllers.delete(controller); }, { once: true }); this.listenerCount++; // Warn if listener count is getting high if (this.listenerCount > 5) { console.warn(`⚠️ AbortSignal listener count: ${this.listenerCount} (potential memory leak)`); } return controller; } /** * Manually cleanup a controller and all its listeners */ static cleanupController(controller) { if (this.activeControllers.has(controller)) { if (!controller.signal.aborted) { controller.abort(); } this.activeControllers.delete(controller); this.listenerCount = Math.max(0, this.listenerCount - 1); } } /** * Create a controller with automatic timeout cleanup */ static createWithTimeout(timeoutMs) { const controller = this.createController(); const timeoutId = setTimeout(() => { this.cleanupController(controller); }, timeoutMs); return { controller, timeoutId }; } /** * Emergency cleanup of all active controllers */ static emergencyCleanup() { console.log(`🧹 Emergency AbortSignal cleanup: ${this.activeControllers.size} controllers`); this.activeControllers.forEach(controller => { try { if (!controller.signal.aborted) { controller.abort(); } } catch (error) { console.error('Error during emergency AbortController cleanup:', error); } }); this.activeControllers.clear(); this.listenerCount = 0; } /** * Get current AbortSignal memory usage stats */ static getStats() { const activeControllers = this.activeControllers.size; const estimatedListeners = this.listenerCount; let memoryPressure = 'low'; if (estimatedListeners > 10) memoryPressure = 'high'; else if (estimatedListeners > 5) memoryPressure = 'medium'; return { activeControllers, estimatedListeners, memoryPressure }; } /** * Set up process-level cleanup */ static setupGlobalCleanup() { // Clean up on process exit process.on('beforeExit', () => { this.emergencyCleanup(); }); process.on('SIGTERM', () => { this.emergencyCleanup(); process.exit(0); }); process.on('SIGINT', () => { this.emergencyCleanup(); process.exit(0); }); } } // Auto-setup global cleanup AbortSignalManager.setupGlobalCleanup(); //# sourceMappingURL=abort-signal-manager.js.map