Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Created November 5, 2022 15:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanflorence/320ff6ac24ec9dd306e746b0e5df4d4c to your computer and use it in GitHub Desktop.
Save ryanflorence/320ff6ac24ec9dd306e746b0e5df4d4c to your computer and use it in GitHub Desktop.
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" },
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment