// ---------------------------------------------------------------------------
// sse-helpers.ts -- SSE event emission utilities
// ---------------------------------------------------------------------------
export function initSSE(res, req) {
    const headers = {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache",
        Connection: "keep-alive",
        "X-Accel-Buffering": "no",
    };
    const origin = req?.headers?.origin;
    if (origin && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin)) {
        headers["Access-Control-Allow-Origin"] = origin;
    }
    res.writeHead(200, headers);
}
export function sendSSE(res, event, data) {
    res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
}
export function sendSSEDone(res, data) {
    sendSSE(res, "done", data);
    res.end();
}
/**
 * Start a dynamic heartbeat that can switch phase/message on the fly.
 * Unlike `withHeartbeat`, this is imperative: call `update()` to change
 * what the next tick emits, and `stop()` when done.
 */
export function startDynamicHeartbeat(res, evalId, initialPhase, initialMessage, intervalMs = 3000) {
    const start = Date.now();
    let currentPhase = initialPhase;
    let currentMessage = initialMessage;
    let timer = setInterval(() => {
        const elapsed = Math.round((Date.now() - start) / 1000);
        const data = {
            phase: currentPhase,
            message: `${currentMessage} (${elapsed}s)`,
            elapsed_ms: Date.now() - start,
        };
        if (evalId != null)
            data.eval_id = evalId;
        sendSSE(res, "progress", data);
    }, intervalMs);
    return {
        update(phase, message) {
            currentPhase = phase;
            currentMessage = message;
            const elapsed = Math.round((Date.now() - start) / 1000);
            const data = {
                phase,
                message: `${message} (${elapsed}s)`,
                elapsed_ms: Date.now() - start,
            };
            if (evalId != null)
                data.eval_id = evalId;
            sendSSE(res, "progress", data);
        },
        stop() {
            if (timer != null) {
                clearInterval(timer);
                timer = null;
            }
        },
    };
}
/**
 * Wrap an async operation with periodic heartbeat SSE events.
 * Emits a progress event every `intervalMs` with elapsed time so the
 * frontend knows the system is still alive during long LLM calls.
 */
export async function withHeartbeat(res, evalId, phase, messagePrefix, fn, intervalMs = 3000) {
    const start = Date.now();
    const timer = setInterval(() => {
        const elapsed = Math.round((Date.now() - start) / 1000);
        const data = {
            phase,
            message: `${messagePrefix} (${elapsed}s)`,
            elapsed_ms: Date.now() - start,
        };
        if (evalId != null)
            data.eval_id = evalId;
        sendSSE(res, "progress", data);
    }, intervalMs);
    try {
        return await fn();
    }
    finally {
        clearInterval(timer);
    }
}
//# sourceMappingURL=sse-helpers.js.map