@webtypen/webframez-react 0.0.27 → 0.0.29

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/README.md CHANGED
@@ -132,15 +132,15 @@ Route.renderReact("/app", {
132
132
 
133
133
  ## `Head()` Assets
134
134
 
135
- Inside a page, layout, or error `Head()` method you can set `assetsBaseUrl`.
136
- That base URL is applied to `favicon` and `links[].href`, which is useful for CSS
137
- files and other head assets served from a CDN or shared asset host.
135
+ Inside a page, layout, or error `Head()` method you can set `basename`.
136
+ That basename is applied to `favicon` and `links[].href`, and also updates the
137
+ router basename used by `Link`, `Redirect`, and client-side navigation.
138
138
 
139
139
  ```ts
140
140
  export function Head() {
141
141
  return {
142
142
  title: "Dashboard",
143
- assetsBaseUrl: "https://cdn.example.com/app",
143
+ basename: "/app",
144
144
  favicon: "/favicon.ico",
145
145
  links: [{ rel: "stylesheet", href: "/styles/dashboard.css" }],
146
146
  };
package/dist/client.cjs CHANGED
@@ -1 +1 @@
1
- var H=Object.create;var f=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var W=(e,n)=>{for(var t in n)f(e,t,{get:n[t],enumerable:!0})},v=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of z(n))!M.call(e,r)&&r!==t&&f(e,r,{get:()=>n[r],enumerable:!(o=N(n,r))||o.enumerable});return e};var D=(e,n,t)=>(t=e!=null?H(B(e)):{},v(n||!e||!e.__esModule?f(t,"default",{value:e,enumerable:!0}):t,e)),F=e=>v(f({},"__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"),u=require("react-server-dom-webpack/client");var G=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function g(e){let n=e?.trim();if(n)return n==="/"?"/":n.replace(/\/+$/,"")}function x(e,n){let t=e.trim(),o=g(n);return!t||!o||G.test(t)||o!=="/"&&(t===o||t.startsWith(`${o}/`))?t:o==="/"?t.startsWith("/")?t:`/${t}`:t.startsWith("/")?`${o}${t}`:`${o}/${t}`}function E(e,n){if(!e)return;let t=g(e.assetsBaseUrl)??g(n),o={...e,...t?{assetsBaseUrl:t}:{}};return o.favicon&&(o.favicon=x(o.favicon,t)),o.links&&(o.links=o.links.map(r=>({...r,href:x(r.href,t)}))),o}var s=require("react/jsx-runtime"),Y={push:()=>{},replace:()=>{},refresh:()=>{}},p=typeof i.default.createContext=="function"?i.default.createContext(null):null,U="__WEBFRAMEZ_ROUTER__",Z="[data-webframez-head='true']";function q(){return typeof window>"u"?null:window[U]??null}function j(e){typeof window>"u"||(window[U]=e)}function S(){let e={},n=typeof document>"u"?"":document.cookie;if(!n||n.trim()==="")return e;for(let t of n.split(";")){let o=t.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 k(e,n,t={}){let o=[`${e}=${encodeURIComponent(n)}`];return t.path&&o.push(`Path=${t.path}`),t.domain&&o.push(`Domain=${t.domain}`),typeof t.maxAge=="number"&&o.push(`Max-Age=${Math.floor(t.maxAge)}`),t.expires&&o.push(`Expires=${t.expires.toUTCString()}`),t.sameSite&&o.push(`SameSite=${t.sameSite}`),t.secure&&o.push("Secure"),o.join("; ")}function X(){return i.default.useMemo(()=>({all:()=>S(),get:e=>S()[e],set:(e,n,t)=>{typeof document>"u"||(document.cookie=k(e,n,t))},remove:(e,n)=>{typeof document>"u"||(document.cookie=k(e,"",{...n??{},maxAge:0}))}}),[])}function K(){let e=p?i.default.useContext(p):null;if(!e){let n=q();if(n)return n;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 I(e){let n=document.createElement("meta");n.setAttribute("data-webframez-head","true");let t=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of t)n.setAttribute(o,String(r));document.head.appendChild(n)}function b(e){let n=document.createElement("link");n.setAttribute("data-webframez-head","true");let t=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of t)n.setAttribute(o,String(r));document.head.appendChild(n)}function P(e){if(typeof document>"u")return;let n=E(e)??e;document.title=n.title||"Webframez React";for(let t of document.head.querySelectorAll(Z))t.remove();n.description&&I({name:"description",content:n.description}),n.favicon&&b({rel:"icon",href:n.favicon});for(let t of n.meta??[])I(t);for(let t of n.links??[])b(t)}function J(e){let n=new TextEncoder;return new ReadableStream({start(t){t.enqueue(n.encode(e)),t.close()}})}function Q(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,u.createFromReadableStream)(J(e)))}function ee(e){return Q()??(0,u.createFromFetch)(fetch(`${e}?path=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}`,{headers:{Accept:"text/x-component"}}))}function te(e,n){return function(){let o=i.default.use(e),[r,d]=(0,i.useState)(o.model),[c,h]=(0,i.useState)(o.head),[O,w]=(0,i.useState)(!1),[T,$]=(0,i.useState)(!1);async function l(a,A="push"){w(!0);try{let m=await(0,u.createFromFetch)(fetch(`${n}?path=${encodeURIComponent(a.pathname)}&search=${encodeURIComponent(a.search)}`,{headers:{Accept:"text/x-component"}}));P(m.head),h(m.head),d(m.model);let _=`${a.pathname}${a.search}`;A==="replace"?history.replaceState(null,"",_):A==="push"&&history.pushState(null,"",_)}catch(y){console.error("[webframez-react] Failed to render route",y),d((0,s.jsx)("p",{children:"Failed to load route."}))}finally{w(!1)}}(0,i.useEffect)(()=>{P(c)},[c]),(0,i.useEffect)(()=>{$(!0);let a=()=>{l(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),()=>{window.removeEventListener("popstate",a)}},[]);let R=i.default.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(R);let C=(0,s.jsxs)(s.Fragment,{children:[T?(0,s.jsx)(V,{active:O}):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 n=e.rootId??"root",t=document.getElementById(n);if(!t)throw new Error(`Missing #${n} 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)(t,(0,s.jsx)(c,{}))}
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,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import c,{useEffect as x,useState as l}from"react";import{hydrateRoot as H}from"react-dom/client";import{createFromFetch as P,createFromReadableStream as N}from"react-server-dom-webpack/client";var $=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function m(t){let n=t?.trim();if(n)return n==="/"?"/":n.replace(/\/+$/,"")}function _(t,n){let e=t.trim(),o=m(n);return!e||!o||$.test(e)||o!=="/"&&(e===o||e.startsWith(`${o}/`))?e:o==="/"?e.startsWith("/")?e:`/${e}`:e.startsWith("/")?`${o}${e}`:`${o}/${e}`}function v(t,n){if(!t)return;let e=m(t.assetsBaseUrl)??m(n),o={...t,...e?{assetsBaseUrl:e}:{}};return o.favicon&&(o.favicon=_(o.favicon,e)),o.links&&(o.links=o.links.map(r=>({...r,href:_(r.href,e)}))),o}import{Fragment as q,jsx as d,jsxs as j}from"react/jsx-runtime";var z={push:()=>{},replace:()=>{},refresh:()=>{}},f=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={},n=typeof document>"u"?"":document.cookie;if(!n||n.trim()==="")return t;for(let e of n.split(";")){let o=e.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&&(t[a]=decodeURIComponent(s))}return t}function S(t,n,e={}){let o=[`${t}=${encodeURIComponent(n)}`];return e.path&&o.push(`Path=${e.path}`),e.domain&&o.push(`Domain=${e.domain}`),typeof e.maxAge=="number"&&o.push(`Max-Age=${Math.floor(e.maxAge)}`),e.expires&&o.push(`Expires=${e.expires.toUTCString()}`),e.sameSite&&o.push(`SameSite=${e.sameSite}`),e.secure&&o.push("Secure"),o.join("; ")}function ee(){return c.useMemo(()=>({all:()=>E(),get:t=>E()[t],set:(t,n,e)=>{typeof document>"u"||(document.cookie=S(t,n,e))},remove:(t,n)=>{typeof document>"u"||(document.cookie=S(t,"",{...n??{},maxAge:0}))}}),[])}function te(){let t=f?c.useContext(f):null;if(!t){let n=M();if(n)return n;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 k(t){let n=document.createElement("meta");n.setAttribute("data-webframez-head","true");let e=Object.entries(t).filter(([,o])=>!!o);for(let[o,r]of e)n.setAttribute(o,String(r));document.head.appendChild(n)}function I(t){let n=document.createElement("link");n.setAttribute("data-webframez-head","true");let e=Object.entries(t).filter(([,o])=>!!o);for(let[o,r]of e)n.setAttribute(o,String(r));document.head.appendChild(n)}function b(t){if(typeof document>"u")return;let n=v(t)??t;document.title=n.title||"Webframez React";for(let e of document.head.querySelectorAll(B))e.remove();n.description&&k({name:"description",content:n.description}),n.favicon&&I({rel:"icon",href:n.favicon});for(let e of n.meta??[])k(e);for(let e of n.links??[])I(e)}function F(t){let n=new TextEncoder;return new ReadableStream({start(e){e.enqueue(n.encode(t)),e.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,N(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,n){return function(){let o=c.use(t),[r,a]=l(o.model),[s,g]=l(o.head),[U,h]=l(!1),[O,T]=l(!1);async function u(i,C="push"){h(!0);try{let p=await P(fetch(`${n}?path=${encodeURIComponent(i.pathname)}&search=${encodeURIComponent(i.search)}`,{headers:{Accept:"text/x-component"}}));b(p.head),g(p.head),a(p.model);let y=`${i.pathname}${i.search}`;C==="replace"?history.replaceState(null,"",y):C==="push"&&history.pushState(null,"",y)}catch(A){console.error("[webframez-react] Failed to render route",A),a(d("p",{children:"Failed to load route."}))}finally{h(!1)}}x(()=>{b(s)},[s]),x(()=>{T(!0);let i=()=>{u(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let w=c.useMemo(()=>({push:i=>{u(new URL(i,window.location.origin),"push")},replace:i=>{u(new URL(i,window.location.origin),"replace")},refresh:()=>{u(new URL(window.location.href),"none")}}),[]);W(w);let R=j(q,{children:[O?d(D,{active:U}):null,r??d("p",{style:{padding:24},children:"Loading..."})]});return f?d(f.Provider,{value:w,children:R}):R}}function ne(t={}){let n=t.rootId??"root",e=document.getElementById(n);if(!e)throw new Error(`Missing #${n} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=t.rscEndpoint??o??"/rsc",a=Y(r),s=Z(a,r);return H(e,d(s,{}))}export{ne as mountWebframezClient,ee as useCookie,te as useRouter};
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};
package/dist/http.cjs CHANGED
@@ -152,7 +152,7 @@ var import_node_path2 = __toESM(require("node:path"), 1);
152
152
 
153
153
  // src/head.ts
154
154
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
155
- function normalizeAssetsBaseUrl(value) {
155
+ function normalizeHeadBasename(value) {
156
156
  const trimmed = value?.trim();
157
157
  if (!trimmed) {
158
158
  return void 0;
@@ -162,45 +162,45 @@ function normalizeAssetsBaseUrl(value) {
162
162
  }
163
163
  return trimmed.replace(/\/+$/, "");
164
164
  }
165
- function resolveHeadAssetUrl(assetUrl, assetsBaseUrl) {
165
+ function resolveHeadAssetUrl(assetUrl, basename) {
166
166
  const normalizedAssetUrl = assetUrl.trim();
167
- const normalizedAssetsBaseUrl = normalizeAssetsBaseUrl(assetsBaseUrl);
168
- if (!normalizedAssetUrl || !normalizedAssetsBaseUrl) {
167
+ const normalizedBasename = normalizeHeadBasename(basename);
168
+ if (!normalizedAssetUrl || !normalizedBasename) {
169
169
  return normalizedAssetUrl;
170
170
  }
171
171
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
172
172
  return normalizedAssetUrl;
173
173
  }
174
- if (normalizedAssetsBaseUrl !== "/" && (normalizedAssetUrl === normalizedAssetsBaseUrl || normalizedAssetUrl.startsWith(`${normalizedAssetsBaseUrl}/`))) {
174
+ if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
175
175
  return normalizedAssetUrl;
176
176
  }
177
- if (normalizedAssetsBaseUrl === "/") {
177
+ if (normalizedBasename === "/") {
178
178
  return normalizedAssetUrl.startsWith("/") ? normalizedAssetUrl : `/${normalizedAssetUrl}`;
179
179
  }
180
180
  if (normalizedAssetUrl.startsWith("/")) {
181
- return `${normalizedAssetsBaseUrl}${normalizedAssetUrl}`;
181
+ return `${normalizedBasename}${normalizedAssetUrl}`;
182
182
  }
183
- return `${normalizedAssetsBaseUrl}/${normalizedAssetUrl}`;
183
+ return `${normalizedBasename}/${normalizedAssetUrl}`;
184
184
  }
185
- function normalizeHeadConfig(head, inheritedAssetsBaseUrl) {
185
+ function normalizeHeadConfig(head, inheritedBasename) {
186
186
  if (!head) {
187
187
  return void 0;
188
188
  }
189
- const effectiveAssetsBaseUrl = normalizeAssetsBaseUrl(head.assetsBaseUrl) ?? normalizeAssetsBaseUrl(inheritedAssetsBaseUrl);
189
+ const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
190
190
  const normalizedHead = {
191
191
  ...head,
192
- ...effectiveAssetsBaseUrl ? { assetsBaseUrl: effectiveAssetsBaseUrl } : {}
192
+ ...effectiveBasename ? { basename: effectiveBasename } : {}
193
193
  };
194
194
  if (normalizedHead.favicon) {
195
195
  normalizedHead.favicon = resolveHeadAssetUrl(
196
196
  normalizedHead.favicon,
197
- effectiveAssetsBaseUrl
197
+ effectiveBasename
198
198
  );
199
199
  }
200
200
  if (normalizedHead.links) {
201
201
  normalizedHead.links = normalizedHead.links.map((link) => ({
202
202
  ...link,
203
- href: resolveHeadAssetUrl(link.href, effectiveAssetsBaseUrl)
203
+ href: resolveHeadAssetUrl(link.href, effectiveBasename)
204
204
  }));
205
205
  }
206
206
  return normalizedHead;
@@ -422,7 +422,7 @@ function mergeHead(...configs) {
422
422
  links: []
423
423
  };
424
424
  for (const candidate of configs) {
425
- const config = normalizeHeadConfig(candidate, merged.assetsBaseUrl);
425
+ const config = normalizeHeadConfig(candidate, merged.basename);
426
426
  if (!config) {
427
427
  continue;
428
428
  }
@@ -432,8 +432,8 @@ function mergeHead(...configs) {
432
432
  if (config.description) {
433
433
  merged.description = config.description;
434
434
  }
435
- if (config.assetsBaseUrl) {
436
- merged.assetsBaseUrl = config.assetsBaseUrl;
435
+ if (config.basename) {
436
+ merged.basename = config.basename;
437
437
  }
438
438
  if (config.favicon) {
439
439
  merged.favicon = config.favicon;
@@ -680,6 +680,12 @@ function createFileRouter(options) {
680
680
  params: {},
681
681
  searchParams: input.searchParams,
682
682
  cookies: input.cookies ?? {},
683
+ request: input.request ?? {
684
+ host: null,
685
+ pathname,
686
+ originalPathname: pathname,
687
+ headers: {}
688
+ },
683
689
  abort: (options2) => {
684
690
  throw createAbort(options2);
685
691
  }
@@ -907,6 +913,60 @@ function normalizeBasePath(basePath) {
907
913
  const withLeadingSlash = basePath.startsWith("/") ? basePath : `/${basePath}`;
908
914
  return withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
909
915
  }
916
+ function normalizeRequestHostValue(value) {
917
+ const trimmed = value.trim();
918
+ if (!trimmed) {
919
+ return null;
920
+ }
921
+ const firstValue = trimmed.split(",")[0]?.trim() || "";
922
+ if (!firstValue) {
923
+ return null;
924
+ }
925
+ if (firstValue.startsWith("[")) {
926
+ const closingIndex = firstValue.indexOf("]");
927
+ if (closingIndex > 0) {
928
+ return firstValue.slice(1, closingIndex).toLowerCase();
929
+ }
930
+ }
931
+ return firstValue.replace(/:\d+$/, "").toLowerCase();
932
+ }
933
+ function getRequestHost(req) {
934
+ const candidates = [
935
+ req.headers["x-forwarded-host"],
936
+ req.headers["x-original-host"],
937
+ req.headers.host
938
+ ];
939
+ for (const candidate of candidates) {
940
+ if (Array.isArray(candidate)) {
941
+ for (const singleValue of candidate) {
942
+ if (typeof singleValue !== "string") {
943
+ continue;
944
+ }
945
+ const normalized2 = normalizeRequestHostValue(singleValue);
946
+ if (normalized2) {
947
+ return normalized2;
948
+ }
949
+ }
950
+ continue;
951
+ }
952
+ if (typeof candidate !== "string") {
953
+ continue;
954
+ }
955
+ const normalized = normalizeRequestHostValue(candidate);
956
+ if (normalized) {
957
+ return normalized;
958
+ }
959
+ }
960
+ return null;
961
+ }
962
+ function createRouteRequestContext(req, pathname, originalPathname) {
963
+ return {
964
+ host: getRequestHost(req),
965
+ pathname,
966
+ originalPathname,
967
+ headers: req.headers
968
+ };
969
+ }
910
970
  function stripBasePath(pathname, basePath) {
911
971
  if (!basePath) {
912
972
  return pathname;
@@ -1252,13 +1312,19 @@ function createNodeRequestHandler(options) {
1252
1312
  }
1253
1313
  if (url.pathname === rscPath) {
1254
1314
  const pathname = stripBasePath(url.searchParams.get("path") || "/", basePath);
1315
+ const requestContext = createRouteRequestContext(
1316
+ req,
1317
+ pathname,
1318
+ url.searchParams.get("path") || "/"
1319
+ );
1255
1320
  const search = new URLSearchParams(url.searchParams.get("search") || "");
1256
1321
  const resolved2 = await withRequestBasename(
1257
1322
  basePath,
1258
1323
  () => router.resolve({
1259
1324
  pathname,
1260
1325
  searchParams: parseSearchParams(search),
1261
- cookies: requestCookies
1326
+ cookies: requestCookies,
1327
+ request: requestContext
1262
1328
  })
1263
1329
  );
1264
1330
  const payload = {
@@ -1298,7 +1364,12 @@ function createNodeRequestHandler(options) {
1298
1364
  () => router.resolve({
1299
1365
  pathname: stripBasePath(url.pathname, basePath),
1300
1366
  searchParams: parseSearchParams(url.searchParams),
1301
- cookies: requestCookies
1367
+ cookies: requestCookies,
1368
+ request: createRouteRequestContext(
1369
+ req,
1370
+ stripBasePath(url.pathname, basePath),
1371
+ url.pathname
1372
+ )
1302
1373
  })
1303
1374
  );
1304
1375
  const initialPayload = {
@@ -1342,7 +1413,7 @@ function createNodeRequestHandler(options) {
1342
1413
  rscEndpoint: rscPath,
1343
1414
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1344
1415
  initialFlightData,
1345
- basename: basePath,
1416
+ basename: resolved?.head?.basename ?? basePath,
1346
1417
  liveReloadPath: liveReloadPath || void 0,
1347
1418
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1348
1419
  })
@@ -1361,7 +1432,7 @@ function createNodeRequestHandler(options) {
1361
1432
  rscEndpoint: rscPath,
1362
1433
  rootHtml,
1363
1434
  initialFlightData,
1364
- basename: basePath,
1435
+ basename: resolved.head.basename ?? basePath,
1365
1436
  liveReloadPath: liveReloadPath || void 0,
1366
1437
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1367
1438
  })
package/dist/http.js CHANGED
@@ -127,7 +127,7 @@ import path2 from "node:path";
127
127
 
128
128
  // src/head.ts
129
129
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
130
- function normalizeAssetsBaseUrl(value) {
130
+ function normalizeHeadBasename(value) {
131
131
  const trimmed = value?.trim();
132
132
  if (!trimmed) {
133
133
  return void 0;
@@ -137,45 +137,45 @@ function normalizeAssetsBaseUrl(value) {
137
137
  }
138
138
  return trimmed.replace(/\/+$/, "");
139
139
  }
140
- function resolveHeadAssetUrl(assetUrl, assetsBaseUrl) {
140
+ function resolveHeadAssetUrl(assetUrl, basename) {
141
141
  const normalizedAssetUrl = assetUrl.trim();
142
- const normalizedAssetsBaseUrl = normalizeAssetsBaseUrl(assetsBaseUrl);
143
- if (!normalizedAssetUrl || !normalizedAssetsBaseUrl) {
142
+ const normalizedBasename = normalizeHeadBasename(basename);
143
+ if (!normalizedAssetUrl || !normalizedBasename) {
144
144
  return normalizedAssetUrl;
145
145
  }
146
146
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
147
147
  return normalizedAssetUrl;
148
148
  }
149
- if (normalizedAssetsBaseUrl !== "/" && (normalizedAssetUrl === normalizedAssetsBaseUrl || normalizedAssetUrl.startsWith(`${normalizedAssetsBaseUrl}/`))) {
149
+ if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
150
150
  return normalizedAssetUrl;
151
151
  }
152
- if (normalizedAssetsBaseUrl === "/") {
152
+ if (normalizedBasename === "/") {
153
153
  return normalizedAssetUrl.startsWith("/") ? normalizedAssetUrl : `/${normalizedAssetUrl}`;
154
154
  }
155
155
  if (normalizedAssetUrl.startsWith("/")) {
156
- return `${normalizedAssetsBaseUrl}${normalizedAssetUrl}`;
156
+ return `${normalizedBasename}${normalizedAssetUrl}`;
157
157
  }
158
- return `${normalizedAssetsBaseUrl}/${normalizedAssetUrl}`;
158
+ return `${normalizedBasename}/${normalizedAssetUrl}`;
159
159
  }
160
- function normalizeHeadConfig(head, inheritedAssetsBaseUrl) {
160
+ function normalizeHeadConfig(head, inheritedBasename) {
161
161
  if (!head) {
162
162
  return void 0;
163
163
  }
164
- const effectiveAssetsBaseUrl = normalizeAssetsBaseUrl(head.assetsBaseUrl) ?? normalizeAssetsBaseUrl(inheritedAssetsBaseUrl);
164
+ const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
165
165
  const normalizedHead = {
166
166
  ...head,
167
- ...effectiveAssetsBaseUrl ? { assetsBaseUrl: effectiveAssetsBaseUrl } : {}
167
+ ...effectiveBasename ? { basename: effectiveBasename } : {}
168
168
  };
169
169
  if (normalizedHead.favicon) {
170
170
  normalizedHead.favicon = resolveHeadAssetUrl(
171
171
  normalizedHead.favicon,
172
- effectiveAssetsBaseUrl
172
+ effectiveBasename
173
173
  );
174
174
  }
175
175
  if (normalizedHead.links) {
176
176
  normalizedHead.links = normalizedHead.links.map((link) => ({
177
177
  ...link,
178
- href: resolveHeadAssetUrl(link.href, effectiveAssetsBaseUrl)
178
+ href: resolveHeadAssetUrl(link.href, effectiveBasename)
179
179
  }));
180
180
  }
181
181
  return normalizedHead;
@@ -397,7 +397,7 @@ function mergeHead(...configs) {
397
397
  links: []
398
398
  };
399
399
  for (const candidate of configs) {
400
- const config = normalizeHeadConfig(candidate, merged.assetsBaseUrl);
400
+ const config = normalizeHeadConfig(candidate, merged.basename);
401
401
  if (!config) {
402
402
  continue;
403
403
  }
@@ -407,8 +407,8 @@ function mergeHead(...configs) {
407
407
  if (config.description) {
408
408
  merged.description = config.description;
409
409
  }
410
- if (config.assetsBaseUrl) {
411
- merged.assetsBaseUrl = config.assetsBaseUrl;
410
+ if (config.basename) {
411
+ merged.basename = config.basename;
412
412
  }
413
413
  if (config.favicon) {
414
414
  merged.favicon = config.favicon;
@@ -655,6 +655,12 @@ function createFileRouter(options) {
655
655
  params: {},
656
656
  searchParams: input.searchParams,
657
657
  cookies: input.cookies ?? {},
658
+ request: input.request ?? {
659
+ host: null,
660
+ pathname,
661
+ originalPathname: pathname,
662
+ headers: {}
663
+ },
658
664
  abort: (options2) => {
659
665
  throw createAbort(options2);
660
666
  }
@@ -882,6 +888,60 @@ function normalizeBasePath(basePath) {
882
888
  const withLeadingSlash = basePath.startsWith("/") ? basePath : `/${basePath}`;
883
889
  return withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
884
890
  }
891
+ function normalizeRequestHostValue(value) {
892
+ const trimmed = value.trim();
893
+ if (!trimmed) {
894
+ return null;
895
+ }
896
+ const firstValue = trimmed.split(",")[0]?.trim() || "";
897
+ if (!firstValue) {
898
+ return null;
899
+ }
900
+ if (firstValue.startsWith("[")) {
901
+ const closingIndex = firstValue.indexOf("]");
902
+ if (closingIndex > 0) {
903
+ return firstValue.slice(1, closingIndex).toLowerCase();
904
+ }
905
+ }
906
+ return firstValue.replace(/:\d+$/, "").toLowerCase();
907
+ }
908
+ function getRequestHost(req) {
909
+ const candidates = [
910
+ req.headers["x-forwarded-host"],
911
+ req.headers["x-original-host"],
912
+ req.headers.host
913
+ ];
914
+ for (const candidate of candidates) {
915
+ if (Array.isArray(candidate)) {
916
+ for (const singleValue of candidate) {
917
+ if (typeof singleValue !== "string") {
918
+ continue;
919
+ }
920
+ const normalized2 = normalizeRequestHostValue(singleValue);
921
+ if (normalized2) {
922
+ return normalized2;
923
+ }
924
+ }
925
+ continue;
926
+ }
927
+ if (typeof candidate !== "string") {
928
+ continue;
929
+ }
930
+ const normalized = normalizeRequestHostValue(candidate);
931
+ if (normalized) {
932
+ return normalized;
933
+ }
934
+ }
935
+ return null;
936
+ }
937
+ function createRouteRequestContext(req, pathname, originalPathname) {
938
+ return {
939
+ host: getRequestHost(req),
940
+ pathname,
941
+ originalPathname,
942
+ headers: req.headers
943
+ };
944
+ }
885
945
  function stripBasePath(pathname, basePath) {
886
946
  if (!basePath) {
887
947
  return pathname;
@@ -1227,13 +1287,19 @@ function createNodeRequestHandler(options) {
1227
1287
  }
1228
1288
  if (url.pathname === rscPath) {
1229
1289
  const pathname = stripBasePath(url.searchParams.get("path") || "/", basePath);
1290
+ const requestContext = createRouteRequestContext(
1291
+ req,
1292
+ pathname,
1293
+ url.searchParams.get("path") || "/"
1294
+ );
1230
1295
  const search = new URLSearchParams(url.searchParams.get("search") || "");
1231
1296
  const resolved2 = await withRequestBasename(
1232
1297
  basePath,
1233
1298
  () => router.resolve({
1234
1299
  pathname,
1235
1300
  searchParams: parseSearchParams(search),
1236
- cookies: requestCookies
1301
+ cookies: requestCookies,
1302
+ request: requestContext
1237
1303
  })
1238
1304
  );
1239
1305
  const payload = {
@@ -1273,7 +1339,12 @@ function createNodeRequestHandler(options) {
1273
1339
  () => router.resolve({
1274
1340
  pathname: stripBasePath(url.pathname, basePath),
1275
1341
  searchParams: parseSearchParams(url.searchParams),
1276
- cookies: requestCookies
1342
+ cookies: requestCookies,
1343
+ request: createRouteRequestContext(
1344
+ req,
1345
+ stripBasePath(url.pathname, basePath),
1346
+ url.pathname
1347
+ )
1277
1348
  })
1278
1349
  );
1279
1350
  const initialPayload = {
@@ -1317,7 +1388,7 @@ function createNodeRequestHandler(options) {
1317
1388
  rscEndpoint: rscPath,
1318
1389
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1319
1390
  initialFlightData,
1320
- basename: basePath,
1391
+ basename: resolved?.head?.basename ?? basePath,
1321
1392
  liveReloadPath: liveReloadPath || void 0,
1322
1393
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1323
1394
  })
@@ -1336,7 +1407,7 @@ function createNodeRequestHandler(options) {
1336
1407
  rscEndpoint: rscPath,
1337
1408
  rootHtml,
1338
1409
  initialFlightData,
1339
- basename: basePath,
1410
+ basename: resolved.head.basename ?? basePath,
1340
1411
  liveReloadPath: liveReloadPath || void 0,
1341
1412
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1342
1413
  })