export type Listener
= (payload: P) => void;
type Listeners = {
[E in keyof (EventMap)]?: Listener[];
};
export abstract class EventEmitter {
protected listeners: Listeners = {};
on(
event: E,
listener: Listener
): () => void {
if (!Array.isArray(this.listeners[event])) {
this.listeners[event] = [];
}
this.listeners[event]?.push(listener);
return () => {
this.off(event, listener);
};
}
off(
event: E,
listener: Listener
): void {
const filtered = this.listeners[event]?.filter(l => l !== listener);
this.listeners[event] = filtered && filtered.length > 0 ? filtered : undefined;
}
protected emit(event: E, payload: EventMap[E]): void {
const listeners = this.listeners[event];
if (!Array.isArray(listeners)) return;
for (const listener of listeners) {
try {
listener(payload);
} catch (error) {
console.error(error instanceof Error ? error.stack : error);
}
}
}
}