@webtypen/webframez-react 0.0.47 → 0.0.49

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 fe=Object.create;var y=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var Re=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var n in t)y(e,n,{get:t[n],enumerable:!0})},D=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of me(t))!_e.call(e,r)&&r!==n&&y(e,r,{get:()=>t[r],enumerable:!(o=pe(t,r))||o.enumerable});return e};var M=(e,t,n)=>(n=e!=null?fe(Re(e)):{},D(t||!e||!e.__esModule?y(n,"default",{value:e,enumerable:!0}):n,e)),we=e=>D(y({},"__esModule",{value:!0}),e);var Fe={};he(Fe,{mountWebframezClient:()=>We,useCookie:()=>ke,useRouter:()=>Ue});module.exports=we(Fe);var s=M(require("react"),1),Q=require("react-dom/client"),h=require("react-server-dom-webpack/client"),ee=require("@webtypen/webframez-react/route-slot");var ge=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function l(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function $(e,t){let n=e.trim(),o=l(t);return!n||!o||ge.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=l(e.basename)??l(t),o=l(e.routeBasePath),r=l(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=$(a.favicon,n)),a.links&&(a.links=a.links.map(c=>({...c,href:$(c.href,n)}))),a}var p=M(require("react"),1),G="webframez-route-children",q="__webframezRouteChildren",Y="WebframezRouteChildren",Ce="__webframezRouteChildrenSlot",Ee="WebframezRouteChildrenSlot",I=()=>p.default.createElement(G);I.displayName=Y;I[q]=!0;var ye=I;function W(e){if(e===G||e===ye)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[q]===!0||t.displayName===Y||t.name==="RouteChildren"}catch{return!1}}function F(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[Ce]===!0||t.displayName===Ee||t.name==="RouteChildrenSlot"}catch{return!1}}function j(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function T(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let u=!1,w=e.map(m=>{let R=T(m,t);return R!==m&&(u=!0),R});return u?w:e}if(j(e)&&(W(e.type)||F(e.type)))return t;let n=p.default.isValidElement(e);if(!n&&!j(e))return e;if(n&&(W(e.type)||F(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=T(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?p.default.cloneElement(e,void 0,...r):p.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 p.default.createElement(a.type,c)}var d=require("react/jsx-runtime"),Te={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},A=typeof s.default.createContext=="function"?s.default.createContext(null):null,te="__WEBFRAMEZ_ROUTER__",Ae="__WEBFRAMEZ_REACT_BUILD_ID",Ne="x-webframez-react-build",Se="[data-webframez-head='true']";function Z(){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 L(e){return l(e)??""}function Pe(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function ne(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Ie(){return L(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function oe(e){if(typeof window>"u")return e||"/";let t=L(window.__RSC_BASENAME),n=Ie(),o=Pe(e||"/",t);return ne(n,o)}function re(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function ve(){if(typeof window>"u")return"";let e=window[Ae];return typeof e=="string"?e:""}function xe(e){let t=ve();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Le(){return typeof window>"u"?null:window[te]??null}function be(e){typeof window>"u"||(window[te]=e)}function Be(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Oe(e){return Be(e)?s.default.use(e):e}function N(e){let t=Oe(e);if(Array.isArray(t)){let r=!1,a=t.map(c=>{let u=N(c);return u!==c&&(r=!0),u});return r?a:t}if(!s.default.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=N(n.children);return o===n.children?t:Array.isArray(o)?s.default.cloneElement(t,void 0,...o):s.default.cloneElement(t,void 0,o)}function K(){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 V(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 ke(){return s.default.useMemo(()=>({all:()=>K(),get:e=>K()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=V(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=V(e,"",{...t??{},maxAge:0}))}}),[])}function Ue(){let e=A?s.default.useContext(A):null;if(!e){let t=Le();if(t)return t;if(typeof window>"u")return Te;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function He({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 X(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 J(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=P(e)??e;ie(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(Se))n.remove();t.description&&X({name:"description",content:t.description}),t.favicon&&J({rel:"icon",href:t.favicon});for(let n of t.meta??[])X(n);for(let n of t.links??[])J(n)}function ie(e){if(typeof window>"u")return;let t=P(e)??e,n=l(t.basename),o=l(t.routeBasePath),r=l(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=ne(r,"/rsc"))}function ze(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function De(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,h.createFromReadableStream)(ze(e)))}function Me(e){let t=re(e),n=oe(window.location.pathname);return De()??(0,h.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function $e(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),[u,w]=(0,s.useState)(o.contextModel),[m,R]=(0,s.useState)(o.pageModel),[b,B]=(0,s.useState)(o.head),[ae,g]=(0,s.useState)(!1),[se,ce]=(0,s.useState)(!1),[de,O]=(0,s.useState)(r);async function k(i){let E=re(t),f=oe(i.pathname),_=await fetch(`${E}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return xe(_.headers.get(Ne))?(v(i),await new Promise(()=>{})):await(0,h.createFromFetch)(Promise.resolve(_))}async function C(i,E="push"){g(!0);try{let f=await k(i);x(f.head),B(f.head),c(f.model),w(f.contextModel),R(f.pageModel),O(!1);let _=`${i.pathname}${i.search}${i.hash}`;E==="replace"?(history.replaceState(null,"",_),Z()):E==="push"&&(history.pushState(null,"",_),Z())}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 ue(){g(!0);try{let i=await k(new URL(window.location.href));x(i.head),B(i.head),c(i.model),w(i.contextModel),R(i.pageModel),O(!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)(()=>{ce(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let U=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:()=>{ue()}}),[]);be(U);let H=N(u),S=N(m),le=de&&typeof m<"u"?H?(0,d.jsx)(ee.RouteChildrenSlotProvider,{page:S,children:T(H,S)}):S:a,z=(0,d.jsxs)(d.Fragment,{children:[se?(0,d.jsx)(He,{active:ae}):null,le??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return A?(0,d.jsx)(A.Provider,{value:U,children:z}):z}}function We(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(Me(r)).then(u=>(u?.head&&ie(u.head),u)),c=$e(a,r);return(0,Q.hydrateRoot)(n,(0,d.jsx)(c,{}))}
1
+ var fe=Object.create;var E=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},D=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pe(t))!Re.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(o=me(t,r))||o.enumerable});return e};var W=(e,t,n)=>(n=e!=null?fe(ge(e)):{},D(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),we=e=>D(E({},"__esModule",{value:!0}),e);var Ye={};he(Ye,{mountWebframezClient:()=>Ke,useCookie:()=>Be,useRouter:()=>Oe});module.exports=we(Ye);var c=W(require("react"),1),J=require("react-dom/client"),h=require("react-server-dom-webpack/client"),Q=require("@webtypen/webframez-react/route-slot");var _e=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function l(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function b(e,t){let n=e.trim(),o=l(t);return!n||!o||_e.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function L(e,t){if(!e)return;let n=l(e.basename)??l(t),o=l(e.routeBasePath),r=l(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=b(i.favicon,n)),i.links&&(i.links=i.links.map(a=>({...a,href:b(a.href,n)}))),i.scripts&&(i.scripts=i.scripts.map(a=>({...a,...a.src?{src:b(a.src,n)}:{}}))),i}var m=W(require("react"),1),q="webframez-route-children",K="__webframezRouteChildren",Y="WebframezRouteChildren",Ce="__webframezRouteChildrenSlot",ye="WebframezRouteChildrenSlot",x=()=>m.default.createElement(q);x.displayName=Y;x[K]=!0;var Ee=x;function F(e){if(e===q||e===Ee)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[K]===!0||t.displayName===Y||t.name==="RouteChildren"}catch{return!1}}function j(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[Ce]===!0||t.displayName===ye||t.name==="RouteChildrenSlot"}catch{return!1}}function G(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function T(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let u=!1,w=e.map(p=>{let g=T(p,t);return g!==p&&(u=!0),g});return u?w:e}if(G(e)&&(F(e.type)||j(e.type)))return t;let n=m.default.isValidElement(e);if(!n&&!G(e))return e;if(n&&(F(e.type)||j(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=T(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 i=e,a={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return m.default.createElement(i.type,a)}var d=require("react/jsx-runtime"),Te={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},N=typeof c.default.createContext=="function"?c.default.createContext(null):null,ee="__WEBFRAMEZ_ROUTER__",Ne="__WEBFRAMEZ_REACT_BUILD_ID",Ae="x-webframez-react-build",Se="[data-webframez-head='true']";function Z(){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 k(e){return l(e)??""}function Pe(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function te(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function be(){return k(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function ne(e){if(typeof window>"u")return e||"/";let t=k(window.__RSC_BASENAME),n=be(),o=Pe(e||"/",t);return te(n,o)}function oe(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Le(){if(typeof window>"u")return"";let e=window[Ne];return typeof e=="string"?e:""}function xe(e){let t=Le();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function ve(){return typeof window>"u"?null:window[ee]??null}function Ie(e){typeof window>"u"||(window[ee]=e)}function ke(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function He(e){return ke(e)?c.default.use(e):e}function A(e){let t=He(e);if(Array.isArray(t)){let r=!1,i=t.map(a=>{let u=A(a);return u!==a&&(r=!0),u});return r?i:t}if(!c.default.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=A(n.children);return o===n.children?t:Array.isArray(o)?c.default.cloneElement(t,void 0,...o):c.default.cloneElement(t,void 0,o)}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 r=o.indexOf("="),i=r>=0?o.slice(0,r).trim():o,a=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(a))}return e}function X(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 Be(){return c.default.useMemo(()=>({all:()=>V(),get:e=>V()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=X(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=X(e,"",{...t??{},maxAge:0}))}}),[])}function Oe(){let e=N?c.default.useContext(N):null;if(!e){let t=ve();if(t)return t;if(typeof window>"u")return Te;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Me({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 Ue(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 ze(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 $e(e){if(e.html){re(e.html);return}let t=document.createElement("script");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([o,r])=>o!=="content"&&o!=="html"&&r!==void 0&&r!==null&&r!==!1);for(let[o,r]of n)r===!0?t.setAttribute(o,""):t.setAttribute(o,String(r));e.content&&(t.textContent=e.content),document.head.appendChild(t)}function re(e){let t=document.createElement("template");t.innerHTML=e;for(let n of Array.from(t.content.childNodes))n.nodeType===Node.ELEMENT_NODE&&n.setAttribute("data-webframez-head","true"),document.head.appendChild(n)}function S(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function De(e){if(e.tagName.toLowerCase()==="script"&&e.textContent){let n={content:e.textContent};for(let o of Array.from(e.attributes))n[o.name]=o.value;return S(e.tagName,n)}let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return S(e.tagName,t)}function We(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});for(let n of e.scripts??[])t.push({tagName:"script",attrs:n});for(let n of e.html??[])typeof n=="string"&&n.trim()!==""&&t.push({tagName:"html",attrs:{html:n}});return t}function I(e){if(typeof document>"u")return;let t=L(e)??e;ie(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=We(t),o=new Set(n.map(i=>S(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(Se)){let a=De(i);if(o.has(a)&&!r.has(a)){r.add(a);continue}i.remove()}for(let i of n){let a=S(i.tagName,i.attrs);r.has(a)||(i.tagName==="meta"?Ue(i.attrs):i.tagName==="link"?ze(i.attrs):i.tagName==="script"?$e(i.attrs):re(i.attrs.html),r.add(a))}}function ie(e){if(typeof window>"u")return;let t=L(e)??e,n=l(t.basename),o=l(t.routeBasePath),r=l(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=te(r,"/rsc"))}function Fe(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function je(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,h.createFromReadableStream)(Fe(e)))}function Ge(e){let t=oe(e),n=ne(window.location.pathname);return je()??(0,h.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function qe(e,t){return function(){let o=c.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,a]=(0,c.useState)(o.model),[u,w]=(0,c.useState)(o.contextModel),[p,g]=(0,c.useState)(o.pageModel),[H,B]=(0,c.useState)(o.head),[ae,_]=(0,c.useState)(!1),[se,ce]=(0,c.useState)(!1),[de,O]=(0,c.useState)(r);async function M(s){let y=oe(t),f=ne(s.pathname),R=await fetch(`${y}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(s.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return xe(R.headers.get(Ae))?(v(s),await new Promise(()=>{})):await(0,h.createFromFetch)(Promise.resolve(R))}async function C(s,y="push"){_(!0);try{let f=await M(s);I(f.head),B(f.head),a(f.model),w(f.contextModel),g(f.pageModel),O(!1);let R=`${s.pathname}${s.search}${s.hash}`;y==="replace"?(history.replaceState(null,"",R),Z()):y==="push"&&(history.pushState(null,"",R),Z())}catch(f){console.error("[webframez-react] Failed to render route",f),v(s),a((0,d.jsx)("p",{children:"Failed to load route."}))}finally{_(!1)}}async function ue(){_(!0);try{let s=await M(new URL(window.location.href));I(s.head),B(s.head),a(s.model),w(s.contextModel),g(s.pageModel),O(!1)}catch(s){console.error("[webframez-react] Failed to refresh route context",s),v(new URL(window.location.href))}finally{_(!1)}}(0,c.useEffect)(()=>{I(H)},[H]),(0,c.useEffect)(()=>{ce(!0);let s=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let U=c.default.useMemo(()=>({push:s=>{C(new URL(s,window.location.origin),"push")},replace:s=>{C(new URL(s,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{ue()}}),[]);Ie(U);let z=A(u),P=A(p),le=de&&typeof p<"u"?z?(0,d.jsx)(Q.RouteChildrenSlotProvider,{page:P,children:T(z,P)}):P:i,$=(0,d.jsxs)(d.Fragment,{children:[se?(0,d.jsx)(Me,{active:ae}):null,le??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return N?(0,d.jsx)(N.Provider,{value:U,children:$}):$}}function Ke(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",i=Promise.resolve(Ge(r)).then(u=>(u?.head&&ie(u.head),u)),a=qe(i,r);return(0,J.hydrateRoot)(n,(0,d.jsx)(a,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import u,{useEffect as G,useState as f}from"react";import{hydrateRoot as pe}from"react-dom/client";import{createFromFetch as X,createFromReadableStream as me}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as Re}from"@webtypen/webframez-react/route-slot";var de=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function d(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function z(e,t){let n=e.trim(),o=d(t);return!n||!o||de.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=d(e.basename)??d(t),o=d(e.routeBasePath),r=d(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(s=>({...s,href:z(s.href,n)}))),a}import h from"react";var W="webframez-route-children",F="__webframezRouteChildren",j="WebframezRouteChildren",ue="__webframezRouteChildrenSlot",le="WebframezRouteChildrenSlot",P=()=>h.createElement(W);P.displayName=j;P[F]=!0;var fe=P;function D(e){if(e===W||e===fe)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[F]===!0||t.displayName===j||t.name==="RouteChildren"}catch{return!1}}function M(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[ue]===!0||t.displayName===le||t.name==="RouteChildrenSlot"}catch{return!1}}function $(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function y(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let c=!1,w=e.map(m=>{let R=y(m,t);return R!==m&&(c=!0),R});return c?w:e}if($(e)&&(D(e.type)||M(e.type)))return t;let n=h.isValidElement(e);if(!n&&!$(e))return e;if(n&&(D(e.type)||M(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=y(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?h.cloneElement(e,void 0,...r):h.cloneElement(e,void 0,r);let a=e,s={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return h.createElement(a.type,s)}import{Fragment as Be,jsx as p,jsxs as Oe}from"react/jsx-runtime";var _e={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof u.createContext=="function"?u.createContext(null):null,J="__WEBFRAMEZ_ROUTER__",he="__WEBFRAMEZ_REACT_BUILD_ID",we="x-webframez-react-build",ge="[data-webframez-head='true']";function q(){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 d(e)??""}function Ce(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function Q(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Ee(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function ee(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=Ee(),o=Ce(e||"/",t);return Q(n,o)}function te(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function ye(){if(typeof window>"u")return"";let e=window[he];return typeof e=="string"?e:""}function Te(e){let t=ye();return!!t&&!!e&&t!==e}function I(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Ae(){return typeof window>"u"?null:window[J]??null}function Ne(e){typeof window>"u"||(window[J]=e)}function Se(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Pe(e){return Se(e)?u.use(e):e}function A(e){let t=Pe(e);if(Array.isArray(t)){let r=!1,a=t.map(s=>{let c=A(s);return c!==s&&(r=!0),c});return r?a:t}if(!u.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=A(n.children);return o===n.children?t:Array.isArray(o)?u.cloneElement(t,void 0,...o):u.cloneElement(t,void 0,o)}function Y(){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 Z(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 Ge(){return u.useMemo(()=>({all:()=>Y(),get:e=>Y()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=Z(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=Z(e,"",{...t??{},maxAge:0}))}}),[])}function qe(){let e=T?u.useContext(T):null;if(!e){let t=Ae();if(t)return t;if(typeof window>"u")return _e;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Ie({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 K(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 V(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=S(e)??e;ne(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(ge))n.remove();t.description&&K({name:"description",content:t.description}),t.favicon&&V({rel:"icon",href:t.favicon});for(let n of t.meta??[])K(n);for(let n of t.links??[])V(n)}function ne(e){if(typeof window>"u")return;let t=S(e)??e,n=d(t.basename),o=d(t.routeBasePath),r=d(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=Q(r,"/rsc"))}function ve(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function xe(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,me(ve(e)))}function Le(e){let t=te(e),n=ee(window.location.pathname);return xe()??X(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=u.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,s]=f(o.model),[c,w]=f(o.contextModel),[m,R]=f(o.pageModel),[L,b]=f(o.head),[oe,g]=f(!1),[re,ie]=f(!1),[ae,B]=f(r);async function O(i){let E=te(t),l=ee(i.pathname),_=await fetch(`${E}?path=${encodeURIComponent(l)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Te(_.headers.get(we))?(I(i),await new Promise(()=>{})):await X(Promise.resolve(_))}async function C(i,E="push"){g(!0);try{let l=await O(i);v(l.head),b(l.head),s(l.model),w(l.contextModel),R(l.pageModel),B(!1);let _=`${i.pathname}${i.search}${i.hash}`;E==="replace"?(history.replaceState(null,"",_),q()):E==="push"&&(history.pushState(null,"",_),q())}catch(l){console.error("[webframez-react] Failed to render route",l),I(i),s(p("p",{children:"Failed to load route."}))}finally{g(!1)}}async function se(){g(!0);try{let i=await O(new URL(window.location.href));v(i.head),b(i.head),s(i.model),w(i.contextModel),R(i.pageModel),B(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i),I(new URL(window.location.href))}finally{g(!1)}}G(()=>{v(L)},[L]),G(()=>{ie(!0);let i=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let k=u.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:()=>{se()}}),[]);Ne(k);let U=A(c),N=A(m),ce=ae&&typeof m<"u"?U?p(Re,{page:N,children:y(U,N)}):N:a,H=Oe(Be,{children:[re?p(Ie,{active:oe}):null,ce??p("p",{style:{padding:24},children:"Loading..."})]});return T?p(T.Provider,{value:k,children:H}):H}}function Ye(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(c=>(c?.head&&ne(c.head),c)),s=be(a,r);return pe(n,p(s,{}))}export{Ye as mountWebframezClient,Ge as useCookie,qe as useRouter};
1
+ import u,{useEffect as q,useState as f}from"react";import{hydrateRoot as me}from"react-dom/client";import{createFromFetch as V,createFromReadableStream as pe}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as ge}from"@webtypen/webframez-react/route-slot";var de=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function d(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function P(e,t){let n=e.trim(),o=d(t);return!n||!o||de.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function b(e,t){if(!e)return;let n=d(e.basename)??d(t),o=d(e.routeBasePath),r=d(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=P(i.favicon,n)),i.links&&(i.links=i.links.map(a=>({...a,href:P(a.href,n)}))),i.scripts&&(i.scripts=i.scripts.map(a=>({...a,...a.src?{src:P(a.src,n)}:{}}))),i}import h from"react";var F="webframez-route-children",j="__webframezRouteChildren",G="WebframezRouteChildren",ue="__webframezRouteChildrenSlot",le="WebframezRouteChildrenSlot",L=()=>h.createElement(F);L.displayName=G;L[j]=!0;var fe=L;function $(e){if(e===F||e===fe)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[j]===!0||t.displayName===G||t.name==="RouteChildren"}catch{return!1}}function D(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[ue]===!0||t.displayName===le||t.name==="RouteChildrenSlot"}catch{return!1}}function W(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 c=!1,w=e.map(p=>{let g=E(p,t);return g!==p&&(c=!0),g});return c?w:e}if(W(e)&&($(e.type)||D(e.type)))return t;let n=h.isValidElement(e);if(!n&&!W(e))return e;if(n&&($(e.type)||D(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)?h.cloneElement(e,void 0,...r):h.cloneElement(e,void 0,r);let i=e,a={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return h.createElement(i.type,a)}import{Fragment as Ue,jsx as m,jsxs as ze}from"react/jsx-runtime";var Re={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof u.createContext=="function"?u.createContext(null):null,X="__WEBFRAMEZ_ROUTER__",he="__WEBFRAMEZ_REACT_BUILD_ID",we="x-webframez-react-build",_e="[data-webframez-head='true']";function K(){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 d(e)??""}function Ce(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 ye(){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=ye(),o=Ce(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 Ee(){if(typeof window>"u")return"";let e=window[he];return typeof e=="string"?e:""}function Te(e){let t=Ee();return!!t&&!!e&&t!==e}function x(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Ne(){return typeof window>"u"?null:window[X]??null}function Ae(e){typeof window>"u"||(window[X]=e)}function Se(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Pe(e){return Se(e)?u.use(e):e}function N(e){let t=Pe(e);if(Array.isArray(t)){let r=!1,i=t.map(a=>{let c=N(a);return c!==a&&(r=!0),c});return r?i:t}if(!u.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=N(n.children);return o===n.children?t:Array.isArray(o)?u.cloneElement(t,void 0,...o):u.cloneElement(t,void 0,o)}function Y(){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("="),i=r>=0?o.slice(0,r).trim():o,a=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(a))}return e}function Z(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 Ve(){return u.useMemo(()=>({all:()=>Y(),get:e=>Y()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=Z(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=Z(e,"",{...t??{},maxAge:0}))}}),[])}function Xe(){let e=T?u.useContext(T):null;if(!e){let t=Ne();if(t)return t;if(typeof window>"u")return Re;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function be({active:e}){return m("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 Le(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 xe(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 ve(e){if(e.html){te(e.html);return}let t=document.createElement("script");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([o,r])=>o!=="content"&&o!=="html"&&r!==void 0&&r!==null&&r!==!1);for(let[o,r]of n)r===!0?t.setAttribute(o,""):t.setAttribute(o,String(r));e.content&&(t.textContent=e.content),document.head.appendChild(t)}function te(e){let t=document.createElement("template");t.innerHTML=e;for(let n of Array.from(t.content.childNodes))n.nodeType===Node.ELEMENT_NODE&&n.setAttribute("data-webframez-head","true"),document.head.appendChild(n)}function A(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function Ie(e){if(e.tagName.toLowerCase()==="script"&&e.textContent){let n={content:e.textContent};for(let o of Array.from(e.attributes))n[o.name]=o.value;return A(e.tagName,n)}let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return A(e.tagName,t)}function ke(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});for(let n of e.scripts??[])t.push({tagName:"script",attrs:n});for(let n of e.html??[])typeof n=="string"&&n.trim()!==""&&t.push({tagName:"html",attrs:{html:n}});return t}function v(e){if(typeof document>"u")return;let t=b(e)??e;ne(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=ke(t),o=new Set(n.map(i=>A(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(_e)){let a=Ie(i);if(o.has(a)&&!r.has(a)){r.add(a);continue}i.remove()}for(let i of n){let a=A(i.tagName,i.attrs);r.has(a)||(i.tagName==="meta"?Le(i.attrs):i.tagName==="link"?xe(i.attrs):i.tagName==="script"?ve(i.attrs):te(i.attrs.html),r.add(a))}}function ne(e){if(typeof window>"u")return;let t=b(e)??e,n=d(t.basename),o=d(t.routeBasePath),r=d(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=J(r,"/rsc"))}function He(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,pe(He(e)))}function Oe(e){let t=ee(e),n=Q(window.location.pathname);return Be()??V(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function Me(e,t){return function(){let o=u.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,a]=f(o.model),[c,w]=f(o.contextModel),[p,g]=f(o.pageModel),[k,H]=f(o.head),[oe,_]=f(!1),[re,ie]=f(!1),[ae,B]=f(r);async function O(s){let y=ee(t),l=Q(s.pathname),R=await fetch(`${y}?path=${encodeURIComponent(l)}&search=${encodeURIComponent(s.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Te(R.headers.get(we))?(x(s),await new Promise(()=>{})):await V(Promise.resolve(R))}async function C(s,y="push"){_(!0);try{let l=await O(s);v(l.head),H(l.head),a(l.model),w(l.contextModel),g(l.pageModel),B(!1);let R=`${s.pathname}${s.search}${s.hash}`;y==="replace"?(history.replaceState(null,"",R),K()):y==="push"&&(history.pushState(null,"",R),K())}catch(l){console.error("[webframez-react] Failed to render route",l),x(s),a(m("p",{children:"Failed to load route."}))}finally{_(!1)}}async function se(){_(!0);try{let s=await O(new URL(window.location.href));v(s.head),H(s.head),a(s.model),w(s.contextModel),g(s.pageModel),B(!1)}catch(s){console.error("[webframez-react] Failed to refresh route context",s),x(new URL(window.location.href))}finally{_(!1)}}q(()=>{v(k)},[k]),q(()=>{ie(!0);let s=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let M=u.useMemo(()=>({push:s=>{C(new URL(s,window.location.origin),"push")},replace:s=>{C(new URL(s,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{se()}}),[]);Ae(M);let U=N(c),S=N(p),ce=ae&&typeof p<"u"?U?m(ge,{page:S,children:E(U,S)}):S:i,z=ze(Ue,{children:[re?m(be,{active:oe}):null,ce??m("p",{style:{padding:24},children:"Loading..."})]});return T?m(T.Provider,{value:M,children:z}):z}}function Je(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",i=Promise.resolve(Oe(r)).then(c=>(c?.head&&ne(c.head),c)),a=Me(i,r);return me(n,m(a,{}))}export{Je as mountWebframezClient,Ve as useCookie,Xe as useRouter};
package/dist/http.cjs CHANGED
@@ -55,6 +55,8 @@ function createHTMLShell(options = {}) {
55
55
  buildId = "",
56
56
  headTags = "",
57
57
  bodyClassName = "",
58
+ bodyStartHtml = "",
59
+ bodyEndHtml = "",
58
60
  rootHtml = "",
59
61
  initialFlightData = "",
60
62
  basename = "",
@@ -104,7 +106,9 @@ function createHTMLShell(options = {}) {
104
106
  ${headTags}
105
107
  </head>
106
108
  <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
109
+ ${bodyStartHtml}
107
110
  <div id="root">${rootHtml}</div>
111
+ ${bodyEndHtml}
108
112
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
109
113
  <script>window.__RSC_BASENAME = "${basename}";</script>
110
114
  <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
@@ -219,6 +223,12 @@ function normalizeHeadConfig(head, inheritedBasename) {
219
223
  href: resolveHeadAssetUrl(link.href, effectiveBasename)
220
224
  }));
221
225
  }
226
+ if (normalizedHead.scripts) {
227
+ normalizedHead.scripts = normalizedHead.scripts.map((script) => ({
228
+ ...script,
229
+ ...script.src ? { src: resolveHeadAssetUrl(script.src, effectiveBasename) } : {}
230
+ }));
231
+ }
222
232
  return normalizedHead;
223
233
  }
224
234
 
@@ -471,7 +481,9 @@ function matchRoute(entry, pathname) {
471
481
  function mergeHead(...configs) {
472
482
  const merged = {
473
483
  meta: [],
474
- links: []
484
+ links: [],
485
+ scripts: [],
486
+ html: []
475
487
  };
476
488
  for (const candidate of configs) {
477
489
  const config = normalizeHeadConfig(candidate, merged.basename);
@@ -506,9 +518,28 @@ function mergeHead(...configs) {
506
518
  if (config.links) {
507
519
  merged.links?.push(...config.links);
508
520
  }
521
+ if (config.scripts) {
522
+ merged.scripts?.push(...config.scripts);
523
+ }
524
+ if (config.html) {
525
+ merged.html?.push(...Array.isArray(config.html) ? config.html : [config.html]);
526
+ }
527
+ if (config.bodyStartHtml) {
528
+ merged.bodyStartHtml = [merged.bodyStartHtml, config.bodyStartHtml].filter(Boolean).join("\n");
529
+ }
530
+ if (config.bodyEndHtml) {
531
+ merged.bodyEndHtml = [merged.bodyEndHtml, config.bodyEndHtml].filter(Boolean).join("\n");
532
+ }
509
533
  }
510
534
  return merged;
511
535
  }
536
+ function renderGenericAttributes(entry, excluded = []) {
537
+ return Object.entries(entry).filter(
538
+ ([key, value]) => !excluded.includes(key) && value !== void 0 && value !== null && value !== false
539
+ ).map(
540
+ ([key, value]) => value === true ? key : `${key}="${escapeHtml(String(value))}"`
541
+ ).join(" ");
542
+ }
512
543
  function renderHeadToString(head) {
513
544
  const normalizedHead = normalizeHeadConfig(head) ?? head;
514
545
  const tags = [];
@@ -530,6 +561,23 @@ function renderHeadToString(head) {
530
561
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
531
562
  tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
532
563
  }
564
+ for (const script of normalizedHead.scripts ?? []) {
565
+ if (script.html) {
566
+ tags.push(script.html);
567
+ continue;
568
+ }
569
+ const attrs = renderGenericAttributes(script, [
570
+ "content",
571
+ "html"
572
+ ]);
573
+ const content = script.content ? String(script.content) : "";
574
+ tags.push(`<script ${createManagedAttributes()} ${attrs}>${content}</script>`);
575
+ }
576
+ for (const html of normalizedHead.html ?? []) {
577
+ if (typeof html === "string" && html.trim() !== "") {
578
+ tags.push(html);
579
+ }
580
+ }
533
581
  return tags.join("\n");
534
582
  }
535
583
  function clearModuleCache(modulePath, rootDir, visited = /* @__PURE__ */ new Set()) {
@@ -615,6 +663,7 @@ function isRouteAbort(value) {
615
663
  function createFileRouter(options) {
616
664
  installForcedPackageResolution();
617
665
  const pagesDir = options.pagesDir;
666
+ const onData = options.onData;
618
667
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
619
668
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
620
669
  const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
@@ -779,10 +828,16 @@ function createFileRouter(options) {
779
828
  data: mergeRouteData(middlewareContext.data, pageData)
780
829
  };
781
830
  activeContext = pageContext;
782
- const pageNode = await pageModule.default(pageContext);
783
- const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
784
- const pageHead = await resolveHead(pageModule, pageContext);
785
- const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
831
+ const onDataResult = typeof onData === "function" ? await onData(pageContext) : void 0;
832
+ const eventContext = {
833
+ ...pageContext,
834
+ data: mergeRouteData(pageContext.data, onDataResult)
835
+ };
836
+ activeContext = eventContext;
837
+ const pageNode = await pageModule.default(eventContext);
838
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, eventContext) : void 0;
839
+ const pageHead = await resolveHead(pageModule, eventContext);
840
+ const layoutNode = layoutModule ? await layoutModule.default(eventContext) : null;
786
841
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
787
842
  const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteChildren, {})) : void 0;
788
843
  return {
@@ -791,7 +846,7 @@ function createFileRouter(options) {
791
846
  contextModel,
792
847
  pageModel: pageNode,
793
848
  head: mergeHead(layoutHead, pageHead),
794
- context: pageContext
849
+ context: eventContext
795
850
  };
796
851
  } catch (error) {
797
852
  if (isRouteAbort(error)) {
@@ -1614,7 +1669,7 @@ function createNodeRequestHandler(options) {
1614
1669
  const liveReloadEnabled = options.liveReloadPath !== false && (nodeEnv === "development" || runningInWatchMode);
1615
1670
  const liveReloadPath = !liveReloadEnabled ? "" : options.liveReloadPath ?? `${basePath || ""}/__webframez_live_reload`;
1616
1671
  const liveReloadClients = /* @__PURE__ */ new Set();
1617
- const router = createFileRouter({ pagesDir });
1672
+ const router = createFileRouter({ pagesDir, onData: options.onData });
1618
1673
  const getManifestState = createManifestLoader({
1619
1674
  distRootDir,
1620
1675
  manifestPath,
@@ -1838,6 +1893,8 @@ function createNodeRequestHandler(options) {
1838
1893
  initialFlightData,
1839
1894
  basename: shellBasename,
1840
1895
  routeBasePath: shellRouteBasePath,
1896
+ bodyStartHtml: resolved.head.bodyStartHtml || "",
1897
+ bodyEndHtml: resolved.head.bodyEndHtml || "",
1841
1898
  liveReloadPath: liveReloadPath || void 0,
1842
1899
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1843
1900
  }),
package/dist/http.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { RouteDataHook } from "./types";
2
3
 
3
4
  export type WebframezReactRoutePath = `/${string}` | "/";
4
5
  export type WebframezReactAssetsPrefix = `${WebframezReactRoutePath}/` | "/";
@@ -20,6 +21,7 @@ export interface CreateNodeHandlerRoutingOptions {
20
21
  export interface CreateNodeHandlerOptions
21
22
  extends CreateNodeHandlerPathsOptions,
22
23
  CreateNodeHandlerRoutingOptions {
24
+ onData?: RouteDataHook;
23
25
  }
24
26
 
25
27
  export function createNodeRequestHandler(
package/dist/http.js CHANGED
@@ -35,6 +35,8 @@ function createHTMLShell(options = {}) {
35
35
  buildId = "",
36
36
  headTags = "",
37
37
  bodyClassName = "",
38
+ bodyStartHtml = "",
39
+ bodyEndHtml = "",
38
40
  rootHtml = "",
39
41
  initialFlightData = "",
40
42
  basename = "",
@@ -84,7 +86,9 @@ function createHTMLShell(options = {}) {
84
86
  ${headTags}
85
87
  </head>
86
88
  <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
89
+ ${bodyStartHtml}
87
90
  <div id="root">${rootHtml}</div>
91
+ ${bodyEndHtml}
88
92
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
89
93
  <script>window.__RSC_BASENAME = "${basename}";</script>
90
94
  <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
@@ -199,6 +203,12 @@ function normalizeHeadConfig(head, inheritedBasename) {
199
203
  href: resolveHeadAssetUrl(link.href, effectiveBasename)
200
204
  }));
201
205
  }
206
+ if (normalizedHead.scripts) {
207
+ normalizedHead.scripts = normalizedHead.scripts.map((script) => ({
208
+ ...script,
209
+ ...script.src ? { src: resolveHeadAssetUrl(script.src, effectiveBasename) } : {}
210
+ }));
211
+ }
202
212
  return normalizedHead;
203
213
  }
204
214
 
@@ -451,7 +461,9 @@ function matchRoute(entry, pathname) {
451
461
  function mergeHead(...configs) {
452
462
  const merged = {
453
463
  meta: [],
454
- links: []
464
+ links: [],
465
+ scripts: [],
466
+ html: []
455
467
  };
456
468
  for (const candidate of configs) {
457
469
  const config = normalizeHeadConfig(candidate, merged.basename);
@@ -486,9 +498,28 @@ function mergeHead(...configs) {
486
498
  if (config.links) {
487
499
  merged.links?.push(...config.links);
488
500
  }
501
+ if (config.scripts) {
502
+ merged.scripts?.push(...config.scripts);
503
+ }
504
+ if (config.html) {
505
+ merged.html?.push(...Array.isArray(config.html) ? config.html : [config.html]);
506
+ }
507
+ if (config.bodyStartHtml) {
508
+ merged.bodyStartHtml = [merged.bodyStartHtml, config.bodyStartHtml].filter(Boolean).join("\n");
509
+ }
510
+ if (config.bodyEndHtml) {
511
+ merged.bodyEndHtml = [merged.bodyEndHtml, config.bodyEndHtml].filter(Boolean).join("\n");
512
+ }
489
513
  }
490
514
  return merged;
491
515
  }
516
+ function renderGenericAttributes(entry, excluded = []) {
517
+ return Object.entries(entry).filter(
518
+ ([key, value]) => !excluded.includes(key) && value !== void 0 && value !== null && value !== false
519
+ ).map(
520
+ ([key, value]) => value === true ? key : `${key}="${escapeHtml(String(value))}"`
521
+ ).join(" ");
522
+ }
492
523
  function renderHeadToString(head) {
493
524
  const normalizedHead = normalizeHeadConfig(head) ?? head;
494
525
  const tags = [];
@@ -510,6 +541,23 @@ function renderHeadToString(head) {
510
541
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
511
542
  tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
512
543
  }
544
+ for (const script of normalizedHead.scripts ?? []) {
545
+ if (script.html) {
546
+ tags.push(script.html);
547
+ continue;
548
+ }
549
+ const attrs = renderGenericAttributes(script, [
550
+ "content",
551
+ "html"
552
+ ]);
553
+ const content = script.content ? String(script.content) : "";
554
+ tags.push(`<script ${createManagedAttributes()} ${attrs}>${content}</script>`);
555
+ }
556
+ for (const html of normalizedHead.html ?? []) {
557
+ if (typeof html === "string" && html.trim() !== "") {
558
+ tags.push(html);
559
+ }
560
+ }
513
561
  return tags.join("\n");
514
562
  }
515
563
  function clearModuleCache(modulePath, rootDir, visited = /* @__PURE__ */ new Set()) {
@@ -595,6 +643,7 @@ function isRouteAbort(value) {
595
643
  function createFileRouter(options) {
596
644
  installForcedPackageResolution();
597
645
  const pagesDir = options.pagesDir;
646
+ const onData = options.onData;
598
647
  const layoutPath = path2.join(pagesDir, "layout.js");
599
648
  const errorPath = path2.join(pagesDir, "errors.js");
600
649
  const middlewaresPath = path2.join(pagesDir, "middlewares.js");
@@ -759,10 +808,16 @@ function createFileRouter(options) {
759
808
  data: mergeRouteData(middlewareContext.data, pageData)
760
809
  };
761
810
  activeContext = pageContext;
762
- const pageNode = await pageModule.default(pageContext);
763
- const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
764
- const pageHead = await resolveHead(pageModule, pageContext);
765
- const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
811
+ const onDataResult = typeof onData === "function" ? await onData(pageContext) : void 0;
812
+ const eventContext = {
813
+ ...pageContext,
814
+ data: mergeRouteData(pageContext.data, onDataResult)
815
+ };
816
+ activeContext = eventContext;
817
+ const pageNode = await pageModule.default(eventContext);
818
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, eventContext) : void 0;
819
+ const pageHead = await resolveHead(pageModule, eventContext);
820
+ const layoutNode = layoutModule ? await layoutModule.default(eventContext) : null;
766
821
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
767
822
  const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildren, {})) : void 0;
768
823
  return {
@@ -771,7 +826,7 @@ function createFileRouter(options) {
771
826
  contextModel,
772
827
  pageModel: pageNode,
773
828
  head: mergeHead(layoutHead, pageHead),
774
- context: pageContext
829
+ context: eventContext
775
830
  };
776
831
  } catch (error) {
777
832
  if (isRouteAbort(error)) {
@@ -1594,7 +1649,7 @@ function createNodeRequestHandler(options) {
1594
1649
  const liveReloadEnabled = options.liveReloadPath !== false && (nodeEnv === "development" || runningInWatchMode);
1595
1650
  const liveReloadPath = !liveReloadEnabled ? "" : options.liveReloadPath ?? `${basePath || ""}/__webframez_live_reload`;
1596
1651
  const liveReloadClients = /* @__PURE__ */ new Set();
1597
- const router = createFileRouter({ pagesDir });
1652
+ const router = createFileRouter({ pagesDir, onData: options.onData });
1598
1653
  const getManifestState = createManifestLoader({
1599
1654
  distRootDir,
1600
1655
  manifestPath,
@@ -1818,6 +1873,8 @@ function createNodeRequestHandler(options) {
1818
1873
  initialFlightData,
1819
1874
  basename: shellBasename,
1820
1875
  routeBasePath: shellRouteBasePath,
1876
+ bodyStartHtml: resolved.head.bodyStartHtml || "",
1877
+ bodyEndHtml: resolved.head.bodyEndHtml || "",
1821
1878
  liveReloadPath: liveReloadPath || void 0,
1822
1879
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1823
1880
  }),
package/dist/index.cjs CHANGED
@@ -62,6 +62,8 @@ function createHTMLShell(options = {}) {
62
62
  buildId = "",
63
63
  headTags = "",
64
64
  bodyClassName = "",
65
+ bodyStartHtml = "",
66
+ bodyEndHtml = "",
65
67
  rootHtml = "",
66
68
  initialFlightData = "",
67
69
  basename = "",
@@ -111,7 +113,9 @@ function createHTMLShell(options = {}) {
111
113
  ${headTags}
112
114
  </head>
113
115
  <body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}"` : ""}>
116
+ ${bodyStartHtml}
114
117
  <div id="root">${rootHtml}</div>
118
+ ${bodyEndHtml}
115
119
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
116
120
  <script>window.__RSC_BASENAME = "${basename}";</script>
117
121
  <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
@@ -254,6 +258,12 @@ function normalizeHeadConfig(head, inheritedBasename) {
254
258
  href: resolveHeadAssetUrl(link.href, effectiveBasename)
255
259
  }));
256
260
  }
261
+ if (normalizedHead.scripts) {
262
+ normalizedHead.scripts = normalizedHead.scripts.map((script) => ({
263
+ ...script,
264
+ ...script.src ? { src: resolveHeadAssetUrl(script.src, effectiveBasename) } : {}
265
+ }));
266
+ }
257
267
  return normalizedHead;
258
268
  }
259
269
 
@@ -506,7 +516,9 @@ function matchRoute(entry, pathname) {
506
516
  function mergeHead(...configs) {
507
517
  const merged = {
508
518
  meta: [],
509
- links: []
519
+ links: [],
520
+ scripts: [],
521
+ html: []
510
522
  };
511
523
  for (const candidate of configs) {
512
524
  const config = normalizeHeadConfig(candidate, merged.basename);
@@ -541,9 +553,28 @@ function mergeHead(...configs) {
541
553
  if (config.links) {
542
554
  merged.links?.push(...config.links);
543
555
  }
556
+ if (config.scripts) {
557
+ merged.scripts?.push(...config.scripts);
558
+ }
559
+ if (config.html) {
560
+ merged.html?.push(...Array.isArray(config.html) ? config.html : [config.html]);
561
+ }
562
+ if (config.bodyStartHtml) {
563
+ merged.bodyStartHtml = [merged.bodyStartHtml, config.bodyStartHtml].filter(Boolean).join("\n");
564
+ }
565
+ if (config.bodyEndHtml) {
566
+ merged.bodyEndHtml = [merged.bodyEndHtml, config.bodyEndHtml].filter(Boolean).join("\n");
567
+ }
544
568
  }
545
569
  return merged;
546
570
  }
571
+ function renderGenericAttributes(entry, excluded = []) {
572
+ return Object.entries(entry).filter(
573
+ ([key, value]) => !excluded.includes(key) && value !== void 0 && value !== null && value !== false
574
+ ).map(
575
+ ([key, value]) => value === true ? key : `${key}="${escapeHtml(String(value))}"`
576
+ ).join(" ");
577
+ }
547
578
  function renderHeadToString(head) {
548
579
  const normalizedHead = normalizeHeadConfig(head) ?? head;
549
580
  const tags = [];
@@ -565,6 +596,23 @@ function renderHeadToString(head) {
565
596
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
566
597
  tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
567
598
  }
599
+ for (const script of normalizedHead.scripts ?? []) {
600
+ if (script.html) {
601
+ tags.push(script.html);
602
+ continue;
603
+ }
604
+ const attrs = renderGenericAttributes(script, [
605
+ "content",
606
+ "html"
607
+ ]);
608
+ const content = script.content ? String(script.content) : "";
609
+ tags.push(`<script ${createManagedAttributes()} ${attrs}>${content}</script>`);
610
+ }
611
+ for (const html of normalizedHead.html ?? []) {
612
+ if (typeof html === "string" && html.trim() !== "") {
613
+ tags.push(html);
614
+ }
615
+ }
568
616
  return tags.join("\n");
569
617
  }
570
618
  function clearModuleCache(modulePath, rootDir, visited = /* @__PURE__ */ new Set()) {
@@ -650,6 +698,7 @@ function isRouteAbort(value) {
650
698
  function createFileRouter(options) {
651
699
  installForcedPackageResolution();
652
700
  const pagesDir = options.pagesDir;
701
+ const onData = options.onData;
653
702
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
654
703
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
655
704
  const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
@@ -814,10 +863,16 @@ function createFileRouter(options) {
814
863
  data: mergeRouteData(middlewareContext.data, pageData)
815
864
  };
816
865
  activeContext = pageContext;
817
- const pageNode = await pageModule.default(pageContext);
818
- const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
819
- const pageHead = await resolveHead(pageModule, pageContext);
820
- const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
866
+ const onDataResult = typeof onData === "function" ? await onData(pageContext) : void 0;
867
+ const eventContext = {
868
+ ...pageContext,
869
+ data: mergeRouteData(pageContext.data, onDataResult)
870
+ };
871
+ activeContext = eventContext;
872
+ const pageNode = await pageModule.default(eventContext);
873
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, eventContext) : void 0;
874
+ const pageHead = await resolveHead(pageModule, eventContext);
875
+ const layoutNode = layoutModule ? await layoutModule.default(eventContext) : null;
821
876
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
822
877
  const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteChildren, {})) : void 0;
823
878
  return {
@@ -826,7 +881,7 @@ function createFileRouter(options) {
826
881
  contextModel,
827
882
  pageModel: pageNode,
828
883
  head: mergeHead(layoutHead, pageHead),
829
- context: pageContext
884
+ context: eventContext
830
885
  };
831
886
  } catch (error) {
832
887
  if (isRouteAbort(error)) {
@@ -1654,7 +1709,7 @@ function createNodeRequestHandler(options) {
1654
1709
  const liveReloadEnabled = options.liveReloadPath !== false && (nodeEnv === "development" || runningInWatchMode);
1655
1710
  const liveReloadPath = !liveReloadEnabled ? "" : options.liveReloadPath ?? `${basePath || ""}/__webframez_live_reload`;
1656
1711
  const liveReloadClients = /* @__PURE__ */ new Set();
1657
- const router = createFileRouter({ pagesDir });
1712
+ const router = createFileRouter({ pagesDir, onData: options.onData });
1658
1713
  const getManifestState = createManifestLoader({
1659
1714
  distRootDir,
1660
1715
  manifestPath,
@@ -1878,6 +1933,8 @@ function createNodeRequestHandler(options) {
1878
1933
  initialFlightData,
1879
1934
  basename: shellBasename,
1880
1935
  routeBasePath: shellRouteBasePath,
1936
+ bodyStartHtml: resolved.head.bodyStartHtml || "",
1937
+ bodyEndHtml: resolved.head.bodyEndHtml || "",
1881
1938
  liveReloadPath: liveReloadPath || void 0,
1882
1939
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1883
1940
  }),
@@ -2122,7 +2179,8 @@ function resolveWebframezReactRouteOptions(routePathValue, options = {}) {
2122
2179
  clientEntryPath: options.clientEntryPath ? resolveFromProjectRoot(options.clientEntryPath) : void 0,
2123
2180
  styleSrcPath: options.styleSrcPath ? resolveFromProjectRoot(options.styleSrcPath) : defaults.styleSrcPath,
2124
2181
  basePath: options.basePath ?? defaults.basePath,
2125
- liveReloadPath: options.liveReloadPath
2182
+ liveReloadPath: options.liveReloadPath,
2183
+ onData: options.onData
2126
2184
  };
2127
2185
  }
2128
2186
  function getRegisteredReactBuildTargets() {