@webtypen/webframez-react 0.0.5 → 0.0.7

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.cjs CHANGED
@@ -1 +1 @@
1
- var k=Object.create;var d=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var T=(e,t)=>{for(var n in t)d(e,n,{get:t[n],enumerable:!0})},R=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of O(t))!L.call(e,r)&&r!==n&&d(e,r,{get:()=>t[r],enumerable:!(o=A(t,r))||o.enumerable});return e};var U=(e,t,n)=>(n=e!=null?k(S(e)):{},R(t||!e||!e.__esModule?d(n,"default",{value:e,enumerable:!0}):n,e)),M=e=>R(d({},"__esModule",{value:!0}),e);var D={};T(D,{mountWebframezClient:()=>F,useCookie:()=>B,useRouter:()=>H});module.exports=M(D);var s=U(require("react"),1),E=require("react-dom/client"),_=require("react-server-dom-webpack/client"),i=require("react/jsx-runtime"),$={push:()=>{},replace:()=>{},refresh:()=>{}},l=typeof s.default.createContext=="function"?s.default.createContext(null):null,b="__WEBFRAMEZ_ROUTER__",I="[data-webframez-head='true']";function P(){return typeof window>"u"?null:window[b]??null}function N(e){typeof window>"u"||(window[b]=e)}function h(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),u=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";u&&(e[u]=decodeURIComponent(c))}return e}function C(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function B(){return s.default.useMemo(()=>({all:()=>h(),get:e=>h()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=C(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=C(e,"",{...t??{},maxAge:0}))}}),[])}function H(){let e=l?s.default.useContext(l):null;if(!e){let t=P();if(t)return t;if(typeof window>"u")return $;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function v({active:e}){return(0,i.jsx)("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function y(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function x(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function W(e){if(!(typeof document>"u")){document.title=e.title||"Webframez React";for(let t of document.head.querySelectorAll(I))t.remove();e.description&&y({name:"description",content:e.description}),e.favicon&&x({rel:"icon",href:e.favicon});for(let t of e.meta??[])y(t);for(let t of e.links??[])x(t)}}function z(e){return function(){let[n,o]=(0,s.useState)(null),[r,u]=(0,s.useState)(!1);async function c(a,p="push"){u(!0);try{let g=await(0,_.createFromFetch)(fetch(`${e}?path=${encodeURIComponent(a.pathname)}&search=${encodeURIComponent(a.search)}`,{headers:{Accept:"text/x-component"}}));W(g.head),o(g.model);let w=`${a.pathname}${a.search}`;p==="replace"?history.replaceState(null,"",w):p==="push"&&history.pushState(null,"",w)}catch(m){console.error("[webframez-react] Failed to render route",m),o((0,i.jsx)("p",{children:"Failed to load route."}))}finally{u(!1)}}(0,s.useEffect)(()=>{let a=()=>{c(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),c(new URL(window.location.href),"none"),()=>{window.removeEventListener("popstate",a)}},[]);let f=s.default.useMemo(()=>({push:a=>{c(new URL(a,window.location.origin),"push")},replace:a=>{c(new URL(a,window.location.origin),"replace")},refresh:()=>{c(new URL(window.location.href),"none")}}),[]);return N(f),l?(0,i.jsxs)(l.Provider,{value:f,children:[(0,i.jsx)(v,{active:r}),n??(0,i.jsx)("p",{style:{padding:24},children:"Loading..."})]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(v,{active:r}),n??(0,i.jsx)("p",{style:{padding:24},children:"Loading..."})]})}}function F(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??o??"/rsc",u=z(r),c=(0,E.createRoot)(n);return c.render((0,i.jsx)(u,{})),c}
1
+ var P=Object.create;var f=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var $=(e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})},_=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of T(t))!U.call(e,i)&&i!==n&&f(e,i,{get:()=>t[i],enumerable:!(o=O(t,i))||o.enumerable});return e};var M=(e,t,n)=>(n=e!=null?P(N(e)):{},_(t||!e||!e.__esModule?f(n,"default",{value:e,enumerable:!0}):n,e)),H=e=>_(f({},"__esModule",{value:!0}),e);var X={};$(X,{mountWebframezClient:()=>j,useCookie:()=>z,useRouter:()=>G});module.exports=H(X);var r=M(require("react"),1),S=require("react-dom/client"),u=require("react-server-dom-webpack/client"),a=require("react/jsx-runtime"),W={push:()=>{},replace:()=>{},refresh:()=>{}},p=typeof r.default.createContext=="function"?r.default.createContext(null):null,k="__WEBFRAMEZ_ROUTER__",D="[data-webframez-head='true']";function F(){return typeof window>"u"?null:window[k]??null}function B(e){typeof window>"u"||(window[k]=e)}function v(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let i=o.indexOf("="),d=i>=0?o.slice(0,i).trim():o,c=i>=0?o.slice(i+1):"";d&&(e[d]=decodeURIComponent(c))}return e}function A(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function z(){return r.default.useMemo(()=>({all:()=>v(),get:e=>v()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=A(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=A(e,"",{...t??{},maxAge:0}))}}),[])}function G(){let e=p?r.default.useContext(p):null;if(!e){let t=F();if(t)return t;if(typeof window>"u")return W;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function x({active:e}){return(0,a.jsx)("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function E(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function b(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function I(e){if(!(typeof document>"u")){document.title=e.title||"Webframez React";for(let t of document.head.querySelectorAll(D))t.remove();e.description&&E({name:"description",content:e.description}),e.favicon&&b({rel:"icon",href:e.favicon});for(let t of e.meta??[])E(t);for(let t of e.links??[])b(t)}}function Y(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function q(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,u.createFromReadableStream)(Y(e)))}function Z(e){return function(){let[n]=(0,r.useState)(()=>q()??(0,u.createFromFetch)(fetch(`${e}?path=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))),o=r.default.use(n),[i,d]=(0,r.useState)(o.model),[c,L]=(0,r.useState)(o.head),[g,w]=(0,r.useState)(!1);async function l(s,h="push"){w(!0);try{let m=await(0,u.createFromFetch)(fetch(`${e}?path=${encodeURIComponent(s.pathname)}&search=${encodeURIComponent(s.search)}`,{headers:{Accept:"text/x-component"}}));I(m.head),L(m.head),d(m.model);let y=`${s.pathname}${s.search}`;h==="replace"?history.replaceState(null,"",y):h==="push"&&history.pushState(null,"",y)}catch(C){console.error("[webframez-react] Failed to render route",C),d((0,a.jsx)("p",{children:"Failed to load route."}))}finally{w(!1)}}(0,r.useEffect)(()=>{I(c)},[c]),(0,r.useEffect)(()=>{let s=()=>{l(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let R=r.default.useMemo(()=>({push:s=>{l(new URL(s,window.location.origin),"push")},replace:s=>{l(new URL(s,window.location.origin),"replace")},refresh:()=>{l(new URL(window.location.href),"none")}}),[]);return B(R),p?(0,a.jsxs)(p.Provider,{value:R,children:[(0,a.jsx)(x,{active:g}),i??(0,a.jsx)("p",{style:{padding:24},children:"Loading..."})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x,{active:g}),i??(0,a.jsx)("p",{style:{padding:24},children:"Loading..."})]})}}function j(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,i=e.rscEndpoint??o??"/rsc",d=Z(i);return(0,S.hydrateRoot)(n,(0,a.jsx)(d,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import u,{useEffect as _,useState as w}from"react";import{createRoot as b}from"react-dom/client";import{createFromFetch as k}from"react-server-dom-webpack/client";import{Fragment as M,jsx as c,jsxs as x}from"react/jsx-runtime";var A={push:()=>{},replace:()=>{},refresh:()=>{}},d=typeof u.createContext=="function"?u.createContext(null):null,E="__WEBFRAMEZ_ROUTER__",O="[data-webframez-head='true']";function S(){return typeof window>"u"?null:window[E]??null}function L(e){typeof window>"u"||(window[E]=e)}function R(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let o of t.split(";")){let n=o.trim();if(!n)continue;let r=n.indexOf("="),s=r>=0?n.slice(0,r).trim():n,a=r>=0?n.slice(r+1):"";s&&(e[s]=decodeURIComponent(a))}return e}function h(e,t,o={}){let n=[`${e}=${encodeURIComponent(t)}`];return o.path&&n.push(`Path=${o.path}`),o.domain&&n.push(`Domain=${o.domain}`),typeof o.maxAge=="number"&&n.push(`Max-Age=${Math.floor(o.maxAge)}`),o.expires&&n.push(`Expires=${o.expires.toUTCString()}`),o.sameSite&&n.push(`SameSite=${o.sameSite}`),o.secure&&n.push("Secure"),n.join("; ")}function N(){return u.useMemo(()=>({all:()=>R(),get:e=>R()[e],set:(e,t,o)=>{typeof document>"u"||(document.cookie=h(e,t,o))},remove:(e,t)=>{typeof document>"u"||(document.cookie=h(e,"",{...t??{},maxAge:0}))}}),[])}function B(){let e=d?u.useContext(d):null;if(!e){let t=S();if(t)return t;if(typeof window>"u")return A;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function C({active:e}){return c("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function v(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let o=Object.entries(e).filter(([,n])=>!!n);for(let[n,r]of o)t.setAttribute(n,String(r));document.head.appendChild(t)}function y(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let o=Object.entries(e).filter(([,n])=>!!n);for(let[n,r]of o)t.setAttribute(n,String(r));document.head.appendChild(t)}function T(e){if(!(typeof document>"u")){document.title=e.title||"Webframez React";for(let t of document.head.querySelectorAll(O))t.remove();e.description&&v({name:"description",content:e.description}),e.favicon&&y({rel:"icon",href:e.favicon});for(let t of e.meta??[])v(t);for(let t of e.links??[])y(t)}}function U(e){return function(){let[o,n]=w(null),[r,s]=w(!1);async function a(i,f="push"){s(!0);try{let m=await k(fetch(`${e}?path=${encodeURIComponent(i.pathname)}&search=${encodeURIComponent(i.search)}`,{headers:{Accept:"text/x-component"}}));T(m.head),n(m.model);let g=`${i.pathname}${i.search}`;f==="replace"?history.replaceState(null,"",g):f==="push"&&history.pushState(null,"",g)}catch(p){console.error("[webframez-react] Failed to render route",p),n(c("p",{children:"Failed to load route."}))}finally{s(!1)}}_(()=>{let i=()=>{a(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),a(new URL(window.location.href),"none"),()=>{window.removeEventListener("popstate",i)}},[]);let l=u.useMemo(()=>({push:i=>{a(new URL(i,window.location.origin),"push")},replace:i=>{a(new URL(i,window.location.origin),"replace")},refresh:()=>{a(new URL(window.location.href),"none")}}),[]);return L(l),d?x(d.Provider,{value:l,children:[c(C,{active:r}),o??c("p",{style:{padding:24},children:"Loading..."})]}):x(M,{children:[c(C,{active:r}),o??c("p",{style:{padding:24},children:"Loading..."})]})}}function H(e={}){let t=e.rootId??"root",o=document.getElementById(t);if(!o)throw new Error(`Missing #${t} element`);let n=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??n??"/rsc",s=U(r),a=b(o);return a.render(c(s,{})),a}export{H as mountWebframezClient,N as useCookie,B as useRouter};
1
+ import d,{useEffect as y,useState as l}from"react";import{hydrateRoot as P}from"react-dom/client";import{createFromFetch as _,createFromReadableStream as O}from"react-server-dom-webpack/client";import{Fragment as D,jsx as s,jsxs as S}from"react/jsx-runtime";var T={push:()=>{},replace:()=>{},refresh:()=>{}},f=typeof d.createContext=="function"?d.createContext(null):null,k="__WEBFRAMEZ_ROUTER__",N="[data-webframez-head='true']";function U(){return typeof window>"u"?null:window[k]??null}function $(e){typeof window>"u"||(window[k]=e)}function v(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let i=o.indexOf("="),a=i>=0?o.slice(0,i).trim():o,c=i>=0?o.slice(i+1):"";a&&(e[a]=decodeURIComponent(c))}return e}function A(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function G(){return d.useMemo(()=>({all:()=>v(),get:e=>v()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=A(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=A(e,"",{...t??{},maxAge:0}))}}),[])}function Y(){let e=f?d.useContext(f):null;if(!e){let t=U();if(t)return t;if(typeof window>"u")return T;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function x({active:e}){return s("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function E(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function b(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function I(e){if(!(typeof document>"u")){document.title=e.title||"Webframez React";for(let t of document.head.querySelectorAll(N))t.remove();e.description&&E({name:"description",content:e.description}),e.favicon&&b({rel:"icon",href:e.favicon});for(let t of e.meta??[])E(t);for(let t of e.links??[])b(t)}}function M(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function H(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,O(M(e)))}function W(e){return function(){let[n]=l(()=>H()??_(fetch(`${e}?path=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))),o=d.use(n),[i,a]=l(o.model),[c,L]=l(o.head),[m,g]=l(!1);async function u(r,R="push"){g(!0);try{let p=await _(fetch(`${e}?path=${encodeURIComponent(r.pathname)}&search=${encodeURIComponent(r.search)}`,{headers:{Accept:"text/x-component"}}));I(p.head),L(p.head),a(p.model);let C=`${r.pathname}${r.search}`;R==="replace"?history.replaceState(null,"",C):R==="push"&&history.pushState(null,"",C)}catch(h){console.error("[webframez-react] Failed to render route",h),a(s("p",{children:"Failed to load route."}))}finally{g(!1)}}y(()=>{I(c)},[c]),y(()=>{let r=()=>{u(new URL(window.location.href),"none")};return window.addEventListener("popstate",r),()=>{window.removeEventListener("popstate",r)}},[]);let w=d.useMemo(()=>({push:r=>{u(new URL(r,window.location.origin),"push")},replace:r=>{u(new URL(r,window.location.origin),"replace")},refresh:()=>{u(new URL(window.location.href),"none")}}),[]);return $(w),f?S(f.Provider,{value:w,children:[s(x,{active:m}),i??s("p",{style:{padding:24},children:"Loading..."})]}):S(D,{children:[s(x,{active:m}),i??s("p",{style:{padding:24},children:"Loading..."})]})}}function q(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,i=e.rscEndpoint??o??"/rsc",a=W(i);return P(n,s(a,{}))}export{q as mountWebframezClient,G as useCookie,Y as useRouter};
package/dist/http.cjs CHANGED
@@ -37,6 +37,7 @@ var import_node_path2 = __toESM(require("node:path"), 1);
37
37
  var import_node_child_process = require("node:child_process");
38
38
 
39
39
  // src/server.ts
40
+ var import_node_stream = require("node:stream");
40
41
  var import_server = require("react-server-dom-webpack/server");
41
42
  function defaultOnError(err) {
42
43
  console.error("[webframez-react] RSC render error", err);
@@ -48,10 +49,12 @@ function createHTMLShell(options = {}) {
48
49
  clientScriptUrl = "/client.js",
49
50
  headTags = "",
50
51
  rootHtml = "",
52
+ initialFlightData = "",
51
53
  basename = "",
52
54
  liveReloadPath,
53
55
  liveReloadServerId
54
56
  } = options;
57
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
55
58
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
56
59
  (() => {
57
60
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -96,11 +99,34 @@ function createHTMLShell(options = {}) {
96
99
  <div id="root">${rootHtml}</div>
97
100
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
98
101
  <script>window.__RSC_BASENAME = "${basename}";</script>
102
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
99
103
  <script type="module" src="${clientScriptUrl}"></script>
100
104
  ${liveReloadScript}
101
105
  </body>
102
106
  </html>`;
103
107
  }
108
+ function renderRSCToString(payload, options = {}) {
109
+ const {
110
+ moduleMap = {},
111
+ onError = defaultOnError
112
+ } = options;
113
+ return new Promise((resolve, reject) => {
114
+ const chunks = [];
115
+ const writable = new import_node_stream.Writable({
116
+ write(chunk, _encoding, callback) {
117
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
118
+ chunks.push(normalized);
119
+ callback();
120
+ }
121
+ });
122
+ writable.on("finish", () => {
123
+ resolve(Buffer.concat(chunks).toString("utf8"));
124
+ });
125
+ writable.on("error", reject);
126
+ const stream = (0, import_server.renderToPipeableStream)(payload, moduleMap, { onError });
127
+ stream.pipe(writable);
128
+ });
129
+ }
104
130
  function sendRSC(res, model, options = {}) {
105
131
  const {
106
132
  moduleMap = {},
@@ -478,6 +504,9 @@ function parseSearchParams(query) {
478
504
  }
479
505
 
480
506
  // src/http.ts
507
+ function createInitialHtmlErrorMarkup(message) {
508
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
509
+ }
481
510
  var INITIAL_HTML_WORKER_SCRIPT = `
482
511
  const path = require("node:path");
483
512
  const Module = require("node:module");
@@ -559,6 +588,12 @@ function stripBasePath(pathname, basePath) {
559
588
  }
560
589
  return pathname;
561
590
  }
591
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
592
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
593
+ return "";
594
+ }
595
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
596
+ }
562
597
  function createInitialHtmlWorker(pagesDir) {
563
598
  let child = null;
564
599
  let nextRequestId = 1;
@@ -590,6 +625,7 @@ function createInitialHtmlWorker(pagesDir) {
590
625
  cwd: process.cwd(),
591
626
  env: {
592
627
  ...process.env,
628
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
593
629
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
594
630
  },
595
631
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -826,6 +862,10 @@ function createNodeRequestHandler(options) {
826
862
  cookies: requestCookies
827
863
  })
828
864
  );
865
+ const initialPayload = {
866
+ model: resolved.model,
867
+ head: resolved.head
868
+ };
829
869
  let rootHtml = "";
830
870
  try {
831
871
  rootHtml = await initialHtmlWorker.render({
@@ -836,7 +876,36 @@ function createNodeRequestHandler(options) {
836
876
  });
837
877
  } catch (error) {
838
878
  console.error("[webframez-react] Failed to render initial HTML", error);
879
+ try {
880
+ initialHtmlWorker.dispose();
881
+ rootHtml = await initialHtmlWorker.render({
882
+ pathname: stripBasePath(url.pathname, basePath),
883
+ searchParams: parseSearchParams(url.searchParams),
884
+ cookies: requestCookies,
885
+ basename: basePath
886
+ });
887
+ } catch (retryError) {
888
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
889
+ res.statusCode = 500;
890
+ res.setHeader("Content-Type", "text/html");
891
+ res.end(
892
+ createHTMLShell({
893
+ title: "500 - Initial HTML render failed",
894
+ headTags: "",
895
+ clientScriptUrl,
896
+ rscEndpoint: rscPath,
897
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
898
+ basename: basePath,
899
+ liveReloadPath: liveReloadPath || void 0,
900
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
901
+ })
902
+ );
903
+ return;
904
+ }
839
905
  }
906
+ const initialFlightData = await renderRSCToString(initialPayload, {
907
+ moduleMap
908
+ });
840
909
  res.statusCode = resolved.statusCode;
841
910
  res.setHeader("Content-Type", "text/html");
842
911
  res.end(
@@ -846,6 +915,7 @@ function createNodeRequestHandler(options) {
846
915
  clientScriptUrl,
847
916
  rscEndpoint: rscPath,
848
917
  rootHtml,
918
+ initialFlightData,
849
919
  basename: basePath,
850
920
  liveReloadPath: liveReloadPath || void 0,
851
921
  liveReloadServerId: liveReloadPath ? devServerId : void 0
package/dist/http.js CHANGED
@@ -12,6 +12,7 @@ import path2 from "node:path";
12
12
  import { spawn } from "node:child_process";
13
13
 
14
14
  // src/server.ts
15
+ import { Writable } from "node:stream";
15
16
  import { renderToPipeableStream } from "react-server-dom-webpack/server";
16
17
  function defaultOnError(err) {
17
18
  console.error("[webframez-react] RSC render error", err);
@@ -23,10 +24,12 @@ function createHTMLShell(options = {}) {
23
24
  clientScriptUrl = "/client.js",
24
25
  headTags = "",
25
26
  rootHtml = "",
27
+ initialFlightData = "",
26
28
  basename = "",
27
29
  liveReloadPath,
28
30
  liveReloadServerId
29
31
  } = options;
32
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
30
33
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
31
34
  (() => {
32
35
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -71,11 +74,34 @@ function createHTMLShell(options = {}) {
71
74
  <div id="root">${rootHtml}</div>
72
75
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
73
76
  <script>window.__RSC_BASENAME = "${basename}";</script>
77
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
74
78
  <script type="module" src="${clientScriptUrl}"></script>
75
79
  ${liveReloadScript}
76
80
  </body>
77
81
  </html>`;
78
82
  }
83
+ function renderRSCToString(payload, options = {}) {
84
+ const {
85
+ moduleMap = {},
86
+ onError = defaultOnError
87
+ } = options;
88
+ return new Promise((resolve, reject) => {
89
+ const chunks = [];
90
+ const writable = new Writable({
91
+ write(chunk, _encoding, callback) {
92
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
93
+ chunks.push(normalized);
94
+ callback();
95
+ }
96
+ });
97
+ writable.on("finish", () => {
98
+ resolve(Buffer.concat(chunks).toString("utf8"));
99
+ });
100
+ writable.on("error", reject);
101
+ const stream = renderToPipeableStream(payload, moduleMap, { onError });
102
+ stream.pipe(writable);
103
+ });
104
+ }
79
105
  function sendRSC(res, model, options = {}) {
80
106
  const {
81
107
  moduleMap = {},
@@ -453,6 +479,9 @@ function parseSearchParams(query) {
453
479
  }
454
480
 
455
481
  // src/http.ts
482
+ function createInitialHtmlErrorMarkup(message) {
483
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
484
+ }
456
485
  var INITIAL_HTML_WORKER_SCRIPT = `
457
486
  const path = require("node:path");
458
487
  const Module = require("node:module");
@@ -534,6 +563,12 @@ function stripBasePath(pathname, basePath) {
534
563
  }
535
564
  return pathname;
536
565
  }
566
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
567
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
568
+ return "";
569
+ }
570
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
571
+ }
537
572
  function createInitialHtmlWorker(pagesDir) {
538
573
  let child = null;
539
574
  let nextRequestId = 1;
@@ -565,6 +600,7 @@ function createInitialHtmlWorker(pagesDir) {
565
600
  cwd: process.cwd(),
566
601
  env: {
567
602
  ...process.env,
603
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
568
604
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
569
605
  },
570
606
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -801,6 +837,10 @@ function createNodeRequestHandler(options) {
801
837
  cookies: requestCookies
802
838
  })
803
839
  );
840
+ const initialPayload = {
841
+ model: resolved.model,
842
+ head: resolved.head
843
+ };
804
844
  let rootHtml = "";
805
845
  try {
806
846
  rootHtml = await initialHtmlWorker.render({
@@ -811,7 +851,36 @@ function createNodeRequestHandler(options) {
811
851
  });
812
852
  } catch (error) {
813
853
  console.error("[webframez-react] Failed to render initial HTML", error);
854
+ try {
855
+ initialHtmlWorker.dispose();
856
+ rootHtml = await initialHtmlWorker.render({
857
+ pathname: stripBasePath(url.pathname, basePath),
858
+ searchParams: parseSearchParams(url.searchParams),
859
+ cookies: requestCookies,
860
+ basename: basePath
861
+ });
862
+ } catch (retryError) {
863
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
864
+ res.statusCode = 500;
865
+ res.setHeader("Content-Type", "text/html");
866
+ res.end(
867
+ createHTMLShell({
868
+ title: "500 - Initial HTML render failed",
869
+ headTags: "",
870
+ clientScriptUrl,
871
+ rscEndpoint: rscPath,
872
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
873
+ basename: basePath,
874
+ liveReloadPath: liveReloadPath || void 0,
875
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
876
+ })
877
+ );
878
+ return;
879
+ }
814
880
  }
881
+ const initialFlightData = await renderRSCToString(initialPayload, {
882
+ moduleMap
883
+ });
815
884
  res.statusCode = resolved.statusCode;
816
885
  res.setHeader("Content-Type", "text/html");
817
886
  res.end(
@@ -821,6 +890,7 @@ function createNodeRequestHandler(options) {
821
890
  clientScriptUrl,
822
891
  rscEndpoint: rscPath,
823
892
  rootHtml,
893
+ initialFlightData,
824
894
  basename: basePath,
825
895
  liveReloadPath: liveReloadPath || void 0,
826
896
  liveReloadServerId: liveReloadPath ? devServerId : void 0
package/dist/index.cjs CHANGED
@@ -43,6 +43,7 @@ __export(src_exports, {
43
43
  module.exports = __toCommonJS(src_exports);
44
44
 
45
45
  // src/server.ts
46
+ var import_node_stream = require("node:stream");
46
47
  var import_server = require("react-server-dom-webpack/server");
47
48
  function defaultOnError(err) {
48
49
  console.error("[webframez-react] RSC render error", err);
@@ -54,10 +55,12 @@ function createHTMLShell(options = {}) {
54
55
  clientScriptUrl = "/client.js",
55
56
  headTags = "",
56
57
  rootHtml = "",
58
+ initialFlightData = "",
57
59
  basename = "",
58
60
  liveReloadPath,
59
61
  liveReloadServerId
60
62
  } = options;
63
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
61
64
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
62
65
  (() => {
63
66
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -102,11 +105,34 @@ function createHTMLShell(options = {}) {
102
105
  <div id="root">${rootHtml}</div>
103
106
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
104
107
  <script>window.__RSC_BASENAME = "${basename}";</script>
108
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
105
109
  <script type="module" src="${clientScriptUrl}"></script>
106
110
  ${liveReloadScript}
107
111
  </body>
108
112
  </html>`;
109
113
  }
114
+ function renderRSCToString(payload, options = {}) {
115
+ const {
116
+ moduleMap = {},
117
+ onError = defaultOnError
118
+ } = options;
119
+ return new Promise((resolve, reject) => {
120
+ const chunks = [];
121
+ const writable = new import_node_stream.Writable({
122
+ write(chunk, _encoding, callback) {
123
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
124
+ chunks.push(normalized);
125
+ callback();
126
+ }
127
+ });
128
+ writable.on("finish", () => {
129
+ resolve(Buffer.concat(chunks).toString("utf8"));
130
+ });
131
+ writable.on("error", reject);
132
+ const stream = (0, import_server.renderToPipeableStream)(payload, moduleMap, { onError });
133
+ stream.pipe(writable);
134
+ });
135
+ }
110
136
  function sendRSC(res, model, options = {}) {
111
137
  const {
112
138
  moduleMap = {},
@@ -515,6 +541,9 @@ function parseSearchParams(query) {
515
541
  var import_node_fs2 = __toESM(require("node:fs"), 1);
516
542
  var import_node_path2 = __toESM(require("node:path"), 1);
517
543
  var import_node_child_process = require("node:child_process");
544
+ function createInitialHtmlErrorMarkup(message) {
545
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
546
+ }
518
547
  var INITIAL_HTML_WORKER_SCRIPT = `
519
548
  const path = require("node:path");
520
549
  const Module = require("node:module");
@@ -596,6 +625,12 @@ function stripBasePath(pathname, basePath) {
596
625
  }
597
626
  return pathname;
598
627
  }
628
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
629
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
630
+ return "";
631
+ }
632
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
633
+ }
599
634
  function createInitialHtmlWorker(pagesDir) {
600
635
  let child = null;
601
636
  let nextRequestId = 1;
@@ -627,6 +662,7 @@ function createInitialHtmlWorker(pagesDir) {
627
662
  cwd: process.cwd(),
628
663
  env: {
629
664
  ...process.env,
665
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
630
666
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
631
667
  },
632
668
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -863,6 +899,10 @@ function createNodeRequestHandler(options) {
863
899
  cookies: requestCookies
864
900
  })
865
901
  );
902
+ const initialPayload = {
903
+ model: resolved.model,
904
+ head: resolved.head
905
+ };
866
906
  let rootHtml = "";
867
907
  try {
868
908
  rootHtml = await initialHtmlWorker.render({
@@ -873,7 +913,36 @@ function createNodeRequestHandler(options) {
873
913
  });
874
914
  } catch (error) {
875
915
  console.error("[webframez-react] Failed to render initial HTML", error);
916
+ try {
917
+ initialHtmlWorker.dispose();
918
+ rootHtml = await initialHtmlWorker.render({
919
+ pathname: stripBasePath(url.pathname, basePath),
920
+ searchParams: parseSearchParams(url.searchParams),
921
+ cookies: requestCookies,
922
+ basename: basePath
923
+ });
924
+ } catch (retryError) {
925
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
926
+ res.statusCode = 500;
927
+ res.setHeader("Content-Type", "text/html");
928
+ res.end(
929
+ createHTMLShell({
930
+ title: "500 - Initial HTML render failed",
931
+ headTags: "",
932
+ clientScriptUrl,
933
+ rscEndpoint: rscPath,
934
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
935
+ basename: basePath,
936
+ liveReloadPath: liveReloadPath || void 0,
937
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
938
+ })
939
+ );
940
+ return;
941
+ }
876
942
  }
943
+ const initialFlightData = await renderRSCToString(initialPayload, {
944
+ moduleMap
945
+ });
877
946
  res.statusCode = resolved.statusCode;
878
947
  res.setHeader("Content-Type", "text/html");
879
948
  res.end(
@@ -883,6 +952,7 @@ function createNodeRequestHandler(options) {
883
952
  clientScriptUrl,
884
953
  rscEndpoint: rscPath,
885
954
  rootHtml,
955
+ initialFlightData,
886
956
  basename: basePath,
887
957
  liveReloadPath: liveReloadPath || void 0,
888
958
  liveReloadServerId: liveReloadPath ? devServerId : void 0
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
  });
8
8
 
9
9
  // src/server.ts
10
+ import { Writable } from "node:stream";
10
11
  import { renderToPipeableStream } from "react-server-dom-webpack/server";
11
12
  function defaultOnError(err) {
12
13
  console.error("[webframez-react] RSC render error", err);
@@ -18,10 +19,12 @@ function createHTMLShell(options = {}) {
18
19
  clientScriptUrl = "/client.js",
19
20
  headTags = "",
20
21
  rootHtml = "",
22
+ initialFlightData = "",
21
23
  basename = "",
22
24
  liveReloadPath,
23
25
  liveReloadServerId
24
26
  } = options;
27
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
25
28
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
26
29
  (() => {
27
30
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -66,11 +69,34 @@ function createHTMLShell(options = {}) {
66
69
  <div id="root">${rootHtml}</div>
67
70
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
68
71
  <script>window.__RSC_BASENAME = "${basename}";</script>
72
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
69
73
  <script type="module" src="${clientScriptUrl}"></script>
70
74
  ${liveReloadScript}
71
75
  </body>
72
76
  </html>`;
73
77
  }
78
+ function renderRSCToString(payload, options = {}) {
79
+ const {
80
+ moduleMap = {},
81
+ onError = defaultOnError
82
+ } = options;
83
+ return new Promise((resolve, reject) => {
84
+ const chunks = [];
85
+ const writable = new Writable({
86
+ write(chunk, _encoding, callback) {
87
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
88
+ chunks.push(normalized);
89
+ callback();
90
+ }
91
+ });
92
+ writable.on("finish", () => {
93
+ resolve(Buffer.concat(chunks).toString("utf8"));
94
+ });
95
+ writable.on("error", reject);
96
+ const stream = renderToPipeableStream(payload, moduleMap, { onError });
97
+ stream.pipe(writable);
98
+ });
99
+ }
74
100
  function sendRSC(res, model, options = {}) {
75
101
  const {
76
102
  moduleMap = {},
@@ -479,6 +505,9 @@ function parseSearchParams(query) {
479
505
  import fs2 from "node:fs";
480
506
  import path2 from "node:path";
481
507
  import { spawn } from "node:child_process";
508
+ function createInitialHtmlErrorMarkup(message) {
509
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
510
+ }
482
511
  var INITIAL_HTML_WORKER_SCRIPT = `
483
512
  const path = require("node:path");
484
513
  const Module = require("node:module");
@@ -560,6 +589,12 @@ function stripBasePath(pathname, basePath) {
560
589
  }
561
590
  return pathname;
562
591
  }
592
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
593
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
594
+ return "";
595
+ }
596
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
597
+ }
563
598
  function createInitialHtmlWorker(pagesDir) {
564
599
  let child = null;
565
600
  let nextRequestId = 1;
@@ -591,6 +626,7 @@ function createInitialHtmlWorker(pagesDir) {
591
626
  cwd: process.cwd(),
592
627
  env: {
593
628
  ...process.env,
629
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
594
630
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
595
631
  },
596
632
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -827,6 +863,10 @@ function createNodeRequestHandler(options) {
827
863
  cookies: requestCookies
828
864
  })
829
865
  );
866
+ const initialPayload = {
867
+ model: resolved.model,
868
+ head: resolved.head
869
+ };
830
870
  let rootHtml = "";
831
871
  try {
832
872
  rootHtml = await initialHtmlWorker.render({
@@ -837,7 +877,36 @@ function createNodeRequestHandler(options) {
837
877
  });
838
878
  } catch (error) {
839
879
  console.error("[webframez-react] Failed to render initial HTML", error);
880
+ try {
881
+ initialHtmlWorker.dispose();
882
+ rootHtml = await initialHtmlWorker.render({
883
+ pathname: stripBasePath(url.pathname, basePath),
884
+ searchParams: parseSearchParams(url.searchParams),
885
+ cookies: requestCookies,
886
+ basename: basePath
887
+ });
888
+ } catch (retryError) {
889
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
890
+ res.statusCode = 500;
891
+ res.setHeader("Content-Type", "text/html");
892
+ res.end(
893
+ createHTMLShell({
894
+ title: "500 - Initial HTML render failed",
895
+ headTags: "",
896
+ clientScriptUrl,
897
+ rscEndpoint: rscPath,
898
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
899
+ basename: basePath,
900
+ liveReloadPath: liveReloadPath || void 0,
901
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
902
+ })
903
+ );
904
+ return;
905
+ }
840
906
  }
907
+ const initialFlightData = await renderRSCToString(initialPayload, {
908
+ moduleMap
909
+ });
841
910
  res.statusCode = resolved.statusCode;
842
911
  res.setHeader("Content-Type", "text/html");
843
912
  res.end(
@@ -847,6 +916,7 @@ function createNodeRequestHandler(options) {
847
916
  clientScriptUrl,
848
917
  rscEndpoint: rscPath,
849
918
  rootHtml,
919
+ initialFlightData,
850
920
  basename: basePath,
851
921
  liveReloadPath: liveReloadPath || void 0,
852
922
  liveReloadServerId: liveReloadPath ? devServerId : void 0
@@ -40,6 +40,7 @@ var import_node_path2 = __toESM(require("node:path"), 1);
40
40
  var import_node_child_process = require("node:child_process");
41
41
 
42
42
  // src/server.ts
43
+ var import_node_stream = require("node:stream");
43
44
  var import_server = require("react-server-dom-webpack/server");
44
45
  function defaultOnError(err) {
45
46
  console.error("[webframez-react] RSC render error", err);
@@ -51,10 +52,12 @@ function createHTMLShell(options = {}) {
51
52
  clientScriptUrl = "/client.js",
52
53
  headTags = "",
53
54
  rootHtml = "",
55
+ initialFlightData = "",
54
56
  basename = "",
55
57
  liveReloadPath,
56
58
  liveReloadServerId
57
59
  } = options;
60
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
58
61
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
59
62
  (() => {
60
63
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -99,11 +102,34 @@ function createHTMLShell(options = {}) {
99
102
  <div id="root">${rootHtml}</div>
100
103
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
101
104
  <script>window.__RSC_BASENAME = "${basename}";</script>
105
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
102
106
  <script type="module" src="${clientScriptUrl}"></script>
103
107
  ${liveReloadScript}
104
108
  </body>
105
109
  </html>`;
106
110
  }
111
+ function renderRSCToString(payload, options = {}) {
112
+ const {
113
+ moduleMap = {},
114
+ onError = defaultOnError
115
+ } = options;
116
+ return new Promise((resolve, reject) => {
117
+ const chunks = [];
118
+ const writable = new import_node_stream.Writable({
119
+ write(chunk, _encoding, callback) {
120
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
121
+ chunks.push(normalized);
122
+ callback();
123
+ }
124
+ });
125
+ writable.on("finish", () => {
126
+ resolve(Buffer.concat(chunks).toString("utf8"));
127
+ });
128
+ writable.on("error", reject);
129
+ const stream = (0, import_server.renderToPipeableStream)(payload, moduleMap, { onError });
130
+ stream.pipe(writable);
131
+ });
132
+ }
107
133
  function sendRSC(res, model, options = {}) {
108
134
  const {
109
135
  moduleMap = {},
@@ -481,6 +507,9 @@ function parseSearchParams(query) {
481
507
  }
482
508
 
483
509
  // src/http.ts
510
+ function createInitialHtmlErrorMarkup(message) {
511
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
512
+ }
484
513
  var INITIAL_HTML_WORKER_SCRIPT = `
485
514
  const path = require("node:path");
486
515
  const Module = require("node:module");
@@ -562,6 +591,12 @@ function stripBasePath(pathname, basePath) {
562
591
  }
563
592
  return pathname;
564
593
  }
594
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
595
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
596
+ return "";
597
+ }
598
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
599
+ }
565
600
  function createInitialHtmlWorker(pagesDir) {
566
601
  let child = null;
567
602
  let nextRequestId = 1;
@@ -593,6 +628,7 @@ function createInitialHtmlWorker(pagesDir) {
593
628
  cwd: process.cwd(),
594
629
  env: {
595
630
  ...process.env,
631
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
596
632
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
597
633
  },
598
634
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -829,6 +865,10 @@ function createNodeRequestHandler(options) {
829
865
  cookies: requestCookies
830
866
  })
831
867
  );
868
+ const initialPayload = {
869
+ model: resolved.model,
870
+ head: resolved.head
871
+ };
832
872
  let rootHtml = "";
833
873
  try {
834
874
  rootHtml = await initialHtmlWorker.render({
@@ -839,7 +879,36 @@ function createNodeRequestHandler(options) {
839
879
  });
840
880
  } catch (error) {
841
881
  console.error("[webframez-react] Failed to render initial HTML", error);
882
+ try {
883
+ initialHtmlWorker.dispose();
884
+ rootHtml = await initialHtmlWorker.render({
885
+ pathname: stripBasePath(url.pathname, basePath),
886
+ searchParams: parseSearchParams(url.searchParams),
887
+ cookies: requestCookies,
888
+ basename: basePath
889
+ });
890
+ } catch (retryError) {
891
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
892
+ res.statusCode = 500;
893
+ res.setHeader("Content-Type", "text/html");
894
+ res.end(
895
+ createHTMLShell({
896
+ title: "500 - Initial HTML render failed",
897
+ headTags: "",
898
+ clientScriptUrl,
899
+ rscEndpoint: rscPath,
900
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
901
+ basename: basePath,
902
+ liveReloadPath: liveReloadPath || void 0,
903
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
904
+ })
905
+ );
906
+ return;
907
+ }
842
908
  }
909
+ const initialFlightData = await renderRSCToString(initialPayload, {
910
+ moduleMap
911
+ });
843
912
  res.statusCode = resolved.statusCode;
844
913
  res.setHeader("Content-Type", "text/html");
845
914
  res.end(
@@ -849,6 +918,7 @@ function createNodeRequestHandler(options) {
849
918
  clientScriptUrl,
850
919
  rscEndpoint: rscPath,
851
920
  rootHtml,
921
+ initialFlightData,
852
922
  basename: basePath,
853
923
  liveReloadPath: liveReloadPath || void 0,
854
924
  liveReloadServerId: liveReloadPath ? devServerId : void 0
@@ -12,6 +12,7 @@ import path2 from "node:path";
12
12
  import { spawn } from "node:child_process";
13
13
 
14
14
  // src/server.ts
15
+ import { Writable } from "node:stream";
15
16
  import { renderToPipeableStream } from "react-server-dom-webpack/server";
16
17
  function defaultOnError(err) {
17
18
  console.error("[webframez-react] RSC render error", err);
@@ -23,10 +24,12 @@ function createHTMLShell(options = {}) {
23
24
  clientScriptUrl = "/client.js",
24
25
  headTags = "",
25
26
  rootHtml = "",
27
+ initialFlightData = "",
26
28
  basename = "",
27
29
  liveReloadPath,
28
30
  liveReloadServerId
29
31
  } = options;
32
+ const escapedInitialFlightData = initialFlightData ? JSON.stringify(initialFlightData).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") : '""';
30
33
  const liveReloadScript = liveReloadPath && liveReloadServerId ? `<script>
31
34
  (() => {
32
35
  const endpoint = ${JSON.stringify(liveReloadPath)};
@@ -71,11 +74,34 @@ function createHTMLShell(options = {}) {
71
74
  <div id="root">${rootHtml}</div>
72
75
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
73
76
  <script>window.__RSC_BASENAME = "${basename}";</script>
77
+ <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
74
78
  <script type="module" src="${clientScriptUrl}"></script>
75
79
  ${liveReloadScript}
76
80
  </body>
77
81
  </html>`;
78
82
  }
83
+ function renderRSCToString(payload, options = {}) {
84
+ const {
85
+ moduleMap = {},
86
+ onError = defaultOnError
87
+ } = options;
88
+ return new Promise((resolve, reject) => {
89
+ const chunks = [];
90
+ const writable = new Writable({
91
+ write(chunk, _encoding, callback) {
92
+ const normalized = typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk);
93
+ chunks.push(normalized);
94
+ callback();
95
+ }
96
+ });
97
+ writable.on("finish", () => {
98
+ resolve(Buffer.concat(chunks).toString("utf8"));
99
+ });
100
+ writable.on("error", reject);
101
+ const stream = renderToPipeableStream(payload, moduleMap, { onError });
102
+ stream.pipe(writable);
103
+ });
104
+ }
79
105
  function sendRSC(res, model, options = {}) {
80
106
  const {
81
107
  moduleMap = {},
@@ -453,6 +479,9 @@ function parseSearchParams(query) {
453
479
  }
454
480
 
455
481
  // src/http.ts
482
+ function createInitialHtmlErrorMarkup(message) {
483
+ return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
484
+ }
456
485
  var INITIAL_HTML_WORKER_SCRIPT = `
457
486
  const path = require("node:path");
458
487
  const Module = require("node:module");
@@ -534,6 +563,12 @@ function stripBasePath(pathname, basePath) {
534
563
  }
535
564
  return pathname;
536
565
  }
566
+ function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
567
+ if (!rawNodeOptions || rawNodeOptions.trim() === "") {
568
+ return "";
569
+ }
570
+ return rawNodeOptions.replace(/(^|\s)--conditions\s+react-server(?=\s|$)/g, " ").replace(/(^|\s)-r\s+(\S*webframez-react\/register)(?=\s|$)/g, " ").replace(/\s+/g, " ").trim();
571
+ }
537
572
  function createInitialHtmlWorker(pagesDir) {
538
573
  let child = null;
539
574
  let nextRequestId = 1;
@@ -565,6 +600,7 @@ function createInitialHtmlWorker(pagesDir) {
565
600
  cwd: process.cwd(),
566
601
  env: {
567
602
  ...process.env,
603
+ NODE_OPTIONS: sanitizeInitialHtmlWorkerNodeOptions(process.env.NODE_OPTIONS),
568
604
  WEBFRAMEZ_REACT_PAGES_DIR: pagesDir
569
605
  },
570
606
  stdio: ["ignore", "ignore", "pipe", "ipc"]
@@ -801,6 +837,10 @@ function createNodeRequestHandler(options) {
801
837
  cookies: requestCookies
802
838
  })
803
839
  );
840
+ const initialPayload = {
841
+ model: resolved.model,
842
+ head: resolved.head
843
+ };
804
844
  let rootHtml = "";
805
845
  try {
806
846
  rootHtml = await initialHtmlWorker.render({
@@ -811,7 +851,36 @@ function createNodeRequestHandler(options) {
811
851
  });
812
852
  } catch (error) {
813
853
  console.error("[webframez-react] Failed to render initial HTML", error);
854
+ try {
855
+ initialHtmlWorker.dispose();
856
+ rootHtml = await initialHtmlWorker.render({
857
+ pathname: stripBasePath(url.pathname, basePath),
858
+ searchParams: parseSearchParams(url.searchParams),
859
+ cookies: requestCookies,
860
+ basename: basePath
861
+ });
862
+ } catch (retryError) {
863
+ console.error("[webframez-react] Retry for initial HTML failed", retryError);
864
+ res.statusCode = 500;
865
+ res.setHeader("Content-Type", "text/html");
866
+ res.end(
867
+ createHTMLShell({
868
+ title: "500 - Initial HTML render failed",
869
+ headTags: "",
870
+ clientScriptUrl,
871
+ rscEndpoint: rscPath,
872
+ rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
873
+ basename: basePath,
874
+ liveReloadPath: liveReloadPath || void 0,
875
+ liveReloadServerId: liveReloadPath ? devServerId : void 0
876
+ })
877
+ );
878
+ return;
879
+ }
814
880
  }
881
+ const initialFlightData = await renderRSCToString(initialPayload, {
882
+ moduleMap
883
+ });
815
884
  res.statusCode = resolved.statusCode;
816
885
  res.setHeader("Content-Type", "text/html");
817
886
  res.end(
@@ -821,6 +890,7 @@ function createNodeRequestHandler(options) {
821
890
  clientScriptUrl,
822
891
  rscEndpoint: rscPath,
823
892
  rootHtml,
893
+ initialFlightData,
824
894
  basename: basePath,
825
895
  liveReloadPath: liveReloadPath || void 0,
826
896
  liveReloadServerId: liveReloadPath ? devServerId : void 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {