export const SHORTCUT_STREAM_IDLE_TIMEOUT_MS = 180_000;
function parseSseBlock(block) {
    if (!block.trim()) {
        return null;
    }
    let eventName = '';
    let data = '';
    for (const rawLine of block.replace(/\r\n/g, '\n').split('\n')) {
        const line = rawLine.trimEnd();
        if (line.startsWith('event: ')) {
            eventName = line.slice(7);
            continue;
        }
        if (line.startsWith('data: ')) {
            data = line.slice(6);
        }
    }
    if (!eventName || !data) {
        return null;
    }
    return JSON.parse(`{"event":${JSON.stringify(eventName)},"payload":${data}}`);
}
export async function readShortcutStream(response, onEvent, idleTimeoutMs = SHORTCUT_STREAM_IDLE_TIMEOUT_MS, observers = {}) {
    if (!response.body) {
        throw new Error('ShortcutXL runtime stream returned no response body.');
    }
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    while (true) {
        const next = await readWithIdleTimeout(reader, idleTimeoutMs);
        if (next.done) {
            break;
        }
        observers.onBytes?.(next.value.byteLength);
        buffer += decoder.decode(next.value, { stream: true });
        const parts = buffer.replace(/\r\n/g, '\n').split('\n\n');
        buffer = parts.pop() ?? '';
        for (const part of parts) {
            const parsed = parseSseBlock(part);
            if (parsed) {
                observers.onEvent?.();
                onEvent(parsed);
            }
        }
    }
    buffer += decoder.decode();
    const parsed = parseSseBlock(buffer);
    if (parsed) {
        observers.onEvent?.();
        onEvent(parsed);
    }
}
async function readWithIdleTimeout(reader, idleTimeoutMs) {
    if (idleTimeoutMs <= 0)
        return reader.read();
    let timeout;
    try {
        return await Promise.race([
            reader.read(),
            new Promise((_, reject) => {
                timeout = setTimeout(() => {
                    reject(new Error('ShortcutXL runtime stream timed out waiting for data.'));
                }, idleTimeoutMs);
            })
        ]);
    }
    finally {
        if (timeout !== undefined)
            clearTimeout(timeout);
    }
}
//# sourceMappingURL=stream-sse.js.map