reactivated 0.45.3 → 0.46.0
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/dist/client.js +7 -2
- package/dist/client.js.map +1 -1
- package/dist/render.d.mts +3 -11
- package/dist/render.mjs +53 -55
- package/dist/render.mjs.map +1 -1
- package/dist/server.mjs +1 -7
- package/dist/server.mjs.map +1 -1
- package/dist/vite.mjs +2 -8
- package/dist/vite.mjs.map +1 -1
- package/package.json +9 -9
- package/src/client.tsx +7 -2
- package/src/render.mts +71 -94
- package/src/server.mts +1 -17
- package/src/vite.mts +2 -9
package/dist/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { hydrateRoot } from "react-dom/client";
|
|
1
2
|
import React from "react";
|
|
2
|
-
import { hydrate } from "react-dom";
|
|
3
3
|
const props = window.__PRELOADED_STATE__;
|
|
4
4
|
if (module.hot) {
|
|
5
5
|
module.hot.accept();
|
|
@@ -7,6 +7,11 @@ if (module.hot) {
|
|
|
7
7
|
// tslint:disable-next-line
|
|
8
8
|
const Template = require("client/templates/" + props.template_name + ".tsx").default;
|
|
9
9
|
export const bootstrap = () => {
|
|
10
|
-
|
|
10
|
+
const root = document.getElementById("root");
|
|
11
|
+
if (!root) {
|
|
12
|
+
console.error("div#root is missing!");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
hydrateRoot(root, React.createElement(Template, { ...props }));
|
|
11
16
|
};
|
|
12
17
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,KAAK,GAAI,MAAc,CAAC,mBAAmB,CAAC;AAElD,IAAK,MAAc,CAAC,GAAG,EAAE,CAAC;IACrB,MAAc,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;AACjC,CAAC;AAED,2BAA2B;AAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,mBAAmB,GAAG,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;AAErF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,OAAO;IACX,CAAC;IACD,WAAW,CAAC,IAAI,EAAE,oBAAC,QAAQ,OAAK,KAAK,GAAI,CAAC,CAAC;AAC/C,CAAC,CAAC"}
|
package/dist/render.d.mts
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { Request } from "express";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
html: string;
|
|
5
|
-
vite: string;
|
|
6
|
-
helmet: HelmetServerState;
|
|
7
|
-
context: any;
|
|
8
|
-
props: any;
|
|
9
|
-
mode: "production" | "development";
|
|
10
|
-
entryPoint: string;
|
|
11
|
-
}) => string;
|
|
2
|
+
import { type JSX } from "react";
|
|
3
|
+
import { Response } from "express";
|
|
12
4
|
export type Renderer<T = unknown> = (content: JSX.Element, req: {
|
|
13
5
|
context: T;
|
|
14
6
|
props: unknown;
|
|
15
7
|
}) => Promise<JSX.Element>;
|
|
16
|
-
export declare const render: (req: Request, vite: string, mode: "production" | "development", entryPoint: string) => Promise<
|
|
8
|
+
export declare const render: (req: Request, res: Response, vite: string, mode: "production" | "development", entryPoint: string, ssrFixStacktrace?: (error: Error) => void) => Promise<void>;
|
package/dist/render.mjs
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
3
|
+
import { Transform } from "node:stream";
|
|
4
|
+
import { serializeError } from "./errors.js";
|
|
4
5
|
// @ts-ignore
|
|
5
6
|
import { Provider } from "@reactivated";
|
|
6
7
|
// @ts-ignore
|
|
7
8
|
import { getTemplate } from "@reactivated/template";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const defaultRenderer = (content) => Promise.resolve(content);
|
|
10
|
+
function serJSON(data) {
|
|
11
|
+
return JSON.stringify(data).replace(/</g, "\\u003c");
|
|
12
|
+
}
|
|
13
|
+
export const render = async (req, res, vite, mode, entryPoint, ssrFixStacktrace) => {
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
const customConfiguration = import.meta.glob("@client/renderer.tsx", { eager: true })["/client/renderer.tsx"];
|
|
16
|
+
const { context, props } = req.body;
|
|
17
|
+
const Template = await getTemplate(context);
|
|
18
|
+
const scriptNonce = context.request.csp_nonce ?? undefined;
|
|
12
19
|
const { STATIC_URL } = context;
|
|
13
20
|
if (STATIC_URL == null) {
|
|
14
21
|
console.error("Ensure your context processor includes STATIC_URL");
|
|
@@ -19,56 +26,47 @@ export const renderPage = ({ html, vite, helmet, context, props, mode, entryPoin
|
|
|
19
26
|
const js = mode == "production"
|
|
20
27
|
? `<script type="module" src="${STATIC_URL}dist/${entryPoint}.js" defer crossOrigin="anonymous"></script>`
|
|
21
28
|
: `<script type="module" src="${STATIC_URL}dist/client/${entryPoint}.tsx"></script>`;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<head>
|
|
26
|
-
${vite}
|
|
27
|
-
<script ${scriptNonce}>
|
|
28
|
-
// These go first because scripts below need them.
|
|
29
|
-
// WARNING: See the following for security issues around embedding JSON in HTML:
|
|
30
|
-
// http://redux.js.org/recipes/ServerRendering.html#security-considerations
|
|
31
|
-
window.__PRELOADED_PROPS__ = ${JSON.stringify(props).replace(/</g, "\\u003c")}
|
|
32
|
-
window.__PRELOADED_CONTEXT__ = ${JSON.stringify(context).replace(/</g, "\\u003c")}
|
|
33
|
-
</script>
|
|
34
|
-
${css}
|
|
35
|
-
|
|
36
|
-
${helmet.base.toString()}
|
|
37
|
-
${helmet.link.toString()}
|
|
38
|
-
${helmet.meta.toString()}
|
|
39
|
-
${helmet.noscript.toString()}
|
|
40
|
-
${helmet.script.toString()}
|
|
41
|
-
${helmet.style.toString()}
|
|
42
|
-
${helmet.title.toString()}
|
|
43
|
-
</head>
|
|
44
|
-
<body ${helmet.bodyAttributes.toString()}>
|
|
45
|
-
<div id="root">${html}</div>
|
|
46
|
-
${js}
|
|
47
|
-
</body>
|
|
48
|
-
</html>`;
|
|
49
|
-
};
|
|
50
|
-
const defaultRenderer = (content) => Promise.resolve(content);
|
|
51
|
-
export const render = async (req, vite, mode, entryPoint) => {
|
|
52
|
-
// @ts-ignore
|
|
53
|
-
const customConfiguration = import.meta.glob("@client/renderer.tsx", { eager: true })["/client/renderer.tsx"];
|
|
54
|
-
const { context, props } = req.body;
|
|
55
|
-
const Template = await getTemplate(context);
|
|
56
|
-
const helmetContext = {};
|
|
57
|
-
const content = React.createElement(React.StrictMode, {}, React.createElement(HelmetProvider, { context: helmetContext }, React.createElement(Provider, { value: context }, React.createElement(Template, props))));
|
|
58
|
-
const html = ReactDOMServer.renderToString(await (customConfiguration?.default ?? defaultRenderer)(content, {
|
|
29
|
+
const content = React.createElement(React.StrictMode, {}, React.createElement(Provider, { value: context }, React.createElement(Template, props)));
|
|
30
|
+
let hasError = false;
|
|
31
|
+
const { pipe } = renderToPipeableStream(await (customConfiguration?.default ?? defaultRenderer)(content, {
|
|
59
32
|
context,
|
|
60
33
|
props,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
34
|
+
}), {
|
|
35
|
+
nonce: scriptNonce,
|
|
36
|
+
bootstrapScriptContent: `
|
|
37
|
+
window.__PRELOADED_PROPS__ = ${serJSON(props)};
|
|
38
|
+
window.__PRELOADED_CONTEXT__ = ${serJSON(context)};
|
|
39
|
+
`,
|
|
40
|
+
onError(error) {
|
|
41
|
+
hasError = true;
|
|
42
|
+
if (ssrFixStacktrace) {
|
|
43
|
+
console.log("fixing stacktrace");
|
|
44
|
+
ssrFixStacktrace(error);
|
|
45
|
+
}
|
|
46
|
+
const errResp = {
|
|
47
|
+
error: serializeError(error),
|
|
48
|
+
};
|
|
49
|
+
res.status(500).json(errResp);
|
|
50
|
+
},
|
|
51
|
+
onAllReady() {
|
|
52
|
+
if (hasError) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
res.status(200);
|
|
56
|
+
// Seems like the renderer.py, at least for unix socket, requires a charset
|
|
57
|
+
// unlike the React docs
|
|
58
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
59
|
+
const transformStream = new Transform({
|
|
60
|
+
transform(chunk, encoding, callback) {
|
|
61
|
+
res.write(chunk, encoding);
|
|
62
|
+
callback();
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
transformStream.on("finish", () => {
|
|
66
|
+
res.end(vite + css + js);
|
|
67
|
+
});
|
|
68
|
+
pipe(transformStream);
|
|
69
|
+
},
|
|
71
70
|
});
|
|
72
|
-
return rendered;
|
|
73
71
|
};
|
|
74
72
|
//# sourceMappingURL=render.mjs.map
|
package/dist/render.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.mjs","sourceRoot":"","sources":["../src/render.mts"],"names":[],"mappings":"AACA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"render.mjs","sourceRoot":"","sources":["../src/render.mts"],"names":[],"mappings":"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"}
|
package/dist/server.mjs
CHANGED
|
@@ -4,18 +4,12 @@ import http from "node:http";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import { serializeError } from "./errors.js";
|
|
6
6
|
import { render } from "./render.mjs";
|
|
7
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
8
7
|
const socketPath = path.join(os.tmpdir(), `reactivated.${process.pid}.sock`);
|
|
9
|
-
const base = process.env.BASE || "/";
|
|
10
|
-
const escapedBase = base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11
|
-
const reactivatedEndpoint = "/_reactivated/".replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12
8
|
const app = express();
|
|
13
9
|
app.use(express.json({ limit: "200mb" }));
|
|
14
10
|
app.use("/_reactivated/", async (req, res) => {
|
|
15
|
-
const { context, props } = req.body;
|
|
16
11
|
try {
|
|
17
|
-
|
|
18
|
-
res.status(200).set({ "Content-Type": "text/html" }).end(rendered);
|
|
12
|
+
render(req, res, "", "production", "index");
|
|
19
13
|
}
|
|
20
14
|
catch (error) {
|
|
21
15
|
const errResp = {
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","sourceRoot":"","sources":["../src/server.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.mjs","sourceRoot":"","sources":["../src/server.mts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAmB,cAAc,EAAC,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAE7E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC,CAAC;AACxC,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACzC,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,OAAO,GAAqB;YAC9B,KAAK,EAAE,cAAc,CAAC,KAAY,CAAC;SACtC,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,UAAU,YAAY,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,MAAM,CAAC,KAAK,EAAE,CAAC;AACnB,CAAC,CAAC,CAAC"}
|
package/dist/vite.mjs
CHANGED
|
@@ -50,12 +50,7 @@ const rendererConfig = {
|
|
|
50
50
|
vanillaExtractPlugin(),
|
|
51
51
|
cjsInterop({
|
|
52
52
|
// List of CJS dependencies that require interop
|
|
53
|
-
dependencies: [
|
|
54
|
-
"react-syntax-highlighter",
|
|
55
|
-
"lz-string",
|
|
56
|
-
"react-use",
|
|
57
|
-
"react-helmet-async",
|
|
58
|
-
],
|
|
53
|
+
dependencies: ["react-syntax-highlighter", "lz-string", "react-use"],
|
|
59
54
|
}),
|
|
60
55
|
],
|
|
61
56
|
resolve: {
|
|
@@ -79,8 +74,7 @@ app.use("/_reactivated/", async (req, res) => {
|
|
|
79
74
|
// manage.py build step necessary. So we ensure vite head always points
|
|
80
75
|
// to the per-request STATIC_URL.
|
|
81
76
|
const viteHead = (await vite.transformIndexHtml(url, "")).replaceAll(base, `${context.STATIC_URL}dist/`);
|
|
82
|
-
|
|
83
|
-
res.status(200).set({ "Content-Type": "text/html" }).end(rendered);
|
|
77
|
+
render(req, res, viteHead, "development", "index", vite.ssrFixStacktrace);
|
|
84
78
|
}
|
|
85
79
|
catch (error) {
|
|
86
80
|
vite.ssrFixStacktrace(error);
|
package/dist/vite.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.mjs","sourceRoot":"","sources":["../src/vite.mts"],"names":[],"mappings":";AAEA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,sBAAsB,CAAC;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAmB,cAAc,EAAC,MAAM,aAAa,CAAC;AAI7D,aAAa;AACb,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAC,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAElE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,CAAC;AACvD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;AACrC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAChE,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAEpF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,qDAAqD;AACrD,6DAA6D;AAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACjC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AACH,MAAM,EAAC,YAAY,EAAC,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;AAE5C,MAAM,cAAc,GAAiB;IACjC,WAAW,EAAE,KAAK;IAClB;;;;;;;MAOE;IACF,MAAM,EAAE;QACJ,cAAc,EAAE,IAAI;QACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,GAAG,CAAC;QAC5D,KAAK,EAAE;YACH,CAAC,OAAO,WAAW,IAAI,mBAAmB,KAAK,CAAC,EAAE;gBAC9C,MAAM,EAAE,oBAAoB,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG;aACrE;SACJ;QACD,GAAG,EAAE;YACD,MAAM;SACT;QACD,KAAK,EAAE;YACH,OAAO,EAAE,CAAC,aAAa,EAAE,iBAAiB,CAAC;SAC9C;KACJ;IACD,MAAM,EAAE,MAAM,EAAE;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE;QACL,KAAK,EAAE;QACP,oBAAoB,EAAE;QACtB,UAAU,CAAC;YACP,gDAAgD;YAChD,YAAY,EAAE
|
|
1
|
+
{"version":3,"file":"vite.mjs","sourceRoot":"","sources":["../src/vite.mts"],"names":[],"mappings":";AAEA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,sBAAsB,CAAC;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAmB,cAAc,EAAC,MAAM,aAAa,CAAC;AAI7D,aAAa;AACb,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAC,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAElE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,CAAC;AACvD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;AACrC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAChE,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAEpF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,qDAAqD;AACrD,6DAA6D;AAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACjC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AACH,MAAM,EAAC,YAAY,EAAC,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;AAE5C,MAAM,cAAc,GAAiB;IACjC,WAAW,EAAE,KAAK;IAClB;;;;;;;MAOE;IACF,MAAM,EAAE;QACJ,cAAc,EAAE,IAAI;QACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,GAAG,CAAC;QAC5D,KAAK,EAAE;YACH,CAAC,OAAO,WAAW,IAAI,mBAAmB,KAAK,CAAC,EAAE;gBAC9C,MAAM,EAAE,oBAAoB,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG;aACrE;SACJ;QACD,GAAG,EAAE;YACD,MAAM;SACT;QACD,KAAK,EAAE;YACH,OAAO,EAAE,CAAC,aAAa,EAAE,iBAAiB,CAAC;SAC9C;KACJ;IACD,MAAM,EAAE,MAAM,EAAE;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE;QACL,KAAK,EAAE;QACP,oBAAoB,EAAE;QACtB,UAAU,CAAC;YACP,gDAAgD;YAChD,YAAY,EAAE,CAAC,0BAA0B,EAAE,WAAW,EAAE,WAAW,CAAC;SACvE,CAAC;KACL;IACD,OAAO,EAAE;QACL,KAAK,EAAE;YACH,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;YAClD,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,6BAA6B,CAAC;SAC7E;KACJ;IACD,IAAI;CACP,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,CAAC;AAEvD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1B,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC,CAAC;AAExC,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACzC,MAAM,EAAC,OAAO,EAAE,KAAK,EAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IAElC,IAAI,CAAC;QACD,MAAM,EAAC,MAAM,EAAC,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,6BAA6B,CAAC,CAExE,CAAC;QAEF,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QACjC,oEAAoE;QACpE,uEAAuE;QACvE,uEAAuE;QACvE,iCAAiC;QACjC,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAChE,IAAI,EACJ,GAAG,OAAO,CAAC,UAAU,OAAO,CAC/B,CAAC;QACF,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,KAAY,CAAC,CAAC;QACpC,MAAM,OAAO,GAAqB;YAC9B,KAAK,EAAE,cAAc,CAAC,KAAY,CAAC;SACtC,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactivated",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./dist/context": "./dist/context.js",
|
|
11
11
|
"./dist/conf": "./dist/conf.js",
|
|
12
12
|
"./dist/vite.mjs": "./dist/vite.mjs",
|
|
13
|
+
"./dist/shell": "./dist/shell.js",
|
|
13
14
|
"./dist/render.mjs": "./dist/render.mjs",
|
|
14
15
|
"./dist/server.mjs": "./dist/server.mjs",
|
|
15
16
|
"./dist/rpc": "./dist/rpc.js"
|
|
@@ -30,13 +31,13 @@
|
|
|
30
31
|
},
|
|
31
32
|
"license": "ISC",
|
|
32
33
|
"peerDependencies": {
|
|
33
|
-
"@eslint/js": "^9.
|
|
34
|
+
"@eslint/js": "^9.18.0",
|
|
34
35
|
"@types/eslint__eslintrc": "^2.1.2",
|
|
35
36
|
"@types/eslint__js": "^8.42.3",
|
|
36
37
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
37
38
|
"@types/express": "^5.0.0",
|
|
38
|
-
"@types/react": "^
|
|
39
|
-
"@types/react-dom": "^
|
|
39
|
+
"@types/react": "^19.0.2",
|
|
40
|
+
"@types/react-dom": "^19.0.2",
|
|
40
41
|
"@vanilla-extract/css": "^1.16.0",
|
|
41
42
|
"@vanilla-extract/css-utils": "^0.1.4",
|
|
42
43
|
"@vanilla-extract/dynamic": "^2.1.2",
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"@vanilla-extract/sprinkles": "^1.6.3",
|
|
46
47
|
"@vanilla-extract/vite-plugin": "3.9.5",
|
|
47
48
|
"@vitejs/plugin-react": "^4.3.3",
|
|
48
|
-
"eslint": "^9.
|
|
49
|
+
"eslint": "^9.18.0",
|
|
49
50
|
"eslint-config-prettier": "^9.1.0",
|
|
50
51
|
"eslint-import-resolver-typescript": "^3.6.3",
|
|
51
52
|
"eslint-plugin-import": "^2.31.0",
|
|
@@ -57,13 +58,12 @@
|
|
|
57
58
|
"jiti": "^2.4.1",
|
|
58
59
|
"json-schema-to-typescript": "^15.0.2",
|
|
59
60
|
"prettier": "^3.3.3",
|
|
60
|
-
"react": "^
|
|
61
|
-
"react-dom": "^
|
|
62
|
-
"react-helmet-async": "^2.0.5",
|
|
61
|
+
"react": "^19.0.0",
|
|
62
|
+
"react-dom": "^19.0.0",
|
|
63
63
|
"terser": "^5.36.0",
|
|
64
64
|
"ts-morph": "^24.0.0",
|
|
65
65
|
"typescript": "^5.6.3",
|
|
66
|
-
"typescript-eslint": "^8.
|
|
66
|
+
"typescript-eslint": "^8.20.0",
|
|
67
67
|
"vite": "5.1.4",
|
|
68
68
|
"vite-plugin-cjs-interop": "2.0.6"
|
|
69
69
|
}
|
package/src/client.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import {hydrateRoot} from "react-dom/client";
|
|
1
2
|
import React from "react";
|
|
2
|
-
import {hydrate} from "react-dom";
|
|
3
3
|
|
|
4
4
|
const props = (window as any).__PRELOADED_STATE__;
|
|
5
5
|
|
|
@@ -11,5 +11,10 @@ if ((module as any).hot) {
|
|
|
11
11
|
const Template = require("client/templates/" + props.template_name + ".tsx").default;
|
|
12
12
|
|
|
13
13
|
export const bootstrap = () => {
|
|
14
|
-
|
|
14
|
+
const root = document.getElementById("root");
|
|
15
|
+
if (!root) {
|
|
16
|
+
console.error("div#root is missing!");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
hydrateRoot(root, <Template {...props} />);
|
|
15
20
|
};
|
package/src/render.mts
CHANGED
|
@@ -1,83 +1,16 @@
|
|
|
1
1
|
import {Request} from "express";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import React, {type JSX} from "react";
|
|
3
|
+
import {Response} from "express";
|
|
4
|
+
import ReactDOMServer from "react-dom/server";
|
|
5
|
+
import {renderToPipeableStream} from "react-dom/server";
|
|
6
|
+
import {Transform} from "node:stream";
|
|
5
7
|
|
|
8
|
+
import {SSRErrorResponse, serializeError} from "./errors.js";
|
|
6
9
|
// @ts-ignore
|
|
7
10
|
import {Provider} from "@reactivated";
|
|
8
11
|
// @ts-ignore
|
|
9
12
|
import {getTemplate} from "@reactivated/template";
|
|
10
13
|
|
|
11
|
-
export const renderPage = ({
|
|
12
|
-
html,
|
|
13
|
-
vite,
|
|
14
|
-
helmet,
|
|
15
|
-
context,
|
|
16
|
-
props,
|
|
17
|
-
mode,
|
|
18
|
-
entryPoint,
|
|
19
|
-
}: {
|
|
20
|
-
html: string;
|
|
21
|
-
vite: string;
|
|
22
|
-
helmet: HelmetServerState;
|
|
23
|
-
context: any;
|
|
24
|
-
props: any;
|
|
25
|
-
mode: "production" | "development";
|
|
26
|
-
entryPoint: string;
|
|
27
|
-
}) => {
|
|
28
|
-
const scriptNonce = context.request.csp_nonce
|
|
29
|
-
? `nonce="${context.request.csp_nonce}"`
|
|
30
|
-
: "";
|
|
31
|
-
const {STATIC_URL} = context;
|
|
32
|
-
|
|
33
|
-
if (STATIC_URL == null) {
|
|
34
|
-
console.error("Ensure your context processor includes STATIC_URL");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const css =
|
|
38
|
-
mode == "production"
|
|
39
|
-
? `<link rel="stylesheet" type="text/css" href="${STATIC_URL}dist/${entryPoint}.css">`
|
|
40
|
-
: "";
|
|
41
|
-
const js =
|
|
42
|
-
mode == "production"
|
|
43
|
-
? `<script type="module" src="${STATIC_URL}dist/${entryPoint}.js" defer crossOrigin="anonymous"></script>`
|
|
44
|
-
: `<script type="module" src="${STATIC_URL}dist/client/${entryPoint}.tsx"></script>`;
|
|
45
|
-
|
|
46
|
-
return `
|
|
47
|
-
<!DOCTYPE html>
|
|
48
|
-
<html ${helmet.htmlAttributes.toString()}>
|
|
49
|
-
<head>
|
|
50
|
-
${vite}
|
|
51
|
-
<script ${scriptNonce}>
|
|
52
|
-
// These go first because scripts below need them.
|
|
53
|
-
// WARNING: See the following for security issues around embedding JSON in HTML:
|
|
54
|
-
// http://redux.js.org/recipes/ServerRendering.html#security-considerations
|
|
55
|
-
window.__PRELOADED_PROPS__ = ${JSON.stringify(props).replace(
|
|
56
|
-
/</g,
|
|
57
|
-
"\\u003c",
|
|
58
|
-
)}
|
|
59
|
-
window.__PRELOADED_CONTEXT__ = ${JSON.stringify(context).replace(
|
|
60
|
-
/</g,
|
|
61
|
-
"\\u003c",
|
|
62
|
-
)}
|
|
63
|
-
</script>
|
|
64
|
-
${css}
|
|
65
|
-
|
|
66
|
-
${helmet.base.toString()}
|
|
67
|
-
${helmet.link.toString()}
|
|
68
|
-
${helmet.meta.toString()}
|
|
69
|
-
${helmet.noscript.toString()}
|
|
70
|
-
${helmet.script.toString()}
|
|
71
|
-
${helmet.style.toString()}
|
|
72
|
-
${helmet.title.toString()}
|
|
73
|
-
</head>
|
|
74
|
-
<body ${helmet.bodyAttributes.toString()}>
|
|
75
|
-
<div id="root">${html}</div>
|
|
76
|
-
${js}
|
|
77
|
-
</body>
|
|
78
|
-
</html>`;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
14
|
export type Renderer<T = unknown> = (
|
|
82
15
|
content: JSX.Element,
|
|
83
16
|
req: {
|
|
@@ -88,11 +21,17 @@ export type Renderer<T = unknown> = (
|
|
|
88
21
|
|
|
89
22
|
const defaultRenderer: Renderer = (content) => Promise.resolve(content);
|
|
90
23
|
|
|
24
|
+
function serJSON(data: unknown): string {
|
|
25
|
+
return JSON.stringify(data).replace(/</g, "\\u003c");
|
|
26
|
+
}
|
|
27
|
+
|
|
91
28
|
export const render = async (
|
|
92
29
|
req: Request,
|
|
30
|
+
res: Response,
|
|
93
31
|
vite: string,
|
|
94
32
|
mode: "production" | "development",
|
|
95
33
|
entryPoint: string,
|
|
34
|
+
ssrFixStacktrace?: (error: Error) => void,
|
|
96
35
|
) => {
|
|
97
36
|
// @ts-ignore
|
|
98
37
|
const customConfiguration: {default?: Renderer} | null = import.meta.glob(
|
|
@@ -102,39 +41,77 @@ export const render = async (
|
|
|
102
41
|
|
|
103
42
|
const {context, props} = req.body;
|
|
104
43
|
const Template = await getTemplate(context);
|
|
105
|
-
const
|
|
44
|
+
const scriptNonce = context.request.csp_nonce ?? undefined;
|
|
45
|
+
|
|
46
|
+
const {STATIC_URL} = context;
|
|
47
|
+
|
|
48
|
+
if (STATIC_URL == null) {
|
|
49
|
+
console.error("Ensure your context processor includes STATIC_URL");
|
|
50
|
+
}
|
|
51
|
+
const css =
|
|
52
|
+
mode == "production"
|
|
53
|
+
? `<link rel="stylesheet" type="text/css" href="${STATIC_URL}dist/${entryPoint}.css">`
|
|
54
|
+
: "";
|
|
55
|
+
const js =
|
|
56
|
+
mode == "production"
|
|
57
|
+
? `<script type="module" src="${STATIC_URL}dist/${entryPoint}.js" defer crossOrigin="anonymous"></script>`
|
|
58
|
+
: `<script type="module" src="${STATIC_URL}dist/client/${entryPoint}.tsx"></script>`;
|
|
106
59
|
|
|
107
60
|
const content = React.createElement(
|
|
108
61
|
React.StrictMode,
|
|
109
62
|
{},
|
|
110
63
|
React.createElement(
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
React.createElement(
|
|
114
|
-
Provider,
|
|
115
|
-
{value: context},
|
|
116
|
-
React.createElement(Template, props),
|
|
117
|
-
),
|
|
64
|
+
Provider,
|
|
65
|
+
{value: context},
|
|
66
|
+
React.createElement(Template, props),
|
|
118
67
|
),
|
|
119
68
|
);
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
let hasError = false;
|
|
71
|
+
|
|
72
|
+
const {pipe} = renderToPipeableStream(
|
|
122
73
|
await (customConfiguration?.default ?? defaultRenderer)(content, {
|
|
123
74
|
context,
|
|
124
75
|
props,
|
|
125
76
|
}),
|
|
126
|
-
);
|
|
127
|
-
const {helmet} = helmetContext;
|
|
128
77
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
78
|
+
{
|
|
79
|
+
nonce: scriptNonce,
|
|
80
|
+
bootstrapScriptContent: `
|
|
81
|
+
window.__PRELOADED_PROPS__ = ${serJSON(props)};
|
|
82
|
+
window.__PRELOADED_CONTEXT__ = ${serJSON(context)};
|
|
83
|
+
`,
|
|
84
|
+
onError(error) {
|
|
85
|
+
hasError = true;
|
|
86
|
+
if (ssrFixStacktrace) {
|
|
87
|
+
console.log("fixing stacktrace");
|
|
88
|
+
ssrFixStacktrace(error as any);
|
|
89
|
+
}
|
|
90
|
+
const errResp: SSRErrorResponse = {
|
|
91
|
+
error: serializeError(error as any),
|
|
92
|
+
};
|
|
93
|
+
res.status(500).json(errResp);
|
|
94
|
+
},
|
|
95
|
+
onAllReady() {
|
|
96
|
+
if (hasError) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
res.status(200);
|
|
100
|
+
// Seems like the renderer.py, at least for unix socket, requires a charset
|
|
101
|
+
// unlike the React docs
|
|
102
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
103
|
+
const transformStream = new Transform({
|
|
104
|
+
transform(chunk, encoding, callback) {
|
|
105
|
+
res.write(chunk, encoding);
|
|
106
|
+
callback();
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
transformStream.on("finish", () => {
|
|
110
|
+
res.end(vite + css + js);
|
|
111
|
+
});
|
|
138
112
|
|
|
139
|
-
|
|
113
|
+
pipe(transformStream);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
);
|
|
140
117
|
};
|
package/src/server.mts
CHANGED
|
@@ -1,34 +1,18 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import express from "express";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import http from "node:http";
|
|
5
4
|
import os from "node:os";
|
|
6
|
-
import react from "@vitejs/plugin-react";
|
|
7
|
-
import ReactDOMServer from "react-dom/server";
|
|
8
5
|
import {SSRErrorResponse, serializeError} from "./errors.js";
|
|
9
6
|
import {render} from "./render.mjs";
|
|
10
7
|
|
|
11
|
-
import {Helmet, HelmetProvider, HelmetServerState} from "react-helmet-async";
|
|
12
|
-
import {vanillaExtractPlugin} from "@vanilla-extract/vite-plugin";
|
|
13
|
-
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
import {Provider, getTemplate} from "@reactivated";
|
|
16
|
-
|
|
17
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
18
8
|
const socketPath = path.join(os.tmpdir(), `reactivated.${process.pid}.sock`);
|
|
19
|
-
const base = process.env.BASE || "/";
|
|
20
|
-
const escapedBase = base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
-
const reactivatedEndpoint = "/_reactivated/".replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
22
9
|
|
|
23
10
|
const app = express();
|
|
24
11
|
|
|
25
12
|
app.use(express.json({limit: "200mb"}));
|
|
26
13
|
app.use("/_reactivated/", async (req, res) => {
|
|
27
|
-
const {context, props} = req.body;
|
|
28
|
-
|
|
29
14
|
try {
|
|
30
|
-
|
|
31
|
-
res.status(200).set({"Content-Type": "text/html"}).end(rendered);
|
|
15
|
+
render(req, res, "", "production", "index");
|
|
32
16
|
} catch (error) {
|
|
33
17
|
const errResp: SSRErrorResponse = {
|
|
34
18
|
error: serializeError(error as any),
|
package/src/vite.mts
CHANGED
|
@@ -59,12 +59,7 @@ const rendererConfig: InlineConfig = {
|
|
|
59
59
|
vanillaExtractPlugin(),
|
|
60
60
|
cjsInterop({
|
|
61
61
|
// List of CJS dependencies that require interop
|
|
62
|
-
dependencies: [
|
|
63
|
-
"react-syntax-highlighter",
|
|
64
|
-
"lz-string",
|
|
65
|
-
"react-use",
|
|
66
|
-
"react-helmet-async",
|
|
67
|
-
],
|
|
62
|
+
dependencies: ["react-syntax-highlighter", "lz-string", "react-use"],
|
|
68
63
|
}),
|
|
69
64
|
],
|
|
70
65
|
resolve: {
|
|
@@ -98,9 +93,7 @@ app.use("/_reactivated/", async (req, res) => {
|
|
|
98
93
|
base,
|
|
99
94
|
`${context.STATIC_URL}dist/`,
|
|
100
95
|
);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
res.status(200).set({"Content-Type": "text/html"}).end(rendered);
|
|
96
|
+
render(req, res, viteHead, "development", "index", vite.ssrFixStacktrace);
|
|
104
97
|
} catch (error) {
|
|
105
98
|
vite.ssrFixStacktrace(error as any);
|
|
106
99
|
const errResp: SSRErrorResponse = {
|