@webtypen/webframez-react 0.0.30 → 0.0.31

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 N=Object.create;var m=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var W=(e,t)=>{for(var n in t)m(e,n,{get:t[n],enumerable:!0})},v=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of z(t))!M.call(e,r)&&r!==n&&m(e,r,{get:()=>t[r],enumerable:!(o=U(t,r))||o.enumerable});return e};var D=(e,t,n)=>(n=e!=null?N(B(e)):{},v(t||!e||!e.__esModule?m(n,"default",{value:e,enumerable:!0}):n,e)),F=e=>v(m({},"__esModule",{value:!0}),e);var oe={};W(oe,{mountWebframezClient:()=>ne,useCookie:()=>X,useRouter:()=>K});module.exports=F(oe);var i=D(require("react"),1),L=require("react-dom/client"),l=require("react-server-dom-webpack/client");var G=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function u(e){let t=e?.trim();if(t)return t==="/"?"/":t.replace(/\/+$/,"")}function x(e,t){let n=e.trim(),o=u(t);return!n||!o||G.test(n)||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function E(e,t){if(!e)return;let n=u(e.basename)??u(t),o={...e,...n?{basename:n}:{}};return o.favicon&&(o.favicon=x(o.favicon,n)),o.links&&(o.links=o.links.map(r=>({...r,href:x(r.href,n)}))),o}var s=require("react/jsx-runtime"),Y={push:()=>{},replace:()=>{},refresh:()=>{}},p=typeof i.default.createContext=="function"?i.default.createContext(null):null,O="__WEBFRAMEZ_ROUTER__",Z="[data-webframez-head='true']";function q(){return typeof window>"u"?null:window[O]??null}function j(e){typeof window>"u"||(window[O]=e)}function S(){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("="),d=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";d&&(e[d]=decodeURIComponent(c))}return e}function b(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 X(){return i.default.useMemo(()=>({all:()=>S(),get:e=>S()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=b(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=b(e,"",{...t??{},maxAge:0}))}}),[])}function K(){let e=p?i.default.useContext(p):null;if(!e){let t=q();if(t)return t;if(typeof window>"u")return Y;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function V({active:e}){return(0,s.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 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 I(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 P(e){if(typeof document>"u")return;let t=E(e)??e,n=u(t.basename);window.__RSC_BASENAME=n??"",document.title=t.title||"Webframez React";for(let o of document.head.querySelectorAll(Z))o.remove();t.description&&k({name:"description",content:t.description}),t.favicon&&I({rel:"icon",href:t.favicon});for(let o of t.meta??[])k(o);for(let o of t.links??[])I(o)}function J(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Q(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,l.createFromReadableStream)(J(e)))}function ee(e){return Q()??(0,l.createFromFetch)(fetch(`${e}?path=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))}function te(e,t){return function(){let o=i.default.use(e),[r,d]=(0,i.useState)(o.model),[c,w]=(0,i.useState)(o.head),[T,h]=(0,i.useState)(!1),[$,H]=(0,i.useState)(!1);async function f(a,_="push"){h(!0);try{let g=await(0,l.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(a.pathname)}&search=${encodeURIComponent(a.search)}`,{headers:{Accept:"text/x-component"}}));P(g.head),w(g.head),d(g.model);let y=`${a.pathname}${a.search}`;_==="replace"?history.replaceState(null,"",y):_==="push"&&history.pushState(null,"",y)}catch(A){console.error("[webframez-react] Failed to render route",A),d((0,s.jsx)("p",{children:"Failed to load route."}))}finally{h(!1)}}(0,i.useEffect)(()=>{P(c)},[c]),(0,i.useEffect)(()=>{H(!0);let a=()=>{f(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),()=>{window.removeEventListener("popstate",a)}},[]);let R=i.default.useMemo(()=>({push:a=>{f(new URL(a,window.location.origin),"push")},replace:a=>{f(new URL(a,window.location.origin),"replace")},refresh:()=>{f(new URL(window.location.href),"none")}}),[]);j(R);let C=(0,s.jsxs)(s.Fragment,{children:[$?(0,s.jsx)(V,{active:T}):null,r??(0,s.jsx)("p",{style:{padding:24},children:"Loading..."})]});return p?(0,s.jsx)(p.Provider,{value:R,children:C}):C}}function ne(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",d=ee(r),c=te(d,r);return(0,L.hydrateRoot)(n,(0,s.jsx)(c,{}))}
1
+ var M=Object.create;var m=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var Y=(e,t)=>{for(var n in t)m(e,n,{get:t[n],enumerable:!0})},S=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of F(t))!G.call(e,r)&&r!==n&&m(e,r,{get:()=>t[r],enumerable:!(o=D(t,r))||o.enumerable});return e};var Z=(e,t,n)=>(n=e!=null?M(q(e)):{},S(t||!e||!e.__esModule?m(n,"default",{value:e,enumerable:!0}):n,e)),j=e=>S(m({},"__esModule",{value:!0}),e);var ce={};Y(ce,{mountWebframezClient:()=>ue,useCookie:()=>ne,useRouter:()=>oe});module.exports=j(ce);var a=Z(require("react"),1),b=require("react-dom/client"),l=require("react-server-dom-webpack/client");var X=/^(?:[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 y(e,t){let n=e.trim(),o=u(t);return!n||!o||X.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function v(e,t){if(!e)return;let n=u(e.basename)??u(t),o=u(e.routeBasePath),r=u(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=y(i.favicon,n)),i.links&&(i.links=i.links.map(c=>({...c,href:y(c.href,n)}))),i}var d=require("react/jsx-runtime"),K={push:()=>{},replace:()=>{},refresh:()=>{}},p=typeof a.default.createContext=="function"?a.default.createContext(null):null,N="__WEBFRAMEZ_ROUTER__",V="[data-webframez-head='true']";function w(e){return u(e)??""}function J(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 Q(){return w(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function H(e){if(typeof window>"u")return e||"/";let t=w(window.__RSC_BASENAME),n=Q(),o=J(e||"/",t);return k(n,o)}function U(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function ee(){return typeof window>"u"?null:window[N]??null}function te(e){typeof window>"u"||(window[N]=e)}function T(){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,c=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(c))}return e}function B(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 a.default.useMemo(()=>({all:()=>T(),get:e=>T()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=B(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=B(e,"",{...t??{},maxAge:0}))}}),[])}function oe(){let e=p?a.default.useContext(p):null;if(!e){let t=ee();if(t)return t;if(typeof window>"u")return K;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function re({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 O(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 I(e){if(typeof document>"u")return;let t=v(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=k(r,"/rsc")),document.title=t.title||"Webframez React";for(let i of document.head.querySelectorAll(V))i.remove();t.description&&x({name:"description",content:t.description}),t.favicon&&O({rel:"icon",href:t.favicon});for(let i of t.meta??[])x(i);for(let i of t.links??[])O(i)}function ie(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function ae(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,l.createFromReadableStream)(ie(e)))}function se(e){let t=U(e),n=H(window.location.pathname);return ae()??(0,l.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))}function de(e,t){return function(){let o=a.default.use(e),[r,i]=(0,a.useState)(o.model),[c,R]=(0,a.useState)(o.head),[$,h]=(0,a.useState)(!1),[L,z]=(0,a.useState)(!1);async function f(s,E="push"){h(!0);try{let g=U(t),W=H(s.pathname),_=await(0,l.createFromFetch)(fetch(`${g}?path=${encodeURIComponent(W)}&search=${encodeURIComponent(s.search)}`,{headers:{Accept:"text/x-component"}}));I(_.head),R(_.head),i(_.model);let P=`${s.pathname}${s.search}`;E==="replace"?history.replaceState(null,"",P):E==="push"&&history.pushState(null,"",P)}catch(g){console.error("[webframez-react] Failed to render route",g),i((0,d.jsx)("p",{children:"Failed to load route."}))}finally{h(!1)}}(0,a.useEffect)(()=>{I(c)},[c]),(0,a.useEffect)(()=>{z(!0);let s=()=>{f(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let C=a.default.useMemo(()=>({push:s=>{f(new URL(s,window.location.origin),"push")},replace:s=>{f(new URL(s,window.location.origin),"replace")},refresh:()=>{f(new URL(window.location.href),"none")}}),[]);te(C);let A=(0,d.jsxs)(d.Fragment,{children:[L?(0,d.jsx)(re,{active:$}):null,r??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return p?(0,d.jsx)(p.Provider,{value:C,children:A}):A}}function ue(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=se(r),c=de(i,r);return(0,b.hydrateRoot)(n,(0,d.jsx)(c,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import c,{useEffect as x,useState as f}from"react";import{hydrateRoot as N}from"react-dom/client";import{createFromFetch as P,createFromReadableStream as U}from"react-server-dom-webpack/client";var H=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function u(t){let o=t?.trim();if(o)return o==="/"?"/":o.replace(/\/+$/,"")}function y(t,o){let n=t.trim(),e=u(o);return!n||!e||H.test(n)||e!=="/"&&(n===e||n.startsWith(`${e}/`))?n:e==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${e}${n}`:`${e}/${n}`}function v(t,o){if(!t)return;let n=u(t.basename)??u(o),e={...t,...n?{basename:n}:{}};return e.favicon&&(e.favicon=y(e.favicon,n)),e.links&&(e.links=e.links.map(r=>({...r,href:y(r.href,n)}))),e}import{Fragment as q,jsx as d,jsxs as j}from"react/jsx-runtime";var z={push:()=>{},replace:()=>{},refresh:()=>{}},m=typeof c.createContext=="function"?c.createContext(null):null,L="__WEBFRAMEZ_ROUTER__",B="[data-webframez-head='true']";function M(){return typeof window>"u"?null:window[L]??null}function W(t){typeof window>"u"||(window[L]=t)}function E(){let t={},o=typeof document>"u"?"":document.cookie;if(!o||o.trim()==="")return t;for(let n of o.split(";")){let e=n.trim();if(!e)continue;let r=e.indexOf("="),a=r>=0?e.slice(0,r).trim():e,s=r>=0?e.slice(r+1):"";a&&(t[a]=decodeURIComponent(s))}return t}function S(t,o,n={}){let e=[`${t}=${encodeURIComponent(o)}`];return n.path&&e.push(`Path=${n.path}`),n.domain&&e.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&e.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&e.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&e.push(`SameSite=${n.sameSite}`),n.secure&&e.push("Secure"),e.join("; ")}function ee(){return c.useMemo(()=>({all:()=>E(),get:t=>E()[t],set:(t,o,n)=>{typeof document>"u"||(document.cookie=S(t,o,n))},remove:(t,o)=>{typeof document>"u"||(document.cookie=S(t,"",{...o??{},maxAge:0}))}}),[])}function te(){let t=m?c.useContext(m):null;if(!t){let o=M();if(o)return o;if(typeof window>"u")return z;throw new Error("useRouter must be used inside mountWebframezClient()")}return t}function D({active:t}){return d("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:t?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function b(t){let o=document.createElement("meta");o.setAttribute("data-webframez-head","true");let n=Object.entries(t).filter(([,e])=>!!e);for(let[e,r]of n)o.setAttribute(e,String(r));document.head.appendChild(o)}function k(t){let o=document.createElement("link");o.setAttribute("data-webframez-head","true");let n=Object.entries(t).filter(([,e])=>!!e);for(let[e,r]of n)o.setAttribute(e,String(r));document.head.appendChild(o)}function I(t){if(typeof document>"u")return;let o=v(t)??t,n=u(o.basename);window.__RSC_BASENAME=n??"",document.title=o.title||"Webframez React";for(let e of document.head.querySelectorAll(B))e.remove();o.description&&b({name:"description",content:o.description}),o.favicon&&k({rel:"icon",href:o.favicon});for(let e of o.meta??[])b(e);for(let e of o.links??[])k(e)}function F(t){let o=new TextEncoder;return new ReadableStream({start(n){n.enqueue(o.encode(t)),n.close()}})}function G(){if(typeof window>"u")return null;let t=window.__RSC_INITIAL_PAYLOAD;return typeof t!="string"||t===""?null:(delete window.__RSC_INITIAL_PAYLOAD,U(F(t)))}function Y(t){return G()??P(fetch(`${t}?path=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))}function Z(t,o){return function(){let e=c.use(t),[r,a]=f(e.model),[s,g]=f(e.head),[O,w]=f(!1),[T,$]=f(!1);async function l(i,C="push"){w(!0);try{let p=await P(fetch(`${o}?path=${encodeURIComponent(i.pathname)}&search=${encodeURIComponent(i.search)}`,{headers:{Accept:"text/x-component"}}));I(p.head),g(p.head),a(p.model);let A=`${i.pathname}${i.search}`;C==="replace"?history.replaceState(null,"",A):C==="push"&&history.pushState(null,"",A)}catch(_){console.error("[webframez-react] Failed to render route",_),a(d("p",{children:"Failed to load route."}))}finally{w(!1)}}x(()=>{I(s)},[s]),x(()=>{$(!0);let i=()=>{l(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let h=c.useMemo(()=>({push:i=>{l(new URL(i,window.location.origin),"push")},replace:i=>{l(new URL(i,window.location.origin),"replace")},refresh:()=>{l(new URL(window.location.href),"none")}}),[]);W(h);let R=j(q,{children:[T?d(D,{active:O}):null,r??d("p",{style:{padding:24},children:"Loading..."})]});return m?d(m.Provider,{value:h,children:R}):R}}function ne(t={}){let o=t.rootId??"root",n=document.getElementById(o);if(!n)throw new Error(`Missing #${o} element`);let e=typeof window<"u"&&window.__RSC_ENDPOINT,r=t.rscEndpoint??e??"/rsc",a=Y(r),s=Z(a,r);return N(n,d(s,{}))}export{ne as mountWebframezClient,ee as useCookie,te as useRouter};
1
+ import c,{useEffect as y,useState as f}from"react";import{hydrateRoot as M}from"react-dom/client";import{createFromFetch as I,createFromReadableStream as D}from"react-server-dom-webpack/client";var W=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function s(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function P(e,t){let n=e.trim(),o=s(t);return!n||!o||W.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=s(e.basename)??s(t),o=s(e.routeBasePath),i=s(e.transportBasePath),r={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...i!==void 0?{transportBasePath:i}:{}};return r.favicon&&(r.favicon=P(r.favicon,n)),r.links&&(r.links=r.links.map(d=>({...d,href:P(d.href,n)}))),r}import{Fragment as ee,jsx as u,jsxs as te}from"react/jsx-runtime";var F={push:()=>{},replace:()=>{},refresh:()=>{}},m=typeof c.createContext=="function"?c.createContext(null):null,b="__WEBFRAMEZ_ROUTER__",q="[data-webframez-head='true']";function _(e){return s(e)??""}function G(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function N(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Y(){return _(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function k(e){if(typeof window>"u")return e||"/";let t=_(window.__RSC_BASENAME),n=Y(),o=G(e||"/",t);return N(n,o)}function H(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Z(){return typeof window>"u"?null:window[b]??null}function j(e){typeof window>"u"||(window[b]=e)}function v(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let i=o.indexOf("="),r=i>=0?o.slice(0,i).trim():o,d=i>=0?o.slice(i+1):"";r&&(e[r]=decodeURIComponent(d))}return e}function T(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 de(){return c.useMemo(()=>({all:()=>v(),get:e=>v()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=T(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=T(e,"",{...t??{},maxAge:0}))}}),[])}function ue(){let e=m?c.useContext(m):null;if(!e){let t=Z();if(t)return t;if(typeof window>"u")return F;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function X({active:e}){return u("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 B(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function x(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,i]of n)t.setAttribute(o,String(i));document.head.appendChild(t)}function O(e){if(typeof document>"u")return;let t=S(e)??e,n=s(t.basename),o=s(t.routeBasePath),i=s(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",i!==void 0&&(window.__RSC_ENDPOINT=N(i,"/rsc")),document.title=t.title||"Webframez React";for(let r of document.head.querySelectorAll(q))r.remove();t.description&&B({name:"description",content:t.description}),t.favicon&&x({rel:"icon",href:t.favicon});for(let r of t.meta??[])B(r);for(let r of t.links??[])x(r)}function K(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function V(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,D(K(e)))}function J(e){let t=H(e),n=k(window.location.pathname);return V()??I(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))}function Q(e,t){return function(){let o=c.use(e),[i,r]=f(o.model),[d,w]=f(o.head),[U,R]=f(!1),[$,L]=f(!1);async function l(a,A="push"){R(!0);try{let p=H(t),z=k(a.pathname),g=await I(fetch(`${p}?path=${encodeURIComponent(z)}&search=${encodeURIComponent(a.search)}`,{headers:{Accept:"text/x-component"}}));O(g.head),w(g.head),r(g.model);let E=`${a.pathname}${a.search}`;A==="replace"?history.replaceState(null,"",E):A==="push"&&history.pushState(null,"",E)}catch(p){console.error("[webframez-react] Failed to render route",p),r(u("p",{children:"Failed to load route."}))}finally{R(!1)}}y(()=>{O(d)},[d]),y(()=>{L(!0);let a=()=>{l(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),()=>{window.removeEventListener("popstate",a)}},[]);let h=c.useMemo(()=>({push:a=>{l(new URL(a,window.location.origin),"push")},replace:a=>{l(new URL(a,window.location.origin),"replace")},refresh:()=>{l(new URL(window.location.href),"none")}}),[]);j(h);let C=te(ee,{children:[$?u(X,{active:U}):null,i??u("p",{style:{padding:24},children:"Loading..."})]});return m?u(m.Provider,{value:h,children:C}):C}}function ce(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,i=e.rscEndpoint??o??"/rsc",r=J(i),d=Q(r,i);return M(n,u(d,{}))}export{ce as mountWebframezClient,de as useCookie,ue as useRouter};
package/dist/http.cjs CHANGED
@@ -55,6 +55,7 @@ function createHTMLShell(options = {}) {
55
55
  rootHtml = "",
56
56
  initialFlightData = "",
57
57
  basename = "",
58
+ routeBasePath = "",
58
59
  liveReloadPath,
59
60
  liveReloadServerId
60
61
  } = options;
@@ -103,6 +104,7 @@ function createHTMLShell(options = {}) {
103
104
  <div id="root">${rootHtml}</div>
104
105
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
105
106
  <script>window.__RSC_BASENAME = "${basename}";</script>
107
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
106
108
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
107
109
  <script type="module" src="${clientScriptUrl}"></script>
108
110
  ${liveReloadScript}
@@ -153,12 +155,12 @@ var import_node_path2 = __toESM(require("node:path"), 1);
153
155
  // src/head.ts
154
156
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
155
157
  function normalizeHeadBasename(value) {
156
- const trimmed = value?.trim();
157
- if (!trimmed) {
158
+ if (typeof value !== "string") {
158
159
  return void 0;
159
160
  }
160
- if (trimmed === "/") {
161
- return "/";
161
+ const trimmed = value.trim();
162
+ if (!trimmed || trimmed === "/") {
163
+ return "";
162
164
  }
163
165
  return trimmed.replace(/\/+$/, "");
164
166
  }
@@ -171,6 +173,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
171
173
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
172
174
  return normalizedAssetUrl;
173
175
  }
176
+ if (normalizedAssetUrl.startsWith("/")) {
177
+ return normalizedAssetUrl;
178
+ }
174
179
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
175
180
  return normalizedAssetUrl;
176
181
  }
@@ -187,9 +192,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
187
192
  return void 0;
188
193
  }
189
194
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
195
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
196
+ const normalizedTransportBasePath = normalizeHeadBasename(
197
+ head.transportBasePath
198
+ );
190
199
  const normalizedHead = {
191
200
  ...head,
192
- ...effectiveBasename ? { basename: effectiveBasename } : {}
201
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
202
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
203
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
193
204
  };
194
205
  if (normalizedHead.favicon) {
195
206
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -999,6 +1010,23 @@ function stripBasePath(pathname, basePath) {
999
1010
  }
1000
1011
  return pathname;
1001
1012
  }
1013
+ function normalizeRuntimeBasePath(value) {
1014
+ if (typeof value !== "string") {
1015
+ return void 0;
1016
+ }
1017
+ const trimmed = value.trim();
1018
+ if (!trimmed || trimmed === "/") {
1019
+ return "";
1020
+ }
1021
+ return trimmed.replace(/\/+$/, "");
1022
+ }
1023
+ function joinRuntimeBasePath(basePath, pathname) {
1024
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1025
+ if (!basePath) {
1026
+ return normalizedPath;
1027
+ }
1028
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1029
+ }
1002
1030
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1003
1031
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1004
1032
  return "";
@@ -1399,6 +1427,14 @@ function createNodeRequestHandler(options) {
1399
1427
  const initialFlightData = await renderRSCToString(initialPayload, {
1400
1428
  moduleMap
1401
1429
  });
1430
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1431
+ const shellClientScriptUrl = joinRuntimeBasePath(
1432
+ transportBasePath,
1433
+ "/assets/client.js"
1434
+ );
1435
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1436
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1437
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1402
1438
  let rootHtml = "";
1403
1439
  try {
1404
1440
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1429,11 +1465,12 @@ function createNodeRequestHandler(options) {
1429
1465
  createHTMLShell({
1430
1466
  title: "500 - Initial HTML render failed",
1431
1467
  headTags: "",
1432
- clientScriptUrl,
1433
- rscEndpoint: rscPath,
1468
+ clientScriptUrl: shellClientScriptUrl,
1469
+ rscEndpoint: shellRscEndpoint,
1434
1470
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1435
1471
  initialFlightData,
1436
- basename: resolved?.head?.basename ?? basePath,
1472
+ basename: shellBasename,
1473
+ routeBasePath: shellRouteBasePath,
1437
1474
  liveReloadPath: liveReloadPath || void 0,
1438
1475
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1439
1476
  })
@@ -1448,11 +1485,12 @@ function createNodeRequestHandler(options) {
1448
1485
  createHTMLShell({
1449
1486
  title: resolved.head.title || "Webframez React",
1450
1487
  headTags: renderHeadToString(resolved.head),
1451
- clientScriptUrl,
1452
- rscEndpoint: rscPath,
1488
+ clientScriptUrl: shellClientScriptUrl,
1489
+ rscEndpoint: shellRscEndpoint,
1453
1490
  rootHtml,
1454
1491
  initialFlightData,
1455
- basename: resolved.head.basename ?? basePath,
1492
+ basename: shellBasename,
1493
+ routeBasePath: shellRouteBasePath,
1456
1494
  liveReloadPath: liveReloadPath || void 0,
1457
1495
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1458
1496
  })
package/dist/http.js CHANGED
@@ -30,6 +30,7 @@ function createHTMLShell(options = {}) {
30
30
  rootHtml = "",
31
31
  initialFlightData = "",
32
32
  basename = "",
33
+ routeBasePath = "",
33
34
  liveReloadPath,
34
35
  liveReloadServerId
35
36
  } = options;
@@ -78,6 +79,7 @@ function createHTMLShell(options = {}) {
78
79
  <div id="root">${rootHtml}</div>
79
80
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
80
81
  <script>window.__RSC_BASENAME = "${basename}";</script>
82
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
81
83
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
82
84
  <script type="module" src="${clientScriptUrl}"></script>
83
85
  ${liveReloadScript}
@@ -128,12 +130,12 @@ import path2 from "node:path";
128
130
  // src/head.ts
129
131
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
130
132
  function normalizeHeadBasename(value) {
131
- const trimmed = value?.trim();
132
- if (!trimmed) {
133
+ if (typeof value !== "string") {
133
134
  return void 0;
134
135
  }
135
- if (trimmed === "/") {
136
- return "/";
136
+ const trimmed = value.trim();
137
+ if (!trimmed || trimmed === "/") {
138
+ return "";
137
139
  }
138
140
  return trimmed.replace(/\/+$/, "");
139
141
  }
@@ -146,6 +148,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
146
148
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
147
149
  return normalizedAssetUrl;
148
150
  }
151
+ if (normalizedAssetUrl.startsWith("/")) {
152
+ return normalizedAssetUrl;
153
+ }
149
154
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
150
155
  return normalizedAssetUrl;
151
156
  }
@@ -162,9 +167,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
162
167
  return void 0;
163
168
  }
164
169
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
170
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
171
+ const normalizedTransportBasePath = normalizeHeadBasename(
172
+ head.transportBasePath
173
+ );
165
174
  const normalizedHead = {
166
175
  ...head,
167
- ...effectiveBasename ? { basename: effectiveBasename } : {}
176
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
177
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
178
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
168
179
  };
169
180
  if (normalizedHead.favicon) {
170
181
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -974,6 +985,23 @@ function stripBasePath(pathname, basePath) {
974
985
  }
975
986
  return pathname;
976
987
  }
988
+ function normalizeRuntimeBasePath(value) {
989
+ if (typeof value !== "string") {
990
+ return void 0;
991
+ }
992
+ const trimmed = value.trim();
993
+ if (!trimmed || trimmed === "/") {
994
+ return "";
995
+ }
996
+ return trimmed.replace(/\/+$/, "");
997
+ }
998
+ function joinRuntimeBasePath(basePath, pathname) {
999
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1000
+ if (!basePath) {
1001
+ return normalizedPath;
1002
+ }
1003
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1004
+ }
977
1005
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
978
1006
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
979
1007
  return "";
@@ -1374,6 +1402,14 @@ function createNodeRequestHandler(options) {
1374
1402
  const initialFlightData = await renderRSCToString(initialPayload, {
1375
1403
  moduleMap
1376
1404
  });
1405
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1406
+ const shellClientScriptUrl = joinRuntimeBasePath(
1407
+ transportBasePath,
1408
+ "/assets/client.js"
1409
+ );
1410
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1411
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1412
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1377
1413
  let rootHtml = "";
1378
1414
  try {
1379
1415
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1404,11 +1440,12 @@ function createNodeRequestHandler(options) {
1404
1440
  createHTMLShell({
1405
1441
  title: "500 - Initial HTML render failed",
1406
1442
  headTags: "",
1407
- clientScriptUrl,
1408
- rscEndpoint: rscPath,
1443
+ clientScriptUrl: shellClientScriptUrl,
1444
+ rscEndpoint: shellRscEndpoint,
1409
1445
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1410
1446
  initialFlightData,
1411
- basename: resolved?.head?.basename ?? basePath,
1447
+ basename: shellBasename,
1448
+ routeBasePath: shellRouteBasePath,
1412
1449
  liveReloadPath: liveReloadPath || void 0,
1413
1450
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1414
1451
  })
@@ -1423,11 +1460,12 @@ function createNodeRequestHandler(options) {
1423
1460
  createHTMLShell({
1424
1461
  title: resolved.head.title || "Webframez React",
1425
1462
  headTags: renderHeadToString(resolved.head),
1426
- clientScriptUrl,
1427
- rscEndpoint: rscPath,
1463
+ clientScriptUrl: shellClientScriptUrl,
1464
+ rscEndpoint: shellRscEndpoint,
1428
1465
  rootHtml,
1429
1466
  initialFlightData,
1430
- basename: resolved.head.basename ?? basePath,
1467
+ basename: shellBasename,
1468
+ routeBasePath: shellRouteBasePath,
1431
1469
  liveReloadPath: liveReloadPath || void 0,
1432
1470
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1433
1471
  })
package/dist/index.cjs CHANGED
@@ -60,6 +60,7 @@ function createHTMLShell(options = {}) {
60
60
  rootHtml = "",
61
61
  initialFlightData = "",
62
62
  basename = "",
63
+ routeBasePath = "",
63
64
  liveReloadPath,
64
65
  liveReloadServerId
65
66
  } = options;
@@ -108,6 +109,7 @@ function createHTMLShell(options = {}) {
108
109
  <div id="root">${rootHtml}</div>
109
110
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
110
111
  <script>window.__RSC_BASENAME = "${basename}";</script>
112
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
111
113
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
112
114
  <script type="module" src="${clientScriptUrl}"></script>
113
115
  ${liveReloadScript}
@@ -186,12 +188,12 @@ var import_node_path2 = __toESM(require("node:path"), 1);
186
188
  // src/head.ts
187
189
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
188
190
  function normalizeHeadBasename(value) {
189
- const trimmed = value?.trim();
190
- if (!trimmed) {
191
+ if (typeof value !== "string") {
191
192
  return void 0;
192
193
  }
193
- if (trimmed === "/") {
194
- return "/";
194
+ const trimmed = value.trim();
195
+ if (!trimmed || trimmed === "/") {
196
+ return "";
195
197
  }
196
198
  return trimmed.replace(/\/+$/, "");
197
199
  }
@@ -204,6 +206,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
204
206
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
205
207
  return normalizedAssetUrl;
206
208
  }
209
+ if (normalizedAssetUrl.startsWith("/")) {
210
+ return normalizedAssetUrl;
211
+ }
207
212
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
208
213
  return normalizedAssetUrl;
209
214
  }
@@ -220,9 +225,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
220
225
  return void 0;
221
226
  }
222
227
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
228
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
229
+ const normalizedTransportBasePath = normalizeHeadBasename(
230
+ head.transportBasePath
231
+ );
223
232
  const normalizedHead = {
224
233
  ...head,
225
- ...effectiveBasename ? { basename: effectiveBasename } : {}
234
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
235
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
236
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
226
237
  };
227
238
  if (normalizedHead.favicon) {
228
239
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -1036,6 +1047,23 @@ function stripBasePath(pathname, basePath) {
1036
1047
  }
1037
1048
  return pathname;
1038
1049
  }
1050
+ function normalizeRuntimeBasePath(value) {
1051
+ if (typeof value !== "string") {
1052
+ return void 0;
1053
+ }
1054
+ const trimmed = value.trim();
1055
+ if (!trimmed || trimmed === "/") {
1056
+ return "";
1057
+ }
1058
+ return trimmed.replace(/\/+$/, "");
1059
+ }
1060
+ function joinRuntimeBasePath(basePath, pathname) {
1061
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1062
+ if (!basePath) {
1063
+ return normalizedPath;
1064
+ }
1065
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1066
+ }
1039
1067
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1040
1068
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1041
1069
  return "";
@@ -1436,6 +1464,14 @@ function createNodeRequestHandler(options) {
1436
1464
  const initialFlightData = await renderRSCToString(initialPayload, {
1437
1465
  moduleMap
1438
1466
  });
1467
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1468
+ const shellClientScriptUrl = joinRuntimeBasePath(
1469
+ transportBasePath,
1470
+ "/assets/client.js"
1471
+ );
1472
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1473
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1474
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1439
1475
  let rootHtml = "";
1440
1476
  try {
1441
1477
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1466,11 +1502,12 @@ function createNodeRequestHandler(options) {
1466
1502
  createHTMLShell({
1467
1503
  title: "500 - Initial HTML render failed",
1468
1504
  headTags: "",
1469
- clientScriptUrl,
1470
- rscEndpoint: rscPath,
1505
+ clientScriptUrl: shellClientScriptUrl,
1506
+ rscEndpoint: shellRscEndpoint,
1471
1507
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1472
1508
  initialFlightData,
1473
- basename: resolved?.head?.basename ?? basePath,
1509
+ basename: shellBasename,
1510
+ routeBasePath: shellRouteBasePath,
1474
1511
  liveReloadPath: liveReloadPath || void 0,
1475
1512
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1476
1513
  })
@@ -1485,11 +1522,12 @@ function createNodeRequestHandler(options) {
1485
1522
  createHTMLShell({
1486
1523
  title: resolved.head.title || "Webframez React",
1487
1524
  headTags: renderHeadToString(resolved.head),
1488
- clientScriptUrl,
1489
- rscEndpoint: rscPath,
1525
+ clientScriptUrl: shellClientScriptUrl,
1526
+ rscEndpoint: shellRscEndpoint,
1490
1527
  rootHtml,
1491
1528
  initialFlightData,
1492
- basename: resolved.head.basename ?? basePath,
1529
+ basename: shellBasename,
1530
+ routeBasePath: shellRouteBasePath,
1493
1531
  liveReloadPath: liveReloadPath || void 0,
1494
1532
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1495
1533
  })
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ function createHTMLShell(options = {}) {
24
24
  rootHtml = "",
25
25
  initialFlightData = "",
26
26
  basename = "",
27
+ routeBasePath = "",
27
28
  liveReloadPath,
28
29
  liveReloadServerId
29
30
  } = options;
@@ -72,6 +73,7 @@ function createHTMLShell(options = {}) {
72
73
  <div id="root">${rootHtml}</div>
73
74
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
74
75
  <script>window.__RSC_BASENAME = "${basename}";</script>
76
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
75
77
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
76
78
  <script type="module" src="${clientScriptUrl}"></script>
77
79
  ${liveReloadScript}
@@ -150,12 +152,12 @@ import path2 from "node:path";
150
152
  // src/head.ts
151
153
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
152
154
  function normalizeHeadBasename(value) {
153
- const trimmed = value?.trim();
154
- if (!trimmed) {
155
+ if (typeof value !== "string") {
155
156
  return void 0;
156
157
  }
157
- if (trimmed === "/") {
158
- return "/";
158
+ const trimmed = value.trim();
159
+ if (!trimmed || trimmed === "/") {
160
+ return "";
159
161
  }
160
162
  return trimmed.replace(/\/+$/, "");
161
163
  }
@@ -168,6 +170,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
168
170
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
169
171
  return normalizedAssetUrl;
170
172
  }
173
+ if (normalizedAssetUrl.startsWith("/")) {
174
+ return normalizedAssetUrl;
175
+ }
171
176
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
172
177
  return normalizedAssetUrl;
173
178
  }
@@ -184,9 +189,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
184
189
  return void 0;
185
190
  }
186
191
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
192
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
193
+ const normalizedTransportBasePath = normalizeHeadBasename(
194
+ head.transportBasePath
195
+ );
187
196
  const normalizedHead = {
188
197
  ...head,
189
- ...effectiveBasename ? { basename: effectiveBasename } : {}
198
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
199
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
200
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
190
201
  };
191
202
  if (normalizedHead.favicon) {
192
203
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -1000,6 +1011,23 @@ function stripBasePath(pathname, basePath) {
1000
1011
  }
1001
1012
  return pathname;
1002
1013
  }
1014
+ function normalizeRuntimeBasePath(value) {
1015
+ if (typeof value !== "string") {
1016
+ return void 0;
1017
+ }
1018
+ const trimmed = value.trim();
1019
+ if (!trimmed || trimmed === "/") {
1020
+ return "";
1021
+ }
1022
+ return trimmed.replace(/\/+$/, "");
1023
+ }
1024
+ function joinRuntimeBasePath(basePath, pathname) {
1025
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1026
+ if (!basePath) {
1027
+ return normalizedPath;
1028
+ }
1029
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1030
+ }
1003
1031
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1004
1032
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1005
1033
  return "";
@@ -1400,6 +1428,14 @@ function createNodeRequestHandler(options) {
1400
1428
  const initialFlightData = await renderRSCToString(initialPayload, {
1401
1429
  moduleMap
1402
1430
  });
1431
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1432
+ const shellClientScriptUrl = joinRuntimeBasePath(
1433
+ transportBasePath,
1434
+ "/assets/client.js"
1435
+ );
1436
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1437
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1438
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1403
1439
  let rootHtml = "";
1404
1440
  try {
1405
1441
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1430,11 +1466,12 @@ function createNodeRequestHandler(options) {
1430
1466
  createHTMLShell({
1431
1467
  title: "500 - Initial HTML render failed",
1432
1468
  headTags: "",
1433
- clientScriptUrl,
1434
- rscEndpoint: rscPath,
1469
+ clientScriptUrl: shellClientScriptUrl,
1470
+ rscEndpoint: shellRscEndpoint,
1435
1471
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1436
1472
  initialFlightData,
1437
- basename: resolved?.head?.basename ?? basePath,
1473
+ basename: shellBasename,
1474
+ routeBasePath: shellRouteBasePath,
1438
1475
  liveReloadPath: liveReloadPath || void 0,
1439
1476
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1440
1477
  })
@@ -1449,11 +1486,12 @@ function createNodeRequestHandler(options) {
1449
1486
  createHTMLShell({
1450
1487
  title: resolved.head.title || "Webframez React",
1451
1488
  headTags: renderHeadToString(resolved.head),
1452
- clientScriptUrl,
1453
- rscEndpoint: rscPath,
1489
+ clientScriptUrl: shellClientScriptUrl,
1490
+ rscEndpoint: shellRscEndpoint,
1454
1491
  rootHtml,
1455
1492
  initialFlightData,
1456
- basename: resolved.head.basename ?? basePath,
1493
+ basename: shellBasename,
1494
+ routeBasePath: shellRouteBasePath,
1457
1495
  liveReloadPath: liveReloadPath || void 0,
1458
1496
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1459
1497
  })
package/dist/router.cjs CHANGED
@@ -44,12 +44,12 @@ var import_node_path = __toESM(require("node:path"), 1);
44
44
  // src/head.ts
45
45
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
46
46
  function normalizeHeadBasename(value) {
47
- const trimmed = value?.trim();
48
- if (!trimmed) {
47
+ if (typeof value !== "string") {
49
48
  return void 0;
50
49
  }
51
- if (trimmed === "/") {
52
- return "/";
50
+ const trimmed = value.trim();
51
+ if (!trimmed || trimmed === "/") {
52
+ return "";
53
53
  }
54
54
  return trimmed.replace(/\/+$/, "");
55
55
  }
@@ -62,6 +62,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
62
62
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
63
63
  return normalizedAssetUrl;
64
64
  }
65
+ if (normalizedAssetUrl.startsWith("/")) {
66
+ return normalizedAssetUrl;
67
+ }
65
68
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
66
69
  return normalizedAssetUrl;
67
70
  }
@@ -78,9 +81,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
78
81
  return void 0;
79
82
  }
80
83
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
84
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
85
+ const normalizedTransportBasePath = normalizeHeadBasename(
86
+ head.transportBasePath
87
+ );
81
88
  const normalizedHead = {
82
89
  ...head,
83
- ...effectiveBasename ? { basename: effectiveBasename } : {}
90
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
91
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
92
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
84
93
  };
85
94
  if (normalizedHead.favicon) {
86
95
  normalizedHead.favicon = resolveHeadAssetUrl(
package/dist/router.js CHANGED
@@ -14,12 +14,12 @@ import path from "node:path";
14
14
  // src/head.ts
15
15
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
16
16
  function normalizeHeadBasename(value) {
17
- const trimmed = value?.trim();
18
- if (!trimmed) {
17
+ if (typeof value !== "string") {
19
18
  return void 0;
20
19
  }
21
- if (trimmed === "/") {
22
- return "/";
20
+ const trimmed = value.trim();
21
+ if (!trimmed || trimmed === "/") {
22
+ return "";
23
23
  }
24
24
  return trimmed.replace(/\/+$/, "");
25
25
  }
@@ -32,6 +32,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
32
32
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
33
33
  return normalizedAssetUrl;
34
34
  }
35
+ if (normalizedAssetUrl.startsWith("/")) {
36
+ return normalizedAssetUrl;
37
+ }
35
38
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
36
39
  return normalizedAssetUrl;
37
40
  }
@@ -48,9 +51,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
48
51
  return void 0;
49
52
  }
50
53
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
54
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
55
+ const normalizedTransportBasePath = normalizeHeadBasename(
56
+ head.transportBasePath
57
+ );
51
58
  const normalizedHead = {
52
59
  ...head,
53
- ...effectiveBasename ? { basename: effectiveBasename } : {}
60
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
61
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
62
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
54
63
  };
55
64
  if (normalizedHead.favicon) {
56
65
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -58,6 +58,7 @@ function createHTMLShell(options = {}) {
58
58
  rootHtml = "",
59
59
  initialFlightData = "",
60
60
  basename = "",
61
+ routeBasePath = "",
61
62
  liveReloadPath,
62
63
  liveReloadServerId
63
64
  } = options;
@@ -106,6 +107,7 @@ function createHTMLShell(options = {}) {
106
107
  <div id="root">${rootHtml}</div>
107
108
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
108
109
  <script>window.__RSC_BASENAME = "${basename}";</script>
110
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
109
111
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
110
112
  <script type="module" src="${clientScriptUrl}"></script>
111
113
  ${liveReloadScript}
@@ -156,12 +158,12 @@ var import_node_path2 = __toESM(require("node:path"), 1);
156
158
  // src/head.ts
157
159
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
158
160
  function normalizeHeadBasename(value) {
159
- const trimmed = value?.trim();
160
- if (!trimmed) {
161
+ if (typeof value !== "string") {
161
162
  return void 0;
162
163
  }
163
- if (trimmed === "/") {
164
- return "/";
164
+ const trimmed = value.trim();
165
+ if (!trimmed || trimmed === "/") {
166
+ return "";
165
167
  }
166
168
  return trimmed.replace(/\/+$/, "");
167
169
  }
@@ -174,6 +176,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
174
176
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
175
177
  return normalizedAssetUrl;
176
178
  }
179
+ if (normalizedAssetUrl.startsWith("/")) {
180
+ return normalizedAssetUrl;
181
+ }
177
182
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
178
183
  return normalizedAssetUrl;
179
184
  }
@@ -190,9 +195,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
190
195
  return void 0;
191
196
  }
192
197
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
198
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
199
+ const normalizedTransportBasePath = normalizeHeadBasename(
200
+ head.transportBasePath
201
+ );
193
202
  const normalizedHead = {
194
203
  ...head,
195
- ...effectiveBasename ? { basename: effectiveBasename } : {}
204
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
205
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
206
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
196
207
  };
197
208
  if (normalizedHead.favicon) {
198
209
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -1002,6 +1013,23 @@ function stripBasePath(pathname, basePath) {
1002
1013
  }
1003
1014
  return pathname;
1004
1015
  }
1016
+ function normalizeRuntimeBasePath(value) {
1017
+ if (typeof value !== "string") {
1018
+ return void 0;
1019
+ }
1020
+ const trimmed = value.trim();
1021
+ if (!trimmed || trimmed === "/") {
1022
+ return "";
1023
+ }
1024
+ return trimmed.replace(/\/+$/, "");
1025
+ }
1026
+ function joinRuntimeBasePath(basePath, pathname) {
1027
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1028
+ if (!basePath) {
1029
+ return normalizedPath;
1030
+ }
1031
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1032
+ }
1005
1033
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1006
1034
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1007
1035
  return "";
@@ -1402,6 +1430,14 @@ function createNodeRequestHandler(options) {
1402
1430
  const initialFlightData = await renderRSCToString(initialPayload, {
1403
1431
  moduleMap
1404
1432
  });
1433
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1434
+ const shellClientScriptUrl = joinRuntimeBasePath(
1435
+ transportBasePath,
1436
+ "/assets/client.js"
1437
+ );
1438
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1439
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1440
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1405
1441
  let rootHtml = "";
1406
1442
  try {
1407
1443
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1432,11 +1468,12 @@ function createNodeRequestHandler(options) {
1432
1468
  createHTMLShell({
1433
1469
  title: "500 - Initial HTML render failed",
1434
1470
  headTags: "",
1435
- clientScriptUrl,
1436
- rscEndpoint: rscPath,
1471
+ clientScriptUrl: shellClientScriptUrl,
1472
+ rscEndpoint: shellRscEndpoint,
1437
1473
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1438
1474
  initialFlightData,
1439
- basename: resolved?.head?.basename ?? basePath,
1475
+ basename: shellBasename,
1476
+ routeBasePath: shellRouteBasePath,
1440
1477
  liveReloadPath: liveReloadPath || void 0,
1441
1478
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1442
1479
  })
@@ -1451,11 +1488,12 @@ function createNodeRequestHandler(options) {
1451
1488
  createHTMLShell({
1452
1489
  title: resolved.head.title || "Webframez React",
1453
1490
  headTags: renderHeadToString(resolved.head),
1454
- clientScriptUrl,
1455
- rscEndpoint: rscPath,
1491
+ clientScriptUrl: shellClientScriptUrl,
1492
+ rscEndpoint: shellRscEndpoint,
1456
1493
  rootHtml,
1457
1494
  initialFlightData,
1458
- basename: resolved.head.basename ?? basePath,
1495
+ basename: shellBasename,
1496
+ routeBasePath: shellRouteBasePath,
1459
1497
  liveReloadPath: liveReloadPath || void 0,
1460
1498
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1461
1499
  })
@@ -30,6 +30,7 @@ function createHTMLShell(options = {}) {
30
30
  rootHtml = "",
31
31
  initialFlightData = "",
32
32
  basename = "",
33
+ routeBasePath = "",
33
34
  liveReloadPath,
34
35
  liveReloadServerId
35
36
  } = options;
@@ -78,6 +79,7 @@ function createHTMLShell(options = {}) {
78
79
  <div id="root">${rootHtml}</div>
79
80
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
80
81
  <script>window.__RSC_BASENAME = "${basename}";</script>
82
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
81
83
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
82
84
  <script type="module" src="${clientScriptUrl}"></script>
83
85
  ${liveReloadScript}
@@ -128,12 +130,12 @@ import path2 from "node:path";
128
130
  // src/head.ts
129
131
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
130
132
  function normalizeHeadBasename(value) {
131
- const trimmed = value?.trim();
132
- if (!trimmed) {
133
+ if (typeof value !== "string") {
133
134
  return void 0;
134
135
  }
135
- if (trimmed === "/") {
136
- return "/";
136
+ const trimmed = value.trim();
137
+ if (!trimmed || trimmed === "/") {
138
+ return "";
137
139
  }
138
140
  return trimmed.replace(/\/+$/, "");
139
141
  }
@@ -146,6 +148,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
146
148
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
147
149
  return normalizedAssetUrl;
148
150
  }
151
+ if (normalizedAssetUrl.startsWith("/")) {
152
+ return normalizedAssetUrl;
153
+ }
149
154
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
150
155
  return normalizedAssetUrl;
151
156
  }
@@ -162,9 +167,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
162
167
  return void 0;
163
168
  }
164
169
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
170
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
171
+ const normalizedTransportBasePath = normalizeHeadBasename(
172
+ head.transportBasePath
173
+ );
165
174
  const normalizedHead = {
166
175
  ...head,
167
- ...effectiveBasename ? { basename: effectiveBasename } : {}
176
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
177
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
178
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
168
179
  };
169
180
  if (normalizedHead.favicon) {
170
181
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -974,6 +985,23 @@ function stripBasePath(pathname, basePath) {
974
985
  }
975
986
  return pathname;
976
987
  }
988
+ function normalizeRuntimeBasePath(value) {
989
+ if (typeof value !== "string") {
990
+ return void 0;
991
+ }
992
+ const trimmed = value.trim();
993
+ if (!trimmed || trimmed === "/") {
994
+ return "";
995
+ }
996
+ return trimmed.replace(/\/+$/, "");
997
+ }
998
+ function joinRuntimeBasePath(basePath, pathname) {
999
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1000
+ if (!basePath) {
1001
+ return normalizedPath;
1002
+ }
1003
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1004
+ }
977
1005
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
978
1006
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
979
1007
  return "";
@@ -1374,6 +1402,14 @@ function createNodeRequestHandler(options) {
1374
1402
  const initialFlightData = await renderRSCToString(initialPayload, {
1375
1403
  moduleMap
1376
1404
  });
1405
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1406
+ const shellClientScriptUrl = joinRuntimeBasePath(
1407
+ transportBasePath,
1408
+ "/assets/client.js"
1409
+ );
1410
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1411
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1412
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1377
1413
  let rootHtml = "";
1378
1414
  try {
1379
1415
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1404,11 +1440,12 @@ function createNodeRequestHandler(options) {
1404
1440
  createHTMLShell({
1405
1441
  title: "500 - Initial HTML render failed",
1406
1442
  headTags: "",
1407
- clientScriptUrl,
1408
- rscEndpoint: rscPath,
1443
+ clientScriptUrl: shellClientScriptUrl,
1444
+ rscEndpoint: shellRscEndpoint,
1409
1445
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1410
1446
  initialFlightData,
1411
- basename: resolved?.head?.basename ?? basePath,
1447
+ basename: shellBasename,
1448
+ routeBasePath: shellRouteBasePath,
1412
1449
  liveReloadPath: liveReloadPath || void 0,
1413
1450
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1414
1451
  })
@@ -1423,11 +1460,12 @@ function createNodeRequestHandler(options) {
1423
1460
  createHTMLShell({
1424
1461
  title: resolved.head.title || "Webframez React",
1425
1462
  headTags: renderHeadToString(resolved.head),
1426
- clientScriptUrl,
1427
- rscEndpoint: rscPath,
1463
+ clientScriptUrl: shellClientScriptUrl,
1464
+ rscEndpoint: shellRscEndpoint,
1428
1465
  rootHtml,
1429
1466
  initialFlightData,
1430
- basename: resolved.head.basename ?? basePath,
1467
+ basename: shellBasename,
1468
+ routeBasePath: shellRouteBasePath,
1431
1469
  liveReloadPath: liveReloadPath || void 0,
1432
1470
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1433
1471
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {