Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Created November 5, 2022 15:27

Revisions

  1. ryanflorence created this gist Nov 5, 2022.
    35 changes: 35 additions & 0 deletions event-stream.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    type InitFunction = (send: SendFunction) => CleanupFunction;
    type SendFunction = (event: string, data: string) => void;
    type CleanupFunction = () => void;

    export function eventStream(request: Request, init: InitFunction) {
    let stream = new ReadableStream({
    start(controller) {
    let encoder = new TextEncoder();
    let send = (event: string, data: string) => {
    controller.enqueue(encoder.encode(`event: ${event}\n`));
    controller.enqueue(encoder.encode(`data: ${data}\n\n`));
    };
    let cleanup = init(send);

    let closed = false;
    let close = () => {
    if (closed) return;
    cleanup();
    closed = true;
    request.signal.removeEventListener("abort", close);
    controller.close();
    };

    request.signal.addEventListener("abort", close);
    if (request.signal.aborted) {
    close();
    return;
    }
    },
    });

    return new Response(stream, {
    headers: { "Content-Type": "text/event-stream" },
    });
    }