reactivated 0.45.2 → 0.45.3-a2767

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 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
- hydrate(React.createElement(Template, { ...props }), document.getElementById("root"));
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
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,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,OAAO,CAAC,oBAAC,QAAQ,OAAK,KAAK,GAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC"}
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,14 +1,5 @@
1
1
  import { Request } from "express";
2
- import { HelmetServerState } from "react-helmet-async";
3
- export declare const renderPage: ({ html, vite, helmet, context, props, mode, entryPoint, }: {
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";
12
3
  export type Renderer<T = unknown> = (content: JSX.Element, req: {
13
4
  context: T;
14
5
  props: unknown;
package/dist/render.mjs CHANGED
@@ -1,74 +1,29 @@
1
- import { HelmetProvider } from "react-helmet-async";
2
- import * as React from "react";
3
- import * as ReactDOMServer from "react-dom/server";
1
+ import React from "react";
2
+ import ReactDOMServer from "react-dom/server";
4
3
  // @ts-ignore
5
4
  import { Provider } from "@reactivated";
6
5
  // @ts-ignore
7
6
  import { getTemplate } from "@reactivated/template";
8
- export const renderPage = ({ html, vite, helmet, context, props, mode, entryPoint, }) => {
9
- const scriptNonce = context.request.csp_nonce
10
- ? `nonce="${context.request.csp_nonce}"`
11
- : "";
12
- const { STATIC_URL } = context;
13
- if (STATIC_URL == null) {
14
- console.error("Ensure your context processor includes STATIC_URL");
15
- }
16
- const css = mode == "production"
17
- ? `<link rel="stylesheet" type="text/css" href="${STATIC_URL}dist/${entryPoint}.css">`
18
- : "";
19
- const js = mode == "production"
20
- ? `<script type="module" src="${STATIC_URL}dist/${entryPoint}.js" defer crossOrigin="anonymous"></script>`
21
- : `<script type="module" src="${STATIC_URL}dist/client/${entryPoint}.tsx"></script>`;
22
- return `
23
- <!DOCTYPE html>
24
- <html ${helmet.htmlAttributes.toString()}>
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
- };
7
+ import { PageShell } from "./shell";
50
8
  const defaultRenderer = (content) => Promise.resolve(content);
51
9
  export const render = async (req, vite, mode, entryPoint) => {
52
10
  // @ts-ignore
53
11
  const customConfiguration = import.meta.glob("@client/renderer.tsx", { eager: true })["/client/renderer.tsx"];
54
12
  const { context, props } = req.body;
55
13
  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))));
14
+ const content = React.createElement(React.StrictMode, {}, React.createElement(PageShell, {
15
+ vite: vite,
16
+ mode: mode,
17
+ preloadContext: context,
18
+ preloadProps: props,
19
+ entryPoint: entryPoint,
20
+ }, React.createElement(Provider, {
21
+ value: context,
22
+ }, React.createElement(Template, props))));
58
23
  const html = ReactDOMServer.renderToString(await (customConfiguration?.default ?? defaultRenderer)(content, {
59
24
  context,
60
25
  props,
61
26
  }));
62
- const { helmet } = helmetContext;
63
- const rendered = renderPage({
64
- html,
65
- vite,
66
- helmet,
67
- props,
68
- context,
69
- mode,
70
- entryPoint,
71
- });
72
- return rendered;
27
+ return `<!DOCTYPE html>\n${html}`;
73
28
  };
74
29
  //# sourceMappingURL=render.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.mjs","sourceRoot":"","sources":["../src/render.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.mjs","sourceRoot":"","sources":["../src/render.mts"],"names":[],"mappings":"AACA,OAAO,KAAiB,MAAM,OAAO,CAAC;AACtC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,aAAa;AACb,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AACtC,aAAa;AACb,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAUlC,MAAM,eAAe,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EACvB,GAAY,EACZ,IAAY,EACZ,IAAkC,EAClC,UAAkB,EACpB,EAAE;IACA,aAAa;IACb,MAAM,mBAAmB,GAAgC,MAAM,CAAC,IAAI,CAAC,IAAI,CACrE,sBAAsB,EACtB,EAAC,KAAK,EAAE,IAAI,EAAC,CAChB,CAAC,sBAAsB,CAAC,CAAC;IAE1B,MAAM,EAAC,OAAO,EAAE,KAAK,EAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAC/B,KAAK,CAAC,UAAU,EAChB,EAAE,EACF,KAAK,CAAC,aAAa,CACf,SAAS,EACT;QACI,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,cAAc,EAAE,OAAO;QACvB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,UAAU;KACzB,EACD,KAAK,CAAC,aAAa,CACf,QAAQ,EACR;QACI,KAAK,EAAE,OAAO;KACjB,EACD,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,CACvC,CACJ,CACJ,CAAC;IAEF,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,CACtC,MAAM,CAAC,mBAAmB,EAAE,OAAO,IAAI,eAAe,CAAC,CAAC,OAAO,EAAE;QAC7D,OAAO;QACP,KAAK;KACR,CAAC,CACL,CAAC;IACF,OAAO,oBAAoB,IAAI,EAAE,CAAC;AACtC,CAAC,CAAC"}
package/dist/server.mjs CHANGED
@@ -4,15 +4,10 @@ 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
12
  const rendered = await render(req, "", "production", "index");
18
13
  res.status(200).set({ "Content-Type": "text/html" }).end(rendered);
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","sourceRoot":"","sources":["../src/server.mts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,OAAO,EAAmB,cAAc,EAAC,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAQpC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;AAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAC7E,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,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,MAAM,EAAC,OAAO,EAAE,KAAK,EAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IAElC,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAC,cAAc,EAAE,WAAW,EAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrE,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"}
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,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAC,cAAc,EAAE,WAAW,EAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrE,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"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export declare const PageShell: (props: React.PropsWithChildren<{
3
+ vite: string;
4
+ mode: "production" | "development";
5
+ preloadContext: any;
6
+ preloadProps: any;
7
+ entryPoint: string;
8
+ }>) => React.JSX.Element;
package/dist/shell.js ADDED
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ const serJSON = (data) => {
3
+ return JSON.stringify(data).replace(/</g, "\\u003c");
4
+ };
5
+ export const PageShell = (props) => {
6
+ const scriptNonce = props.preloadContext.request.csp_nonce
7
+ ? `nonce="${props.preloadContext.request.csp_nonce}"`
8
+ : "";
9
+ const { STATIC_URL } = props.preloadContext;
10
+ if (STATIC_URL == null) {
11
+ console.error("Ensure your context processor includes STATIC_URL");
12
+ }
13
+ const headHTML = `
14
+ ${props.vite}
15
+ <script ${scriptNonce}>
16
+ // These go first because scripts below need them.
17
+ // WARNING: See the following for security issues around embedding JSON in HTML:
18
+ // http://redux.js.org/recipes/ServerRendering.html#security-considerations
19
+ window.__PRELOADED_PROPS__ = ${serJSON(props.preloadProps)};
20
+ window.__PRELOADED_CONTEXT__ = ${serJSON(props.preloadContext)};
21
+ </script>
22
+ ${props.mode == "production"
23
+ ? `<link rel="stylesheet" type="text/css" href="${STATIC_URL}dist/${props.entryPoint}.css">`
24
+ : ""}
25
+ `.trim();
26
+ return (React.createElement("html", null,
27
+ React.createElement("head", { dangerouslySetInnerHTML: { __html: headHTML } }),
28
+ React.createElement("body", null,
29
+ React.createElement("div", { id: "root" }, props.children),
30
+ props.mode == "production" ? (React.createElement("script", { type: "module", src: `${STATIC_URL}dist/${props.entryPoint}.js`, defer: true, crossOrigin: "anonymous" })) : (React.createElement("script", { type: "module", src: `${STATIC_URL}dist/client/${props.entryPoint}.tsx` })))));
31
+ };
32
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,OAAO,GAAG,CAAC,IAAS,EAAU,EAAE;IAClC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACrB,KAME,EACJ,EAAE;IACA,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS;QACtD,CAAC,CAAC,UAAU,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,GAAG;QACrD,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,EAAC,UAAU,EAAC,GAAG,KAAK,CAAC,cAAc,CAAC;IAC1C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,QAAQ,GAAG;UACX,KAAK,CAAC,IAAI;kBACF,WAAW;;;;2CAIc,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;6CACzB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC;;UAG9D,KAAK,CAAC,IAAI,IAAI,YAAY;QACtB,CAAC,CAAC,gDAAgD,UAAU,QAAQ,KAAK,CAAC,UAAU,QAAQ;QAC5F,CAAC,CAAC,EACV;KACH,CAAC,IAAI,EAAE,CAAC;IACT,OAAO,CACH;QACI,8BAAM,uBAAuB,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAI;QACrD;YACI,6BAAK,EAAE,EAAC,MAAM,IAAE,KAAK,CAAC,QAAQ,CAAO;YACpC,KAAK,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,CAC1B,gCACI,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,GAAG,UAAU,QAAQ,KAAK,CAAC,UAAU,KAAK,EAC/C,KAAK,QACL,WAAW,EAAC,WAAW,GACjB,CACb,CAAC,CAAC,CAAC,CACA,gCACI,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,GAAG,UAAU,eAAe,KAAK,CAAC,UAAU,MAAM,GACjD,CACb,CACE,CACJ,CACV,CAAC;AACN,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: {
@@ -76,9 +71,9 @@ app.use("/_reactivated/", async (req, res) => {
76
71
  const url = context.request.path;
77
72
  // For E2E tests, we may want to run them pointing to a running vite
78
73
  // instance for a quick feedback loop. Intead of the traditional python
79
- // manage.py build step necessary. So we ensure vite head always
80
- // points to the per-request STATIC_URL.
81
- const viteHead = (await vite.transformIndexHtml(url, "")).replace(base, `${context.STATIC_URL}dist/`);
74
+ // manage.py build step necessary. So we ensure vite head always points
75
+ // to the per-request STATIC_URL.
76
+ const viteHead = (await vite.transformIndexHtml(url, "")).replaceAll(base, `${context.STATIC_URL}dist/`);
82
77
  const rendered = await render(req, viteHead, "development", "index");
83
78
  res.status(200).set({ "Content-Type": "text/html" }).end(rendered);
84
79
  }
package/dist/vite.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.mjs","sourceRoot":"","sources":["../src/vite.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vite.mjs","sourceRoot":"","sources":["../src/vite.mts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactivated",
3
- "version": "0.45.2",
3
+ "version": "0.45.3-a2767",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {
@@ -35,8 +35,8 @@
35
35
  "@types/eslint__js": "^8.42.3",
36
36
  "@types/eslint-config-prettier": "^6.11.3",
37
37
  "@types/express": "^5.0.0",
38
- "@types/react": "^18.3.12",
39
- "@types/react-dom": "^18.3.1",
38
+ "@types/react": "^19.0.2",
39
+ "@types/react-dom": "^19.0.2",
40
40
  "@vanilla-extract/css": "^1.16.0",
41
41
  "@vanilla-extract/css-utils": "^0.1.4",
42
42
  "@vanilla-extract/dynamic": "^2.1.2",
@@ -57,9 +57,8 @@
57
57
  "jiti": "^2.4.1",
58
58
  "json-schema-to-typescript": "^15.0.2",
59
59
  "prettier": "^3.3.3",
60
- "react": "^18.3.1",
61
- "react-dom": "^18.3.1",
62
- "react-helmet-async": "^2.0.5",
60
+ "react": "^19.0.0",
61
+ "react-dom": "^19.0.0",
63
62
  "terser": "^5.36.0",
64
63
  "ts-morph": "^24.0.0",
65
64
  "typescript": "^5.6.3",
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
- hydrate(<Template {...props} />, document.getElementById("root"));
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,82 +1,13 @@
1
1
  import {Request} from "express";
2
- import {HelmetProvider, HelmetServerState} from "react-helmet-async";
3
- import * as React from "react";
4
- import * as ReactDOMServer from "react-dom/server";
2
+ import React, {type JSX} from "react";
3
+ import ReactDOMServer from "react-dom/server";
5
4
 
6
5
  // @ts-ignore
7
6
  import {Provider} from "@reactivated";
8
7
  // @ts-ignore
9
8
  import {getTemplate} from "@reactivated/template";
10
9
 
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
- };
10
+ import {PageShell} from "./shell";
80
11
 
81
12
  export type Renderer<T = unknown> = (
82
13
  content: JSX.Element,
@@ -102,17 +33,24 @@ export const render = async (
102
33
 
103
34
  const {context, props} = req.body;
104
35
  const Template = await getTemplate(context);
105
- const helmetContext = {} as {helmet: HelmetServerState};
106
36
 
107
37
  const content = React.createElement(
108
38
  React.StrictMode,
109
39
  {},
110
40
  React.createElement(
111
- HelmetProvider,
112
- {context: helmetContext},
41
+ PageShell,
42
+ {
43
+ vite: vite,
44
+ mode: mode,
45
+ preloadContext: context,
46
+ preloadProps: props,
47
+ entryPoint: entryPoint,
48
+ },
113
49
  React.createElement(
114
50
  Provider,
115
- {value: context},
51
+ {
52
+ value: context,
53
+ },
116
54
  React.createElement(Template, props),
117
55
  ),
118
56
  ),
@@ -124,17 +62,5 @@ export const render = async (
124
62
  props,
125
63
  }),
126
64
  );
127
- const {helmet} = helmetContext;
128
-
129
- const rendered = renderPage({
130
- html,
131
- vite,
132
- helmet,
133
- props,
134
- context,
135
- mode,
136
- entryPoint,
137
- });
138
-
139
- return rendered;
65
+ return `<!DOCTYPE html>\n${html}`;
140
66
  };
package/src/server.mts CHANGED
@@ -1,31 +1,16 @@
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
15
  const rendered = await render(req, "", "production", "index");
31
16
  res.status(200).set({"Content-Type": "text/html"}).end(rendered);
package/src/shell.tsx ADDED
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+
3
+ const serJSON = (data: any): string => {
4
+ return JSON.stringify(data).replace(/</g, "\\u003c");
5
+ };
6
+
7
+ export const PageShell = (
8
+ props: React.PropsWithChildren<{
9
+ vite: string;
10
+ mode: "production" | "development";
11
+ preloadContext: any;
12
+ preloadProps: any;
13
+ entryPoint: string;
14
+ }>,
15
+ ) => {
16
+ const scriptNonce = props.preloadContext.request.csp_nonce
17
+ ? `nonce="${props.preloadContext.request.csp_nonce}"`
18
+ : "";
19
+ const {STATIC_URL} = props.preloadContext;
20
+ if (STATIC_URL == null) {
21
+ console.error("Ensure your context processor includes STATIC_URL");
22
+ }
23
+ const headHTML = `
24
+ ${props.vite}
25
+ <script ${scriptNonce}>
26
+ // These go first because scripts below need them.
27
+ // WARNING: See the following for security issues around embedding JSON in HTML:
28
+ // http://redux.js.org/recipes/ServerRendering.html#security-considerations
29
+ window.__PRELOADED_PROPS__ = ${serJSON(props.preloadProps)};
30
+ window.__PRELOADED_CONTEXT__ = ${serJSON(props.preloadContext)};
31
+ </script>
32
+ ${
33
+ props.mode == "production"
34
+ ? `<link rel="stylesheet" type="text/css" href="${STATIC_URL}dist/${props.entryPoint}.css">`
35
+ : ""
36
+ }
37
+ `.trim();
38
+ return (
39
+ <html>
40
+ <head dangerouslySetInnerHTML={{__html: headHTML}} />
41
+ <body>
42
+ <div id="root">{props.children}</div>
43
+ {props.mode == "production" ? (
44
+ <script
45
+ type="module"
46
+ src={`${STATIC_URL}dist/${props.entryPoint}.js`}
47
+ defer
48
+ crossOrigin="anonymous"
49
+ ></script>
50
+ ) : (
51
+ <script
52
+ type="module"
53
+ src={`${STATIC_URL}dist/client/${props.entryPoint}.tsx`}
54
+ ></script>
55
+ )}
56
+ </body>
57
+ </html>
58
+ );
59
+ };
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: {
@@ -92,9 +87,9 @@ app.use("/_reactivated/", async (req, res) => {
92
87
  const url = context.request.path;
93
88
  // For E2E tests, we may want to run them pointing to a running vite
94
89
  // instance for a quick feedback loop. Intead of the traditional python
95
- // manage.py build step necessary. So we ensure vite head always
96
- // points to the per-request STATIC_URL.
97
- const viteHead = (await vite.transformIndexHtml(url, "")).replace(
90
+ // manage.py build step necessary. So we ensure vite head always points
91
+ // to the per-request STATIC_URL.
92
+ const viteHead = (await vite.transformIndexHtml(url, "")).replaceAll(
98
93
  base,
99
94
  `${context.STATIC_URL}dist/`,
100
95
  );
package/tsconfig.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "strict": true,
4
4
  "sourceMap": true,
5
5
  "module": "ES2022",
6
- "target": "ES2020",
6
+ "target": "ES2021",
7
7
  "moduleResolution": "node",
8
8
  "outDir": "dist",
9
9
  "esModuleInterop": true,