/**
 * EventBus — Typed event emitter for the execution runtime.
 *
 * Provides a type-safe publish/subscribe mechanism for runtime events.
 * Uses a simple listener map instead of Node's EventEmitter for full
 * type safety on both emit() and on() without casting.
 */
/**
 * Typed event bus for runtime events.
 *
 * Usage:
 * ```ts
 * const bus = new EventBus()
 * const unsub = bus.on('agent:spawned', (event) => {
 *   console.log(`Agent ${event.sessionId} spawned`)
 * })
 * bus.emit('agent:spawned', { sessionId: '...', ... })
 * unsub() // unsubscribe
 * ```
 */
export class EventBus {
    listeners = new Map();
    /**
     * Subscribe to an event.
     * Returns an unsubscribe function.
     */
    on(event, listener) {
        let set = this.listeners.get(event);
        if (!set) {
            set = new Set();
            this.listeners.set(event, set);
        }
        set.add(listener);
        return () => {
            set.delete(listener);
            if (set.size === 0) {
                this.listeners.delete(event);
            }
        };
    }
    /**
     * Subscribe to an event for a single emission only.
     * Returns an unsubscribe function (in case you want to cancel early).
     */
    once(event, listener) {
        const unsub = this.on(event, (payload) => {
            unsub();
            listener(payload);
        });
        return unsub;
    }
    /**
     * Emit an event to all subscribed listeners.
     * Listeners are called synchronously in subscription order.
     */
    emit(event, payload) {
        const set = this.listeners.get(event);
        if (!set)
            return;
        for (const listener of set) {
            try {
                listener(payload);
            }
            catch {
                // Listeners should not throw, but don't let one bad listener
                // break the emission chain.
            }
        }
    }
    /** Remove all listeners for a specific event, or all events if no name given. */
    removeAllListeners(event) {
        if (event) {
            this.listeners.delete(event);
        }
        else {
            this.listeners.clear();
        }
    }
    /** Get the number of listeners for a specific event. */
    listenerCount(event) {
        return this.listeners.get(event)?.size ?? 0;
    }
}
// =============================================================================
// Singleton
// =============================================================================
let _defaultBus;
/**
 * Get the global default EventBus instance.
 * Creates one on first access. Use this for application-wide event routing.
 */
export function getEventBus() {
    if (!_defaultBus) {
        _defaultBus = new EventBus();
    }
    return _defaultBus;
}
/**
 * Reset the global EventBus (primarily for testing).
 */
export function resetEventBus() {
    if (_defaultBus) {
        _defaultBus.removeAllListeners();
    }
    _defaultBus = undefined;
}
//# sourceMappingURL=event-bus.js.map