export class EventBus {
    onListenerError;
    listeners = new Map();
    onceListeners = new WeakSet();
    constructor(onListenerError) {
        this.onListenerError = onListenerError;
    }
    on(eventName, listener) {
        const set = this.listeners.get(eventName) ?? new Set();
        set.add(listener);
        this.listeners.set(eventName, set);
        return { unsubscribe: () => this.off(eventName, listener) };
    }
    once(eventName, listener) {
        const subscription = this.on(eventName, listener);
        this.onceListeners.add(listener);
        return subscription;
    }
    off(eventName, listener) {
        const set = this.listeners.get(eventName);
        set?.delete(listener);
        if (set?.size === 0)
            this.listeners.delete(eventName);
    }
    emit(eventName, event) {
        const snapshot = [...(this.listeners.get(eventName) ?? [])];
        for (const listener of snapshot) {
            if (!this.listeners.get(eventName)?.has(listener))
                continue;
            try {
                listener(event);
            }
            catch (error) {
                this.onListenerError?.(error, String(eventName));
            }
            if (this.onceListeners.has(listener)) {
                this.listeners.get(eventName)?.delete(listener);
            }
        }
    }
    clear() {
        this.listeners.clear();
    }
}
//# sourceMappingURL=EventBus.js.map