Skip to content

Commit 39c5703

Browse files
committed
chore: migrate to @resolid/dev and clean up routing configuration
1 parent 91bfea3 commit 39c5703

File tree

11 files changed

+284
-76
lines changed

11 files changed

+284
-76
lines changed

pnpm-lock.yaml

Lines changed: 173 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/env.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
declare namespace NodeJS {
55
export interface ProcessEnv {
66
readonly SERVER_PORT: number | undefined;
7+
8+
readonly VERCEL: number;
79
}
810
}
911

website/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
"@mdx-js/rollup": "^3.1.1",
2929
"@react-router/dev": "^7.13.1",
3030
"@resolid/config": "^5.0.2",
31-
"@resolid/flex-routes": "^1.6.0",
32-
"@resolid/react-router-hono": "^2.3.2",
31+
"@resolid/dev": "^0.2.0",
3332
"@shikijs/rehype": "^3.23.0",
3433
"@tailwindcss/vite": "^4.2.1",
3534
"@types/react": "^19.2.14",

website/react-router.config.ts

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,3 @@
1-
import type { Config } from "@react-router/dev/config";
2-
import { nodePreset } from "@resolid/react-router-hono/node-preset";
3-
import { vercelPreset } from "@resolid/react-router-hono/vercel-preset";
4-
import { env } from "node:process";
1+
import { reactRouterConfig } from "./resolid.config";
52

6-
const includeFiles = [".resolid/content/*.json"];
7-
8-
// noinspection JSUnusedGlobalSymbols
9-
export default {
10-
appDirectory: "src",
11-
ssr: true,
12-
presets: [
13-
env.VERCEL == "1"
14-
? vercelPreset({
15-
entryFile: "server.vercel.ts",
16-
includeFiles,
17-
nodeVersion: 24,
18-
})
19-
: nodePreset({
20-
entryFile: "server.node.ts",
21-
includeFiles,
22-
nodeVersion: 24,
23-
}),
24-
],
25-
future: {
26-
unstable_optimizeDeps: true,
27-
v8_splitRouteModules: true,
28-
v8_viteEnvironmentApi: true,
29-
},
30-
} satisfies Config;
3+
export default reactRouterConfig;

website/resolid.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineDevConfig } from "@resolid/dev";
2+
import { env } from "node:process";
3+
4+
export const { vitePluginOptions, reactRouterConfig } = defineDevConfig({
5+
appDirectory: "src",
6+
nodeVersion: 24,
7+
platform: env.VERCEL == 1 ? "vercel" : "node",
8+
devExclude: ["/.resolid/**/*"],
9+
reactRouterConfig: {
10+
future: {
11+
unstable_optimizeDeps: true,
12+
},
13+
},
14+
});

website/src/entry.server.tsx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { isbot } from "isbot";
2+
import { PassThrough, Readable } from "node:stream";
3+
import { type RenderToPipeableStreamOptions, renderToPipeableStream } from "react-dom/server";
4+
import { type AppLoadContext, type EntryContext, ServerRouter } from "react-router";
5+
6+
export const streamTimeout = 9_000;
7+
8+
export default function handleRequest(
9+
request: Request,
10+
responseStatusCode: number,
11+
responseHeaders: Headers,
12+
routerContext: EntryContext,
13+
_loadContext: AppLoadContext,
14+
): Response | Promise<unknown> {
15+
if (request.method.toUpperCase() === "HEAD") {
16+
return new Response(null, {
17+
status: responseStatusCode,
18+
headers: responseHeaders,
19+
});
20+
}
21+
22+
return new Promise((resolve, reject) => {
23+
let shellRendered = false;
24+
25+
const userAgent = request.headers.get("User-Agent");
26+
27+
const readyOption: keyof RenderToPipeableStreamOptions =
28+
userAgent && isbot(userAgent) ? "onAllReady" : "onShellReady";
29+
30+
let timeoutId: ReturnType<typeof setTimeout> | undefined = setTimeout(
31+
() => abort(),
32+
streamTimeout + 1000,
33+
);
34+
35+
const { pipe, abort } = renderToPipeableStream(
36+
<ServerRouter context={routerContext} url={request.url} />,
37+
{
38+
[readyOption]() {
39+
shellRendered = true;
40+
41+
const body = new PassThrough({
42+
final(callback) {
43+
clearTimeout(timeoutId);
44+
timeoutId = undefined;
45+
callback();
46+
},
47+
});
48+
49+
const stream = Readable.toWeb(body) as ReadableStream<Uint8Array>;
50+
51+
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
52+
53+
pipe(body);
54+
55+
resolve(
56+
new Response(stream, {
57+
headers: responseHeaders,
58+
status: responseStatusCode,
59+
}),
60+
);
61+
},
62+
onShellError(error: unknown) {
63+
reject(error);
64+
},
65+
onError(error: unknown) {
66+
responseStatusCode = 500;
67+
if (shellRendered) {
68+
console.error(error);
69+
}
70+
},
71+
},
72+
);
73+
});
74+
}

website/src/routes.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { RouteConfig } from "@react-router/dev/routes";
2-
import { flexRoutes } from "@resolid/flex-routes";
2+
import { flexRoutes } from "@resolid/dev/routes";
33

4-
// noinspection JSUnusedGlobalSymbols
54
export default flexRoutes() satisfies RouteConfig;

website/src/server.node.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

website/src/server.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { createServer, nodeConfig, vercelConfig } from "@resolid/dev/server";
2+
import { env } from "node:process";
3+
4+
export default await createServer((platform) => {
5+
switch (platform) {
6+
case "vercel":
7+
return vercelConfig({});
8+
9+
default:
10+
return nodeConfig({
11+
port: env.SERVER_PORT,
12+
});
13+
}
14+
});

website/src/server.vercel.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)