Skip to content

Instantly share code, notes, and snippets.

@yskszk63
Last active July 18, 2022 12:05
Show Gist options
  • Save yskszk63/73cc143448688d39628fab4a8f59b78a to your computer and use it in GitHub Desktop.
Save yskszk63/73cc143448688d39628fab4a8f59b78a to your computer and use it in GitHub Desktop.
Longterm React Suspense with Deno.
import { Server } from "https://deno.land/std@0.148.0/http/mod.ts";
import React from "https://esm.sh/react@18.2.0";
import { renderToReadableStream } from "https://esm.sh/react-dom@18.2.0/server"
async function wake(): Promise<boolean> {
console.log("process...");
await new Promise(resolve => setTimeout(resolve, 2000));
return false;
}
const cache = new Map<string, boolean>();
function Woke({ id, children }: { id: string, children: JSX.Element }) {
if (!cache.has(id)) {
throw wake().then(v => void cache.set(id, v));
}
const woke = cache.get(id) ?? false;
cache.delete(id);
if (!woke) {
// If client aborted, then error occurred.
return <>&#8203;<Woke id={id}>{children}</Woke></>;
}
return children;
}
function Index() {
const id = crypto.randomUUID().toString();
return (
<React.Suspense fallback={<>Loading...</>}>
<Woke id={id}>
<>It is works!</>
</Woke>
</React.Suspense>
);
}
function Document({ children }: { children: JSX.Element}) {
return (
<html>
<head>
<title>title</title>
</head>
<body>{children}</body>
</html>
);
}
async function handler(request: Request): Promise<Response> {
const stream = await renderToReadableStream(<Document><Index /></Document>, {
signal: request.signal,
});
return new Response(stream, {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
}
const server = new Server({
port: 3000,
handler,
});
await server.listenAndServe();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment