import { logger } from "../../utils/logger.js";
import { subscriptionMatchesEvent } from "./subscription_types.js";
const BUFFER_CAP = Math.min(10_000, Math.max(100, parseInt(process.env.NEOTOMA_SSE_EVENT_BUFFER ?? "1000", 10) || 1000));
const ring = [];
let seq = 0n;
export function pushSubstrateEventToRing(event) {
    seq += 1n;
    const id = seq.toString();
    ring.push({ id, event });
    while (ring.length > BUFFER_CAP) {
        ring.shift();
    }
    return id;
}
const clients = [];
export function registerSseClient(client) {
    clients.push(client);
    return () => {
        const i = clients.indexOf(client);
        if (i >= 0)
            clients.splice(i, 1);
    };
}
export function broadcastSubstrateEventToSse(event, eventRingId) {
    for (const c of clients) {
        if (c.subscription.delivery_method !== "sse")
            continue;
        if (!subscriptionMatchesEvent(c.subscription, event))
            continue;
        try {
            c.res.write(`id: ${eventRingId}\n`);
            c.res.write(`event: ${event.event_type}\n`);
            c.res.write(`data: ${JSON.stringify(event)}\n\n`);
        }
        catch (err) {
            logger.warn("[subscriptions] sse write failed", {
                subscription_id: c.subscription.subscription_id,
                message: err instanceof Error ? err.message : String(err),
            });
        }
    }
}
export function replayRingAfterLastId(lastEventId, filter) {
    const startIdx = lastEventId === undefined ? 0 : ring.findIndex((e) => e.id === lastEventId) + 1;
    const from = startIdx < 0 ? 0 : startIdx;
    for (let i = from; i < ring.length; i++) {
        const e = ring[i];
        if (filter(e.event)) {
            // Caller writes to res
            void e;
        }
    }
}
export function getRingEntriesAfter(lastEventId, filter) {
    const startIdx = lastEventId === undefined ? 0 : ring.findIndex((e) => e.id === lastEventId) + 1;
    const from = startIdx < 0 ? 0 : startIdx;
    const out = [];
    for (let i = from; i < ring.length; i++) {
        const e = ring[i];
        if (filter(e.event))
            out.push(e);
    }
    return out;
}
//# sourceMappingURL=sse_hub.js.map