/** * EventEmitter - Typsicherer Event-Handler */ type EventCallback = (data: T) => void; // eslint-disable-next-line @typescript-eslint/no-explicit-any export class EventEmitter = Record> { private listeners: Map>> = new Map(); /** * Event-Listener registrieren * @returns Unsubscribe-Funktion */ on( event: K, callback: EventCallback ): () => void { if (!this.listeners.has(event)) { this.listeners.set(event, new Set()); } this.listeners.get(event)!.add(callback as EventCallback); // Unsubscribe-Funktion zurueckgeben return () => this.off(event, callback); } /** * Event-Listener entfernen */ off( event: K, callback: EventCallback ): void { this.listeners.get(event)?.delete(callback as EventCallback); } /** * Event emittieren */ emit(event: K, data: Events[K]): void { this.listeners.get(event)?.forEach((callback) => { try { callback(data); } catch (error) { console.error(`Error in event handler for ${String(event)}:`, error); } }); } /** * Einmaligen Listener registrieren */ once( event: K, callback: EventCallback ): () => void { const wrapper = (data: Events[K]) => { this.off(event, wrapper); callback(data); }; return this.on(event, wrapper); } /** * Alle Listener entfernen */ clear(): void { this.listeners.clear(); } /** * Alle Listener fuer ein Event entfernen */ clearEvent(event: K): void { this.listeners.delete(event); } /** * Anzahl Listener fuer ein Event */ listenerCount(event: K): number { return this.listeners.get(event)?.size ?? 0; } } export default EventEmitter;