// engine/hooks/event-bus.ts — Typed event bus with history (SPEC-130)
import { EventEmitter } from 'node:events';
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const MAX_HISTORY = 100;
// ---------------------------------------------------------------------------
// EventBus
// ---------------------------------------------------------------------------
/**
 * Typed event bus extending EventEmitter.
 * Provides typed events with discriminated unions, filtering,
 * event history (FIFO, last 100), and meta-events.
 */
export class EventBus extends EventEmitter {
    history = [];
    idCounter = 0;
    constructor() {
        super();
        this.setMaxListeners(50);
    }
    /**
     * Emit a typed event. Automatically adds to history and fires meta-events.
     */
    emitEvent(type, data) {
        const event = {
            id: `evt-${String(++this.idCounter)}-${Date.now()}`,
            type,
            timestamp: Date.now(),
            data,
        };
        // FIFO eviction
        if (this.history.length >= MAX_HISTORY) {
            this.history.shift();
        }
        this.history.push(event);
        this.emit(type, event);
        this.emit('*', event);
        return event;
    }
    /**
     * Subscribe to events of a specific type.
     */
    onEvent(type, listener) {
        return this.on(type, listener);
    }
    /**
     * Subscribe to events once.
     */
    onceEvent(type, listener) {
        return this.once(type, listener);
    }
    /**
     * Get filtered event history.
     */
    getHistory(filter) {
        let result = [...this.history];
        if (filter?.type) {
            result = result.filter((e) => e.type === filter.type);
        }
        if (filter?.filePattern) {
            const regex = new RegExp(filter.filePattern);
            result = result.filter((e) => {
                const path = e.data.path;
                return typeof path === 'string' && regex.test(path);
            });
        }
        return result;
    }
    /**
     * Get all events in history (readonly).
     */
    getFullHistory() {
        return this.history;
    }
    /**
     * Clear history.
     */
    clearHistory() {
        this.history.length = 0;
    }
}
//# sourceMappingURL=event-bus.js.map