@cedarjs/vite 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bins/rw-vite-build.mjs +61 -0
- package/bins/rw-vite-dev.mjs +57 -0
- package/bins/vite.mjs +12 -0
- package/dist/build/build.d.ts +21 -0
- package/dist/build/build.d.ts.map +1 -0
- package/dist/build/build.js +78 -0
- package/dist/buildFeServer.d.ts +6 -0
- package/dist/buildFeServer.d.ts.map +1 -0
- package/dist/buildFeServer.js +39 -0
- package/dist/buildRouteHooks.d.ts +3 -0
- package/dist/buildRouteHooks.d.ts.map +1 -0
- package/dist/buildRouteHooks.js +45 -0
- package/dist/buildRouteManifest.d.ts +6 -0
- package/dist/buildRouteManifest.d.ts.map +1 -0
- package/dist/buildRouteManifest.js +58 -0
- package/dist/buildRscClientAndServer.d.ts +4 -0
- package/dist/buildRscClientAndServer.d.ts.map +1 -0
- package/dist/buildRscClientAndServer.js +30 -0
- package/dist/bundled/react-server-dom-webpack.server.d.ts +2 -0
- package/dist/bundled/react-server-dom-webpack.server.d.ts.map +1 -0
- package/dist/bundled/react-server-dom-webpack.server.js +33529 -0
- package/dist/cjs/ClientRouter.d.ts +1 -0
- package/dist/cjs/build/build.d.ts +1 -0
- package/dist/cjs/build/build.js +116 -0
- package/dist/cjs/buildFeServer.d.ts +1 -0
- package/dist/cjs/buildFeServer.js +63 -0
- package/dist/cjs/buildRouteHooks.js +66 -0
- package/dist/cjs/buildRouteManifest.js +92 -0
- package/dist/cjs/buildRscClientAndServer.js +54 -0
- package/dist/cjs/client.d.ts +1 -0
- package/dist/cjs/clientSsr.d.ts +1 -0
- package/dist/cjs/devFeServer.js +153 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +184 -0
- package/dist/cjs/lib/StatusError.js +36 -0
- package/dist/cjs/lib/entries.js +53 -0
- package/dist/cjs/lib/envVarDefinitions.js +87 -0
- package/dist/cjs/lib/getMergedConfig.js +187 -0
- package/dist/cjs/lib/onWarn.js +36 -0
- package/dist/cjs/lib/registerFwGlobalsAndShims.js +117 -0
- package/dist/cjs/middleware/index.js +22 -0
- package/dist/cjs/middleware/invokeMiddleware.js +52 -0
- package/dist/cjs/middleware/register.js +106 -0
- package/dist/cjs/middleware/types.js +16 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/plugins/vite-plugin-jsx-loader.js +42 -0
- package/dist/cjs/plugins/vite-plugin-remove-from-bundle.js +56 -0
- package/dist/cjs/plugins/vite-plugin-rsc-analyze.js +104 -0
- package/dist/cjs/plugins/vite-plugin-rsc-reload.js +75 -0
- package/dist/cjs/plugins/vite-plugin-rsc-routes-auto-loader.js +159 -0
- package/dist/cjs/plugins/vite-plugin-rsc-routes-imports.js +125 -0
- package/dist/cjs/plugins/vite-plugin-rsc-ssr-router-import.js +75 -0
- package/dist/cjs/plugins/vite-plugin-rsc-transform-client.js +229 -0
- package/dist/cjs/plugins/vite-plugin-rsc-transform-server.js +398 -0
- package/dist/cjs/plugins/vite-plugin-swap-apollo-provider.js +41 -0
- package/dist/cjs/rsc/rscBuildAnalyze.js +116 -0
- package/dist/cjs/rsc/rscBuildClient.js +91 -0
- package/dist/cjs/rsc/rscBuildCopyCssAssets.js +56 -0
- package/dist/cjs/rsc/rscBuildEntriesFile.js +115 -0
- package/dist/cjs/rsc/rscBuildForServer.js +157 -0
- package/dist/cjs/rsc/rscBuildForSsr.js +172 -0
- package/dist/cjs/rsc/rscBuildRwEnvVars.js +56 -0
- package/dist/cjs/rsc/rscRenderer.js +165 -0
- package/dist/cjs/rsc/rscRequestHandler.js +162 -0
- package/dist/cjs/rsc/rscStudioHandlers.js +154 -0
- package/dist/cjs/runFeServer.js +166 -0
- package/dist/cjs/streaming/buildForStreamingServer.js +65 -0
- package/dist/cjs/streaming/collectCss.js +52 -0
- package/dist/cjs/streaming/createReactStreamingHandler.js +173 -0
- package/dist/cjs/streaming/streamHelpers.js +228 -0
- package/dist/cjs/streaming/transforms/bufferedTransform.js +61 -0
- package/dist/cjs/streaming/transforms/cancelTimeoutTransform.js +34 -0
- package/dist/cjs/streaming/transforms/encode-decode.js +36 -0
- package/dist/cjs/streaming/transforms/serverInjectionTransform.js +84 -0
- package/dist/cjs/streaming/triggerRouteHooks.js +96 -0
- package/dist/cjs/types.js +16 -0
- package/dist/cjs/utils.js +91 -0
- package/dist/devFeServer.d.ts +2 -0
- package/dist/devFeServer.d.ts.map +1 -0
- package/dist/devFeServer.js +134 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/lib/StatusError.d.ts +8 -0
- package/dist/lib/StatusError.d.ts.map +1 -0
- package/dist/lib/StatusError.js +11 -0
- package/dist/lib/entries.d.ts +3 -0
- package/dist/lib/entries.d.ts.map +1 -0
- package/dist/lib/entries.js +32 -0
- package/dist/lib/envVarDefinitions.d.ts +14 -0
- package/dist/lib/envVarDefinitions.d.ts.map +1 -0
- package/dist/lib/envVarDefinitions.js +53 -0
- package/dist/lib/getMergedConfig.d.ts +11 -0
- package/dist/lib/getMergedConfig.d.ts.map +1 -0
- package/dist/lib/getMergedConfig.js +153 -0
- package/dist/lib/onWarn.d.ts +3 -0
- package/dist/lib/onWarn.d.ts.map +1 -0
- package/dist/lib/onWarn.js +12 -0
- package/dist/lib/registerFwGlobalsAndShims.d.ts +12 -0
- package/dist/lib/registerFwGlobalsAndShims.d.ts.map +1 -0
- package/dist/lib/registerFwGlobalsAndShims.js +83 -0
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +1 -0
- package/dist/middleware/invokeMiddleware.d.ts +14 -0
- package/dist/middleware/invokeMiddleware.d.ts.map +1 -0
- package/dist/middleware/invokeMiddleware.js +32 -0
- package/dist/middleware/register.d.ts +23 -0
- package/dist/middleware/register.d.ts.map +1 -0
- package/dist/middleware/register.js +69 -0
- package/dist/middleware/types.d.ts +3 -0
- package/dist/middleware/types.d.ts.map +1 -0
- package/dist/middleware/types.js +0 -0
- package/dist/package.json +1 -0
- package/dist/plugins/vite-plugin-jsx-loader.d.ts +8 -0
- package/dist/plugins/vite-plugin-jsx-loader.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-jsx-loader.js +18 -0
- package/dist/plugins/vite-plugin-remove-from-bundle.d.ts +17 -0
- package/dist/plugins/vite-plugin-remove-from-bundle.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-remove-from-bundle.js +31 -0
- package/dist/plugins/vite-plugin-rsc-analyze.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-analyze.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-analyze.js +70 -0
- package/dist/plugins/vite-plugin-rsc-reload.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-reload.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-reload.js +41 -0
- package/dist/plugins/vite-plugin-rsc-routes-auto-loader.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-routes-auto-loader.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-routes-auto-loader.js +130 -0
- package/dist/plugins/vite-plugin-rsc-routes-imports.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-routes-imports.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-routes-imports.js +96 -0
- package/dist/plugins/vite-plugin-rsc-ssr-router-import.d.ts +7 -0
- package/dist/plugins/vite-plugin-rsc-ssr-router-import.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-ssr-router-import.js +41 -0
- package/dist/plugins/vite-plugin-rsc-transform-client.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-transform-client.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-transform-client.js +195 -0
- package/dist/plugins/vite-plugin-rsc-transform-server.d.ts +3 -0
- package/dist/plugins/vite-plugin-rsc-transform-server.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-rsc-transform-server.js +364 -0
- package/dist/plugins/vite-plugin-swap-apollo-provider.d.ts +12 -0
- package/dist/plugins/vite-plugin-swap-apollo-provider.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-swap-apollo-provider.js +17 -0
- package/dist/rsc/rscBuildAnalyze.d.ts +16 -0
- package/dist/rsc/rscBuildAnalyze.d.ts.map +1 -0
- package/dist/rsc/rscBuildAnalyze.js +92 -0
- package/dist/rsc/rscBuildClient.d.ts +7 -0
- package/dist/rsc/rscBuildClient.d.ts.map +1 -0
- package/dist/rsc/rscBuildClient.js +67 -0
- package/dist/rsc/rscBuildCopyCssAssets.d.ts +7 -0
- package/dist/rsc/rscBuildCopyCssAssets.d.ts.map +1 -0
- package/dist/rsc/rscBuildCopyCssAssets.js +22 -0
- package/dist/rsc/rscBuildEntriesFile.d.ts +10 -0
- package/dist/rsc/rscBuildEntriesFile.d.ts.map +1 -0
- package/dist/rsc/rscBuildEntriesFile.js +81 -0
- package/dist/rsc/rscBuildForServer.d.ts +7 -0
- package/dist/rsc/rscBuildForServer.d.ts.map +1 -0
- package/dist/rsc/rscBuildForServer.js +133 -0
- package/dist/rsc/rscBuildForSsr.d.ts +9 -0
- package/dist/rsc/rscBuildForSsr.d.ts.map +1 -0
- package/dist/rsc/rscBuildForSsr.js +138 -0
- package/dist/rsc/rscBuildRwEnvVars.d.ts +10 -0
- package/dist/rsc/rscBuildRwEnvVars.d.ts.map +1 -0
- package/dist/rsc/rscBuildRwEnvVars.js +22 -0
- package/dist/rsc/rscRenderer.d.ts +9 -0
- package/dist/rsc/rscRenderer.d.ts.map +1 -0
- package/dist/rsc/rscRenderer.js +130 -0
- package/dist/rsc/rscRequestHandler.d.ts +10 -0
- package/dist/rsc/rscRequestHandler.d.ts.map +1 -0
- package/dist/rsc/rscRequestHandler.js +131 -0
- package/dist/rsc/rscStudioHandlers.d.ts +10 -0
- package/dist/rsc/rscStudioHandlers.d.ts.map +1 -0
- package/dist/rsc/rscStudioHandlers.js +120 -0
- package/dist/runFeServer.d.ts +2 -0
- package/dist/runFeServer.d.ts.map +1 -0
- package/dist/runFeServer.js +132 -0
- package/dist/streaming/buildForStreamingServer.d.ts +4 -0
- package/dist/streaming/buildForStreamingServer.d.ts.map +1 -0
- package/dist/streaming/buildForStreamingServer.js +41 -0
- package/dist/streaming/collectCss.d.ts +7 -0
- package/dist/streaming/collectCss.d.ts.map +1 -0
- package/dist/streaming/collectCss.js +27 -0
- package/dist/streaming/createReactStreamingHandler.d.ts +12 -0
- package/dist/streaming/createReactStreamingHandler.d.ts.map +1 -0
- package/dist/streaming/createReactStreamingHandler.js +139 -0
- package/dist/streaming/streamHelpers.d.ts +23 -0
- package/dist/streaming/streamHelpers.d.ts.map +1 -0
- package/dist/streaming/streamHelpers.js +192 -0
- package/dist/streaming/transforms/bufferedTransform.d.ts +2 -0
- package/dist/streaming/transforms/bufferedTransform.d.ts.map +1 -0
- package/dist/streaming/transforms/bufferedTransform.js +37 -0
- package/dist/streaming/transforms/cancelTimeoutTransform.d.ts +2 -0
- package/dist/streaming/transforms/cancelTimeoutTransform.d.ts.map +1 -0
- package/dist/streaming/transforms/cancelTimeoutTransform.js +10 -0
- package/dist/streaming/transforms/encode-decode.d.ts +3 -0
- package/dist/streaming/transforms/encode-decode.d.ts.map +1 -0
- package/dist/streaming/transforms/encode-decode.js +11 -0
- package/dist/streaming/transforms/serverInjectionTransform.d.ts +16 -0
- package/dist/streaming/transforms/serverInjectionTransform.d.ts.map +1 -0
- package/dist/streaming/transforms/serverInjectionTransform.js +60 -0
- package/dist/streaming/triggerRouteHooks.d.ts +26 -0
- package/dist/streaming/triggerRouteHooks.d.ts.map +1 -0
- package/dist/streaming/triggerRouteHooks.js +71 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +62 -0
- package/inject/reactRefresh.js +7 -0
- package/package.json +116 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
import * as DefaultFetchAPI from "@whatwg-node/fetch";
|
|
3
|
+
import { normalizeNodeRequest } from "@whatwg-node/server";
|
|
4
|
+
import busboy from "busboy";
|
|
5
|
+
import {
|
|
6
|
+
decodeReply,
|
|
7
|
+
decodeReplyFromBusboy
|
|
8
|
+
} from "../bundled/react-server-dom-webpack.server.js";
|
|
9
|
+
import { hasStatusCode } from "../lib/StatusError.js";
|
|
10
|
+
import { invoke } from "../middleware/invokeMiddleware.js";
|
|
11
|
+
import { renderRscToStream } from "./rscRenderer.js";
|
|
12
|
+
import { sendRscFlightToStudio } from "./rscStudioHandlers.js";
|
|
13
|
+
const BASE_PATH = "/rw-rsc/";
|
|
14
|
+
function createRscRequestHandler(options) {
|
|
15
|
+
return async (req, res, next) => {
|
|
16
|
+
console.log("BASE_PATH", BASE_PATH);
|
|
17
|
+
console.log("req.originalUrl", req.originalUrl, "req.url", req.url);
|
|
18
|
+
console.log("req.headers.host", req.headers.host);
|
|
19
|
+
console.log("req.headers['rw-rsc']", req.headers["rw-rsc"]);
|
|
20
|
+
const mwRouter = await options.getMiddlewareRouter();
|
|
21
|
+
if (mwRouter) {
|
|
22
|
+
const webReq = normalizeNodeRequest(req, DefaultFetchAPI);
|
|
23
|
+
const matchedMw = mwRouter.find(webReq.method, webReq.url);
|
|
24
|
+
const [mwResponse] = await invoke(
|
|
25
|
+
webReq,
|
|
26
|
+
matchedMw?.handler,
|
|
27
|
+
{
|
|
28
|
+
params: matchedMw?.params,
|
|
29
|
+
viteDevServer: options.viteDevServer
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
const webRes = mwResponse.toResponse();
|
|
33
|
+
webRes.headers.forEach((value, key) => {
|
|
34
|
+
res.setHeader(key, value);
|
|
35
|
+
});
|
|
36
|
+
if (mwResponse.isRedirect() || mwResponse.body) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
"Not Implemented: What should happen if this RSC handler fails? And which part - Client side router?"
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (req.headers["rw-rsc"] !== "1") {
|
|
43
|
+
return next();
|
|
44
|
+
}
|
|
45
|
+
const url = new URL(req.originalUrl || "", "http://" + req.headers.host);
|
|
46
|
+
let rscId;
|
|
47
|
+
let rsaId;
|
|
48
|
+
let args = [];
|
|
49
|
+
if (url.pathname.startsWith(BASE_PATH)) {
|
|
50
|
+
rscId = url.pathname.split("/").pop();
|
|
51
|
+
rsaId = url.searchParams.get("action_id") || void 0;
|
|
52
|
+
console.log("rscId", rscId);
|
|
53
|
+
console.log("rsaId", rsaId);
|
|
54
|
+
if (rscId && rscId !== "_") {
|
|
55
|
+
res.setHeader("Content-Type", "text/x-component");
|
|
56
|
+
} else {
|
|
57
|
+
rscId = void 0;
|
|
58
|
+
}
|
|
59
|
+
args = await handleRsa(rsaId, req, args);
|
|
60
|
+
}
|
|
61
|
+
console.log("rscRequestHandler: args", args);
|
|
62
|
+
if (rscId || rsaId) {
|
|
63
|
+
const handleError = (err) => {
|
|
64
|
+
console.log("handleError() err", err);
|
|
65
|
+
if (hasStatusCode(err)) {
|
|
66
|
+
res.statusCode = err.statusCode;
|
|
67
|
+
} else {
|
|
68
|
+
console.info("Cannot render RSC", err);
|
|
69
|
+
res.statusCode = 500;
|
|
70
|
+
}
|
|
71
|
+
res.end(String(err));
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
const readable = await renderRscToStream({ rscId, rsaId, args });
|
|
75
|
+
Readable.fromWeb(readable).pipe(res);
|
|
76
|
+
await sendRscFlightToStudio({
|
|
77
|
+
rscId,
|
|
78
|
+
rsaId,
|
|
79
|
+
args,
|
|
80
|
+
basePath: BASE_PATH,
|
|
81
|
+
req,
|
|
82
|
+
handleError
|
|
83
|
+
});
|
|
84
|
+
} catch (e) {
|
|
85
|
+
handleError(e);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
async function handleRsa(rsaId, req, args) {
|
|
91
|
+
if (!rsaId) {
|
|
92
|
+
return args;
|
|
93
|
+
}
|
|
94
|
+
if (req.headers["content-type"]?.startsWith("multipart/form-data")) {
|
|
95
|
+
console.log("RSA: multipart/form-data");
|
|
96
|
+
const bb = busboy({ headers: req.headers });
|
|
97
|
+
const reply = decodeReplyFromBusboy(bb);
|
|
98
|
+
req.pipe(bb);
|
|
99
|
+
args = await reply;
|
|
100
|
+
if (args[0] instanceof FormData) {
|
|
101
|
+
const serializedFormData = {};
|
|
102
|
+
for (const [key, value] of args[0]) {
|
|
103
|
+
if (serializedFormData[key] !== void 0) {
|
|
104
|
+
if (!Array.isArray(serializedFormData[key])) {
|
|
105
|
+
serializedFormData[key] = [serializedFormData[key]];
|
|
106
|
+
}
|
|
107
|
+
serializedFormData[key].push(value);
|
|
108
|
+
} else {
|
|
109
|
+
serializedFormData[key] = value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
args[0] = {
|
|
113
|
+
__formData__: true,
|
|
114
|
+
state: serializedFormData
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
console.log("RSA: regular body");
|
|
119
|
+
let body = "";
|
|
120
|
+
for await (const chunk of req) {
|
|
121
|
+
body += chunk;
|
|
122
|
+
}
|
|
123
|
+
if (body) {
|
|
124
|
+
args = await decodeReply(body);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return args;
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
createRscRequestHandler
|
|
131
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Request } from 'express';
|
|
2
|
+
import type { RenderInput } from './rscRenderer.js';
|
|
3
|
+
interface StudioRenderInput extends Omit<RenderInput, 'serverState'> {
|
|
4
|
+
basePath: string;
|
|
5
|
+
req: Request;
|
|
6
|
+
handleError: (e: Error) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const sendRscFlightToStudio: (input: StudioRenderInput) => Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=rscStudioHandlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rscStudioHandlers.d.ts","sourceRoot":"","sources":["../../src/rsc/rscStudioHandlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAKtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAyGnD,UAAU,iBAAkB,SAAQ,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,OAAO,CAAA;IACZ,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;CAChC;AAED,eAAO,MAAM,qBAAqB,UAAiB,iBAAiB,kBA8CnE,CAAA"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { getConfig, getRawConfig } from "@cedarjs/project-config";
|
|
3
|
+
import { renderRscToStream } from "./rscRenderer.js";
|
|
4
|
+
const isTest = () => {
|
|
5
|
+
return process.env.NODE_ENV === "test";
|
|
6
|
+
};
|
|
7
|
+
const isDevelopment = () => {
|
|
8
|
+
return process.env.NODE_ENV !== "production" && !isTest();
|
|
9
|
+
};
|
|
10
|
+
const isStudioEnabled = () => {
|
|
11
|
+
return getRawConfig()["studio"] !== void 0;
|
|
12
|
+
};
|
|
13
|
+
const shouldSendToStudio = () => {
|
|
14
|
+
return isStudioEnabled() && !isDevelopment();
|
|
15
|
+
};
|
|
16
|
+
const getStudioPort = () => {
|
|
17
|
+
return getConfig().studio.basePort;
|
|
18
|
+
};
|
|
19
|
+
const processRenderRscStream = async (readable) => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
const writable = new WritableStream({
|
|
23
|
+
write(chunk) {
|
|
24
|
+
chunks.push(chunk);
|
|
25
|
+
},
|
|
26
|
+
close() {
|
|
27
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
readable.pipeTo(writable).catch((error) => reject(error));
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
const postFlightToStudio = (payload, metadata) => {
|
|
34
|
+
if (!shouldSendToStudio()) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const base64Payload = Buffer.from(payload).toString("base64");
|
|
38
|
+
const encodedMetadata = Buffer.from(JSON.stringify(metadata)).toString(
|
|
39
|
+
"base64"
|
|
40
|
+
);
|
|
41
|
+
const jsonBody = JSON.stringify({
|
|
42
|
+
flight: {
|
|
43
|
+
encodedPayload: base64Payload,
|
|
44
|
+
encoding: "base64",
|
|
45
|
+
encodedMetadata
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const options = {
|
|
49
|
+
hostname: "localhost",
|
|
50
|
+
port: getStudioPort(),
|
|
51
|
+
path: "/.redwood/functions/rsc-flight",
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: {
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
"Content-Length": Buffer.byteLength(jsonBody)
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const req = http.request(options, (res) => {
|
|
59
|
+
res.setEncoding("utf8");
|
|
60
|
+
});
|
|
61
|
+
req.on("error", (e) => {
|
|
62
|
+
console.error("An error occurred sending the Flight Payload to Studio");
|
|
63
|
+
console.error(e);
|
|
64
|
+
});
|
|
65
|
+
req.write(jsonBody);
|
|
66
|
+
req.end();
|
|
67
|
+
};
|
|
68
|
+
const createStudioFlightHandler = (readable, metadata) => {
|
|
69
|
+
processRenderRscStream(readable).then((payload) => {
|
|
70
|
+
console.debug("Sending RSC Rendered stream to Studio");
|
|
71
|
+
postFlightToStudio(payload, metadata);
|
|
72
|
+
console.debug("Sent RSC Rendered stream to Studio");
|
|
73
|
+
console.debug("payload to Studio:", payload);
|
|
74
|
+
console.debug("metadata to Studio:", metadata);
|
|
75
|
+
}).catch((error) => {
|
|
76
|
+
console.error("An error occurred getting RSC Rendered steam:", error);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const sendRscFlightToStudio = async (input) => {
|
|
80
|
+
if (!shouldSendToStudio()) {
|
|
81
|
+
console.debug("Studio is not enabled");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const { rscId, rsaId, args, basePath, req, handleError } = input;
|
|
85
|
+
try {
|
|
86
|
+
const startedAt = Date.now();
|
|
87
|
+
const start = performance.now();
|
|
88
|
+
const readable = await renderRscToStream({ rscId, rsaId, args });
|
|
89
|
+
const endedAt = Date.now();
|
|
90
|
+
const end = performance.now();
|
|
91
|
+
const duration = end - start;
|
|
92
|
+
const metadata = {
|
|
93
|
+
rsc: {
|
|
94
|
+
rscId,
|
|
95
|
+
rsaId,
|
|
96
|
+
args
|
|
97
|
+
},
|
|
98
|
+
request: {
|
|
99
|
+
basePath,
|
|
100
|
+
originalUrl: req.originalUrl,
|
|
101
|
+
url: req.url,
|
|
102
|
+
headers: req.headers
|
|
103
|
+
},
|
|
104
|
+
performance: {
|
|
105
|
+
startedAt,
|
|
106
|
+
endedAt,
|
|
107
|
+
duration
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
createStudioFlightHandler(readable, metadata);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
if (e instanceof Error) {
|
|
113
|
+
console.error("An error occurred rendering RSC and sending to Studio:", e);
|
|
114
|
+
handleError(e);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
export {
|
|
119
|
+
sendRscFlightToStudio
|
|
120
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runFeServer.d.ts","sourceRoot":"","sources":["../src/runFeServer.ts"],"names":[],"mappings":"AAkDA,wBAAsB,WAAW,kBAsJhC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import url from "node:url";
|
|
3
|
+
import { createServerAdapter } from "@whatwg-node/server";
|
|
4
|
+
import { config as loadDotEnv } from "dotenv-defaults";
|
|
5
|
+
import express from "express";
|
|
6
|
+
import { createProxyMiddleware } from "http-proxy-middleware";
|
|
7
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
8
|
+
import { getConfig, getPaths } from "@cedarjs/project-config";
|
|
9
|
+
import { getRscStylesheetLinkGenerator } from "@cedarjs/router/rscCss";
|
|
10
|
+
import { createPerRequestMap, createServerStorage } from "@cedarjs/server-store";
|
|
11
|
+
import { registerFwGlobalsAndShims } from "./lib/registerFwGlobalsAndShims.js";
|
|
12
|
+
import { invoke } from "./middleware/invokeMiddleware.js";
|
|
13
|
+
import { createMiddlewareRouter } from "./middleware/register.js";
|
|
14
|
+
import { createReactStreamingHandler } from "./streaming/createReactStreamingHandler.js";
|
|
15
|
+
import { convertExpressHeaders, getFullUrl } from "./utils.js";
|
|
16
|
+
loadDotEnv({
|
|
17
|
+
path: path.join(getPaths().base, ".env"),
|
|
18
|
+
defaults: path.join(getPaths().base, ".env.defaults"),
|
|
19
|
+
// @ts-expect-error - Old typings. @types/dotenv-defaults depends on dotenv
|
|
20
|
+
// v8. dotenv-defaults uses dotenv v14
|
|
21
|
+
multiline: true
|
|
22
|
+
});
|
|
23
|
+
async function runFeServer() {
|
|
24
|
+
const app = express();
|
|
25
|
+
const rwPaths = getPaths();
|
|
26
|
+
const rwConfig = getConfig();
|
|
27
|
+
const rscEnabled = rwConfig.experimental?.rsc?.enabled;
|
|
28
|
+
registerFwGlobalsAndShims();
|
|
29
|
+
if (rscEnabled) {
|
|
30
|
+
const { setClientEntries } = await import("./rsc/rscRenderer.js");
|
|
31
|
+
createWebSocketServer();
|
|
32
|
+
try {
|
|
33
|
+
await setClientEntries();
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.error("Failed to load client entries");
|
|
36
|
+
console.error(e);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const routeManifestUrl = url.pathToFileURL(rwPaths.web.routeManifest).href;
|
|
41
|
+
const routeManifest = (await import(routeManifestUrl, { with: { type: "json" } })).default;
|
|
42
|
+
const clientBuildManifestUrl = url.pathToFileURL(
|
|
43
|
+
path.join(rwPaths.web.distBrowser, "client-build-manifest.json")
|
|
44
|
+
).href;
|
|
45
|
+
const clientBuildManifest = (await import(clientBuildManifestUrl, { with: { type: "json" } })).default;
|
|
46
|
+
const clientEntry = rscEnabled ? clientBuildManifest["entry.client.tsx"] || clientBuildManifest["entry.client.jsx"] : Object.values(clientBuildManifest).find(
|
|
47
|
+
(manifestItem) => manifestItem.isEntry
|
|
48
|
+
);
|
|
49
|
+
if (!clientEntry) {
|
|
50
|
+
throw new Error("Could not find client entry in build manifest");
|
|
51
|
+
}
|
|
52
|
+
const middlewareRouter = await createMiddlewareRouter();
|
|
53
|
+
const serverStorage = createServerStorage();
|
|
54
|
+
const handleWithMiddleware = () => {
|
|
55
|
+
return createServerAdapter(async (req) => {
|
|
56
|
+
const matchedMw = middlewareRouter.find(req.method, req.url);
|
|
57
|
+
const handler = matchedMw?.handler;
|
|
58
|
+
if (!matchedMw) {
|
|
59
|
+
return new Response("No middleware found", { status: 404 });
|
|
60
|
+
}
|
|
61
|
+
const [mwRes] = await invoke(req, handler, {
|
|
62
|
+
params: matchedMw?.params
|
|
63
|
+
});
|
|
64
|
+
return mwRes.toResponse();
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
app.use(
|
|
68
|
+
"/assets",
|
|
69
|
+
express.static(rwPaths.web.distBrowser + "/assets", { index: false })
|
|
70
|
+
);
|
|
71
|
+
app.use("*", (req, _res, next) => {
|
|
72
|
+
const fullUrl = getFullUrl(req, rscEnabled);
|
|
73
|
+
const headers = convertExpressHeaders(req.headersDistinct);
|
|
74
|
+
const perReqStore = createPerRequestMap({ headers, fullUrl });
|
|
75
|
+
serverStorage.run(perReqStore, next);
|
|
76
|
+
});
|
|
77
|
+
app.use(
|
|
78
|
+
rwConfig.web.apiUrl,
|
|
79
|
+
createProxyMiddleware({
|
|
80
|
+
changeOrigin: false,
|
|
81
|
+
// Using 127.0.0.1 to force ipv4. With `localhost` you don't really know
|
|
82
|
+
// if it's going to be ipv4 or ipv6
|
|
83
|
+
target: `http://127.0.0.1:${rwConfig.api.port}`
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
if (rscEnabled) {
|
|
87
|
+
const { createRscRequestHandler } = await import("./rsc/rscRequestHandler.js");
|
|
88
|
+
app.use(
|
|
89
|
+
"/rw-rsc",
|
|
90
|
+
createRscRequestHandler({
|
|
91
|
+
getMiddlewareRouter: async () => middlewareRouter
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
app.use(express.static(rwPaths.web.distBrowser, { index: false }));
|
|
96
|
+
const getStylesheetLinks = rscEnabled ? getRscStylesheetLinkGenerator(clientEntry.css) : () => clientEntry.css || [];
|
|
97
|
+
const routeHandler = await createReactStreamingHandler({
|
|
98
|
+
routes: Object.values(routeManifest),
|
|
99
|
+
clientEntryPath: clientEntry.file,
|
|
100
|
+
getStylesheetLinks,
|
|
101
|
+
getMiddlewareRouter: async () => middlewareRouter
|
|
102
|
+
});
|
|
103
|
+
app.get("*", createServerAdapter(routeHandler));
|
|
104
|
+
app.post("*", handleWithMiddleware());
|
|
105
|
+
app.listen(rwConfig.web.port);
|
|
106
|
+
console.log(
|
|
107
|
+
`Started production FE server on http://localhost:${rwConfig.web.port}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
function createWebSocketServer() {
|
|
111
|
+
const wsServer = new WebSocketServer({ port: 18998 });
|
|
112
|
+
wsServer.on("connection", (ws) => {
|
|
113
|
+
console.log("A new client connected.");
|
|
114
|
+
ws.on("message", (data) => {
|
|
115
|
+
const message = data.toString();
|
|
116
|
+
console.log("runFeServer.ts: Received message:");
|
|
117
|
+
console.log(message.slice(0, 120) + "...");
|
|
118
|
+
wsServer.clients.forEach((client) => {
|
|
119
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
120
|
+
client.send(message);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
ws.on("close", () => {
|
|
125
|
+
console.log("A client disconnected.");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
runFeServer();
|
|
130
|
+
export {
|
|
131
|
+
runFeServer
|
|
132
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildForStreamingServer.d.ts","sourceRoot":"","sources":["../../src/streaming/buildForStreamingServer.ts"],"names":[],"mappings":"AAKA,wBAAsB,uBAAuB,CAAC,EAC5C,OAAe,GAChB,EAAE;IACD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,iBAkCA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { build as viteBuild } from "vite";
|
|
2
|
+
import { cjsInterop } from "vite-plugin-cjs-interop";
|
|
3
|
+
import { getPaths } from "@cedarjs/project-config";
|
|
4
|
+
async function buildForStreamingServer({
|
|
5
|
+
verbose = false
|
|
6
|
+
}) {
|
|
7
|
+
console.log("Starting streaming server build...\n");
|
|
8
|
+
const rwPaths = getPaths();
|
|
9
|
+
if (!rwPaths.web.viteConfig) {
|
|
10
|
+
throw new Error("Vite config not found");
|
|
11
|
+
}
|
|
12
|
+
await viteBuild({
|
|
13
|
+
configFile: rwPaths.web.viteConfig,
|
|
14
|
+
plugins: [
|
|
15
|
+
cjsInterop({
|
|
16
|
+
dependencies: [
|
|
17
|
+
// Skip ESM modules: rwjs/auth, rwjs/web, rwjs/auth-*-middleware, rwjs/router
|
|
18
|
+
"@cedarjs/forms",
|
|
19
|
+
"@cedarjs/prerender/*",
|
|
20
|
+
"@cedarjs/auth-*-api",
|
|
21
|
+
"@cedarjs/auth-*-web"
|
|
22
|
+
]
|
|
23
|
+
})
|
|
24
|
+
],
|
|
25
|
+
build: {
|
|
26
|
+
// TODO (RSC): Remove `minify: false` when we don't need to debug as often
|
|
27
|
+
minify: false,
|
|
28
|
+
outDir: rwPaths.web.distSsr,
|
|
29
|
+
ssr: true,
|
|
30
|
+
emptyOutDir: true
|
|
31
|
+
},
|
|
32
|
+
envFile: false,
|
|
33
|
+
define: {
|
|
34
|
+
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
|
|
35
|
+
},
|
|
36
|
+
logLevel: verbose ? "info" : "warn"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
buildForStreamingServer
|
|
41
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ViteDevServer, ModuleNode } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Collect SSR CSS for Vite
|
|
4
|
+
*/
|
|
5
|
+
export declare const componentsModules: (components: string[], vite: ViteDevServer) => Set<ModuleNode>;
|
|
6
|
+
export declare const collectCssPaths: (mods: Set<ModuleNode>, cssLinks?: Set<string>, checkedComponents?: Set<unknown>) => Set<string>;
|
|
7
|
+
//# sourceMappingURL=collectCss.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectCss.d.ts","sourceRoot":"","sources":["../../src/streaming/collectCss.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAGrD;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAChB,MAAM,EAAE,QACd,aAAa,oBAUpB,CAAA;AAED,eAAO,MAAM,eAAe,SACpB,GAAG,CAAC,UAAU,CAAC,0EAmBtB,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { normalizePath } from "vite";
|
|
2
|
+
const componentsModules = (components, vite) => {
|
|
3
|
+
const matchedModules = /* @__PURE__ */ new Set();
|
|
4
|
+
components.forEach((component) => {
|
|
5
|
+
const modules = vite.moduleGraph.getModulesByFile(normalizePath(component));
|
|
6
|
+
modules?.forEach((mod) => {
|
|
7
|
+
matchedModules.add(mod);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
return matchedModules;
|
|
11
|
+
};
|
|
12
|
+
const collectCssPaths = (mods, cssLinks = /* @__PURE__ */ new Set(), checkedComponents = /* @__PURE__ */ new Set()) => {
|
|
13
|
+
for (const mod of mods) {
|
|
14
|
+
if (mod.file?.endsWith(".scss") || mod.file?.endsWith(".css") || mod.file?.endsWith(".less")) {
|
|
15
|
+
cssLinks.add(mod.url);
|
|
16
|
+
}
|
|
17
|
+
if (mod.importedModules.size > 0 && !checkedComponents.has(mod.id)) {
|
|
18
|
+
checkedComponents.add(mod.id);
|
|
19
|
+
collectCssPaths(mod.importedModules, cssLinks, checkedComponents);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return cssLinks;
|
|
23
|
+
};
|
|
24
|
+
export {
|
|
25
|
+
collectCssPaths,
|
|
26
|
+
componentsModules
|
|
27
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type Router from 'find-my-way';
|
|
2
|
+
import type { ViteDevServer } from 'vite';
|
|
3
|
+
import type { RouteSpec, RWRouteManifestItem } from '@cedarjs/internal';
|
|
4
|
+
interface CreateReactStreamingHandlerOptions {
|
|
5
|
+
routes: RWRouteManifestItem[];
|
|
6
|
+
clientEntryPath: string;
|
|
7
|
+
getStylesheetLinks: (route?: RWRouteManifestItem | RouteSpec) => string[];
|
|
8
|
+
getMiddlewareRouter: () => Promise<Router.Instance<any>>;
|
|
9
|
+
}
|
|
10
|
+
export declare const createReactStreamingHandler: ({ routes, clientEntryPath, getStylesheetLinks, getMiddlewareRouter, }: CreateReactStreamingHandlerOptions, viteDevServer?: ViteDevServer) => Promise<(req: Request) => Promise<Response>>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=createReactStreamingHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createReactStreamingHandler.d.ts","sourceRoot":"","sources":["../../src/streaming/createReactStreamingHandler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAGrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAIzC,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAcvE,UAAU,kCAAkC;IAC1C,MAAM,EAAE,mBAAmB,EAAE,CAAA;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,kBAAkB,EAAE,CAAC,KAAK,CAAC,EAAE,mBAAmB,GAAG,SAAS,KAAK,MAAM,EAAE,CAAA;IACzE,mBAAmB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;CACzD;AAOD,eAAO,MAAM,2BAA2B,0EAMnC,kCAAkC,kBACrB,aAAa,mBA6BV,OAAO,uBA8I3B,CAAA"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { Response } from "@whatwg-node/fetch";
|
|
3
|
+
import { createIsbotFromList, list as isbotList } from "isbot";
|
|
4
|
+
import { middlewareDefaultAuthProviderState } from "@cedarjs/auth/dist/AuthProvider/AuthProviderState.js";
|
|
5
|
+
import { getAppRouteHook, getConfig, getPaths } from "@cedarjs/project-config";
|
|
6
|
+
import { matchPath } from "@cedarjs/router/util";
|
|
7
|
+
import { MiddlewareResponse } from "@cedarjs/web/middleware";
|
|
8
|
+
import { invoke } from "../middleware/invokeMiddleware.js";
|
|
9
|
+
import { makeFilePath, ssrLoadEntryServer } from "../utils.js";
|
|
10
|
+
import { reactRenderToStreamResponse } from "./streamHelpers.js";
|
|
11
|
+
import { loadAndRunRouteHooks } from "./triggerRouteHooks.js";
|
|
12
|
+
const isbot = createIsbotFromList(
|
|
13
|
+
isbotList.filter((record) => !record.includes("chrome-lighthouse"))
|
|
14
|
+
);
|
|
15
|
+
const createReactStreamingHandler = async ({
|
|
16
|
+
routes,
|
|
17
|
+
clientEntryPath,
|
|
18
|
+
getStylesheetLinks,
|
|
19
|
+
getMiddlewareRouter
|
|
20
|
+
}, viteDevServer) => {
|
|
21
|
+
const rwPaths = getPaths();
|
|
22
|
+
const rwConfig = getConfig();
|
|
23
|
+
const isProd = !viteDevServer;
|
|
24
|
+
const middlewareRouter = await getMiddlewareRouter();
|
|
25
|
+
let entryServerImport;
|
|
26
|
+
let fallbackDocumentImport;
|
|
27
|
+
const rscEnabled = rwConfig.experimental?.rsc?.enabled;
|
|
28
|
+
if (isProd) {
|
|
29
|
+
if (rscEnabled) {
|
|
30
|
+
entryServerImport = await import(makeFilePath(rwPaths.web.distSsrEntryServer));
|
|
31
|
+
} else {
|
|
32
|
+
entryServerImport = await import(makeFilePath(rwPaths.web.distSsrEntryServer));
|
|
33
|
+
}
|
|
34
|
+
fallbackDocumentImport = await import(makeFilePath(rwPaths.web.distSsrDocument));
|
|
35
|
+
}
|
|
36
|
+
return async (req) => {
|
|
37
|
+
let mwResponse = MiddlewareResponse.next();
|
|
38
|
+
let decodedAuthState = {
|
|
39
|
+
...middlewareDefaultAuthProviderState,
|
|
40
|
+
cookieHeader: req.headers.get("cookie"),
|
|
41
|
+
roles: []
|
|
42
|
+
};
|
|
43
|
+
let currentRoute;
|
|
44
|
+
let parsedParams = {};
|
|
45
|
+
const currentUrl = new URL(req.url);
|
|
46
|
+
for (const route of routes) {
|
|
47
|
+
const { match, ...rest } = matchPath(
|
|
48
|
+
route.pathDefinition,
|
|
49
|
+
currentUrl.pathname
|
|
50
|
+
);
|
|
51
|
+
if (match) {
|
|
52
|
+
currentRoute = route;
|
|
53
|
+
parsedParams = rest;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const cssLinks = getStylesheetLinks(currentRoute);
|
|
58
|
+
if (middlewareRouter) {
|
|
59
|
+
const matchedMw = middlewareRouter.find(req.method, req.url);
|
|
60
|
+
[mwResponse, decodedAuthState] = await invoke(
|
|
61
|
+
req,
|
|
62
|
+
matchedMw?.handler,
|
|
63
|
+
{
|
|
64
|
+
route: currentRoute,
|
|
65
|
+
cssPaths: cssLinks,
|
|
66
|
+
params: matchedMw?.params,
|
|
67
|
+
viteDevServer
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
if (mwResponse.isRedirect() || mwResponse.body) {
|
|
71
|
+
return mwResponse.toResponse();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!currentRoute) {
|
|
75
|
+
throw new Error("404 handling not implemented");
|
|
76
|
+
}
|
|
77
|
+
if (currentRoute.redirect) {
|
|
78
|
+
return new Response(null, {
|
|
79
|
+
status: 302,
|
|
80
|
+
headers: {
|
|
81
|
+
Location: currentRoute.redirect.to
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (!isProd) {
|
|
86
|
+
entryServerImport = await ssrLoadEntryServer(viteDevServer);
|
|
87
|
+
fallbackDocumentImport = await viteDevServer.ssrLoadModule(
|
|
88
|
+
rwPaths.web.document
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const ServerEntry = entryServerImport.ServerEntry || entryServerImport.default;
|
|
92
|
+
const FallbackDocument = fallbackDocumentImport.Document || fallbackDocumentImport.default;
|
|
93
|
+
let metaTags = [];
|
|
94
|
+
let routeHookPath = currentRoute.routeHooks;
|
|
95
|
+
if (isProd) {
|
|
96
|
+
routeHookPath = currentRoute.routeHooks ? path.join(rwPaths.web.distRouteHooks, currentRoute.routeHooks) : null;
|
|
97
|
+
}
|
|
98
|
+
const routeHookOutput = await loadAndRunRouteHooks({
|
|
99
|
+
paths: [getAppRouteHook(isProd), routeHookPath],
|
|
100
|
+
reqMeta: {
|
|
101
|
+
req,
|
|
102
|
+
parsedParams
|
|
103
|
+
},
|
|
104
|
+
viteDevServer
|
|
105
|
+
});
|
|
106
|
+
metaTags = routeHookOutput.meta;
|
|
107
|
+
const jsBundles = [viteDevServer ? clientEntryPath : "/" + clientEntryPath];
|
|
108
|
+
if (currentRoute.bundle) {
|
|
109
|
+
jsBundles.push("/" + currentRoute.bundle);
|
|
110
|
+
}
|
|
111
|
+
const isSeoCrawler = isbot(req.headers.get("user-agent") || "");
|
|
112
|
+
const reactResponse = await reactRenderToStreamResponse(
|
|
113
|
+
mwResponse,
|
|
114
|
+
{
|
|
115
|
+
ServerEntry,
|
|
116
|
+
FallbackDocument,
|
|
117
|
+
currentUrl,
|
|
118
|
+
metaTags,
|
|
119
|
+
cssLinks,
|
|
120
|
+
isProd,
|
|
121
|
+
jsBundles,
|
|
122
|
+
authState: decodedAuthState
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
waitForAllReady: isSeoCrawler,
|
|
126
|
+
onError: (err) => {
|
|
127
|
+
if (!isProd && viteDevServer) {
|
|
128
|
+
viteDevServer.ssrFixStacktrace(err);
|
|
129
|
+
}
|
|
130
|
+
console.error(err);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
return reactResponse;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
createReactStreamingHandler
|
|
139
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { ServerAuthState } from '@cedarjs/auth/dist/AuthProvider/ServerAuthProvider.js';
|
|
3
|
+
import type { TagDescriptor } from '@cedarjs/web';
|
|
4
|
+
import type { MiddlewareResponse } from '@cedarjs/web/middleware';
|
|
5
|
+
import type { ServerEntryType } from '../types.js';
|
|
6
|
+
interface RenderToStreamArgs {
|
|
7
|
+
ServerEntry: ServerEntryType;
|
|
8
|
+
FallbackDocument: React.FunctionComponent;
|
|
9
|
+
currentUrl: URL;
|
|
10
|
+
metaTags: TagDescriptor[];
|
|
11
|
+
cssLinks: string[];
|
|
12
|
+
isProd: boolean;
|
|
13
|
+
jsBundles?: string[];
|
|
14
|
+
authState: ServerAuthState;
|
|
15
|
+
}
|
|
16
|
+
interface StreamOptions {
|
|
17
|
+
waitForAllReady?: boolean;
|
|
18
|
+
onError?: (err: Error) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function reactRenderToStreamResponse(mwRes: MiddlewareResponse, renderOptions: RenderToStreamArgs, streamOptions: StreamOptions): Promise<Response>;
|
|
21
|
+
export declare function importModule(mod: 'rd-server' | '__rwjs__react' | '__rwjs__location' | '__rwjs__server_auth_provider' | '__rwjs__server_inject'): Promise<any>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=streamHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamHelpers.d.ts","sourceRoot":"","sources":["../../src/streaming/streamHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAI5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAYlD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,eAAe,CAAA;IAC5B,gBAAgB,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACzC,UAAU,EAAE,GAAG,CAAA;IACf,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,eAAe,CAAA;CAC3B;AAED,UAAU,aAAa;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CAC/B;AA2BD,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,kBAAkB,EACzB,aAAa,EAAE,kBAAkB,EACjC,aAAa,EAAE,aAAa,qBAgM7B;AA2BD,wBAAsB,YAAY,CAChC,GAAG,EACC,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,8BAA8B,GAC9B,uBAAuB,gBA2B5B"}
|