@webtypen/webframez-react 0.0.30 → 0.0.32
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 +1 -1
- package/dist/client.js +1 -1
- package/dist/http.cjs +58 -13
- package/dist/http.js +58 -13
- package/dist/index.cjs +58 -13
- package/dist/index.js +58 -13
- package/dist/router.cjs +22 -6
- package/dist/router.js +22 -6
- package/dist/types.d.ts +3 -0
- package/dist/webframez-core.cjs +58 -13
- package/dist/webframez-core.js +58 -13
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
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
|
|
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
|
-
|
|
157
|
-
if (!trimmed) {
|
|
158
|
+
if (typeof value !== "string") {
|
|
158
159
|
return void 0;
|
|
159
160
|
}
|
|
160
|
-
|
|
161
|
-
|
|
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(
|
|
@@ -426,15 +437,22 @@ function mergeHead(...configs) {
|
|
|
426
437
|
if (!config) {
|
|
427
438
|
continue;
|
|
428
439
|
}
|
|
440
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
429
441
|
if (config.title) {
|
|
430
442
|
merged.title = config.title;
|
|
431
443
|
}
|
|
432
444
|
if (config.description) {
|
|
433
445
|
merged.description = config.description;
|
|
434
446
|
}
|
|
435
|
-
if (
|
|
447
|
+
if (hasOwn("basename")) {
|
|
436
448
|
merged.basename = config.basename;
|
|
437
449
|
}
|
|
450
|
+
if (hasOwn("routeBasePath")) {
|
|
451
|
+
merged.routeBasePath = config.routeBasePath;
|
|
452
|
+
}
|
|
453
|
+
if (hasOwn("transportBasePath")) {
|
|
454
|
+
merged.transportBasePath = config.transportBasePath;
|
|
455
|
+
}
|
|
438
456
|
if (config.favicon) {
|
|
439
457
|
merged.favicon = config.favicon;
|
|
440
458
|
}
|
|
@@ -874,7 +892,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
874
892
|
|
|
875
893
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
876
894
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
877
|
-
Readable.from([flightData]),
|
|
895
|
+
Readable.from([Buffer.from(flightData)]),
|
|
878
896
|
serverConsumerManifest
|
|
879
897
|
);
|
|
880
898
|
}
|
|
@@ -999,6 +1017,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
999
1017
|
}
|
|
1000
1018
|
return pathname;
|
|
1001
1019
|
}
|
|
1020
|
+
function normalizeRuntimeBasePath(value) {
|
|
1021
|
+
if (typeof value !== "string") {
|
|
1022
|
+
return void 0;
|
|
1023
|
+
}
|
|
1024
|
+
const trimmed = value.trim();
|
|
1025
|
+
if (!trimmed || trimmed === "/") {
|
|
1026
|
+
return "";
|
|
1027
|
+
}
|
|
1028
|
+
return trimmed.replace(/\/+$/, "");
|
|
1029
|
+
}
|
|
1030
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1031
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1032
|
+
if (!basePath) {
|
|
1033
|
+
return normalizedPath;
|
|
1034
|
+
}
|
|
1035
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1036
|
+
}
|
|
1002
1037
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
1003
1038
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
1004
1039
|
return "";
|
|
@@ -1399,6 +1434,14 @@ function createNodeRequestHandler(options) {
|
|
|
1399
1434
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1400
1435
|
moduleMap
|
|
1401
1436
|
});
|
|
1437
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1438
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1439
|
+
transportBasePath,
|
|
1440
|
+
"/assets/client.js"
|
|
1441
|
+
);
|
|
1442
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1443
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1444
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1402
1445
|
let rootHtml = "";
|
|
1403
1446
|
try {
|
|
1404
1447
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1429,11 +1472,12 @@ function createNodeRequestHandler(options) {
|
|
|
1429
1472
|
createHTMLShell({
|
|
1430
1473
|
title: "500 - Initial HTML render failed",
|
|
1431
1474
|
headTags: "",
|
|
1432
|
-
clientScriptUrl,
|
|
1433
|
-
rscEndpoint:
|
|
1475
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1476
|
+
rscEndpoint: shellRscEndpoint,
|
|
1434
1477
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1435
1478
|
initialFlightData,
|
|
1436
|
-
basename:
|
|
1479
|
+
basename: shellBasename,
|
|
1480
|
+
routeBasePath: shellRouteBasePath,
|
|
1437
1481
|
liveReloadPath: liveReloadPath || void 0,
|
|
1438
1482
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1439
1483
|
})
|
|
@@ -1448,11 +1492,12 @@ function createNodeRequestHandler(options) {
|
|
|
1448
1492
|
createHTMLShell({
|
|
1449
1493
|
title: resolved.head.title || "Webframez React",
|
|
1450
1494
|
headTags: renderHeadToString(resolved.head),
|
|
1451
|
-
clientScriptUrl,
|
|
1452
|
-
rscEndpoint:
|
|
1495
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1496
|
+
rscEndpoint: shellRscEndpoint,
|
|
1453
1497
|
rootHtml,
|
|
1454
1498
|
initialFlightData,
|
|
1455
|
-
basename:
|
|
1499
|
+
basename: shellBasename,
|
|
1500
|
+
routeBasePath: shellRouteBasePath,
|
|
1456
1501
|
liveReloadPath: liveReloadPath || void 0,
|
|
1457
1502
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1458
1503
|
})
|
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
|
-
|
|
132
|
-
if (!trimmed) {
|
|
133
|
+
if (typeof value !== "string") {
|
|
133
134
|
return void 0;
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
-
|
|
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(
|
|
@@ -401,15 +412,22 @@ function mergeHead(...configs) {
|
|
|
401
412
|
if (!config) {
|
|
402
413
|
continue;
|
|
403
414
|
}
|
|
415
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
404
416
|
if (config.title) {
|
|
405
417
|
merged.title = config.title;
|
|
406
418
|
}
|
|
407
419
|
if (config.description) {
|
|
408
420
|
merged.description = config.description;
|
|
409
421
|
}
|
|
410
|
-
if (
|
|
422
|
+
if (hasOwn("basename")) {
|
|
411
423
|
merged.basename = config.basename;
|
|
412
424
|
}
|
|
425
|
+
if (hasOwn("routeBasePath")) {
|
|
426
|
+
merged.routeBasePath = config.routeBasePath;
|
|
427
|
+
}
|
|
428
|
+
if (hasOwn("transportBasePath")) {
|
|
429
|
+
merged.transportBasePath = config.transportBasePath;
|
|
430
|
+
}
|
|
413
431
|
if (config.favicon) {
|
|
414
432
|
merged.favicon = config.favicon;
|
|
415
433
|
}
|
|
@@ -849,7 +867,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
849
867
|
|
|
850
868
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
851
869
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
852
|
-
Readable.from([flightData]),
|
|
870
|
+
Readable.from([Buffer.from(flightData)]),
|
|
853
871
|
serverConsumerManifest
|
|
854
872
|
);
|
|
855
873
|
}
|
|
@@ -974,6 +992,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
974
992
|
}
|
|
975
993
|
return pathname;
|
|
976
994
|
}
|
|
995
|
+
function normalizeRuntimeBasePath(value) {
|
|
996
|
+
if (typeof value !== "string") {
|
|
997
|
+
return void 0;
|
|
998
|
+
}
|
|
999
|
+
const trimmed = value.trim();
|
|
1000
|
+
if (!trimmed || trimmed === "/") {
|
|
1001
|
+
return "";
|
|
1002
|
+
}
|
|
1003
|
+
return trimmed.replace(/\/+$/, "");
|
|
1004
|
+
}
|
|
1005
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1006
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1007
|
+
if (!basePath) {
|
|
1008
|
+
return normalizedPath;
|
|
1009
|
+
}
|
|
1010
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1011
|
+
}
|
|
977
1012
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
978
1013
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
979
1014
|
return "";
|
|
@@ -1374,6 +1409,14 @@ function createNodeRequestHandler(options) {
|
|
|
1374
1409
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1375
1410
|
moduleMap
|
|
1376
1411
|
});
|
|
1412
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1413
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1414
|
+
transportBasePath,
|
|
1415
|
+
"/assets/client.js"
|
|
1416
|
+
);
|
|
1417
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1418
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1419
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1377
1420
|
let rootHtml = "";
|
|
1378
1421
|
try {
|
|
1379
1422
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1404,11 +1447,12 @@ function createNodeRequestHandler(options) {
|
|
|
1404
1447
|
createHTMLShell({
|
|
1405
1448
|
title: "500 - Initial HTML render failed",
|
|
1406
1449
|
headTags: "",
|
|
1407
|
-
clientScriptUrl,
|
|
1408
|
-
rscEndpoint:
|
|
1450
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1451
|
+
rscEndpoint: shellRscEndpoint,
|
|
1409
1452
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1410
1453
|
initialFlightData,
|
|
1411
|
-
basename:
|
|
1454
|
+
basename: shellBasename,
|
|
1455
|
+
routeBasePath: shellRouteBasePath,
|
|
1412
1456
|
liveReloadPath: liveReloadPath || void 0,
|
|
1413
1457
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1414
1458
|
})
|
|
@@ -1423,11 +1467,12 @@ function createNodeRequestHandler(options) {
|
|
|
1423
1467
|
createHTMLShell({
|
|
1424
1468
|
title: resolved.head.title || "Webframez React",
|
|
1425
1469
|
headTags: renderHeadToString(resolved.head),
|
|
1426
|
-
clientScriptUrl,
|
|
1427
|
-
rscEndpoint:
|
|
1470
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1471
|
+
rscEndpoint: shellRscEndpoint,
|
|
1428
1472
|
rootHtml,
|
|
1429
1473
|
initialFlightData,
|
|
1430
|
-
basename:
|
|
1474
|
+
basename: shellBasename,
|
|
1475
|
+
routeBasePath: shellRouteBasePath,
|
|
1431
1476
|
liveReloadPath: liveReloadPath || void 0,
|
|
1432
1477
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1433
1478
|
})
|
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
|
-
|
|
190
|
-
if (!trimmed) {
|
|
191
|
+
if (typeof value !== "string") {
|
|
191
192
|
return void 0;
|
|
192
193
|
}
|
|
193
|
-
|
|
194
|
-
|
|
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(
|
|
@@ -459,15 +470,22 @@ function mergeHead(...configs) {
|
|
|
459
470
|
if (!config) {
|
|
460
471
|
continue;
|
|
461
472
|
}
|
|
473
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
462
474
|
if (config.title) {
|
|
463
475
|
merged.title = config.title;
|
|
464
476
|
}
|
|
465
477
|
if (config.description) {
|
|
466
478
|
merged.description = config.description;
|
|
467
479
|
}
|
|
468
|
-
if (
|
|
480
|
+
if (hasOwn("basename")) {
|
|
469
481
|
merged.basename = config.basename;
|
|
470
482
|
}
|
|
483
|
+
if (hasOwn("routeBasePath")) {
|
|
484
|
+
merged.routeBasePath = config.routeBasePath;
|
|
485
|
+
}
|
|
486
|
+
if (hasOwn("transportBasePath")) {
|
|
487
|
+
merged.transportBasePath = config.transportBasePath;
|
|
488
|
+
}
|
|
471
489
|
if (config.favicon) {
|
|
472
490
|
merged.favicon = config.favicon;
|
|
473
491
|
}
|
|
@@ -911,7 +929,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
911
929
|
|
|
912
930
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
913
931
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
914
|
-
Readable.from([flightData]),
|
|
932
|
+
Readable.from([Buffer.from(flightData)]),
|
|
915
933
|
serverConsumerManifest
|
|
916
934
|
);
|
|
917
935
|
}
|
|
@@ -1036,6 +1054,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
1036
1054
|
}
|
|
1037
1055
|
return pathname;
|
|
1038
1056
|
}
|
|
1057
|
+
function normalizeRuntimeBasePath(value) {
|
|
1058
|
+
if (typeof value !== "string") {
|
|
1059
|
+
return void 0;
|
|
1060
|
+
}
|
|
1061
|
+
const trimmed = value.trim();
|
|
1062
|
+
if (!trimmed || trimmed === "/") {
|
|
1063
|
+
return "";
|
|
1064
|
+
}
|
|
1065
|
+
return trimmed.replace(/\/+$/, "");
|
|
1066
|
+
}
|
|
1067
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1068
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1069
|
+
if (!basePath) {
|
|
1070
|
+
return normalizedPath;
|
|
1071
|
+
}
|
|
1072
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1073
|
+
}
|
|
1039
1074
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
1040
1075
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
1041
1076
|
return "";
|
|
@@ -1436,6 +1471,14 @@ function createNodeRequestHandler(options) {
|
|
|
1436
1471
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1437
1472
|
moduleMap
|
|
1438
1473
|
});
|
|
1474
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1475
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1476
|
+
transportBasePath,
|
|
1477
|
+
"/assets/client.js"
|
|
1478
|
+
);
|
|
1479
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1480
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1481
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1439
1482
|
let rootHtml = "";
|
|
1440
1483
|
try {
|
|
1441
1484
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1466,11 +1509,12 @@ function createNodeRequestHandler(options) {
|
|
|
1466
1509
|
createHTMLShell({
|
|
1467
1510
|
title: "500 - Initial HTML render failed",
|
|
1468
1511
|
headTags: "",
|
|
1469
|
-
clientScriptUrl,
|
|
1470
|
-
rscEndpoint:
|
|
1512
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1513
|
+
rscEndpoint: shellRscEndpoint,
|
|
1471
1514
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1472
1515
|
initialFlightData,
|
|
1473
|
-
basename:
|
|
1516
|
+
basename: shellBasename,
|
|
1517
|
+
routeBasePath: shellRouteBasePath,
|
|
1474
1518
|
liveReloadPath: liveReloadPath || void 0,
|
|
1475
1519
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1476
1520
|
})
|
|
@@ -1485,11 +1529,12 @@ function createNodeRequestHandler(options) {
|
|
|
1485
1529
|
createHTMLShell({
|
|
1486
1530
|
title: resolved.head.title || "Webframez React",
|
|
1487
1531
|
headTags: renderHeadToString(resolved.head),
|
|
1488
|
-
clientScriptUrl,
|
|
1489
|
-
rscEndpoint:
|
|
1532
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1533
|
+
rscEndpoint: shellRscEndpoint,
|
|
1490
1534
|
rootHtml,
|
|
1491
1535
|
initialFlightData,
|
|
1492
|
-
basename:
|
|
1536
|
+
basename: shellBasename,
|
|
1537
|
+
routeBasePath: shellRouteBasePath,
|
|
1493
1538
|
liveReloadPath: liveReloadPath || void 0,
|
|
1494
1539
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1495
1540
|
})
|
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
|
-
|
|
154
|
-
if (!trimmed) {
|
|
155
|
+
if (typeof value !== "string") {
|
|
155
156
|
return void 0;
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
-
|
|
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(
|
|
@@ -423,15 +434,22 @@ function mergeHead(...configs) {
|
|
|
423
434
|
if (!config) {
|
|
424
435
|
continue;
|
|
425
436
|
}
|
|
437
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
426
438
|
if (config.title) {
|
|
427
439
|
merged.title = config.title;
|
|
428
440
|
}
|
|
429
441
|
if (config.description) {
|
|
430
442
|
merged.description = config.description;
|
|
431
443
|
}
|
|
432
|
-
if (
|
|
444
|
+
if (hasOwn("basename")) {
|
|
433
445
|
merged.basename = config.basename;
|
|
434
446
|
}
|
|
447
|
+
if (hasOwn("routeBasePath")) {
|
|
448
|
+
merged.routeBasePath = config.routeBasePath;
|
|
449
|
+
}
|
|
450
|
+
if (hasOwn("transportBasePath")) {
|
|
451
|
+
merged.transportBasePath = config.transportBasePath;
|
|
452
|
+
}
|
|
435
453
|
if (config.favicon) {
|
|
436
454
|
merged.favicon = config.favicon;
|
|
437
455
|
}
|
|
@@ -875,7 +893,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
875
893
|
|
|
876
894
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
877
895
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
878
|
-
Readable.from([flightData]),
|
|
896
|
+
Readable.from([Buffer.from(flightData)]),
|
|
879
897
|
serverConsumerManifest
|
|
880
898
|
);
|
|
881
899
|
}
|
|
@@ -1000,6 +1018,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
1000
1018
|
}
|
|
1001
1019
|
return pathname;
|
|
1002
1020
|
}
|
|
1021
|
+
function normalizeRuntimeBasePath(value) {
|
|
1022
|
+
if (typeof value !== "string") {
|
|
1023
|
+
return void 0;
|
|
1024
|
+
}
|
|
1025
|
+
const trimmed = value.trim();
|
|
1026
|
+
if (!trimmed || trimmed === "/") {
|
|
1027
|
+
return "";
|
|
1028
|
+
}
|
|
1029
|
+
return trimmed.replace(/\/+$/, "");
|
|
1030
|
+
}
|
|
1031
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1032
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1033
|
+
if (!basePath) {
|
|
1034
|
+
return normalizedPath;
|
|
1035
|
+
}
|
|
1036
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1037
|
+
}
|
|
1003
1038
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
1004
1039
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
1005
1040
|
return "";
|
|
@@ -1400,6 +1435,14 @@ function createNodeRequestHandler(options) {
|
|
|
1400
1435
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1401
1436
|
moduleMap
|
|
1402
1437
|
});
|
|
1438
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1439
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1440
|
+
transportBasePath,
|
|
1441
|
+
"/assets/client.js"
|
|
1442
|
+
);
|
|
1443
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1444
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1445
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1403
1446
|
let rootHtml = "";
|
|
1404
1447
|
try {
|
|
1405
1448
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1430,11 +1473,12 @@ function createNodeRequestHandler(options) {
|
|
|
1430
1473
|
createHTMLShell({
|
|
1431
1474
|
title: "500 - Initial HTML render failed",
|
|
1432
1475
|
headTags: "",
|
|
1433
|
-
clientScriptUrl,
|
|
1434
|
-
rscEndpoint:
|
|
1476
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1477
|
+
rscEndpoint: shellRscEndpoint,
|
|
1435
1478
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1436
1479
|
initialFlightData,
|
|
1437
|
-
basename:
|
|
1480
|
+
basename: shellBasename,
|
|
1481
|
+
routeBasePath: shellRouteBasePath,
|
|
1438
1482
|
liveReloadPath: liveReloadPath || void 0,
|
|
1439
1483
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1440
1484
|
})
|
|
@@ -1449,11 +1493,12 @@ function createNodeRequestHandler(options) {
|
|
|
1449
1493
|
createHTMLShell({
|
|
1450
1494
|
title: resolved.head.title || "Webframez React",
|
|
1451
1495
|
headTags: renderHeadToString(resolved.head),
|
|
1452
|
-
clientScriptUrl,
|
|
1453
|
-
rscEndpoint:
|
|
1496
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1497
|
+
rscEndpoint: shellRscEndpoint,
|
|
1454
1498
|
rootHtml,
|
|
1455
1499
|
initialFlightData,
|
|
1456
|
-
basename:
|
|
1500
|
+
basename: shellBasename,
|
|
1501
|
+
routeBasePath: shellRouteBasePath,
|
|
1457
1502
|
liveReloadPath: liveReloadPath || void 0,
|
|
1458
1503
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1459
1504
|
})
|
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
|
-
|
|
48
|
-
if (!trimmed) {
|
|
47
|
+
if (typeof value !== "string") {
|
|
49
48
|
return void 0;
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
|
|
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(
|
|
@@ -317,15 +326,22 @@ function mergeHead(...configs) {
|
|
|
317
326
|
if (!config) {
|
|
318
327
|
continue;
|
|
319
328
|
}
|
|
329
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
320
330
|
if (config.title) {
|
|
321
331
|
merged.title = config.title;
|
|
322
332
|
}
|
|
323
333
|
if (config.description) {
|
|
324
334
|
merged.description = config.description;
|
|
325
335
|
}
|
|
326
|
-
if (
|
|
336
|
+
if (hasOwn("basename")) {
|
|
327
337
|
merged.basename = config.basename;
|
|
328
338
|
}
|
|
339
|
+
if (hasOwn("routeBasePath")) {
|
|
340
|
+
merged.routeBasePath = config.routeBasePath;
|
|
341
|
+
}
|
|
342
|
+
if (hasOwn("transportBasePath")) {
|
|
343
|
+
merged.transportBasePath = config.transportBasePath;
|
|
344
|
+
}
|
|
329
345
|
if (config.favicon) {
|
|
330
346
|
merged.favicon = config.favicon;
|
|
331
347
|
}
|
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
|
-
|
|
18
|
-
if (!trimmed) {
|
|
17
|
+
if (typeof value !== "string") {
|
|
19
18
|
return void 0;
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
|
|
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(
|
|
@@ -287,15 +296,22 @@ function mergeHead(...configs) {
|
|
|
287
296
|
if (!config) {
|
|
288
297
|
continue;
|
|
289
298
|
}
|
|
299
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
290
300
|
if (config.title) {
|
|
291
301
|
merged.title = config.title;
|
|
292
302
|
}
|
|
293
303
|
if (config.description) {
|
|
294
304
|
merged.description = config.description;
|
|
295
305
|
}
|
|
296
|
-
if (
|
|
306
|
+
if (hasOwn("basename")) {
|
|
297
307
|
merged.basename = config.basename;
|
|
298
308
|
}
|
|
309
|
+
if (hasOwn("routeBasePath")) {
|
|
310
|
+
merged.routeBasePath = config.routeBasePath;
|
|
311
|
+
}
|
|
312
|
+
if (hasOwn("transportBasePath")) {
|
|
313
|
+
merged.transportBasePath = config.transportBasePath;
|
|
314
|
+
}
|
|
299
315
|
if (config.favicon) {
|
|
300
316
|
merged.favicon = config.favicon;
|
|
301
317
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -61,6 +61,8 @@ export type HeadConfig = {
|
|
|
61
61
|
title?: string;
|
|
62
62
|
description?: string;
|
|
63
63
|
basename?: string;
|
|
64
|
+
routeBasePath?: string;
|
|
65
|
+
transportBasePath?: string;
|
|
64
66
|
favicon?: string;
|
|
65
67
|
meta?: HeadMetaTag[];
|
|
66
68
|
links?: HeadLinkTag[];
|
|
@@ -112,6 +114,7 @@ export type CreateHtmlShellOptions = {
|
|
|
112
114
|
initialFlightData?: string;
|
|
113
115
|
clientRenderMode?: "hydrate" | "mount";
|
|
114
116
|
basename?: string;
|
|
117
|
+
routeBasePath?: string;
|
|
115
118
|
liveReloadPath?: string;
|
|
116
119
|
liveReloadServerId?: string;
|
|
117
120
|
};
|
package/dist/webframez-core.cjs
CHANGED
|
@@ -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
|
-
|
|
160
|
-
if (!trimmed) {
|
|
161
|
+
if (typeof value !== "string") {
|
|
161
162
|
return void 0;
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
-
|
|
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(
|
|
@@ -429,15 +440,22 @@ function mergeHead(...configs) {
|
|
|
429
440
|
if (!config) {
|
|
430
441
|
continue;
|
|
431
442
|
}
|
|
443
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
432
444
|
if (config.title) {
|
|
433
445
|
merged.title = config.title;
|
|
434
446
|
}
|
|
435
447
|
if (config.description) {
|
|
436
448
|
merged.description = config.description;
|
|
437
449
|
}
|
|
438
|
-
if (
|
|
450
|
+
if (hasOwn("basename")) {
|
|
439
451
|
merged.basename = config.basename;
|
|
440
452
|
}
|
|
453
|
+
if (hasOwn("routeBasePath")) {
|
|
454
|
+
merged.routeBasePath = config.routeBasePath;
|
|
455
|
+
}
|
|
456
|
+
if (hasOwn("transportBasePath")) {
|
|
457
|
+
merged.transportBasePath = config.transportBasePath;
|
|
458
|
+
}
|
|
441
459
|
if (config.favicon) {
|
|
442
460
|
merged.favicon = config.favicon;
|
|
443
461
|
}
|
|
@@ -877,7 +895,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
877
895
|
|
|
878
896
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
879
897
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
880
|
-
Readable.from([flightData]),
|
|
898
|
+
Readable.from([Buffer.from(flightData)]),
|
|
881
899
|
serverConsumerManifest
|
|
882
900
|
);
|
|
883
901
|
}
|
|
@@ -1002,6 +1020,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
1002
1020
|
}
|
|
1003
1021
|
return pathname;
|
|
1004
1022
|
}
|
|
1023
|
+
function normalizeRuntimeBasePath(value) {
|
|
1024
|
+
if (typeof value !== "string") {
|
|
1025
|
+
return void 0;
|
|
1026
|
+
}
|
|
1027
|
+
const trimmed = value.trim();
|
|
1028
|
+
if (!trimmed || trimmed === "/") {
|
|
1029
|
+
return "";
|
|
1030
|
+
}
|
|
1031
|
+
return trimmed.replace(/\/+$/, "");
|
|
1032
|
+
}
|
|
1033
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1034
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1035
|
+
if (!basePath) {
|
|
1036
|
+
return normalizedPath;
|
|
1037
|
+
}
|
|
1038
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1039
|
+
}
|
|
1005
1040
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
1006
1041
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
1007
1042
|
return "";
|
|
@@ -1402,6 +1437,14 @@ function createNodeRequestHandler(options) {
|
|
|
1402
1437
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1403
1438
|
moduleMap
|
|
1404
1439
|
});
|
|
1440
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1441
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1442
|
+
transportBasePath,
|
|
1443
|
+
"/assets/client.js"
|
|
1444
|
+
);
|
|
1445
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1446
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1447
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1405
1448
|
let rootHtml = "";
|
|
1406
1449
|
try {
|
|
1407
1450
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1432,11 +1475,12 @@ function createNodeRequestHandler(options) {
|
|
|
1432
1475
|
createHTMLShell({
|
|
1433
1476
|
title: "500 - Initial HTML render failed",
|
|
1434
1477
|
headTags: "",
|
|
1435
|
-
clientScriptUrl,
|
|
1436
|
-
rscEndpoint:
|
|
1478
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1479
|
+
rscEndpoint: shellRscEndpoint,
|
|
1437
1480
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1438
1481
|
initialFlightData,
|
|
1439
|
-
basename:
|
|
1482
|
+
basename: shellBasename,
|
|
1483
|
+
routeBasePath: shellRouteBasePath,
|
|
1440
1484
|
liveReloadPath: liveReloadPath || void 0,
|
|
1441
1485
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1442
1486
|
})
|
|
@@ -1451,11 +1495,12 @@ function createNodeRequestHandler(options) {
|
|
|
1451
1495
|
createHTMLShell({
|
|
1452
1496
|
title: resolved.head.title || "Webframez React",
|
|
1453
1497
|
headTags: renderHeadToString(resolved.head),
|
|
1454
|
-
clientScriptUrl,
|
|
1455
|
-
rscEndpoint:
|
|
1498
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1499
|
+
rscEndpoint: shellRscEndpoint,
|
|
1456
1500
|
rootHtml,
|
|
1457
1501
|
initialFlightData,
|
|
1458
|
-
basename:
|
|
1502
|
+
basename: shellBasename,
|
|
1503
|
+
routeBasePath: shellRouteBasePath,
|
|
1459
1504
|
liveReloadPath: liveReloadPath || void 0,
|
|
1460
1505
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1461
1506
|
})
|
package/dist/webframez-core.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
|
-
|
|
132
|
-
if (!trimmed) {
|
|
133
|
+
if (typeof value !== "string") {
|
|
133
134
|
return void 0;
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
-
|
|
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(
|
|
@@ -401,15 +412,22 @@ function mergeHead(...configs) {
|
|
|
401
412
|
if (!config) {
|
|
402
413
|
continue;
|
|
403
414
|
}
|
|
415
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
|
|
404
416
|
if (config.title) {
|
|
405
417
|
merged.title = config.title;
|
|
406
418
|
}
|
|
407
419
|
if (config.description) {
|
|
408
420
|
merged.description = config.description;
|
|
409
421
|
}
|
|
410
|
-
if (
|
|
422
|
+
if (hasOwn("basename")) {
|
|
411
423
|
merged.basename = config.basename;
|
|
412
424
|
}
|
|
425
|
+
if (hasOwn("routeBasePath")) {
|
|
426
|
+
merged.routeBasePath = config.routeBasePath;
|
|
427
|
+
}
|
|
428
|
+
if (hasOwn("transportBasePath")) {
|
|
429
|
+
merged.transportBasePath = config.transportBasePath;
|
|
430
|
+
}
|
|
413
431
|
if (config.favicon) {
|
|
414
432
|
merged.favicon = config.favicon;
|
|
415
433
|
}
|
|
@@ -849,7 +867,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
|
|
|
849
867
|
|
|
850
868
|
if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
|
|
851
869
|
return await reactServerDomClientNode.createFromNodeStream(
|
|
852
|
-
Readable.from([flightData]),
|
|
870
|
+
Readable.from([Buffer.from(flightData)]),
|
|
853
871
|
serverConsumerManifest
|
|
854
872
|
);
|
|
855
873
|
}
|
|
@@ -974,6 +992,23 @@ function stripBasePath(pathname, basePath) {
|
|
|
974
992
|
}
|
|
975
993
|
return pathname;
|
|
976
994
|
}
|
|
995
|
+
function normalizeRuntimeBasePath(value) {
|
|
996
|
+
if (typeof value !== "string") {
|
|
997
|
+
return void 0;
|
|
998
|
+
}
|
|
999
|
+
const trimmed = value.trim();
|
|
1000
|
+
if (!trimmed || trimmed === "/") {
|
|
1001
|
+
return "";
|
|
1002
|
+
}
|
|
1003
|
+
return trimmed.replace(/\/+$/, "");
|
|
1004
|
+
}
|
|
1005
|
+
function joinRuntimeBasePath(basePath, pathname) {
|
|
1006
|
+
const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1007
|
+
if (!basePath) {
|
|
1008
|
+
return normalizedPath;
|
|
1009
|
+
}
|
|
1010
|
+
return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
|
|
1011
|
+
}
|
|
977
1012
|
function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
|
|
978
1013
|
if (!rawNodeOptions || rawNodeOptions.trim() === "") {
|
|
979
1014
|
return "";
|
|
@@ -1374,6 +1409,14 @@ function createNodeRequestHandler(options) {
|
|
|
1374
1409
|
const initialFlightData = await renderRSCToString(initialPayload, {
|
|
1375
1410
|
moduleMap
|
|
1376
1411
|
});
|
|
1412
|
+
const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1413
|
+
const shellClientScriptUrl = joinRuntimeBasePath(
|
|
1414
|
+
transportBasePath,
|
|
1415
|
+
"/assets/client.js"
|
|
1416
|
+
);
|
|
1417
|
+
const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
|
|
1418
|
+
const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
|
|
1419
|
+
const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
|
|
1377
1420
|
let rootHtml = "";
|
|
1378
1421
|
try {
|
|
1379
1422
|
rootHtml = await initialHtmlWorker.renderFromFlightData({
|
|
@@ -1404,11 +1447,12 @@ function createNodeRequestHandler(options) {
|
|
|
1404
1447
|
createHTMLShell({
|
|
1405
1448
|
title: "500 - Initial HTML render failed",
|
|
1406
1449
|
headTags: "",
|
|
1407
|
-
clientScriptUrl,
|
|
1408
|
-
rscEndpoint:
|
|
1450
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1451
|
+
rscEndpoint: shellRscEndpoint,
|
|
1409
1452
|
rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
|
|
1410
1453
|
initialFlightData,
|
|
1411
|
-
basename:
|
|
1454
|
+
basename: shellBasename,
|
|
1455
|
+
routeBasePath: shellRouteBasePath,
|
|
1412
1456
|
liveReloadPath: liveReloadPath || void 0,
|
|
1413
1457
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1414
1458
|
})
|
|
@@ -1423,11 +1467,12 @@ function createNodeRequestHandler(options) {
|
|
|
1423
1467
|
createHTMLShell({
|
|
1424
1468
|
title: resolved.head.title || "Webframez React",
|
|
1425
1469
|
headTags: renderHeadToString(resolved.head),
|
|
1426
|
-
clientScriptUrl,
|
|
1427
|
-
rscEndpoint:
|
|
1470
|
+
clientScriptUrl: shellClientScriptUrl,
|
|
1471
|
+
rscEndpoint: shellRscEndpoint,
|
|
1428
1472
|
rootHtml,
|
|
1429
1473
|
initialFlightData,
|
|
1430
|
-
basename:
|
|
1474
|
+
basename: shellBasename,
|
|
1475
|
+
routeBasePath: shellRouteBasePath,
|
|
1431
1476
|
liveReloadPath: liveReloadPath || void 0,
|
|
1432
1477
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1433
1478
|
})
|