UNPKG

js-memory-leak-detector

Version:

A comprehensive memory leak detector for web applications with Redux Toolkit support

77 lines 3.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventListenerTracker = void 0; class EventListenerTracker { constructor() { this.listeners = new Map(); this.originalAddEventListener = EventTarget.prototype.addEventListener; this.originalRemoveEventListener = EventTarget.prototype.removeEventListener; this.patchEventListeners(); } patchEventListeners() { const self = this; EventTarget.prototype.addEventListener = function (type, listener, options) { // Track the listener if (!self.listeners.has(this)) { self.listeners.set(this, new Map()); } const targetListeners = self.listeners.get(this); if (!targetListeners.has(type)) { targetListeners.set(type, new Set()); } targetListeners.get(type).add(listener); // Call original method return self.originalAddEventListener.call(this, type, listener, options); }; EventTarget.prototype.removeEventListener = function (type, listener, options) { // Remove from tracking const targetListeners = self.listeners.get(this); if (targetListeners && targetListeners.has(type)) { targetListeners.get(type).delete(listener); if (targetListeners.get(type).size === 0) { targetListeners.delete(type); } if (targetListeners.size === 0) { self.listeners.delete(this); } } // Call original method return self.originalRemoveEventListener.call(this, type, listener, options); }; } getActiveListeners() { let count = 0; for (const [target, listeners] of this.listeners) { for (const [type, listenerSet] of listeners) { count += listenerSet.size; } } return count; } detectLeaks() { const suspects = []; const threshold = 50; // Arbitrary threshold for (const [target, listeners] of this.listeners) { let totalListeners = 0; for (const [type, listenerSet] of listeners) { totalListeners += listenerSet.size; } if (totalListeners > threshold) { suspects.push({ type: 'event-listener', severity: totalListeners > 100 ? 'critical' : 'high', description: `${totalListeners} event listeners attached to ${target.constructor.name}`, count: totalListeners }); } } return suspects; } cleanup() { EventTarget.prototype.addEventListener = this.originalAddEventListener; EventTarget.prototype.removeEventListener = this.originalRemoveEventListener; this.listeners.clear(); } } exports.EventListenerTracker = EventListenerTracker; //# sourceMappingURL=event-listener-tracker.js.map