"use strict";
// Nervous System — Signal model and signal bus.
//
// Signals are structured events emitted by the sensory layer and consumed
// by the reflex engine, attention controller, and pain engine.
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignalBus = void 0;
exports.createSignal = createSignal;
/**
 * In-memory signal bus. Publishes signals to registered handlers
 * and keeps a rolling log of recent signals for inspection.
 */
class SignalBus {
    handlers = new Map();
    allHandlers = [];
    log = [];
    maxLog;
    constructor(maxLog = 200) {
        this.maxLog = maxLog;
    }
    /** Subscribe to a specific signal type. */
    on(type, handler) {
        const list = this.handlers.get(type) ?? [];
        list.push(handler);
        this.handlers.set(type, list);
    }
    /** Subscribe to all signals. */
    onAny(handler) {
        this.allHandlers.push(handler);
    }
    /** Publish a signal to all matching handlers. */
    publish(signal) {
        this.log.push(signal);
        if (this.log.length > this.maxLog)
            this.log.shift();
        for (const handler of this.allHandlers)
            handler(signal);
        const typed = this.handlers.get(signal.type);
        if (typed)
            for (const handler of typed)
                handler(signal);
    }
    /** Publish multiple signals. */
    publishMany(signals) {
        for (const signal of signals)
            this.publish(signal);
    }
    /** Get recent signals, optionally filtered by type or severity. */
    recent(filter) {
        let result = this.log;
        if (filter?.type)
            result = result.filter((s) => s.type === filter.type);
        if (filter?.severity)
            result = result.filter((s) => s.severity === filter.severity);
        return result.slice(-(filter?.limit ?? 50));
    }
    /** Count signals by type in the current log. */
    counts() {
        const counts = {};
        for (const signal of this.log)
            counts[signal.type] = (counts[signal.type] ?? 0) + 1;
        return counts;
    }
    /** Clear the log. */
    clear() {
        this.log = [];
    }
}
exports.SignalBus = SignalBus;
let signalCounter = 0;
const SIGNAL_COUNTER_MAX = Number.MAX_SAFE_INTEGER - 1;
/** Create a signal with auto-generated ID and timestamp. */
function createSignal(type, source, severity, message, metadata) {
    if (signalCounter >= SIGNAL_COUNTER_MAX)
        signalCounter = 0;
    const seq = ++signalCounter;
    const rand = Math.floor(Math.random() * 0xffff).toString(36);
    return {
        id: `sig-${Date.now().toString(36)}-${seq.toString(36)}-${rand}`,
        type,
        source,
        severity,
        confidence: severityToConfidence(severity),
        message,
        metadata,
        handled: false,
        createdAt: new Date().toISOString(),
    };
}
function severityToConfidence(severity) {
    switch (severity) {
        case 'critical': return 0.95;
        case 'high': return 0.85;
        case 'medium': return 0.7;
        case 'low': return 0.5;
        case 'info': return 0.3;
    }
}
//# sourceMappingURL=signals.js.map