Skip to content

Instantly share code, notes, and snippets.

@jacob-ebey
Created September 28, 2023 06:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacob-ebey/32c01e3acfb7f5477ec860d0245e105c to your computer and use it in GitHub Desktop.
Save jacob-ebey/32c01e3acfb7f5477ec860d0245e105c to your computer and use it in GitHub Desktop.
Event Stream Dev Middleware
export function createDevMiddleware(pathname: string) {
return {
hmr(request: Request) {
return new Response(
new ReadableStream({
start(controller) {
controller.enqueue(
`id:0\nevent: message\ndata: ${JSON.stringify({
type: "connected",
})}\n\n`
);
request.signal.addEventListener("abort", () => {
setTimeout(() => {
controller.close();
}, 0);
});
},
}),
{
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
"Transfer-Encoding": "chunked",
},
}
);
},
html(response: Response) {
if (!response.body) {
return response;
}
const encoder = new TextEncoder();
const transformStream = new TransformStream({
flush(controller) {
controller.enqueue(
encoder.encode(
`<script type="module">
const timeoutMs = 100;
let reloadCount = 0;
function connect() {
const eventSource = new EventSource(
${JSON.stringify(pathname)}
);
function tryReload() {
eventSource.close();
location.reload();
}
const COUNT_LIMIT = 10;
eventSource.addEventListener("open", () => {
if (reloadCount > 0) {
tryReload();
reloadCount = 1;
}
reloadCount++;
});
eventSource.addEventListener("error", () => {
if (reloadCount > COUNT_LIMIT) {
return;
}
eventSource.close();
reloadCount++;
setTimeout(connect, timeoutMs);
});
}
connect();
</script>
`
)
);
},
});
response.body.pipeTo(transformStream.writable);
return new Response(transformStream.readable, {
headers: response.headers,
status: response.status,
statusText: response.statusText,
// @ts-expect-error - TS doesn't know about this property
duplex: "half",
});
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment