@webtypen/webframez-react 0.0.48 → 0.0.50
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 +61 -0
- package/defaults/webpack.client.cjs +6 -2
- package/dist/client.cjs +1 -1
- package/dist/client.js +1 -1
- package/dist/http.cjs +134 -46
- package/dist/http.d.ts +5 -0
- package/dist/http.js +131 -45
- package/dist/index.cjs +207 -53
- package/dist/index.d.ts +2 -0
- package/dist/index.js +227 -53
- package/dist/navigation.cjs +80 -15
- package/dist/navigation.d.ts +1 -1
- package/dist/navigation.js +92 -15
- package/dist/paths.cjs +102 -0
- package/dist/paths.d.ts +4 -0
- package/dist/paths.js +92 -0
- package/dist/router.cjs +58 -8
- package/dist/router.d.ts +8 -2
- package/dist/router.js +58 -8
- package/dist/types.d.ts +24 -0
- package/dist/webframez-core.cjs +186 -53
- package/dist/webframez-core.d.ts +2 -8
- package/dist/webframez-core.js +206 -53
- package/package.json +18 -4
package/README.md
CHANGED
|
@@ -491,3 +491,64 @@ Watch mode for package development:
|
|
|
491
491
|
```bash
|
|
492
492
|
npm run build:watch
|
|
493
493
|
```
|
|
494
|
+
|
|
495
|
+
## Persistent navigation in consuming applications
|
|
496
|
+
|
|
497
|
+
Use the host router's Link component for URLs. Keep the Suite renderer mounted
|
|
498
|
+
across paths inside one authorized project; do not add `key={path}` or conditionally
|
|
499
|
+
unmount it while reloading project context. Revalidate/reset the context when the
|
|
500
|
+
project changes, and continue enforcing authorization on every server request.
|
|
501
|
+
Only the page content resets for a new screen. The renderer retains its layout and
|
|
502
|
+
prior page while a same-project request is pending, with stale interactions disabled.
|
|
503
|
+
|
|
504
|
+
For webframez-react, configure the DOM link adapter at the host boundary:
|
|
505
|
+
|
|
506
|
+
```tsx
|
|
507
|
+
import React from "react";
|
|
508
|
+
import { Link } from "@webtypen/webframez-react/navigation";
|
|
509
|
+
|
|
510
|
+
const SuiteLink = React.forwardRef<HTMLAnchorElement,
|
|
511
|
+
React.AnchorHTMLAttributes<HTMLAnchorElement>
|
|
512
|
+
>(function SuiteLink({ href, ...props }, ref) {
|
|
513
|
+
return <Link {...props} ref={ref} to={href || "#"} basename="" />;
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
// Inside an already authorized project context; paths are fully qualified.
|
|
517
|
+
<NativeDesignProvider
|
|
518
|
+
key={projectId}
|
|
519
|
+
suite={{ endpoint: "/manager", navigation: {
|
|
520
|
+
pathname, linkComponent: SuiteLink,
|
|
521
|
+
onNavigate: to => router.push(to),
|
|
522
|
+
} }}
|
|
523
|
+
>
|
|
524
|
+
<WebframezSuiteRenderer />
|
|
525
|
+
</NativeDesignProvider>
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Screen definitions remain JSON-serializable: links use `to`/`path`; React Link
|
|
529
|
+
components belong in the consuming application's adapter, never in server schemas.
|
|
530
|
+
See `AGENTS.md` for the navigation invariants and regression-test requirements.
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
## Core router basename
|
|
534
|
+
|
|
535
|
+
With the updated Core router, set `application.router.basename` in the Core
|
|
536
|
+
configuration. `initWebframezReact(Route).renderReact("/", options)` inherits it;
|
|
537
|
+
no duplicate `basePath`, `assetsPrefix`, `rscPath`, `clientScriptUrl`, or
|
|
538
|
+
`Head.basename` is needed. Nested render routes and `Route.group` prefixes are
|
|
539
|
+
included in the runtime mount while build target names and directories stay
|
|
540
|
+
stable. Explicit external asset URLs remain unchanged. Without Core, the Node
|
|
541
|
+
handler still supports `basePath` and explicit transport URLs.
|
|
542
|
+
|
|
543
|
+
For API calls, form actions, raw links and redirects in shared/client code:
|
|
544
|
+
|
|
545
|
+
```ts
|
|
546
|
+
import { appPath, appRelativePath, getBasename } from "@webtypen/webframez-react/paths";
|
|
547
|
+
fetch(appPath("/api/items"));
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
These browser-safe helpers bundle Core's URL logic and read the runtime mount;
|
|
551
|
+
no server dependencies are included. `Link` and `Redirect` inherit it
|
|
552
|
+
implicitly. Server requests use an async-local context, and HTML rendering and
|
|
553
|
+
client navigation receive the same basename through the Flight head and HTML
|
|
554
|
+
shell. External URLs and already-prefixed URLs are preserved.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const
|
|
3
|
+
const { createRequire } = require("node:module");
|
|
4
4
|
const { fileURLToPath, pathToFileURL } = require("url");
|
|
5
5
|
|
|
6
6
|
const projectRoot = process.cwd();
|
|
7
|
+
const projectRequire = createRequire(path.join(projectRoot, "package.json"));
|
|
8
|
+
const ReactFlightWebpackPlugin = projectRequire("react-server-dom-webpack/plugin");
|
|
9
|
+
const reactDomRequire = createRequire(projectRequire.resolve("react-dom/package.json"));
|
|
7
10
|
const frameworkDistDir = path.resolve(__dirname, "..", "dist");
|
|
8
11
|
const clientEntry = process.env.WEBFRAMEZ_REACT_CLIENT_ENTRY
|
|
9
12
|
? path.resolve(projectRoot, process.env.WEBFRAMEZ_REACT_CLIENT_ENTRY)
|
|
@@ -266,7 +269,8 @@ module.exports = {
|
|
|
266
269
|
"react-dom": path.resolve(projectRoot, "node_modules", "react-dom"),
|
|
267
270
|
"react/jsx-runtime": path.resolve(projectRoot, "node_modules", "react", "jsx-runtime.js"),
|
|
268
271
|
"react/jsx-dev-runtime": path.resolve(projectRoot, "node_modules", "react", "jsx-dev-runtime.js"),
|
|
269
|
-
|
|
272
|
+
// Resolve React DOM's own scheduler, including pnpm's isolated layout.
|
|
273
|
+
scheduler: path.dirname(reactDomRequire.resolve("scheduler/package.json")),
|
|
270
274
|
},
|
|
271
275
|
},
|
|
272
276
|
watchOptions: {
|
package/dist/client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var le=Object.create;var E=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var pe=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var ge=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},$=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of me(t))!Re.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(o=fe(t,r))||o.enumerable});return e};var D=(e,t,n)=>(n=e!=null?le(pe(e)):{},$(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),he=e=>$(E({},"__esModule",{value:!0}),e);var qe={};ge(qe,{mountWebframezClient:()=>Ge,useCookie:()=>Be,useRouter:()=>He});module.exports=he(qe);var c=D(require("react"),1),J=require("react-dom/client"),h=require("react-server-dom-webpack/client"),Q=require("@webtypen/webframez-react/route-slot");var we=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function l(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function W(e,t){let n=e.trim(),o=l(t);return!n||!o||we.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function P(e,t){if(!e)return;let n=l(e.basename)??l(t),o=l(e.routeBasePath),r=l(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=W(i.favicon,n)),i.links&&(i.links=i.links.map(s=>({...s,href:W(s.href,n)}))),i}var m=D(require("react"),1),q="webframez-route-children",K="__webframezRouteChildren",Y="WebframezRouteChildren",_e="__webframezRouteChildrenSlot",ye="WebframezRouteChildrenSlot",L=()=>m.default.createElement(q);L.displayName=Y;L[K]=!0;var Ce=L;function F(e){if(e===q||e===Ce)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[K]===!0||t.displayName===Y||t.name==="RouteChildren"}catch{return!1}}function j(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[_e]===!0||t.displayName===ye||t.name==="RouteChildrenSlot"}catch{return!1}}function G(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function T(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let u=!1,w=e.map(p=>{let R=T(p,t);return R!==p&&(u=!0),R});return u?w:e}if(G(e)&&(F(e.type)||j(e.type)))return t;let n=m.default.isValidElement(e);if(!n&&!G(e))return e;if(n&&(F(e.type)||j(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=T(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?m.default.cloneElement(e,void 0,...r):m.default.cloneElement(e,void 0,r);let i=e,s={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return m.default.createElement(i.type,s)}var d=require("react/jsx-runtime"),Ee={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},N=typeof c.default.createContext=="function"?c.default.createContext(null):null,ee="__WEBFRAMEZ_ROUTER__",Te="__WEBFRAMEZ_REACT_BUILD_ID",Ne="x-webframez-react-build",Ae="[data-webframez-head='true']";function Z(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function x(e){return l(e)??""}function Se(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function te(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function Pe(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function ne(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=Pe(),o=Se(e||"/",t);return te(n,o)}function oe(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Le(){if(typeof window>"u")return"";let e=window[Te];return typeof e=="string"?e:""}function ve(e){let t=Le();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Ie(){return typeof window>"u"?null:window[ee]??null}function xe(e){typeof window>"u"||(window[ee]=e)}function be(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function ke(e){return be(e)?c.default.use(e):e}function A(e){let t=ke(e);if(Array.isArray(t)){let r=!1,i=t.map(s=>{let u=A(s);return u!==s&&(r=!0),u});return r?i:t}if(!c.default.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=A(n.children);return o===n.children?t:Array.isArray(o)?c.default.cloneElement(t,void 0,...o):c.default.cloneElement(t,void 0,o)}function V(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),i=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(s))}return e}function X(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function Be(){return c.default.useMemo(()=>({all:()=>V(),get:e=>V()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=X(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=X(e,"",{...t??{},maxAge:0}))}}),[])}function He(){let e=N?c.default.useContext(N):null;if(!e){let t=Ie();if(t)return t;if(typeof window>"u")return Ee;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Oe({active:e}){return(0,d.jsx)("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function Ue(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function Me(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 b(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function ze(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return b(e.tagName,t)}function $e(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});return t}function I(e){if(typeof document>"u")return;let t=P(e)??e;re(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=$e(t),o=new Set(n.map(i=>b(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(Ae)){let s=ze(i);if(o.has(s)&&!r.has(s)){r.add(s);continue}i.remove()}for(let i of n){let s=b(i.tagName,i.attrs);r.has(s)||(i.tagName==="meta"?Ue(i.attrs):Me(i.attrs),r.add(s))}}function re(e){if(typeof window>"u")return;let t=P(e)??e,n=l(t.basename),o=l(t.routeBasePath),r=l(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=te(r,"/rsc"))}function De(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function We(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,h.createFromReadableStream)(De(e)))}function Fe(e){let t=oe(e),n=ne(window.location.pathname);return We()??(0,h.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function je(e,t){return function(){let o=c.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,s]=(0,c.useState)(o.model),[u,w]=(0,c.useState)(o.contextModel),[p,R]=(0,c.useState)(o.pageModel),[k,B]=(0,c.useState)(o.head),[ie,_]=(0,c.useState)(!1),[ae,se]=(0,c.useState)(!1),[ce,H]=(0,c.useState)(r);async function O(a){let C=oe(t),f=ne(a.pathname),g=await fetch(`${C}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(a.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return ve(g.headers.get(Ne))?(v(a),await new Promise(()=>{})):await(0,h.createFromFetch)(Promise.resolve(g))}async function y(a,C="push"){_(!0);try{let f=await O(a);I(f.head),B(f.head),s(f.model),w(f.contextModel),R(f.pageModel),H(!1);let g=`${a.pathname}${a.search}${a.hash}`;C==="replace"?(history.replaceState(null,"",g),Z()):C==="push"&&(history.pushState(null,"",g),Z())}catch(f){console.error("[webframez-react] Failed to render route",f),v(a),s((0,d.jsx)("p",{children:"Failed to load route."}))}finally{_(!1)}}async function de(){_(!0);try{let a=await O(new URL(window.location.href));I(a.head),B(a.head),s(a.model),w(a.contextModel),R(a.pageModel),H(!1)}catch(a){console.error("[webframez-react] Failed to refresh route context",a),v(new URL(window.location.href))}finally{_(!1)}}(0,c.useEffect)(()=>{I(k)},[k]),(0,c.useEffect)(()=>{se(!0);let a=()=>{y(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),()=>{window.removeEventListener("popstate",a)}},[]);let U=c.default.useMemo(()=>({push:a=>{y(new URL(a,window.location.origin),"push")},replace:a=>{y(new URL(a,window.location.origin),"replace")},refresh:()=>{y(new URL(window.location.href),"none")},refreshContext:()=>{de()}}),[]);xe(U);let M=A(u),S=A(p),ue=ce&&typeof p<"u"?M?(0,d.jsx)(Q.RouteChildrenSlotProvider,{page:S,children:T(M,S)}):S:i,z=(0,d.jsxs)(d.Fragment,{children:[ae?(0,d.jsx)(Oe,{active:ie}):null,ue??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return N?(0,d.jsx)(N.Provider,{value:U,children:z}):z}}function Ge(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??o??"/rsc",i=Promise.resolve(Fe(r)).then(u=>(u?.head&&re(u.head),u)),s=je(i,r);return(0,J.hydrateRoot)(n,(0,d.jsx)(s,{}))}
|
|
1
|
+
var fe=Object.create;var E=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},D=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pe(t))!Re.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(o=me(t,r))||o.enumerable});return e};var W=(e,t,n)=>(n=e!=null?fe(ge(e)):{},D(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),we=e=>D(E({},"__esModule",{value:!0}),e);var Ye={};he(Ye,{mountWebframezClient:()=>Ke,useCookie:()=>Be,useRouter:()=>Oe});module.exports=we(Ye);var c=W(require("react"),1),J=require("react-dom/client"),h=require("react-server-dom-webpack/client"),Q=require("@webtypen/webframez-react/route-slot");var _e=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function l(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function b(e,t){let n=e.trim(),o=l(t);return!n||!o||_e.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function L(e,t){if(!e)return;let n=l(e.basename)??l(t),o=l(e.routeBasePath),r=l(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=b(i.favicon,n)),i.links&&(i.links=i.links.map(a=>({...a,href:b(a.href,n)}))),i.scripts&&(i.scripts=i.scripts.map(a=>({...a,...a.src?{src:b(a.src,n)}:{}}))),i}var m=W(require("react"),1),q="webframez-route-children",K="__webframezRouteChildren",Y="WebframezRouteChildren",Ce="__webframezRouteChildrenSlot",ye="WebframezRouteChildrenSlot",x=()=>m.default.createElement(q);x.displayName=Y;x[K]=!0;var Ee=x;function F(e){if(e===q||e===Ee)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[K]===!0||t.displayName===Y||t.name==="RouteChildren"}catch{return!1}}function j(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[Ce]===!0||t.displayName===ye||t.name==="RouteChildrenSlot"}catch{return!1}}function G(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function T(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let u=!1,w=e.map(p=>{let g=T(p,t);return g!==p&&(u=!0),g});return u?w:e}if(G(e)&&(F(e.type)||j(e.type)))return t;let n=m.default.isValidElement(e);if(!n&&!G(e))return e;if(n&&(F(e.type)||j(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=T(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?m.default.cloneElement(e,void 0,...r):m.default.cloneElement(e,void 0,r);let i=e,a={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return m.default.createElement(i.type,a)}var d=require("react/jsx-runtime"),Te={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},N=typeof c.default.createContext=="function"?c.default.createContext(null):null,ee="__WEBFRAMEZ_ROUTER__",Ne="__WEBFRAMEZ_REACT_BUILD_ID",Ae="x-webframez-react-build",Se="[data-webframez-head='true']";function Z(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function k(e){return l(e)??""}function Pe(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function te(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function be(){return k(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function ne(e){if(typeof window>"u")return e||"/";let t=k(window.__RSC_BASENAME),n=be(),o=Pe(e||"/",t);return te(n,o)}function oe(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Le(){if(typeof window>"u")return"";let e=window[Ne];return typeof e=="string"?e:""}function xe(e){let t=Le();return!!t&&!!e&&t!==e}function v(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function ve(){return typeof window>"u"?null:window[ee]??null}function Ie(e){typeof window>"u"||(window[ee]=e)}function ke(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function He(e){return ke(e)?c.default.use(e):e}function A(e){let t=He(e);if(Array.isArray(t)){let r=!1,i=t.map(a=>{let u=A(a);return u!==a&&(r=!0),u});return r?i:t}if(!c.default.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=A(n.children);return o===n.children?t:Array.isArray(o)?c.default.cloneElement(t,void 0,...o):c.default.cloneElement(t,void 0,o)}function V(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),i=r>=0?o.slice(0,r).trim():o,a=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(a))}return e}function X(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function Be(){return c.default.useMemo(()=>({all:()=>V(),get:e=>V()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=X(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=X(e,"",{...t??{},maxAge:0}))}}),[])}function Oe(){let e=N?c.default.useContext(N):null;if(!e){let t=ve();if(t)return t;if(typeof window>"u")return Te;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Me({active:e}){return(0,d.jsx)("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function Ue(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function ze(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function $e(e){if(e.html){re(e.html);return}let t=document.createElement("script");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([o,r])=>o!=="content"&&o!=="html"&&r!==void 0&&r!==null&&r!==!1);for(let[o,r]of n)r===!0?t.setAttribute(o,""):t.setAttribute(o,String(r));e.content&&(t.textContent=e.content),document.head.appendChild(t)}function re(e){let t=document.createElement("template");t.innerHTML=e;for(let n of Array.from(t.content.childNodes))n.nodeType===Node.ELEMENT_NODE&&n.setAttribute("data-webframez-head","true"),document.head.appendChild(n)}function S(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function De(e){if(e.tagName.toLowerCase()==="script"&&e.textContent){let n={content:e.textContent};for(let o of Array.from(e.attributes))n[o.name]=o.value;return S(e.tagName,n)}let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return S(e.tagName,t)}function We(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});for(let n of e.scripts??[])t.push({tagName:"script",attrs:n});for(let n of e.html??[])typeof n=="string"&&n.trim()!==""&&t.push({tagName:"html",attrs:{html:n}});return t}function I(e){if(typeof document>"u")return;let t=L(e)??e;ie(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=We(t),o=new Set(n.map(i=>S(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(Se)){let a=De(i);if(o.has(a)&&!r.has(a)){r.add(a);continue}i.remove()}for(let i of n){let a=S(i.tagName,i.attrs);r.has(a)||(i.tagName==="meta"?Ue(i.attrs):i.tagName==="link"?ze(i.attrs):i.tagName==="script"?$e(i.attrs):re(i.attrs.html),r.add(a))}}function ie(e){if(typeof window>"u")return;let t=L(e)??e,n=l(t.basename),o=l(t.routeBasePath),r=l(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=te(r,"/rsc"))}function Fe(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function je(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,h.createFromReadableStream)(Fe(e)))}function Ge(e){let t=oe(e),n=ne(window.location.pathname);return je()??(0,h.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function qe(e,t){return function(){let o=c.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,a]=(0,c.useState)(o.model),[u,w]=(0,c.useState)(o.contextModel),[p,g]=(0,c.useState)(o.pageModel),[H,B]=(0,c.useState)(o.head),[ae,_]=(0,c.useState)(!1),[se,ce]=(0,c.useState)(!1),[de,O]=(0,c.useState)(r);async function M(s){let y=oe(t),f=ne(s.pathname),R=await fetch(`${y}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(s.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return xe(R.headers.get(Ae))?(v(s),await new Promise(()=>{})):await(0,h.createFromFetch)(Promise.resolve(R))}async function C(s,y="push"){_(!0);try{let f=await M(s);I(f.head),B(f.head),a(f.model),w(f.contextModel),g(f.pageModel),O(!1);let R=`${s.pathname}${s.search}${s.hash}`;y==="replace"?(history.replaceState(null,"",R),Z()):y==="push"&&(history.pushState(null,"",R),Z())}catch(f){console.error("[webframez-react] Failed to render route",f),v(s),a((0,d.jsx)("p",{children:"Failed to load route."}))}finally{_(!1)}}async function ue(){_(!0);try{let s=await M(new URL(window.location.href));I(s.head),B(s.head),a(s.model),w(s.contextModel),g(s.pageModel),O(!1)}catch(s){console.error("[webframez-react] Failed to refresh route context",s),v(new URL(window.location.href))}finally{_(!1)}}(0,c.useEffect)(()=>{I(H)},[H]),(0,c.useEffect)(()=>{ce(!0);let s=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let U=c.default.useMemo(()=>({push:s=>{C(new URL(s,window.location.origin),"push")},replace:s=>{C(new URL(s,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{ue()}}),[]);Ie(U);let z=A(u),P=A(p),le=de&&typeof p<"u"?z?(0,d.jsx)(Q.RouteChildrenSlotProvider,{page:P,children:T(z,P)}):P:i,$=(0,d.jsxs)(d.Fragment,{children:[se?(0,d.jsx)(Me,{active:ae}):null,le??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return N?(0,d.jsx)(N.Provider,{value:U,children:$}):$}}function Ke(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??o??"/rsc",i=Promise.resolve(Ge(r)).then(u=>(u?.head&&ie(u.head),u)),a=qe(i,r);return(0,J.hydrateRoot)(n,(0,d.jsx)(a,{}))}
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import u,{useEffect as q,useState as f}from"react";import{hydrateRoot as fe}from"react-dom/client";import{createFromFetch as V,createFromReadableStream as me}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as pe}from"@webtypen/webframez-react/route-slot";var ce=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function d(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function z(e,t){let n=e.trim(),o=d(t);return!n||!o||ce.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function S(e,t){if(!e)return;let n=d(e.basename)??d(t),o=d(e.routeBasePath),r=d(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=z(i.favicon,n)),i.links&&(i.links=i.links.map(s=>({...s,href:z(s.href,n)}))),i}import h from"react";var F="webframez-route-children",j="__webframezRouteChildren",G="WebframezRouteChildren",de="__webframezRouteChildrenSlot",ue="WebframezRouteChildrenSlot",P=()=>h.createElement(F);P.displayName=G;P[j]=!0;var le=P;function $(e){if(e===F||e===le)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[j]===!0||t.displayName===G||t.name==="RouteChildren"}catch{return!1}}function D(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[de]===!0||t.displayName===ue||t.name==="RouteChildrenSlot"}catch{return!1}}function W(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function E(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let c=!1,w=e.map(p=>{let R=E(p,t);return R!==p&&(c=!0),R});return c?w:e}if(W(e)&&($(e.type)||D(e.type)))return t;let n=h.isValidElement(e);if(!n&&!W(e))return e;if(n&&($(e.type)||D(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=E(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?h.cloneElement(e,void 0,...r):h.cloneElement(e,void 0,r);let i=e,s={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return h.createElement(i.type,s)}import{Fragment as Oe,jsx as m,jsxs as Ue}from"react/jsx-runtime";var Re={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof u.createContext=="function"?u.createContext(null):null,X="__WEBFRAMEZ_ROUTER__",ge="__WEBFRAMEZ_REACT_BUILD_ID",he="x-webframez-react-build",we="[data-webframez-head='true']";function K(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function I(e){return d(e)??""}function _e(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function J(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function ye(){return I(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function Q(e){if(typeof window>"u")return e||"/";let t=I(window.__RSC_BASENAME),n=ye(),o=_e(e||"/",t);return J(n,o)}function ee(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ce(){if(typeof window>"u")return"";let e=window[ge];return typeof e=="string"?e:""}function Ee(e){let t=Ce();return!!t&&!!e&&t!==e}function L(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Te(){return typeof window>"u"?null:window[X]??null}function Ne(e){typeof window>"u"||(window[X]=e)}function Ae(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Se(e){return Ae(e)?u.use(e):e}function N(e){let t=Se(e);if(Array.isArray(t)){let r=!1,i=t.map(s=>{let c=N(s);return c!==s&&(r=!0),c});return r?i:t}if(!u.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=N(n.children);return o===n.children?t:Array.isArray(o)?u.cloneElement(t,void 0,...o):u.cloneElement(t,void 0,o)}function Y(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),i=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(s))}return e}function Z(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function Ye(){return u.useMemo(()=>({all:()=>Y(),get:e=>Y()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=Z(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=Z(e,"",{...t??{},maxAge:0}))}}),[])}function Ze(){let e=T?u.useContext(T):null;if(!e){let t=Te();if(t)return t;if(typeof window>"u")return Re;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Pe({active:e}){return m("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function Le(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function ve(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function x(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function Ie(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return x(e.tagName,t)}function xe(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});return t}function v(e){if(typeof document>"u")return;let t=S(e)??e;te(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=xe(t),o=new Set(n.map(i=>x(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(we)){let s=Ie(i);if(o.has(s)&&!r.has(s)){r.add(s);continue}i.remove()}for(let i of n){let s=x(i.tagName,i.attrs);r.has(s)||(i.tagName==="meta"?Le(i.attrs):ve(i.attrs),r.add(s))}}function te(e){if(typeof window>"u")return;let t=S(e)??e,n=d(t.basename),o=d(t.routeBasePath),r=d(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=J(r,"/rsc"))}function be(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function ke(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,me(be(e)))}function Be(e){let t=ee(e),n=Q(window.location.pathname);return ke()??V(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function He(e,t){return function(){let o=u.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,s]=f(o.model),[c,w]=f(o.contextModel),[p,R]=f(o.pageModel),[b,k]=f(o.head),[ne,_]=f(!1),[oe,re]=f(!1),[ie,B]=f(r);async function H(a){let C=ee(t),l=Q(a.pathname),g=await fetch(`${C}?path=${encodeURIComponent(l)}&search=${encodeURIComponent(a.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Ee(g.headers.get(he))?(L(a),await new Promise(()=>{})):await V(Promise.resolve(g))}async function y(a,C="push"){_(!0);try{let l=await H(a);v(l.head),k(l.head),s(l.model),w(l.contextModel),R(l.pageModel),B(!1);let g=`${a.pathname}${a.search}${a.hash}`;C==="replace"?(history.replaceState(null,"",g),K()):C==="push"&&(history.pushState(null,"",g),K())}catch(l){console.error("[webframez-react] Failed to render route",l),L(a),s(m("p",{children:"Failed to load route."}))}finally{_(!1)}}async function ae(){_(!0);try{let a=await H(new URL(window.location.href));v(a.head),k(a.head),s(a.model),w(a.contextModel),R(a.pageModel),B(!1)}catch(a){console.error("[webframez-react] Failed to refresh route context",a),L(new URL(window.location.href))}finally{_(!1)}}q(()=>{v(b)},[b]),q(()=>{re(!0);let a=()=>{y(new URL(window.location.href),"none")};return window.addEventListener("popstate",a),()=>{window.removeEventListener("popstate",a)}},[]);let O=u.useMemo(()=>({push:a=>{y(new URL(a,window.location.origin),"push")},replace:a=>{y(new URL(a,window.location.origin),"replace")},refresh:()=>{y(new URL(window.location.href),"none")},refreshContext:()=>{ae()}}),[]);Ne(O);let U=N(c),A=N(p),se=ie&&typeof p<"u"?U?m(pe,{page:A,children:E(U,A)}):A:i,M=Ue(Oe,{children:[oe?m(Pe,{active:ne}):null,se??m("p",{style:{padding:24},children:"Loading..."})]});return T?m(T.Provider,{value:O,children:M}):M}}function Ve(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??o??"/rsc",i=Promise.resolve(Be(r)).then(c=>(c?.head&&te(c.head),c)),s=He(i,r);return fe(n,m(s,{}))}export{Ve as mountWebframezClient,Ye as useCookie,Ze as useRouter};
|
|
1
|
+
import u,{useEffect as q,useState as f}from"react";import{hydrateRoot as me}from"react-dom/client";import{createFromFetch as V,createFromReadableStream as pe}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as ge}from"@webtypen/webframez-react/route-slot";var de=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function d(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function P(e,t){let n=e.trim(),o=d(t);return!n||!o||de.test(n)||n.startsWith("/")||o!=="/"&&(n===o||n.startsWith(`${o}/`))?n:o==="/"?n.startsWith("/")?n:`/${n}`:n.startsWith("/")?`${o}${n}`:`${o}/${n}`}function b(e,t){if(!e)return;let n=d(e.basename)??d(t),o=d(e.routeBasePath),r=d(e.transportBasePath),i={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return i.favicon&&(i.favicon=P(i.favicon,n)),i.links&&(i.links=i.links.map(a=>({...a,href:P(a.href,n)}))),i.scripts&&(i.scripts=i.scripts.map(a=>({...a,...a.src?{src:P(a.src,n)}:{}}))),i}import h from"react";var F="webframez-route-children",j="__webframezRouteChildren",G="WebframezRouteChildren",ue="__webframezRouteChildrenSlot",le="WebframezRouteChildrenSlot",L=()=>h.createElement(F);L.displayName=G;L[j]=!0;var fe=L;function $(e){if(e===F||e===fe)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[j]===!0||t.displayName===G||t.name==="RouteChildren"}catch{return!1}}function D(e){if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[ue]===!0||t.displayName===le||t.name==="RouteChildrenSlot"}catch{return!1}}function W(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function E(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let c=!1,w=e.map(p=>{let g=E(p,t);return g!==p&&(c=!0),g});return c?w:e}if(W(e)&&($(e.type)||D(e.type)))return t;let n=h.isValidElement(e);if(!n&&!W(e))return e;if(n&&($(e.type)||D(e.type)))return t;let o=e.props??{};if(!("children"in o))return e;let r=E(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?h.cloneElement(e,void 0,...r):h.cloneElement(e,void 0,r);let i=e,a={...i.props??{},children:r,...i.key!==void 0&&i.key!==null?{key:i.key}:{}};return h.createElement(i.type,a)}import{Fragment as Ue,jsx as m,jsxs as ze}from"react/jsx-runtime";var Re={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},T=typeof u.createContext=="function"?u.createContext(null):null,X="__WEBFRAMEZ_ROUTER__",he="__WEBFRAMEZ_REACT_BUILD_ID",we="x-webframez-react-build",_e="[data-webframez-head='true']";function K(){if(typeof window>"u"||typeof document>"u")return;let e=()=>{window.scrollTo({top:0,left:0}),document.scrollingElement&&(document.scrollingElement.scrollTop=0),document.documentElement.scrollTop=0,document.body&&(document.body.scrollTop=0)};if(typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(e);return}window.setTimeout(e,0)}function I(e){return d(e)??""}function Ce(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function J(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function ye(){return I(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function Q(e){if(typeof window>"u")return e||"/";let t=I(window.__RSC_BASENAME),n=ye(),o=Ce(e||"/",t);return J(n,o)}function ee(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ee(){if(typeof window>"u")return"";let e=window[he];return typeof e=="string"?e:""}function Te(e){let t=Ee();return!!t&&!!e&&t!==e}function x(e){typeof window>"u"||window.location.assign(`${e.pathname}${e.search}${e.hash}`)}function Ne(){return typeof window>"u"?null:window[X]??null}function Ae(e){typeof window>"u"||(window[X]=e)}function Se(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Pe(e){return Se(e)?u.use(e):e}function N(e){let t=Pe(e);if(Array.isArray(t)){let r=!1,i=t.map(a=>{let c=N(a);return c!==a&&(r=!0),c});return r?i:t}if(!u.isValidElement(t))return t;let n=t.props;if(!("children"in n))return t;let o=N(n.children);return o===n.children?t:Array.isArray(o)?u.cloneElement(t,void 0,...o):u.cloneElement(t,void 0,o)}function Y(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),i=r>=0?o.slice(0,r).trim():o,a=r>=0?o.slice(r+1):"";i&&(e[i]=decodeURIComponent(a))}return e}function Z(e,t,n={}){let o=[`${e}=${encodeURIComponent(t)}`];return n.path&&o.push(`Path=${n.path}`),n.domain&&o.push(`Domain=${n.domain}`),typeof n.maxAge=="number"&&o.push(`Max-Age=${Math.floor(n.maxAge)}`),n.expires&&o.push(`Expires=${n.expires.toUTCString()}`),n.sameSite&&o.push(`SameSite=${n.sameSite}`),n.secure&&o.push("Secure"),o.join("; ")}function Ve(){return u.useMemo(()=>({all:()=>Y(),get:e=>Y()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=Z(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=Z(e,"",{...t??{},maxAge:0}))}}),[])}function Xe(){let e=T?u.useContext(T):null;if(!e){let t=Ne();if(t)return t;if(typeof window>"u")return Re;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function be({active:e}){return m("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function Le(e){let t=document.createElement("meta");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function xe(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function ve(e){if(e.html){te(e.html);return}let t=document.createElement("script");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([o,r])=>o!=="content"&&o!=="html"&&r!==void 0&&r!==null&&r!==!1);for(let[o,r]of n)r===!0?t.setAttribute(o,""):t.setAttribute(o,String(r));e.content&&(t.textContent=e.content),document.head.appendChild(t)}function te(e){let t=document.createElement("template");t.innerHTML=e;for(let n of Array.from(t.content.childNodes))n.nodeType===Node.ELEMENT_NODE&&n.setAttribute("data-webframez-head","true"),document.head.appendChild(n)}function A(e,t){let n=Object.entries(t).filter(([o,r])=>o!=="data-webframez-head"&&!!r).map(([o,r])=>[o.toLowerCase(),String(r)]).sort(([o],[r])=>o.localeCompare(r));return`${e.toLowerCase()}:${n.map(([o,r])=>`${o}=${r}`).join(";")}`}function Ie(e){if(e.tagName.toLowerCase()==="script"&&e.textContent){let n={content:e.textContent};for(let o of Array.from(e.attributes))n[o.name]=o.value;return A(e.tagName,n)}let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return A(e.tagName,t)}function ke(e){let t=[];e.description&&t.push({tagName:"meta",attrs:{name:"description",content:e.description}}),e.favicon&&t.push({tagName:"link",attrs:{rel:"icon",href:e.favicon}});for(let n of e.meta??[])t.push({tagName:"meta",attrs:n});for(let n of e.links??[])t.push({tagName:"link",attrs:n});for(let n of e.scripts??[])t.push({tagName:"script",attrs:n});for(let n of e.html??[])typeof n=="string"&&n.trim()!==""&&t.push({tagName:"html",attrs:{html:n}});return t}function v(e){if(typeof document>"u")return;let t=b(e)??e;ne(t),document.body.className=t.bodyClassName||"",document.title=t.title||"Webframez React";let n=ke(t),o=new Set(n.map(i=>A(i.tagName,i.attrs))),r=new Set;for(let i of document.head.querySelectorAll(_e)){let a=Ie(i);if(o.has(a)&&!r.has(a)){r.add(a);continue}i.remove()}for(let i of n){let a=A(i.tagName,i.attrs);r.has(a)||(i.tagName==="meta"?Le(i.attrs):i.tagName==="link"?xe(i.attrs):i.tagName==="script"?ve(i.attrs):te(i.attrs.html),r.add(a))}}function ne(e){if(typeof window>"u")return;let t=b(e)??e,n=d(t.basename),o=d(t.routeBasePath),r=d(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=J(r,"/rsc"))}function He(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Be(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,pe(He(e)))}function Oe(e){let t=ee(e),n=Q(window.location.pathname);return Be()??V(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function Me(e,t){return function(){let o=u.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[i,a]=f(o.model),[c,w]=f(o.contextModel),[p,g]=f(o.pageModel),[k,H]=f(o.head),[oe,_]=f(!1),[re,ie]=f(!1),[ae,B]=f(r);async function O(s){let y=ee(t),l=Q(s.pathname),R=await fetch(`${y}?path=${encodeURIComponent(l)}&search=${encodeURIComponent(s.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}});return Te(R.headers.get(we))?(x(s),await new Promise(()=>{})):await V(Promise.resolve(R))}async function C(s,y="push"){_(!0);try{let l=await O(s);v(l.head),H(l.head),a(l.model),w(l.contextModel),g(l.pageModel),B(!1);let R=`${s.pathname}${s.search}${s.hash}`;y==="replace"?(history.replaceState(null,"",R),K()):y==="push"&&(history.pushState(null,"",R),K())}catch(l){console.error("[webframez-react] Failed to render route",l),x(s),a(m("p",{children:"Failed to load route."}))}finally{_(!1)}}async function se(){_(!0);try{let s=await O(new URL(window.location.href));v(s.head),H(s.head),a(s.model),w(s.contextModel),g(s.pageModel),B(!1)}catch(s){console.error("[webframez-react] Failed to refresh route context",s),x(new URL(window.location.href))}finally{_(!1)}}q(()=>{v(k)},[k]),q(()=>{ie(!0);let s=()=>{C(new URL(window.location.href),"none")};return window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s)}},[]);let M=u.useMemo(()=>({push:s=>{C(new URL(s,window.location.origin),"push")},replace:s=>{C(new URL(s,window.location.origin),"replace")},refresh:()=>{C(new URL(window.location.href),"none")},refreshContext:()=>{se()}}),[]);Ae(M);let U=N(c),S=N(p),ce=ae&&typeof p<"u"?U?m(ge,{page:S,children:E(U,S)}):S:i,z=ze(Ue,{children:[re?m(be,{active:oe}):null,ce??m("p",{style:{padding:24},children:"Loading..."})]});return T?m(T.Provider,{value:M,children:z}):z}}function Je(e={}){let t=e.rootId??"root",n=document.getElementById(t);if(!n)throw new Error(`Missing #${t} element`);let o=typeof window<"u"&&window.__RSC_ENDPOINT,r=e.rscEndpoint??o??"/rsc",i=Promise.resolve(Oe(r)).then(c=>(c?.head&&ne(c.head),c)),a=Me(i,r);return me(n,m(a,{}))}export{Je as mountWebframezClient,Ve as useCookie,Xe as useRouter};
|
package/dist/http.cjs
CHANGED
|
@@ -29,9 +29,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/http.ts
|
|
30
30
|
var http_exports = {};
|
|
31
31
|
__export(http_exports, {
|
|
32
|
-
createNodeRequestHandler: () => createNodeRequestHandler
|
|
32
|
+
createNodeRequestHandler: () => createNodeRequestHandler,
|
|
33
|
+
disposeReactHtmlRenderer: () => disposeReactHtmlRenderer,
|
|
34
|
+
renderReactToHtml: () => renderReactToHtml
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(http_exports);
|
|
37
|
+
var import_node_async_hooks = require("node:async_hooks");
|
|
35
38
|
var import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
36
39
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
37
40
|
var import_node_url = require("node:url");
|
|
@@ -55,6 +58,8 @@ function createHTMLShell(options = {}) {
|
|
|
55
58
|
buildId = "",
|
|
56
59
|
headTags = "",
|
|
57
60
|
bodyClassName = "",
|
|
61
|
+
bodyStartHtml = "",
|
|
62
|
+
bodyEndHtml = "",
|
|
58
63
|
rootHtml = "",
|
|
59
64
|
initialFlightData = "",
|
|
60
65
|
basename = "",
|
|
@@ -104,7 +109,9 @@ function createHTMLShell(options = {}) {
|
|
|
104
109
|
${headTags}
|
|
105
110
|
</head>
|
|
106
111
|
<body${bodyClassName ? ` class="${bodyClassName.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">")}"` : ""}>
|
|
112
|
+
${bodyStartHtml}
|
|
107
113
|
<div id="root">${rootHtml}</div>
|
|
114
|
+
${bodyEndHtml}
|
|
108
115
|
<script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
|
|
109
116
|
<script>window.__RSC_BASENAME = "${basename}";</script>
|
|
110
117
|
<script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
|
|
@@ -219,6 +226,12 @@ function normalizeHeadConfig(head, inheritedBasename) {
|
|
|
219
226
|
href: resolveHeadAssetUrl(link.href, effectiveBasename)
|
|
220
227
|
}));
|
|
221
228
|
}
|
|
229
|
+
if (normalizedHead.scripts) {
|
|
230
|
+
normalizedHead.scripts = normalizedHead.scripts.map((script) => ({
|
|
231
|
+
...script,
|
|
232
|
+
...script.src ? { src: resolveHeadAssetUrl(script.src, effectiveBasename) } : {}
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
222
235
|
return normalizedHead;
|
|
223
236
|
}
|
|
224
237
|
|
|
@@ -331,8 +344,7 @@ var FORCED_PACKAGE_REQUESTS = [
|
|
|
331
344
|
"react-server-dom-webpack",
|
|
332
345
|
"react-server-dom-webpack/server",
|
|
333
346
|
"react-server-dom-webpack/client",
|
|
334
|
-
"react-server-dom-webpack/client.node"
|
|
335
|
-
"scheduler"
|
|
347
|
+
"react-server-dom-webpack/client.node"
|
|
336
348
|
];
|
|
337
349
|
var forcedPackageResolutionInstalled = false;
|
|
338
350
|
function normalizePathname(pathname) {
|
|
@@ -471,7 +483,9 @@ function matchRoute(entry, pathname) {
|
|
|
471
483
|
function mergeHead(...configs) {
|
|
472
484
|
const merged = {
|
|
473
485
|
meta: [],
|
|
474
|
-
links: []
|
|
486
|
+
links: [],
|
|
487
|
+
scripts: [],
|
|
488
|
+
html: []
|
|
475
489
|
};
|
|
476
490
|
for (const candidate of configs) {
|
|
477
491
|
const config = normalizeHeadConfig(candidate, merged.basename);
|
|
@@ -506,9 +520,28 @@ function mergeHead(...configs) {
|
|
|
506
520
|
if (config.links) {
|
|
507
521
|
merged.links?.push(...config.links);
|
|
508
522
|
}
|
|
523
|
+
if (config.scripts) {
|
|
524
|
+
merged.scripts?.push(...config.scripts);
|
|
525
|
+
}
|
|
526
|
+
if (config.html) {
|
|
527
|
+
merged.html?.push(...Array.isArray(config.html) ? config.html : [config.html]);
|
|
528
|
+
}
|
|
529
|
+
if (config.bodyStartHtml) {
|
|
530
|
+
merged.bodyStartHtml = [merged.bodyStartHtml, config.bodyStartHtml].filter(Boolean).join("\n");
|
|
531
|
+
}
|
|
532
|
+
if (config.bodyEndHtml) {
|
|
533
|
+
merged.bodyEndHtml = [merged.bodyEndHtml, config.bodyEndHtml].filter(Boolean).join("\n");
|
|
534
|
+
}
|
|
509
535
|
}
|
|
510
536
|
return merged;
|
|
511
537
|
}
|
|
538
|
+
function renderGenericAttributes(entry, excluded = []) {
|
|
539
|
+
return Object.entries(entry).filter(
|
|
540
|
+
([key, value]) => !excluded.includes(key) && value !== void 0 && value !== null && value !== false
|
|
541
|
+
).map(
|
|
542
|
+
([key, value]) => value === true ? key : `${key}="${escapeHtml(String(value))}"`
|
|
543
|
+
).join(" ");
|
|
544
|
+
}
|
|
512
545
|
function renderHeadToString(head) {
|
|
513
546
|
const normalizedHead = normalizeHeadConfig(head) ?? head;
|
|
514
547
|
const tags = [];
|
|
@@ -530,6 +563,23 @@ function renderHeadToString(head) {
|
|
|
530
563
|
const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
|
|
531
564
|
tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
|
|
532
565
|
}
|
|
566
|
+
for (const script of normalizedHead.scripts ?? []) {
|
|
567
|
+
if (script.html) {
|
|
568
|
+
tags.push(script.html);
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
const attrs = renderGenericAttributes(script, [
|
|
572
|
+
"content",
|
|
573
|
+
"html"
|
|
574
|
+
]);
|
|
575
|
+
const content = script.content ? String(script.content) : "";
|
|
576
|
+
tags.push(`<script ${createManagedAttributes()} ${attrs}>${content}</script>`);
|
|
577
|
+
}
|
|
578
|
+
for (const html of normalizedHead.html ?? []) {
|
|
579
|
+
if (typeof html === "string" && html.trim() !== "") {
|
|
580
|
+
tags.push(html);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
533
583
|
return tags.join("\n");
|
|
534
584
|
}
|
|
535
585
|
function clearModuleCache(modulePath, rootDir, visited = /* @__PURE__ */ new Set()) {
|
|
@@ -615,6 +665,7 @@ function isRouteAbort(value) {
|
|
|
615
665
|
function createFileRouter(options) {
|
|
616
666
|
installForcedPackageResolution();
|
|
617
667
|
const pagesDir = options.pagesDir;
|
|
668
|
+
const onData = options.onData;
|
|
618
669
|
const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
|
|
619
670
|
const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
|
|
620
671
|
const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
|
|
@@ -779,10 +830,16 @@ function createFileRouter(options) {
|
|
|
779
830
|
data: mergeRouteData(middlewareContext.data, pageData)
|
|
780
831
|
};
|
|
781
832
|
activeContext = pageContext;
|
|
782
|
-
const
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
833
|
+
const onDataResult = typeof onData === "function" ? await onData(pageContext) : void 0;
|
|
834
|
+
const eventContext = {
|
|
835
|
+
...pageContext,
|
|
836
|
+
data: mergeRouteData(pageContext.data, onDataResult)
|
|
837
|
+
};
|
|
838
|
+
activeContext = eventContext;
|
|
839
|
+
const pageNode = await pageModule.default(eventContext);
|
|
840
|
+
const layoutHead = layoutModule ? await resolveHead(layoutModule, eventContext) : void 0;
|
|
841
|
+
const pageHead = await resolveHead(pageModule, eventContext);
|
|
842
|
+
const layoutNode = layoutModule ? await layoutModule.default(eventContext) : null;
|
|
786
843
|
const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
|
|
787
844
|
const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteChildren, {})) : void 0;
|
|
788
845
|
return {
|
|
@@ -791,7 +848,7 @@ function createFileRouter(options) {
|
|
|
791
848
|
contextModel,
|
|
792
849
|
pageModel: pageNode,
|
|
793
850
|
head: mergeHead(layoutHead, pageHead),
|
|
794
|
-
context:
|
|
851
|
+
context: eventContext
|
|
795
852
|
};
|
|
796
853
|
} catch (error) {
|
|
797
854
|
if (isRouteAbort(error)) {
|
|
@@ -938,6 +995,7 @@ const rootParent = {
|
|
|
938
995
|
path: process.cwd(),
|
|
939
996
|
paths: Module._nodeModulePaths(process.cwd()),
|
|
940
997
|
};
|
|
998
|
+
// Transitive dependencies (e.g. scheduler) must resolve from their importer.
|
|
941
999
|
const forcedPackageRequests = [
|
|
942
1000
|
"@webtypen/webframez-core",
|
|
943
1001
|
"@webtypen/webframez-react",
|
|
@@ -952,7 +1010,6 @@ const forcedPackageRequests = [
|
|
|
952
1010
|
"react-server-dom-webpack/server",
|
|
953
1011
|
"react-server-dom-webpack/client",
|
|
954
1012
|
"react-server-dom-webpack/client.node",
|
|
955
|
-
"scheduler"
|
|
956
1013
|
];
|
|
957
1014
|
|
|
958
1015
|
function shouldForcePackageResolution(request) {
|
|
@@ -1144,13 +1201,17 @@ async function renderHtmlFromFlightData(flightData, moduleMap) {
|
|
|
1144
1201
|
? payload.head.basename
|
|
1145
1202
|
: "";
|
|
1146
1203
|
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1204
|
+
const routingContext = globalThis.__WEBFRAMEZ_ROUTING_CONTEXT__ ??=
|
|
1205
|
+
new (require("node:async_hooks").AsyncLocalStorage)();
|
|
1206
|
+
return routingContext.run(basename, async () => {
|
|
1207
|
+
const previousBasename = globalThis.__RSC_BASENAME;
|
|
1208
|
+
globalThis.__RSC_BASENAME = basename;
|
|
1209
|
+
try {
|
|
1210
|
+
return await renderHtml(model);
|
|
1211
|
+
} finally {
|
|
1212
|
+
globalThis.__RSC_BASENAME = previousBasename;
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1154
1215
|
}
|
|
1155
1216
|
|
|
1156
1217
|
process.on("message", async (message) => {
|
|
@@ -1386,24 +1447,10 @@ ${stderrBuffer.trim()}` : "";
|
|
|
1386
1447
|
}
|
|
1387
1448
|
};
|
|
1388
1449
|
}
|
|
1450
|
+
var routingRuntime = globalThis;
|
|
1451
|
+
var basenameContext = routingRuntime.__WEBFRAMEZ_ROUTING_CONTEXT__ ??= new import_node_async_hooks.AsyncLocalStorage();
|
|
1389
1452
|
function withRequestBasename(basename, fn) {
|
|
1390
|
-
|
|
1391
|
-
const previous = target.__RSC_BASENAME;
|
|
1392
|
-
target.__RSC_BASENAME = basename;
|
|
1393
|
-
const finish = () => {
|
|
1394
|
-
target.__RSC_BASENAME = previous;
|
|
1395
|
-
};
|
|
1396
|
-
try {
|
|
1397
|
-
const result = fn();
|
|
1398
|
-
if (result && typeof result.then === "function") {
|
|
1399
|
-
return result.finally(finish);
|
|
1400
|
-
}
|
|
1401
|
-
finish();
|
|
1402
|
-
return result;
|
|
1403
|
-
} catch (error) {
|
|
1404
|
-
finish();
|
|
1405
|
-
throw error;
|
|
1406
|
-
}
|
|
1453
|
+
return basenameContext.run(basename, fn);
|
|
1407
1454
|
}
|
|
1408
1455
|
function parseCookies(rawCookieHeader) {
|
|
1409
1456
|
const raw = Array.isArray(rawCookieHeader) ? rawCookieHeader.join("; ") : rawCookieHeader ?? "";
|
|
@@ -1438,12 +1485,27 @@ function normalizeClientManifest(manifest, options) {
|
|
|
1438
1485
|
}
|
|
1439
1486
|
};
|
|
1440
1487
|
for (const [key, value] of Object.entries(manifest)) {
|
|
1488
|
+
const hashIndex = key.indexOf("#");
|
|
1489
|
+
const moduleKey = hashIndex < 0 ? key : key.slice(0, hashIndex);
|
|
1490
|
+
const exportSuffix = hashIndex < 0 ? "" : key.slice(hashIndex);
|
|
1491
|
+
if (!import_node_path3.default.isAbsolute(moduleKey) && !moduleKey.includes(":") && !moduleKey.startsWith("file://")) {
|
|
1492
|
+
const runtimePath = import_node_path3.default.resolve(options.cwd, moduleKey);
|
|
1493
|
+
const allowedRoots = [options.distRootDir, ...candidateNodeModulesDirs];
|
|
1494
|
+
const insideArtifact = allowedRoots.some((root) => {
|
|
1495
|
+
const relative = import_node_path3.default.relative(import_node_path3.default.resolve(root), runtimePath);
|
|
1496
|
+
return relative !== "" && relative !== ".." && !relative.startsWith(`..${import_node_path3.default.sep}`) && !import_node_path3.default.isAbsolute(relative);
|
|
1497
|
+
});
|
|
1498
|
+
if (insideArtifact) {
|
|
1499
|
+
addAlias(`${runtimePath}${exportSuffix}`, value);
|
|
1500
|
+
addAlias(`${(0, import_node_url.pathToFileURL)(runtimePath).href}${exportSuffix}`, value);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1441
1503
|
if (!key.startsWith("file://")) {
|
|
1442
1504
|
continue;
|
|
1443
1505
|
}
|
|
1444
1506
|
let absolutePath = "";
|
|
1445
1507
|
try {
|
|
1446
|
-
absolutePath = (0, import_node_url.fileURLToPath)(
|
|
1508
|
+
absolutePath = (0, import_node_url.fileURLToPath)(moduleKey);
|
|
1447
1509
|
} catch {
|
|
1448
1510
|
continue;
|
|
1449
1511
|
}
|
|
@@ -1454,13 +1516,13 @@ function normalizeClientManifest(manifest, options) {
|
|
|
1454
1516
|
}
|
|
1455
1517
|
const relativeModulePath = absolutePath.slice(markerIndex + marker.length);
|
|
1456
1518
|
const relativeModulePathPosix = relativeModulePath.split(import_node_path3.default.sep).join("/");
|
|
1457
|
-
addAlias(`./node_modules/${relativeModulePathPosix}`, value);
|
|
1458
|
-
addAlias(`node_modules/${relativeModulePathPosix}`, value);
|
|
1459
|
-
addAlias(absolutePath
|
|
1519
|
+
addAlias(`./node_modules/${relativeModulePathPosix}${exportSuffix}`, value);
|
|
1520
|
+
addAlias(`node_modules/${relativeModulePathPosix}${exportSuffix}`, value);
|
|
1521
|
+
addAlias(`${absolutePath}${exportSuffix}`, value);
|
|
1460
1522
|
for (const nodeModulesDir of candidateNodeModulesDirs) {
|
|
1461
1523
|
const aliasPath = import_node_path3.default.join(nodeModulesDir, relativeModulePath);
|
|
1462
|
-
addAlias(aliasPath
|
|
1463
|
-
addAlias((0, import_node_url.pathToFileURL)(aliasPath).href
|
|
1524
|
+
addAlias(`${aliasPath}${exportSuffix}`, value);
|
|
1525
|
+
addAlias(`${(0, import_node_url.pathToFileURL)(aliasPath).href}${exportSuffix}`, value);
|
|
1464
1526
|
}
|
|
1465
1527
|
}
|
|
1466
1528
|
return normalized;
|
|
@@ -1605,16 +1667,16 @@ function createNodeRequestHandler(options) {
|
|
|
1605
1667
|
const manifestPath = import_node_path3.default.resolve(
|
|
1606
1668
|
options.manifestPath ?? import_node_path3.default.join(distRootDir, "react-client-manifest.json")
|
|
1607
1669
|
);
|
|
1608
|
-
const assetsPrefix = options.assetsPrefix ?? "/assets/";
|
|
1609
|
-
const rscPath = options.rscPath ?? "/rsc";
|
|
1610
|
-
const clientScriptUrl = options.clientScriptUrl ?? "/assets/client.js";
|
|
1611
1670
|
const basePath = normalizeBasePath(options.basePath);
|
|
1671
|
+
const assetsPrefix = options.assetsPrefix ?? `${basePath}/assets/`;
|
|
1672
|
+
const rscPath = options.rscPath ?? `${basePath}/rsc`;
|
|
1673
|
+
const clientScriptUrl = options.clientScriptUrl ?? `${basePath}/assets/client.js`;
|
|
1612
1674
|
const nodeEnv = process.env.NODE_ENV || "";
|
|
1613
1675
|
const runningInWatchMode = Array.isArray(process.execArgv) && process.execArgv.includes("--watch");
|
|
1614
1676
|
const liveReloadEnabled = options.liveReloadPath !== false && (nodeEnv === "development" || runningInWatchMode);
|
|
1615
1677
|
const liveReloadPath = !liveReloadEnabled ? "" : options.liveReloadPath ?? `${basePath || ""}/__webframez_live_reload`;
|
|
1616
1678
|
const liveReloadClients = /* @__PURE__ */ new Set();
|
|
1617
|
-
const router = createFileRouter({ pagesDir });
|
|
1679
|
+
const router = createFileRouter({ pagesDir, onData: options.onData });
|
|
1618
1680
|
const getManifestState = createManifestLoader({
|
|
1619
1681
|
distRootDir,
|
|
1620
1682
|
manifestPath,
|
|
@@ -1627,7 +1689,7 @@ function createNodeRequestHandler(options) {
|
|
|
1627
1689
|
process.once("exit", disposeInitialHtmlWorker);
|
|
1628
1690
|
process.once("SIGINT", disposeInitialHtmlWorker);
|
|
1629
1691
|
process.once("SIGTERM", disposeInitialHtmlWorker);
|
|
1630
|
-
|
|
1692
|
+
const handleRequest = async (req, res) => {
|
|
1631
1693
|
if (!req.url) {
|
|
1632
1694
|
res.statusCode = 400;
|
|
1633
1695
|
res.end("Bad request");
|
|
@@ -1691,6 +1753,7 @@ function createNodeRequestHandler(options) {
|
|
|
1691
1753
|
request: requestContext
|
|
1692
1754
|
})
|
|
1693
1755
|
);
|
|
1756
|
+
resolved2.head = { ...resolved2.head, basename: resolved2.head.basename ?? basePath };
|
|
1694
1757
|
attachResolvedContextToCoreRequest(req, resolved2.context);
|
|
1695
1758
|
const payload = {
|
|
1696
1759
|
model: resolved2.model,
|
|
@@ -1766,6 +1829,7 @@ function createNodeRequestHandler(options) {
|
|
|
1766
1829
|
)
|
|
1767
1830
|
})
|
|
1768
1831
|
);
|
|
1832
|
+
resolved.head = { ...resolved.head, basename: resolved.head.basename ?? basePath };
|
|
1769
1833
|
attachResolvedContextToCoreRequest(req, resolved.context);
|
|
1770
1834
|
const initialPayload = {
|
|
1771
1835
|
model: resolved.model,
|
|
@@ -1838,6 +1902,8 @@ function createNodeRequestHandler(options) {
|
|
|
1838
1902
|
initialFlightData,
|
|
1839
1903
|
basename: shellBasename,
|
|
1840
1904
|
routeBasePath: shellRouteBasePath,
|
|
1905
|
+
bodyStartHtml: resolved.head.bodyStartHtml || "",
|
|
1906
|
+
bodyEndHtml: resolved.head.bodyEndHtml || "",
|
|
1841
1907
|
liveReloadPath: liveReloadPath || void 0,
|
|
1842
1908
|
liveReloadServerId: liveReloadPath ? devServerId : void 0
|
|
1843
1909
|
}),
|
|
@@ -1849,8 +1915,30 @@ function createNodeRequestHandler(options) {
|
|
|
1849
1915
|
}
|
|
1850
1916
|
);
|
|
1851
1917
|
};
|
|
1918
|
+
return (req, res) => withRequestBasename(basePath, () => handleRequest(req, res));
|
|
1919
|
+
}
|
|
1920
|
+
var standaloneHtmlWorker;
|
|
1921
|
+
async function renderReactToHtml(element) {
|
|
1922
|
+
if (!standaloneHtmlWorker) {
|
|
1923
|
+
standaloneHtmlWorker = createInitialHtmlWorker(process.cwd());
|
|
1924
|
+
process.once("exit", disposeReactHtmlRenderer);
|
|
1925
|
+
}
|
|
1926
|
+
const flightData = await renderRSCToString({ model: element }, {
|
|
1927
|
+
moduleMap: {},
|
|
1928
|
+
onError: (error) => {
|
|
1929
|
+
console.error("[webframez-react] HTML render failed", error);
|
|
1930
|
+
}
|
|
1931
|
+
});
|
|
1932
|
+
return standaloneHtmlWorker.renderFromFlightData({ flightData, moduleMap: {} });
|
|
1933
|
+
}
|
|
1934
|
+
function disposeReactHtmlRenderer() {
|
|
1935
|
+
process.removeListener("exit", disposeReactHtmlRenderer);
|
|
1936
|
+
standaloneHtmlWorker?.dispose();
|
|
1937
|
+
standaloneHtmlWorker = void 0;
|
|
1852
1938
|
}
|
|
1853
1939
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1854
1940
|
0 && (module.exports = {
|
|
1855
|
-
createNodeRequestHandler
|
|
1941
|
+
createNodeRequestHandler,
|
|
1942
|
+
disposeReactHtmlRenderer,
|
|
1943
|
+
renderReactToHtml
|
|
1856
1944
|
});
|
package/dist/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { RouteDataHook } from "./types";
|
|
2
3
|
|
|
3
4
|
export type WebframezReactRoutePath = `/${string}` | "/";
|
|
4
5
|
export type WebframezReactAssetsPrefix = `${WebframezReactRoutePath}/` | "/";
|
|
@@ -20,8 +21,12 @@ export interface CreateNodeHandlerRoutingOptions {
|
|
|
20
21
|
export interface CreateNodeHandlerOptions
|
|
21
22
|
extends CreateNodeHandlerPathsOptions,
|
|
22
23
|
CreateNodeHandlerRoutingOptions {
|
|
24
|
+
onData?: RouteDataHook;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export function createNodeRequestHandler(
|
|
26
28
|
options: CreateNodeHandlerOptions
|
|
27
29
|
): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
30
|
+
|
|
31
|
+
export function renderReactToHtml(element: unknown): Promise<string>;
|
|
32
|
+
export function disposeReactHtmlRenderer(): void;
|