@webtypen/webframez-react 0.0.38 → 0.0.40

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 ce=Object.create;var E=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var le=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var pe=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},U=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ue(t))!fe.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(o=de(t,r))||o.enumerable});return e};var H=(e,t,n)=>(n=e!=null?ce(le(e)):{},U(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),me=e=>U(E({},"__esModule",{value:!0}),e);var ke={};pe(ke,{mountWebframezClient:()=>Oe,useCookie:()=>Ne,useRouter:()=>ve});module.exports=me(ke);var s=H(require("react"),1),K=require("react-dom/client"),w=require("react-server-dom-webpack/client"),V=require("@webtypen/webframez-react/route-slot");var Re=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function u(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function z(e,t){let n=e.trim(),o=u(t);return!n||!o||Re.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function S(e,t){if(!e)return;let n=u(e.basename)??u(t),o=u(e.routeBasePath),r=u(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=z(a.favicon,n)),a.links&&(a.links=a.links.map(c=>({...c,href:z(c.href,n)}))),a}var m=H(require("react"),1),D="webframez-route-children",W="__webframezRouteChildren",F="WebframezRouteChildren",N=()=>m.default.createElement(D);N.displayName=F;N[W]=!0;var we=N;function M(e){if(e===D||e===we)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[W]===!0||t.displayName===F||t.name==="RouteChildren"}catch{return!1}}function $(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function A(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let l=!1,_=e.map(p=>{let h=A(p,t);return h!==p&&(l=!0),h});return l?_:e}if($(e)&&M(e.type))return t;let n=m.default.isValidElement(e);if(!n&&!$(e))return e;if(n&&M(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=A(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?m.default.cloneElement(e,void 0,...r):m.default.cloneElement(e,void 0,r);let a=e,c={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return m.default.createElement(a.type,c)}var d=require("react/jsx-runtime"),_e={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof s.default.createContext=="function"?s.default.createContext(null):null,X="__WEBFRAMEZ_ROUTER__",he="__WEBFRAMEZ_REACT_BUILD_ID",ge="x-webframez-react-build",Ce="[data-webframez-head='true']";function j(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function I(e){return u(e)??""}function ye(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function J(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Ee(){return I(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function Q(e){if(typeof window>"u")return e||"/";let t=I(window.__RSC_BASENAME),n=Ee(),o=ye(e||"/",t);return J(n,o)}function ee(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ae(){if(typeof window>"u")return"";let e=window[he];return typeof e=="string"?e:""}function Te(e){let t=Ae();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Pe(){return typeof window>"u"?null:window[X]??null}function Se(e){typeof window>"u"||(window[X]=e)}function G(){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("="),a=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(c))}return e}function q(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 Ne(){return s.default.useMemo(()=>({all:()=>G(),get:e=>G()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=q(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=q(e,"",{...t??{},maxAge:0}))}}),[])}function ve(){let e=T?s.default.useContext(T):null;if(!e){let t=Pe();if(t)return t;if(typeof window>"u")return _e;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function xe({active:e}){return(0,d.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 Z(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 x(e){if(typeof document>"u")return;let t=S(e)??e;te(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(Ce))n.remove();t.description&&Y({name:"description",content:t.description}),t.favicon&&Z({rel:"icon",href:t.favicon});for(let n of t.meta??[])Y(n);for(let n of t.links??[])Z(n)}function te(e){if(typeof window>"u")return;let t=S(e)??e,n=u(t.basename),o=u(t.routeBasePath),r=u(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=J(r,"/rsc"))}function Ie(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Be(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,w.createFromReadableStream)(Ie(e)))}function Le(e){let t=ee(e),n=Q(window.location.pathname);return Be()??(0,w.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function be(e,t){return function(){let o=s.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,c]=(0,s.useState)(o.model),[l,_]=(0,s.useState)(o.contextModel),[p,h]=(0,s.useState)(o.pageModel),[B,L]=(0,s.useState)(o.head),[ne,g]=(0,s.useState)(!1),[oe,re]=(0,s.useState)(!1),[ie,P]=(0,s.useState)(r);async function b(i){let y=ee(t),f=Q(i.pathname),R=await fetch(`${y}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Te(R.headers.get(ge))?(v(i),await new Promise(()=>{})):await(0,w.createFromFetch)(Promise.resolve(R))}async function C(i,y="push"){g(!0);try{let f=await b(i);x(f.head),L(f.head),c(f.model),_(f.contextModel),h(f.pageModel),P(!0);let R=`${i.pathname}${i.search}${i.hash}`;y==="replace"?(history.replaceState(null,"",R),j()):y==="push"&&(history.pushState(null,"",R),j())}catch(f){console.error("[webframez-react] Failed to render route",f),v(i),c((0,d.jsx)("p",{children:"Failed to load route."}))}finally{g(!1)}}async function ae(){g(!0);try{let i=await b(new URL(window.location.href));if(x(i.head),L(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){_(i.contextModel),P(!0);return}c(i.model),P(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i),v(new URL(window.location.href))}finally{g(!1)}}(0,s.useEffect)(()=>{x(B)},[B]),(0,s.useEffect)(()=>{re(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let O=s.default.useMemo(()=>({push:i=>{C(new URL(i,window.location.origin),"push")},replace:i=>{C(new URL(i,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{ae()}}),[]);Se(O);let se=ie&&typeof p<"u"?l?(0,d.jsx)(V.RouteChildrenSlotProvider,{page:p,children:A(l,p)}):p:a,k=(0,d.jsxs)(d.Fragment,{children:[oe?(0,d.jsx)(xe,{active:ne}):null,se??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return T?(0,d.jsx)(T.Provider,{value:O,children:k}):k}}function Oe(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",a=Promise.resolve(Le(r)).then(l=>(l?.head&&te(l.head),l)),c=be(a,r);return(0,K.hydrateRoot)(n,(0,d.jsx)(c,{}))}
1
+ var ce=Object.create;var E=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var le=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var pe=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},U=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ue(t))!fe.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(o=de(t,r))||o.enumerable});return e};var H=(e,t,n)=>(n=e!=null?ce(le(e)):{},U(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),me=e=>U(E({},"__esModule",{value:!0}),e);var ke={};pe(ke,{mountWebframezClient:()=>Oe,useCookie:()=>Ne,useRouter:()=>ve});module.exports=me(ke);var s=H(require("react"),1),K=require("react-dom/client"),w=require("react-server-dom-webpack/client"),V=require("@webtypen/webframez-react/route-slot");var Re=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function u(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function z(e,t){let n=e.trim(),o=u(t);return!n||!o||Re.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function S(e,t){if(!e)return;let n=u(e.basename)??u(t),o=u(e.routeBasePath),r=u(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=z(a.favicon,n)),a.links&&(a.links=a.links.map(c=>({...c,href:z(c.href,n)}))),a}var m=H(require("react"),1),D="webframez-route-children",W="__webframezRouteChildren",F="WebframezRouteChildren",N=()=>m.default.createElement(D);N.displayName=F;N[W]=!0;var we=N;function M(e){if(e===D||e===we)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[W]===!0||t.displayName===F||t.name==="RouteChildren"}catch{return!1}}function $(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function A(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let l=!1,_=e.map(p=>{let h=A(p,t);return h!==p&&(l=!0),h});return l?_:e}if($(e)&&M(e.type))return t;let n=m.default.isValidElement(e);if(!n&&!$(e))return e;if(n&&M(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=A(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?m.default.cloneElement(e,void 0,...r):m.default.cloneElement(e,void 0,r);let a=e,c={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return m.default.createElement(a.type,c)}var d=require("react/jsx-runtime"),_e={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof s.default.createContext=="function"?s.default.createContext(null):null,X="__WEBFRAMEZ_ROUTER__",he="__WEBFRAMEZ_REACT_BUILD_ID",ge="x-webframez-react-build",Ce="[data-webframez-head='true']";function j(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function I(e){return u(e)??""}function ye(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function J(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Ee(){return I(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function Q(e){if(typeof window>"u")return e||"/";let t=I(window.__RSC_BASENAME),n=Ee(),o=ye(e||"/",t);return J(n,o)}function ee(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ae(){if(typeof window>"u")return"";let e=window[he];return typeof e=="string"?e:""}function Te(e){let t=Ae();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Pe(){return typeof window>"u"?null:window[X]??null}function Se(e){typeof window>"u"||(window[X]=e)}function G(){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("="),a=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(c))}return e}function q(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 Ne(){return s.default.useMemo(()=>({all:()=>G(),get:e=>G()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=q(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=q(e,"",{...t??{},maxAge:0}))}}),[])}function ve(){let e=T?s.default.useContext(T):null;if(!e){let t=Pe();if(t)return t;if(typeof window>"u")return _e;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function xe({active:e}){return(0,d.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 Z(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 x(e){if(typeof document>"u")return;let t=S(e)??e;te(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(Ce))n.remove();t.description&&Y({name:"description",content:t.description}),t.favicon&&Z({rel:"icon",href:t.favicon});for(let n of t.meta??[])Y(n);for(let n of t.links??[])Z(n)}function te(e){if(typeof window>"u")return;let t=S(e)??e,n=u(t.basename),o=u(t.routeBasePath),r=u(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=J(r,"/rsc"))}function Ie(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Be(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,w.createFromReadableStream)(Ie(e)))}function be(e){let t=ee(e),n=Q(window.location.pathname);return Be()??(0,w.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function Le(e,t){return function(){let o=s.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,c]=(0,s.useState)(o.model),[l,_]=(0,s.useState)(o.contextModel),[p,h]=(0,s.useState)(o.pageModel),[B,b]=(0,s.useState)(o.head),[ne,g]=(0,s.useState)(!1),[oe,re]=(0,s.useState)(!1),[ie,P]=(0,s.useState)(r);async function L(i){let y=ee(t),f=Q(i.pathname),R=await fetch(`${y}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Te(R.headers.get(ge))?(v(i),await new Promise(()=>{})):await(0,w.createFromFetch)(Promise.resolve(R))}async function C(i,y="push"){g(!0);try{let f=await L(i);x(f.head),b(f.head),c(f.model),_(f.contextModel),h(f.pageModel),P(!0);let R=`${i.pathname}${i.search}${i.hash}`;y==="replace"?(history.replaceState(null,"",R),j()):y==="push"&&(history.pushState(null,"",R),j())}catch(f){console.error("[webframez-react] Failed to render route",f),v(i),c((0,d.jsx)("p",{children:"Failed to load route."}))}finally{g(!1)}}async function ae(){g(!0);try{let i=await L(new URL(window.location.href));if(x(i.head),b(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){_(i.contextModel),P(!0);return}c(i.model),P(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i),v(new URL(window.location.href))}finally{g(!1)}}(0,s.useEffect)(()=>{x(B)},[B]),(0,s.useEffect)(()=>{re(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let O=s.default.useMemo(()=>({push:i=>{C(new URL(i,window.location.origin),"push")},replace:i=>{C(new URL(i,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{ae()}}),[]);Se(O);let se=ie&&typeof p<"u"?l?(0,d.jsx)(V.RouteChildrenSlotProvider,{page:p,children:A(l,p)}):p:a,k=(0,d.jsxs)(d.Fragment,{children:[oe?(0,d.jsx)(xe,{active:ne}):null,se??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return T?(0,d.jsx)(T.Provider,{value:O,children:k}):k}}function Oe(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",a=Promise.resolve(be(r)).then(l=>(l?.head&&te(l.head),l)),c=Le(a,r);return(0,K.hydrateRoot)(n,(0,d.jsx)(c,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import m,{useEffect as D,useState as f}from"react";import{hydrateRoot as se}from"react-dom/client";import{createFromFetch as Y,createFromReadableStream as ce}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as de}from"@webtypen/webframez-react/route-slot";var ie=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function c(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function k(e,t){let n=e.trim(),o=c(t);return!n||!o||ie.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function P(e,t){if(!e)return;let n=c(e.basename)??c(t),o=c(e.routeBasePath),r=c(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=k(a.favicon,n)),a.links&&(a.links=a.links.map(s=>({...s,href:k(s.href,n)}))),a}import w from"react";var z="webframez-route-children",M="__webframezRouteChildren",$="WebframezRouteChildren",S=()=>w.createElement(z);S.displayName=$;S[M]=!0;var ae=S;function U(e){if(e===z||e===ae)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[M]===!0||t.displayName===$||t.name==="RouteChildren"}catch{return!1}}function H(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function E(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let d=!1,_=e.map(l=>{let h=E(l,t);return h!==l&&(d=!0),h});return d?_:e}if(H(e)&&U(e.type))return t;let n=w.isValidElement(e);if(!n&&!H(e))return e;if(n&&U(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=E(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?w.cloneElement(e,void 0,...r):w.cloneElement(e,void 0,r);let a=e,s={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return w.createElement(a.type,s)}import{Fragment as Pe,jsx as p,jsxs as Se}from"react/jsx-runtime";var ue={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},A=typeof m.createContext=="function"?m.createContext(null):null,Z="__WEBFRAMEZ_ROUTER__",le="__WEBFRAMEZ_REACT_BUILD_ID",fe="x-webframez-react-build",pe="[data-webframez-head='true']";function W(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function x(e){return c(e)??""}function me(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function K(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Re(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function V(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=Re(),o=me(e||"/",t);return K(n,o)}function X(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function we(){if(typeof window>"u")return"";let e=window[le];return typeof e=="string"?e:""}function _e(e){let t=we();return!!t&&!!e&&t!==e}function N(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function he(){return typeof window>"u"?null:window[Z]??null}function ge(e){typeof window>"u"||(window[Z]=e)}function F(){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("="),a=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(s))}return e}function j(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 He(){return m.useMemo(()=>({all:()=>F(),get:e=>F()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=j(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=j(e,"",{...t??{},maxAge:0}))}}),[])}function ze(){let e=A?m.useContext(A):null;if(!e){let t=he();if(t)return t;if(typeof window>"u")return ue;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Ce({active:e}){return p("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 G(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 q(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 v(e){if(typeof document>"u")return;let t=P(e)??e;J(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(pe))n.remove();t.description&&G({name:"description",content:t.description}),t.favicon&&q({rel:"icon",href:t.favicon});for(let n of t.meta??[])G(n);for(let n of t.links??[])q(n)}function J(e){if(typeof window>"u")return;let t=P(e)??e,n=c(t.basename),o=c(t.routeBasePath),r=c(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=K(r,"/rsc"))}function ye(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Ee(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,ce(ye(e)))}function Ae(e){let t=X(e),n=V(window.location.pathname);return Ee()??Y(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function Te(e,t){return function(){let o=m.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,s]=f(o.model),[d,_]=f(o.contextModel),[l,h]=f(o.pageModel),[I,B]=f(o.head),[Q,g]=f(!1),[ee,te]=f(!1),[ne,T]=f(r);async function L(i){let y=X(t),u=V(i.pathname),R=await fetch(`${y}?path=${encodeURIComponent(u)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return _e(R.headers.get(fe))?(N(i),await new Promise(()=>{})):await Y(Promise.resolve(R))}async function C(i,y="push"){g(!0);try{let u=await L(i);v(u.head),B(u.head),s(u.model),_(u.contextModel),h(u.pageModel),T(!0);let R=`${i.pathname}${i.search}${i.hash}`;y==="replace"?(history.replaceState(null,"",R),W()):y==="push"&&(history.pushState(null,"",R),W())}catch(u){console.error("[webframez-react] Failed to render route",u),N(i),s(p("p",{children:"Failed to load route."}))}finally{g(!1)}}async function oe(){g(!0);try{let i=await L(new URL(window.location.href));if(v(i.head),B(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){_(i.contextModel),T(!0);return}s(i.model),T(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i),N(new URL(window.location.href))}finally{g(!1)}}D(()=>{v(I)},[I]),D(()=>{te(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let b=m.useMemo(()=>({push:i=>{C(new URL(i,window.location.origin),"push")},replace:i=>{C(new URL(i,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{oe()}}),[]);ge(b);let re=ne&&typeof l<"u"?d?p(de,{page:l,children:E(d,l)}):l:a,O=Se(Pe,{children:[ee?p(Ce,{active:Q}):null,re??p("p",{style:{padding:24},children:"Loading..."})]});return A?p(A.Provider,{value:b,children:O}):O}}function Me(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",a=Promise.resolve(Ae(r)).then(d=>(d?.head&&J(d.head),d)),s=Te(a,r);return se(n,p(s,{}))}export{Me as mountWebframezClient,He as useCookie,ze as useRouter};
1
+ import m,{useEffect as D,useState as f}from"react";import{hydrateRoot as se}from"react-dom/client";import{createFromFetch as Y,createFromReadableStream as ce}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as de}from"@webtypen/webframez-react/route-slot";var ie=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function c(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function k(e,t){let n=e.trim(),o=c(t);return!n||!o||ie.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function P(e,t){if(!e)return;let n=c(e.basename)??c(t),o=c(e.routeBasePath),r=c(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=k(a.favicon,n)),a.links&&(a.links=a.links.map(s=>({...s,href:k(s.href,n)}))),a}import w from"react";var z="webframez-route-children",M="__webframezRouteChildren",$="WebframezRouteChildren",S=()=>w.createElement(z);S.displayName=$;S[M]=!0;var ae=S;function U(e){if(e===z||e===ae)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[M]===!0||t.displayName===$||t.name==="RouteChildren"}catch{return!1}}function H(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function E(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let d=!1,_=e.map(l=>{let h=E(l,t);return h!==l&&(d=!0),h});return d?_:e}if(H(e)&&U(e.type))return t;let n=w.isValidElement(e);if(!n&&!H(e))return e;if(n&&U(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=E(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?w.cloneElement(e,void 0,...r):w.cloneElement(e,void 0,r);let a=e,s={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return w.createElement(a.type,s)}import{Fragment as Pe,jsx as p,jsxs as Se}from"react/jsx-runtime";var ue={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},A=typeof m.createContext=="function"?m.createContext(null):null,Z="__WEBFRAMEZ_ROUTER__",le="__WEBFRAMEZ_REACT_BUILD_ID",fe="x-webframez-react-build",pe="[data-webframez-head='true']";function W(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function x(e){return c(e)??""}function me(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function K(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Re(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function V(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=Re(),o=me(e||"/",t);return K(n,o)}function X(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function we(){if(typeof window>"u")return"";let e=window[le];return typeof e=="string"?e:""}function _e(e){let t=we();return!!t&&!!e&&t!==e}function N(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function he(){return typeof window>"u"?null:window[Z]??null}function ge(e){typeof window>"u"||(window[Z]=e)}function F(){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("="),a=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(s))}return e}function j(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 He(){return m.useMemo(()=>({all:()=>F(),get:e=>F()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=j(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=j(e,"",{...t??{},maxAge:0}))}}),[])}function ze(){let e=A?m.useContext(A):null;if(!e){let t=he();if(t)return t;if(typeof window>"u")return ue;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Ce({active:e}){return p("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 G(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 q(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 v(e){if(typeof document>"u")return;let t=P(e)??e;J(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(pe))n.remove();t.description&&G({name:"description",content:t.description}),t.favicon&&q({rel:"icon",href:t.favicon});for(let n of t.meta??[])G(n);for(let n of t.links??[])q(n)}function J(e){if(typeof window>"u")return;let t=P(e)??e,n=c(t.basename),o=c(t.routeBasePath),r=c(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=K(r,"/rsc"))}function ye(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Ee(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,ce(ye(e)))}function Ae(e){let t=X(e),n=V(window.location.pathname);return Ee()??Y(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function Te(e,t){return function(){let o=m.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,s]=f(o.model),[d,_]=f(o.contextModel),[l,h]=f(o.pageModel),[I,B]=f(o.head),[Q,g]=f(!1),[ee,te]=f(!1),[ne,T]=f(r);async function b(i){let y=X(t),u=V(i.pathname),R=await fetch(`${y}?path=${encodeURIComponent(u)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return _e(R.headers.get(fe))?(N(i),await new Promise(()=>{})):await Y(Promise.resolve(R))}async function C(i,y="push"){g(!0);try{let u=await b(i);v(u.head),B(u.head),s(u.model),_(u.contextModel),h(u.pageModel),T(!0);let R=`${i.pathname}${i.search}${i.hash}`;y==="replace"?(history.replaceState(null,"",R),W()):y==="push"&&(history.pushState(null,"",R),W())}catch(u){console.error("[webframez-react] Failed to render route",u),N(i),s(p("p",{children:"Failed to load route."}))}finally{g(!1)}}async function oe(){g(!0);try{let i=await b(new URL(window.location.href));if(v(i.head),B(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){_(i.contextModel),T(!0);return}s(i.model),T(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i),N(new URL(window.location.href))}finally{g(!1)}}D(()=>{v(I)},[I]),D(()=>{te(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let L=m.useMemo(()=>({push:i=>{C(new URL(i,window.location.origin),"push")},replace:i=>{C(new URL(i,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{oe()}}),[]);ge(L);let re=ne&&typeof l<"u"?d?p(de,{page:l,children:E(d,l)}):l:a,O=Se(Pe,{children:[ee?p(Ce,{active:Q}):null,re??p("p",{style:{padding:24},children:"Loading..."})]});return A?p(A.Provider,{value:L,children:O}):O}}function Me(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",a=Promise.resolve(Ae(r)).then(d=>(d?.head&&J(d.head),d)),s=Te(a,r);return se(n,p(s,{}))}export{Me as mountWebframezClient,He as useCookie,ze as useRouter};
package/dist/http.cjs CHANGED
@@ -54,6 +54,7 @@ function createHTMLShell(options = {}) {
54
54
  clientScriptUrl = "/client.js",
55
55
  buildId = "",
56
56
  headTags = "",
57
+ bodyClassName = "",
57
58
  rootHtml = "",
58
59
  initialFlightData = "",
59
60
  basename = "",
@@ -102,7 +103,7 @@ function createHTMLShell(options = {}) {
102
103
  <title>${title}</title>
103
104
  ${headTags}
104
105
  </head>
105
- <body>
106
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
106
107
  <div id="root">${rootHtml}</div>
107
108
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
108
109
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -472,6 +473,9 @@ function mergeHead(...configs) {
472
473
  if (config.description) {
473
474
  merged.description = config.description;
474
475
  }
476
+ if (hasOwn("bodyClassName")) {
477
+ merged.bodyClassName = config.bodyClassName;
478
+ }
475
479
  if (hasOwn("basename")) {
476
480
  merged.basename = config.basename;
477
481
  }
@@ -632,7 +636,8 @@ function createFileRouter(options) {
632
636
  model: fallback,
633
637
  head: {
634
638
  title: `${statusCode} - ${message}`
635
- }
639
+ },
640
+ context: errorProps
636
641
  };
637
642
  }
638
643
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -647,7 +652,8 @@ function createFileRouter(options) {
647
652
  model,
648
653
  contextModel,
649
654
  pageModel: errorNode,
650
- head: mergeHead(layoutHead, errorHead)
655
+ head: mergeHead(layoutHead, errorHead),
656
+ context: errorProps
651
657
  };
652
658
  }
653
659
  function normalizeMiddlewareNames(config) {
@@ -772,7 +778,8 @@ function createFileRouter(options) {
772
778
  model,
773
779
  contextModel,
774
780
  pageModel: pageNode,
775
- head: mergeHead(layoutHead, pageHead)
781
+ head: mergeHead(layoutHead, pageHead),
782
+ context: pageContext
776
783
  };
777
784
  } catch (error) {
778
785
  if (isRouteAbort(error)) {
@@ -792,6 +799,38 @@ function parseSearchParams(query) {
792
799
  }
793
800
 
794
801
  // src/http.ts
802
+ function attachResolvedContextToCoreRequest(req, context) {
803
+ if (!context) {
804
+ return;
805
+ }
806
+ const coreRequest = req.__webframezCoreRequest;
807
+ if (!coreRequest) {
808
+ return;
809
+ }
810
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
811
+ const env = data?.env;
812
+ const website = data?.website;
813
+ coreRequest.__webframezReactContext = {
814
+ pathname: context.pathname,
815
+ params: context.params,
816
+ request: context.request,
817
+ data: data ? {
818
+ env,
819
+ website,
820
+ is_env_website_request: data.is_env_website_request,
821
+ is_website_domain_request: data.is_website_domain_request,
822
+ website_base_path: data.website_base_path,
823
+ website_route_base_path: data.website_route_base_path,
824
+ website_transport_base_path: data.website_transport_base_path
825
+ } : void 0
826
+ };
827
+ if (!coreRequest.env && env) {
828
+ coreRequest.env = env;
829
+ }
830
+ if (!coreRequest.website && website) {
831
+ coreRequest.website = website;
832
+ }
833
+ }
795
834
  function createInitialHtmlErrorMarkup(message) {
796
835
  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>`;
797
836
  }
@@ -1622,6 +1661,7 @@ function createNodeRequestHandler(options) {
1622
1661
  request: requestContext
1623
1662
  })
1624
1663
  );
1664
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1625
1665
  const payload = {
1626
1666
  model: resolved2.model,
1627
1667
  contextModel: resolved2.contextModel,
@@ -1696,6 +1736,7 @@ function createNodeRequestHandler(options) {
1696
1736
  )
1697
1737
  })
1698
1738
  );
1739
+ attachResolvedContextToCoreRequest(req, resolved.context);
1699
1740
  const initialPayload = {
1700
1741
  model: resolved.model,
1701
1742
  head: resolved.head
@@ -1759,6 +1800,7 @@ function createNodeRequestHandler(options) {
1759
1800
  createHTMLShell({
1760
1801
  title: resolved.head.title || "Webframez React",
1761
1802
  headTags: renderHeadToString(resolved.head),
1803
+ bodyClassName: resolved.head.bodyClassName || "",
1762
1804
  clientScriptUrl: shellClientScriptUrl,
1763
1805
  buildId: manifestState.buildId,
1764
1806
  rscEndpoint: shellRscEndpoint,
package/dist/http.js CHANGED
@@ -34,6 +34,7 @@ function createHTMLShell(options = {}) {
34
34
  clientScriptUrl = "/client.js",
35
35
  buildId = "",
36
36
  headTags = "",
37
+ bodyClassName = "",
37
38
  rootHtml = "",
38
39
  initialFlightData = "",
39
40
  basename = "",
@@ -82,7 +83,7 @@ function createHTMLShell(options = {}) {
82
83
  <title>${title}</title>
83
84
  ${headTags}
84
85
  </head>
85
- <body>
86
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
86
87
  <div id="root">${rootHtml}</div>
87
88
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
88
89
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -452,6 +453,9 @@ function mergeHead(...configs) {
452
453
  if (config.description) {
453
454
  merged.description = config.description;
454
455
  }
456
+ if (hasOwn("bodyClassName")) {
457
+ merged.bodyClassName = config.bodyClassName;
458
+ }
455
459
  if (hasOwn("basename")) {
456
460
  merged.basename = config.basename;
457
461
  }
@@ -612,7 +616,8 @@ function createFileRouter(options) {
612
616
  model: fallback,
613
617
  head: {
614
618
  title: `${statusCode} - ${message}`
615
- }
619
+ },
620
+ context: errorProps
616
621
  };
617
622
  }
618
623
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -627,7 +632,8 @@ function createFileRouter(options) {
627
632
  model,
628
633
  contextModel,
629
634
  pageModel: errorNode,
630
- head: mergeHead(layoutHead, errorHead)
635
+ head: mergeHead(layoutHead, errorHead),
636
+ context: errorProps
631
637
  };
632
638
  }
633
639
  function normalizeMiddlewareNames(config) {
@@ -752,7 +758,8 @@ function createFileRouter(options) {
752
758
  model,
753
759
  contextModel,
754
760
  pageModel: pageNode,
755
- head: mergeHead(layoutHead, pageHead)
761
+ head: mergeHead(layoutHead, pageHead),
762
+ context: pageContext
756
763
  };
757
764
  } catch (error) {
758
765
  if (isRouteAbort(error)) {
@@ -772,6 +779,38 @@ function parseSearchParams(query) {
772
779
  }
773
780
 
774
781
  // src/http.ts
782
+ function attachResolvedContextToCoreRequest(req, context) {
783
+ if (!context) {
784
+ return;
785
+ }
786
+ const coreRequest = req.__webframezCoreRequest;
787
+ if (!coreRequest) {
788
+ return;
789
+ }
790
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
791
+ const env = data?.env;
792
+ const website = data?.website;
793
+ coreRequest.__webframezReactContext = {
794
+ pathname: context.pathname,
795
+ params: context.params,
796
+ request: context.request,
797
+ data: data ? {
798
+ env,
799
+ website,
800
+ is_env_website_request: data.is_env_website_request,
801
+ is_website_domain_request: data.is_website_domain_request,
802
+ website_base_path: data.website_base_path,
803
+ website_route_base_path: data.website_route_base_path,
804
+ website_transport_base_path: data.website_transport_base_path
805
+ } : void 0
806
+ };
807
+ if (!coreRequest.env && env) {
808
+ coreRequest.env = env;
809
+ }
810
+ if (!coreRequest.website && website) {
811
+ coreRequest.website = website;
812
+ }
813
+ }
775
814
  function createInitialHtmlErrorMarkup(message) {
776
815
  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>`;
777
816
  }
@@ -1602,6 +1641,7 @@ function createNodeRequestHandler(options) {
1602
1641
  request: requestContext
1603
1642
  })
1604
1643
  );
1644
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1605
1645
  const payload = {
1606
1646
  model: resolved2.model,
1607
1647
  contextModel: resolved2.contextModel,
@@ -1676,6 +1716,7 @@ function createNodeRequestHandler(options) {
1676
1716
  )
1677
1717
  })
1678
1718
  );
1719
+ attachResolvedContextToCoreRequest(req, resolved.context);
1679
1720
  const initialPayload = {
1680
1721
  model: resolved.model,
1681
1722
  head: resolved.head
@@ -1739,6 +1780,7 @@ function createNodeRequestHandler(options) {
1739
1780
  createHTMLShell({
1740
1781
  title: resolved.head.title || "Webframez React",
1741
1782
  headTags: renderHeadToString(resolved.head),
1783
+ bodyClassName: resolved.head.bodyClassName || "",
1742
1784
  clientScriptUrl: shellClientScriptUrl,
1743
1785
  buildId: manifestState.buildId,
1744
1786
  rscEndpoint: shellRscEndpoint,
package/dist/index.cjs CHANGED
@@ -61,6 +61,7 @@ function createHTMLShell(options = {}) {
61
61
  clientScriptUrl = "/client.js",
62
62
  buildId = "",
63
63
  headTags = "",
64
+ bodyClassName = "",
64
65
  rootHtml = "",
65
66
  initialFlightData = "",
66
67
  basename = "",
@@ -109,7 +110,7 @@ function createHTMLShell(options = {}) {
109
110
  <title>${title}</title>
110
111
  ${headTags}
111
112
  </head>
112
- <body>
113
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
113
114
  <div id="root">${rootHtml}</div>
114
115
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
115
116
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -507,6 +508,9 @@ function mergeHead(...configs) {
507
508
  if (config.description) {
508
509
  merged.description = config.description;
509
510
  }
511
+ if (hasOwn("bodyClassName")) {
512
+ merged.bodyClassName = config.bodyClassName;
513
+ }
510
514
  if (hasOwn("basename")) {
511
515
  merged.basename = config.basename;
512
516
  }
@@ -667,7 +671,8 @@ function createFileRouter(options) {
667
671
  model: fallback,
668
672
  head: {
669
673
  title: `${statusCode} - ${message}`
670
- }
674
+ },
675
+ context: errorProps
671
676
  };
672
677
  }
673
678
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -682,7 +687,8 @@ function createFileRouter(options) {
682
687
  model,
683
688
  contextModel,
684
689
  pageModel: errorNode,
685
- head: mergeHead(layoutHead, errorHead)
690
+ head: mergeHead(layoutHead, errorHead),
691
+ context: errorProps
686
692
  };
687
693
  }
688
694
  function normalizeMiddlewareNames(config) {
@@ -807,7 +813,8 @@ function createFileRouter(options) {
807
813
  model,
808
814
  contextModel,
809
815
  pageModel: pageNode,
810
- head: mergeHead(layoutHead, pageHead)
816
+ head: mergeHead(layoutHead, pageHead),
817
+ context: pageContext
811
818
  };
812
819
  } catch (error) {
813
820
  if (isRouteAbort(error)) {
@@ -832,6 +839,38 @@ var import_node_path3 = __toESM(require("node:path"), 1);
832
839
  var import_node_url = require("node:url");
833
840
  var import_node_child_process = require("node:child_process");
834
841
  var import_node_zlib = require("node:zlib");
842
+ function attachResolvedContextToCoreRequest(req, context) {
843
+ if (!context) {
844
+ return;
845
+ }
846
+ const coreRequest = req.__webframezCoreRequest;
847
+ if (!coreRequest) {
848
+ return;
849
+ }
850
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
851
+ const env = data?.env;
852
+ const website = data?.website;
853
+ coreRequest.__webframezReactContext = {
854
+ pathname: context.pathname,
855
+ params: context.params,
856
+ request: context.request,
857
+ data: data ? {
858
+ env,
859
+ website,
860
+ is_env_website_request: data.is_env_website_request,
861
+ is_website_domain_request: data.is_website_domain_request,
862
+ website_base_path: data.website_base_path,
863
+ website_route_base_path: data.website_route_base_path,
864
+ website_transport_base_path: data.website_transport_base_path
865
+ } : void 0
866
+ };
867
+ if (!coreRequest.env && env) {
868
+ coreRequest.env = env;
869
+ }
870
+ if (!coreRequest.website && website) {
871
+ coreRequest.website = website;
872
+ }
873
+ }
835
874
  function createInitialHtmlErrorMarkup(message) {
836
875
  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>`;
837
876
  }
@@ -1662,6 +1701,7 @@ function createNodeRequestHandler(options) {
1662
1701
  request: requestContext
1663
1702
  })
1664
1703
  );
1704
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1665
1705
  const payload = {
1666
1706
  model: resolved2.model,
1667
1707
  contextModel: resolved2.contextModel,
@@ -1736,6 +1776,7 @@ function createNodeRequestHandler(options) {
1736
1776
  )
1737
1777
  })
1738
1778
  );
1779
+ attachResolvedContextToCoreRequest(req, resolved.context);
1739
1780
  const initialPayload = {
1740
1781
  model: resolved.model,
1741
1782
  head: resolved.head
@@ -1799,6 +1840,7 @@ function createNodeRequestHandler(options) {
1799
1840
  createHTMLShell({
1800
1841
  title: resolved.head.title || "Webframez React",
1801
1842
  headTags: renderHeadToString(resolved.head),
1843
+ bodyClassName: resolved.head.bodyClassName || "",
1802
1844
  clientScriptUrl: shellClientScriptUrl,
1803
1845
  buildId: manifestState.buildId,
1804
1846
  rscEndpoint: shellRscEndpoint,
@@ -2016,7 +2058,13 @@ function registerRouteRenderer(route, methodName) {
2016
2058
  `Route.${methodName} only supports node/http requests`
2017
2059
  );
2018
2060
  }
2019
- await handleNodeRequest(req.message, res.res);
2061
+ const message = req.message;
2062
+ message.__webframezCoreRequest = req;
2063
+ try {
2064
+ await handleNodeRequest(message, res.res);
2065
+ } finally {
2066
+ delete message.__webframezCoreRequest;
2067
+ }
2020
2068
  await waitForResponseFinish(res.res);
2021
2069
  },
2022
2070
  routeOptions
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ function createHTMLShell(options = {}) {
22
22
  clientScriptUrl = "/client.js",
23
23
  buildId = "",
24
24
  headTags = "",
25
+ bodyClassName = "",
25
26
  rootHtml = "",
26
27
  initialFlightData = "",
27
28
  basename = "",
@@ -70,7 +71,7 @@ function createHTMLShell(options = {}) {
70
71
  <title>${title}</title>
71
72
  ${headTags}
72
73
  </head>
73
- <body>
74
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
74
75
  <div id="root">${rootHtml}</div>
75
76
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
76
77
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -468,6 +469,9 @@ function mergeHead(...configs) {
468
469
  if (config.description) {
469
470
  merged.description = config.description;
470
471
  }
472
+ if (hasOwn("bodyClassName")) {
473
+ merged.bodyClassName = config.bodyClassName;
474
+ }
471
475
  if (hasOwn("basename")) {
472
476
  merged.basename = config.basename;
473
477
  }
@@ -628,7 +632,8 @@ function createFileRouter(options) {
628
632
  model: fallback,
629
633
  head: {
630
634
  title: `${statusCode} - ${message}`
631
- }
635
+ },
636
+ context: errorProps
632
637
  };
633
638
  }
634
639
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -643,7 +648,8 @@ function createFileRouter(options) {
643
648
  model,
644
649
  contextModel,
645
650
  pageModel: errorNode,
646
- head: mergeHead(layoutHead, errorHead)
651
+ head: mergeHead(layoutHead, errorHead),
652
+ context: errorProps
647
653
  };
648
654
  }
649
655
  function normalizeMiddlewareNames(config) {
@@ -768,7 +774,8 @@ function createFileRouter(options) {
768
774
  model,
769
775
  contextModel,
770
776
  pageModel: pageNode,
771
- head: mergeHead(layoutHead, pageHead)
777
+ head: mergeHead(layoutHead, pageHead),
778
+ context: pageContext
772
779
  };
773
780
  } catch (error) {
774
781
  if (isRouteAbort(error)) {
@@ -798,6 +805,38 @@ import {
798
805
  createGzip,
799
806
  gzipSync
800
807
  } from "node:zlib";
808
+ function attachResolvedContextToCoreRequest(req, context) {
809
+ if (!context) {
810
+ return;
811
+ }
812
+ const coreRequest = req.__webframezCoreRequest;
813
+ if (!coreRequest) {
814
+ return;
815
+ }
816
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
817
+ const env = data?.env;
818
+ const website = data?.website;
819
+ coreRequest.__webframezReactContext = {
820
+ pathname: context.pathname,
821
+ params: context.params,
822
+ request: context.request,
823
+ data: data ? {
824
+ env,
825
+ website,
826
+ is_env_website_request: data.is_env_website_request,
827
+ is_website_domain_request: data.is_website_domain_request,
828
+ website_base_path: data.website_base_path,
829
+ website_route_base_path: data.website_route_base_path,
830
+ website_transport_base_path: data.website_transport_base_path
831
+ } : void 0
832
+ };
833
+ if (!coreRequest.env && env) {
834
+ coreRequest.env = env;
835
+ }
836
+ if (!coreRequest.website && website) {
837
+ coreRequest.website = website;
838
+ }
839
+ }
801
840
  function createInitialHtmlErrorMarkup(message) {
802
841
  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>`;
803
842
  }
@@ -1628,6 +1667,7 @@ function createNodeRequestHandler(options) {
1628
1667
  request: requestContext
1629
1668
  })
1630
1669
  );
1670
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1631
1671
  const payload = {
1632
1672
  model: resolved2.model,
1633
1673
  contextModel: resolved2.contextModel,
@@ -1702,6 +1742,7 @@ function createNodeRequestHandler(options) {
1702
1742
  )
1703
1743
  })
1704
1744
  );
1745
+ attachResolvedContextToCoreRequest(req, resolved.context);
1705
1746
  const initialPayload = {
1706
1747
  model: resolved.model,
1707
1748
  head: resolved.head
@@ -1765,6 +1806,7 @@ function createNodeRequestHandler(options) {
1765
1806
  createHTMLShell({
1766
1807
  title: resolved.head.title || "Webframez React",
1767
1808
  headTags: renderHeadToString(resolved.head),
1809
+ bodyClassName: resolved.head.bodyClassName || "",
1768
1810
  clientScriptUrl: shellClientScriptUrl,
1769
1811
  buildId: manifestState.buildId,
1770
1812
  rscEndpoint: shellRscEndpoint,
@@ -1982,7 +2024,13 @@ function registerRouteRenderer(route, methodName) {
1982
2024
  `Route.${methodName} only supports node/http requests`
1983
2025
  );
1984
2026
  }
1985
- await handleNodeRequest(req.message, res.res);
2027
+ const message = req.message;
2028
+ message.__webframezCoreRequest = req;
2029
+ try {
2030
+ await handleNodeRequest(message, res.res);
2031
+ } finally {
2032
+ delete message.__webframezCoreRequest;
2033
+ }
1986
2034
  await waitForResponseFinish(res.res);
1987
2035
  },
1988
2036
  routeOptions
package/dist/router.cjs CHANGED
@@ -357,6 +357,9 @@ function mergeHead(...configs) {
357
357
  if (config.description) {
358
358
  merged.description = config.description;
359
359
  }
360
+ if (hasOwn("bodyClassName")) {
361
+ merged.bodyClassName = config.bodyClassName;
362
+ }
360
363
  if (hasOwn("basename")) {
361
364
  merged.basename = config.basename;
362
365
  }
@@ -517,7 +520,8 @@ function createFileRouter(options) {
517
520
  model: fallback,
518
521
  head: {
519
522
  title: `${statusCode} - ${message}`
520
- }
523
+ },
524
+ context: errorProps
521
525
  };
522
526
  }
523
527
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -532,7 +536,8 @@ function createFileRouter(options) {
532
536
  model,
533
537
  contextModel,
534
538
  pageModel: errorNode,
535
- head: mergeHead(layoutHead, errorHead)
539
+ head: mergeHead(layoutHead, errorHead),
540
+ context: errorProps
536
541
  };
537
542
  }
538
543
  function normalizeMiddlewareNames(config) {
@@ -657,7 +662,8 @@ function createFileRouter(options) {
657
662
  model,
658
663
  contextModel,
659
664
  pageModel: pageNode,
660
- head: mergeHead(layoutHead, pageHead)
665
+ head: mergeHead(layoutHead, pageHead),
666
+ context: pageContext
661
667
  };
662
668
  } catch (error) {
663
669
  if (isRouteAbort(error)) {
package/dist/router.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type { ReactNode } from "react";
2
- import type { HeadConfig, RouteSearchParams } from "./types";
2
+ import type { HeadConfig, RouteContext, RouteRequestContext, RouteSearchParams } from "./types";
3
3
 
4
4
  export type ResolvedRoute = {
5
5
  statusCode: number;
6
6
  model: ReactNode;
7
7
  head: HeadConfig;
8
+ context: RouteContext;
8
9
  contextModel?: ReactNode;
9
10
  pageModel?: ReactNode;
10
11
  };
@@ -14,6 +15,7 @@ export function createFileRouter(options: { pagesDir: string }): {
14
15
  pathname: string;
15
16
  searchParams: RouteSearchParams;
16
17
  cookies?: Record<string, string>;
18
+ request?: RouteRequestContext;
17
19
  }): Promise<ResolvedRoute>;
18
20
  readSearchParams(urlSearchParams: URLSearchParams): RouteSearchParams;
19
21
  };
package/dist/router.js CHANGED
@@ -327,6 +327,9 @@ function mergeHead(...configs) {
327
327
  if (config.description) {
328
328
  merged.description = config.description;
329
329
  }
330
+ if (hasOwn("bodyClassName")) {
331
+ merged.bodyClassName = config.bodyClassName;
332
+ }
330
333
  if (hasOwn("basename")) {
331
334
  merged.basename = config.basename;
332
335
  }
@@ -487,7 +490,8 @@ function createFileRouter(options) {
487
490
  model: fallback,
488
491
  head: {
489
492
  title: `${statusCode} - ${message}`
490
- }
493
+ },
494
+ context: errorProps
491
495
  };
492
496
  }
493
497
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -502,7 +506,8 @@ function createFileRouter(options) {
502
506
  model,
503
507
  contextModel,
504
508
  pageModel: errorNode,
505
- head: mergeHead(layoutHead, errorHead)
509
+ head: mergeHead(layoutHead, errorHead),
510
+ context: errorProps
506
511
  };
507
512
  }
508
513
  function normalizeMiddlewareNames(config) {
@@ -627,7 +632,8 @@ function createFileRouter(options) {
627
632
  model,
628
633
  contextModel,
629
634
  pageModel: pageNode,
630
- head: mergeHead(layoutHead, pageHead)
635
+ head: mergeHead(layoutHead, pageHead),
636
+ context: pageContext
631
637
  };
632
638
  } catch (error) {
633
639
  if (isRouteAbort(error)) {
package/dist/types.d.ts CHANGED
@@ -60,6 +60,7 @@ export type HeadLinkTag = {
60
60
  export type HeadConfig = {
61
61
  title?: string;
62
62
  description?: string;
63
+ bodyClassName?: string;
63
64
  basename?: string;
64
65
  routeBasePath?: string;
65
66
  transportBasePath?: string;
@@ -113,6 +114,7 @@ export type CreateHtmlShellOptions = {
113
114
  clientScriptUrl?: string;
114
115
  buildId?: string;
115
116
  headTags?: string;
117
+ bodyClassName?: string;
116
118
  rootHtml?: string;
117
119
  initialFlightData?: string;
118
120
  basename?: string;
@@ -61,6 +61,7 @@ function createHTMLShell(options = {}) {
61
61
  clientScriptUrl = "/client.js",
62
62
  buildId = "",
63
63
  headTags = "",
64
+ bodyClassName = "",
64
65
  rootHtml = "",
65
66
  initialFlightData = "",
66
67
  basename = "",
@@ -109,7 +110,7 @@ function createHTMLShell(options = {}) {
109
110
  <title>${title}</title>
110
111
  ${headTags}
111
112
  </head>
112
- <body>
113
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
113
114
  <div id="root">${rootHtml}</div>
114
115
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
115
116
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -479,6 +480,9 @@ function mergeHead(...configs) {
479
480
  if (config.description) {
480
481
  merged.description = config.description;
481
482
  }
483
+ if (hasOwn("bodyClassName")) {
484
+ merged.bodyClassName = config.bodyClassName;
485
+ }
482
486
  if (hasOwn("basename")) {
483
487
  merged.basename = config.basename;
484
488
  }
@@ -639,7 +643,8 @@ function createFileRouter(options) {
639
643
  model: fallback,
640
644
  head: {
641
645
  title: `${statusCode} - ${message}`
642
- }
646
+ },
647
+ context: errorProps
643
648
  };
644
649
  }
645
650
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -654,7 +659,8 @@ function createFileRouter(options) {
654
659
  model,
655
660
  contextModel,
656
661
  pageModel: errorNode,
657
- head: mergeHead(layoutHead, errorHead)
662
+ head: mergeHead(layoutHead, errorHead),
663
+ context: errorProps
658
664
  };
659
665
  }
660
666
  function normalizeMiddlewareNames(config) {
@@ -779,7 +785,8 @@ function createFileRouter(options) {
779
785
  model,
780
786
  contextModel,
781
787
  pageModel: pageNode,
782
- head: mergeHead(layoutHead, pageHead)
788
+ head: mergeHead(layoutHead, pageHead),
789
+ context: pageContext
783
790
  };
784
791
  } catch (error) {
785
792
  if (isRouteAbort(error)) {
@@ -799,6 +806,38 @@ function parseSearchParams(query) {
799
806
  }
800
807
 
801
808
  // src/http.ts
809
+ function attachResolvedContextToCoreRequest(req, context) {
810
+ if (!context) {
811
+ return;
812
+ }
813
+ const coreRequest = req.__webframezCoreRequest;
814
+ if (!coreRequest) {
815
+ return;
816
+ }
817
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
818
+ const env = data?.env;
819
+ const website = data?.website;
820
+ coreRequest.__webframezReactContext = {
821
+ pathname: context.pathname,
822
+ params: context.params,
823
+ request: context.request,
824
+ data: data ? {
825
+ env,
826
+ website,
827
+ is_env_website_request: data.is_env_website_request,
828
+ is_website_domain_request: data.is_website_domain_request,
829
+ website_base_path: data.website_base_path,
830
+ website_route_base_path: data.website_route_base_path,
831
+ website_transport_base_path: data.website_transport_base_path
832
+ } : void 0
833
+ };
834
+ if (!coreRequest.env && env) {
835
+ coreRequest.env = env;
836
+ }
837
+ if (!coreRequest.website && website) {
838
+ coreRequest.website = website;
839
+ }
840
+ }
802
841
  function createInitialHtmlErrorMarkup(message) {
803
842
  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>`;
804
843
  }
@@ -1629,6 +1668,7 @@ function createNodeRequestHandler(options) {
1629
1668
  request: requestContext
1630
1669
  })
1631
1670
  );
1671
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1632
1672
  const payload = {
1633
1673
  model: resolved2.model,
1634
1674
  contextModel: resolved2.contextModel,
@@ -1703,6 +1743,7 @@ function createNodeRequestHandler(options) {
1703
1743
  )
1704
1744
  })
1705
1745
  );
1746
+ attachResolvedContextToCoreRequest(req, resolved.context);
1706
1747
  const initialPayload = {
1707
1748
  model: resolved.model,
1708
1749
  head: resolved.head
@@ -1766,6 +1807,7 @@ function createNodeRequestHandler(options) {
1766
1807
  createHTMLShell({
1767
1808
  title: resolved.head.title || "Webframez React",
1768
1809
  headTags: renderHeadToString(resolved.head),
1810
+ bodyClassName: resolved.head.bodyClassName || "",
1769
1811
  clientScriptUrl: shellClientScriptUrl,
1770
1812
  buildId: manifestState.buildId,
1771
1813
  rscEndpoint: shellRscEndpoint,
@@ -1982,7 +2024,13 @@ function registerRouteRenderer(route, methodName) {
1982
2024
  `Route.${methodName} only supports node/http requests`
1983
2025
  );
1984
2026
  }
1985
- await handleNodeRequest(req.message, res.res);
2027
+ const message = req.message;
2028
+ message.__webframezCoreRequest = req;
2029
+ try {
2030
+ await handleNodeRequest(message, res.res);
2031
+ } finally {
2032
+ delete message.__webframezCoreRequest;
2033
+ }
1986
2034
  await waitForResponseFinish(res.res);
1987
2035
  },
1988
2036
  routeOptions
@@ -37,6 +37,7 @@ function createHTMLShell(options = {}) {
37
37
  clientScriptUrl = "/client.js",
38
38
  buildId = "",
39
39
  headTags = "",
40
+ bodyClassName = "",
40
41
  rootHtml = "",
41
42
  initialFlightData = "",
42
43
  basename = "",
@@ -85,7 +86,7 @@ function createHTMLShell(options = {}) {
85
86
  <title>${title}</title>
86
87
  ${headTags}
87
88
  </head>
88
- <body>
89
+ <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
89
90
  <div id="root">${rootHtml}</div>
90
91
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
91
92
  <script>window.__RSC_BASENAME = "${basename}";</script>
@@ -455,6 +456,9 @@ function mergeHead(...configs) {
455
456
  if (config.description) {
456
457
  merged.description = config.description;
457
458
  }
459
+ if (hasOwn("bodyClassName")) {
460
+ merged.bodyClassName = config.bodyClassName;
461
+ }
458
462
  if (hasOwn("basename")) {
459
463
  merged.basename = config.basename;
460
464
  }
@@ -615,7 +619,8 @@ function createFileRouter(options) {
615
619
  model: fallback,
616
620
  head: {
617
621
  title: `${statusCode} - ${message}`
618
- }
622
+ },
623
+ context: errorProps
619
624
  };
620
625
  }
621
626
  const errorModule = resolveModule(errorPath, pagesDir);
@@ -630,7 +635,8 @@ function createFileRouter(options) {
630
635
  model,
631
636
  contextModel,
632
637
  pageModel: errorNode,
633
- head: mergeHead(layoutHead, errorHead)
638
+ head: mergeHead(layoutHead, errorHead),
639
+ context: errorProps
634
640
  };
635
641
  }
636
642
  function normalizeMiddlewareNames(config) {
@@ -755,7 +761,8 @@ function createFileRouter(options) {
755
761
  model,
756
762
  contextModel,
757
763
  pageModel: pageNode,
758
- head: mergeHead(layoutHead, pageHead)
764
+ head: mergeHead(layoutHead, pageHead),
765
+ context: pageContext
759
766
  };
760
767
  } catch (error) {
761
768
  if (isRouteAbort(error)) {
@@ -775,6 +782,38 @@ function parseSearchParams(query) {
775
782
  }
776
783
 
777
784
  // src/http.ts
785
+ function attachResolvedContextToCoreRequest(req, context) {
786
+ if (!context) {
787
+ return;
788
+ }
789
+ const coreRequest = req.__webframezCoreRequest;
790
+ if (!coreRequest) {
791
+ return;
792
+ }
793
+ const data = context.data && typeof context.data === "object" ? context.data : void 0;
794
+ const env = data?.env;
795
+ const website = data?.website;
796
+ coreRequest.__webframezReactContext = {
797
+ pathname: context.pathname,
798
+ params: context.params,
799
+ request: context.request,
800
+ data: data ? {
801
+ env,
802
+ website,
803
+ is_env_website_request: data.is_env_website_request,
804
+ is_website_domain_request: data.is_website_domain_request,
805
+ website_base_path: data.website_base_path,
806
+ website_route_base_path: data.website_route_base_path,
807
+ website_transport_base_path: data.website_transport_base_path
808
+ } : void 0
809
+ };
810
+ if (!coreRequest.env && env) {
811
+ coreRequest.env = env;
812
+ }
813
+ if (!coreRequest.website && website) {
814
+ coreRequest.website = website;
815
+ }
816
+ }
778
817
  function createInitialHtmlErrorMarkup(message) {
779
818
  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>`;
780
819
  }
@@ -1605,6 +1644,7 @@ function createNodeRequestHandler(options) {
1605
1644
  request: requestContext
1606
1645
  })
1607
1646
  );
1647
+ attachResolvedContextToCoreRequest(req, resolved2.context);
1608
1648
  const payload = {
1609
1649
  model: resolved2.model,
1610
1650
  contextModel: resolved2.contextModel,
@@ -1679,6 +1719,7 @@ function createNodeRequestHandler(options) {
1679
1719
  )
1680
1720
  })
1681
1721
  );
1722
+ attachResolvedContextToCoreRequest(req, resolved.context);
1682
1723
  const initialPayload = {
1683
1724
  model: resolved.model,
1684
1725
  head: resolved.head
@@ -1742,6 +1783,7 @@ function createNodeRequestHandler(options) {
1742
1783
  createHTMLShell({
1743
1784
  title: resolved.head.title || "Webframez React",
1744
1785
  headTags: renderHeadToString(resolved.head),
1786
+ bodyClassName: resolved.head.bodyClassName || "",
1745
1787
  clientScriptUrl: shellClientScriptUrl,
1746
1788
  buildId: manifestState.buildId,
1747
1789
  rscEndpoint: shellRscEndpoint,
@@ -1958,7 +2000,13 @@ function registerRouteRenderer(route, methodName) {
1958
2000
  `Route.${methodName} only supports node/http requests`
1959
2001
  );
1960
2002
  }
1961
- await handleNodeRequest(req.message, res.res);
2003
+ const message = req.message;
2004
+ message.__webframezCoreRequest = req;
2005
+ try {
2006
+ await handleNodeRequest(message, res.res);
2007
+ } finally {
2008
+ delete message.__webframezCoreRequest;
2009
+ }
1962
2010
  await waitForResponseFinish(res.res);
1963
2011
  },
1964
2012
  routeOptions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.38",
3
+ "version": "0.0.40",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {