export class EventEmitter { constructor() { this.events = new Map(); } on(event, listener) { if (!this.events.has(event)) { this.events.set(event, []); } this.events.get(event).push(listener); return this; // Allow chaining } off(event, listener) { if (!this.events.has(event)) { return this; } const listeners = this.events.get(event); const index = listeners.indexOf(listener); if (index > -1) { listeners.splice(index, 1); } // Remove event key if no listeners remain if (listeners.length === 0) { this.events.delete(event); } return this; } emit(event, ...args) { if (!this.events.has(event)) { return false; } const listeners = this.events.get(event); for (const listener of listeners) { try { listener.apply(this, args); } catch (error) { console.error('Error in event listener:', error); } } return true; } once(event, listener) { const onceWrapper = (...args) => { this.off(event, onceWrapper); listener.apply(this, args); }; return this.on(event, onceWrapper); } removeAllListeners(event) { if (event) { this.events.delete(event); } else { this.events.clear(); } return this; } listenerCount(event) { return this.events.has(event) ? this.events.get(event).length : 0; } eventNames() { return Array.from(this.events.keys()); } }