/*
 * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
 */
export class EventStream extends ReadableStream {
    constructor(stream, parse) {
        const reader = stream.getReader();
        let buffer = new Uint8Array();
        super({
            async pull(controller) {
                try {
                    const r = await reader.read();
                    if (r.done)
                        return controller.close();
                    buffer = concatBuffer(buffer, r.value);
                    for (const { chunk, remainder } of chunks(buffer)) {
                        buffer = remainder;
                        const item = parseChunk(chunk, parse);
                        if (item?.value)
                            controller.enqueue(item.value);
                        if (item?.done) {
                            await reader.cancel("done");
                            return controller.close();
                        }
                    }
                }
                catch (e) {
                    await reader.cancel(e);
                    controller.error(e);
                }
            },
            cancel: reason => reader.cancel(reason),
        });
    }
    // Polyfill for older browsers
    [Symbol.asyncIterator]() {
        const fn = ReadableStream.prototype[Symbol.asyncIterator];
        if (typeof fn === "function")
            return fn.call(this);
        const reader = this.getReader();
        return {
            next: async () => {
                const r = await reader.read();
                if (r.done) {
                    reader.releaseLock();
                    return { done: true, value: undefined };
                }
                return { done: false, value: r.value };
            },
            throw: async (e) => {
                await reader.cancel(e);
                reader.releaseLock();
                return { done: true, value: undefined };
            },
            return: async () => {
                await reader.cancel("done");
                reader.releaseLock();
                return { done: true, value: undefined };
            },
            [Symbol.asyncIterator]() {
                return this;
            },
        };
    }
}
function concatBuffer(a, b) {
    const c = new Uint8Array(a.length + b.length);
    c.set(a, 0);
    c.set(b, a.length);
    return c;
}
/** Finds the first (CR,LF,CR,LF) or (CR,CR) or (LF,LF) */
function findBoundary(buf) {
    const len = buf.length;
    for (let i = 0; i < len; i++) {
        if (i <= len - 4
            && buf[i] === 13 && buf[i + 1] === 10 && buf[i + 2] === 13
            && buf[i + 3] === 10) {
            return { index: i, length: 4 };
        }
        if (i <= len - 2 && buf[i] === 13 && buf[i + 1] === 13) {
            return { index: i, length: 2 };
        }
        if (i <= len - 2 && buf[i] === 10 && buf[i + 1] === 10) {
            return { index: i, length: 2 };
        }
    }
    return null;
}
function* chunks(remainder) {
    while (true) {
        const match = findBoundary(remainder);
        if (!match) {
            yield { chunk: new Uint8Array(), remainder };
            return;
        }
        const chunk = remainder.slice(0, match.index);
        remainder = remainder.slice(match.index + match.length);
        yield { chunk, remainder };
    }
}
function parseChunk(chunk, parse) {
    const text = new TextDecoder().decode(chunk);
    const lines = text.split(/\r\n|\r|\n/);
    const dataLines = [];
    const ret = {};
    let ignore = true;
    for (const line of lines) {
        if (!line || line.startsWith(":"))
            continue;
        ignore = false;
        const i = line.indexOf(":");
        const field = line.slice(0, i);
        const value = line[i + 1] === " " ? line.slice(i + 2) : line.slice(i + 1);
        if (field === "data")
            dataLines.push(value);
        else if (field === "event")
            ret.event = value;
        else if (field === "id")
            ret.id = value;
        else if (field === "retry") {
            const n = Number(value);
            if (!isNaN(n))
                ret.retry = n;
        }
    }
    if (ignore)
        return;
    if (dataLines.length)
        ret.data = dataLines.join("\n");
    return parse(ret);
}
//# sourceMappingURL=event-streams.js.map