-
Notifications
You must be signed in to change notification settings - Fork 170
/
server.ts
49 lines (45 loc) · 1.39 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { createElement } from "react";
import { renderToReadableStream } from "react-dom/server";
import { serve as alephServe, type ServerOptions } from "../../server/mod.ts";
import type { SSRContext, SSROptions } from "../../server/types.ts";
import util from "../../shared/util.ts";
import { App } from "./router.ts";
if (Deno.args.includes("--dev")) {
// Enable react refresh
Deno.env.set("SWC_REACT_REFRESH", "true");
}
/** The `suspenseMark` to mark the susponse rendering is starting. */
const suspenseMark = `data:text/javascript;/** suspense mark **/`;
export const render = (ctx: SSRContext): Promise<ReadableStream> => {
if (ctx.routing.length === 0 || ctx.routing.at(-1)?.url.pathname === "/_404") {
ctx.setStatus(404);
}
// support suspense rendering in server-side
ctx.setSuspenseMark("script", (el) => {
if (el.getAttribute("src") === suspenseMark) {
el.remove();
return true;
}
return false;
});
return renderToReadableStream(
createElement(App, { ssrContext: ctx }),
{
...util.pick(ctx, "signal", "nonce"),
bootstrapScripts: [suspenseMark],
},
);
};
export function serve(
options?: Omit<ServerOptions, "ssr"> & { ssr?: boolean | SSROptions },
) {
alephServe({
...options,
ssr: options?.ssr
? {
...(typeof options.ssr === "object" ? options.ssr : {}),
render,
}
: undefined,
});
}