@webtypen/webframez-react 0.0.35 → 0.0.36

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.
@@ -0,0 +1,111 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/build-plugin.ts
30
+ var build_plugin_exports = {};
31
+ __export(build_plugin_exports, {
32
+ createPlugin: () => createPlugin,
33
+ default: () => build_plugin_default
34
+ });
35
+ module.exports = __toCommonJS(build_plugin_exports);
36
+ var import_node_fs = __toESM(require("node:fs"), 1);
37
+ var import_node_path = __toESM(require("node:path"), 1);
38
+ function fileExists(filePath) {
39
+ return import_node_fs.default.existsSync(filePath);
40
+ }
41
+ function readJson(filePath) {
42
+ return JSON.parse(import_node_fs.default.readFileSync(filePath, "utf-8"));
43
+ }
44
+ function collectManifestChunks(manifestPath) {
45
+ const manifest = readJson(manifestPath);
46
+ const chunks = /* @__PURE__ */ new Set();
47
+ for (const value of Object.values(manifest)) {
48
+ const entry = value;
49
+ if (!entry || !Array.isArray(entry.chunks)) {
50
+ continue;
51
+ }
52
+ for (const chunk of entry.chunks) {
53
+ if (typeof chunk === "string" && chunk.includes(".")) {
54
+ chunks.add(chunk);
55
+ }
56
+ }
57
+ }
58
+ return chunks;
59
+ }
60
+ function validateRouteDist(distRootDir) {
61
+ const requiredFiles = ["client.js", "react-client-manifest.json", "react-ssr-manifest.json"];
62
+ for (const requiredFile of requiredFiles) {
63
+ const filePath = import_node_path.default.join(distRootDir, requiredFile);
64
+ if (!fileExists(filePath)) {
65
+ throw new Error(`webframez-react build output missing: ${filePath}`);
66
+ }
67
+ }
68
+ for (const chunk of collectManifestChunks(import_node_path.default.join(distRootDir, "react-client-manifest.json"))) {
69
+ const chunkPath = import_node_path.default.join(distRootDir, chunk);
70
+ if (!fileExists(chunkPath)) {
71
+ throw new Error(`webframez-react manifest references missing chunk: ${chunkPath}`);
72
+ }
73
+ }
74
+ }
75
+ function findReactRouteDistRoots(stagingDir) {
76
+ const reactRoot = import_node_path.default.join(stagingDir, "webframez-react");
77
+ if (!fileExists(reactRoot)) {
78
+ return [];
79
+ }
80
+ return import_node_fs.default.readdirSync(reactRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => import_node_path.default.join(reactRoot, entry.name));
81
+ }
82
+ function createPlugin() {
83
+ return {
84
+ name: "webframez-react",
85
+ async buildAssets(context) {
86
+ const routesPath = import_node_path.default.join(context.stagingDir, "app", "routes.js");
87
+ if (!fileExists(routesPath)) {
88
+ return;
89
+ }
90
+ const code = await context.run("webframez-react", [
91
+ "build:routes",
92
+ `--routes=${routesPath}`,
93
+ `--out-dir=${context.stagingDir}`,
94
+ `--runtime-out-dir=${context.outDir}`
95
+ ]);
96
+ if (code !== 0) {
97
+ throw new Error(`webframez-react build failed with code ${code}`);
98
+ }
99
+ },
100
+ validateBuild(context) {
101
+ for (const distRootDir of findReactRouteDistRoots(context.stagingDir)) {
102
+ validateRouteDist(distRootDir);
103
+ }
104
+ }
105
+ };
106
+ }
107
+ var build_plugin_default = createPlugin;
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ createPlugin
111
+ });
@@ -0,0 +1,14 @@
1
+ export type WebframezBuildContext = {
2
+ projectRoot: string;
3
+ stagingDir: string;
4
+ outDir: string;
5
+ run: (binaryName: string, args: string[], envAdditions?: Record<string, string>) => Promise<number>;
6
+ };
7
+
8
+ export declare function createPlugin(): {
9
+ name: string;
10
+ buildAssets(context: WebframezBuildContext): Promise<void>;
11
+ validateBuild(context: WebframezBuildContext): void;
12
+ };
13
+
14
+ export default createPlugin;
@@ -0,0 +1,77 @@
1
+ // src/build-plugin.ts
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ function fileExists(filePath) {
5
+ return fs.existsSync(filePath);
6
+ }
7
+ function readJson(filePath) {
8
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
9
+ }
10
+ function collectManifestChunks(manifestPath) {
11
+ const manifest = readJson(manifestPath);
12
+ const chunks = /* @__PURE__ */ new Set();
13
+ for (const value of Object.values(manifest)) {
14
+ const entry = value;
15
+ if (!entry || !Array.isArray(entry.chunks)) {
16
+ continue;
17
+ }
18
+ for (const chunk of entry.chunks) {
19
+ if (typeof chunk === "string" && chunk.includes(".")) {
20
+ chunks.add(chunk);
21
+ }
22
+ }
23
+ }
24
+ return chunks;
25
+ }
26
+ function validateRouteDist(distRootDir) {
27
+ const requiredFiles = ["client.js", "react-client-manifest.json", "react-ssr-manifest.json"];
28
+ for (const requiredFile of requiredFiles) {
29
+ const filePath = path.join(distRootDir, requiredFile);
30
+ if (!fileExists(filePath)) {
31
+ throw new Error(`webframez-react build output missing: ${filePath}`);
32
+ }
33
+ }
34
+ for (const chunk of collectManifestChunks(path.join(distRootDir, "react-client-manifest.json"))) {
35
+ const chunkPath = path.join(distRootDir, chunk);
36
+ if (!fileExists(chunkPath)) {
37
+ throw new Error(`webframez-react manifest references missing chunk: ${chunkPath}`);
38
+ }
39
+ }
40
+ }
41
+ function findReactRouteDistRoots(stagingDir) {
42
+ const reactRoot = path.join(stagingDir, "webframez-react");
43
+ if (!fileExists(reactRoot)) {
44
+ return [];
45
+ }
46
+ return fs.readdirSync(reactRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path.join(reactRoot, entry.name));
47
+ }
48
+ function createPlugin() {
49
+ return {
50
+ name: "webframez-react",
51
+ async buildAssets(context) {
52
+ const routesPath = path.join(context.stagingDir, "app", "routes.js");
53
+ if (!fileExists(routesPath)) {
54
+ return;
55
+ }
56
+ const code = await context.run("webframez-react", [
57
+ "build:routes",
58
+ `--routes=${routesPath}`,
59
+ `--out-dir=${context.stagingDir}`,
60
+ `--runtime-out-dir=${context.outDir}`
61
+ ]);
62
+ if (code !== 0) {
63
+ throw new Error(`webframez-react build failed with code ${code}`);
64
+ }
65
+ },
66
+ validateBuild(context) {
67
+ for (const distRootDir of findReactRouteDistRoots(context.stagingDir)) {
68
+ validateRouteDist(distRootDir);
69
+ }
70
+ }
71
+ };
72
+ }
73
+ var build_plugin_default = createPlugin;
74
+ export {
75
+ createPlugin,
76
+ build_plugin_default as default
77
+ };
package/dist/client.cjs CHANGED
@@ -1 +1 @@
1
- var se=Object.create;var y=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var fe=(e,t)=>{for(var n in t)y(e,n,{get:t[n],enumerable:!0})},L=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of de(t))!le.call(e,r)&&r!==n&&y(e,r,{get:()=>t[r],enumerable:!(o=ce(t,r))||o.enumerable});return e};var H=(e,t,n)=>(n=e!=null?se(ue(e)):{},L(t||!e||!e.__esModule?y(n,"default",{value:e,enumerable:!0}):n,e)),pe=e=>L(y({},"__esModule",{value:!0}),e);var be={};fe(be,{mountWebframezClient:()=>ve,useCookie:()=>Ee,useRouter:()=>Ae});module.exports=pe(be);var s=H(require("react"),1),Z=require("react-dom/client"),g=require("react-server-dom-webpack/client"),K=require("@webtypen/webframez-react/route-slot");var me=/^(?:[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 U(e,t){let n=e.trim(),o=u(t);return!n||!o||me.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=u(e.basename)??u(t),o=u(e.routeBasePath),r=u(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=U(a.favicon,n)),a.links&&(a.links=a.links.map(c=>({...c,href:U(c.href,n)}))),a}var R=H(require("react"),1),$="webframez-route-children",W="__webframezRouteChildren",D="WebframezRouteChildren",N=()=>R.default.createElement($);N.displayName=D;N[W]=!0;var Re=N;function z(e){if(e===$||e===Re)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[W]===!0||t.displayName===D||t.name==="RouteChildren"}catch{return!1}}function M(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 m=!1,f=e.map(p=>{let w=E(p,t);return w!==p&&(m=!0),w});return m?f:e}if(M(e)&&z(e.type))return t;let n=R.default.isValidElement(e);if(!n&&!M(e))return e;if(n&&z(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)?R.default.cloneElement(e,void 0,...r):R.default.cloneElement(e,void 0,r);let a=e,c={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return R.default.createElement(a.type,c)}var d=require("react/jsx-runtime"),ge={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},A=typeof s.default.createContext=="function"?s.default.createContext(null):null,V="__WEBFRAMEZ_ROUTER__",we="[data-webframez-head='true']";function F(){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 v(e){return u(e)??""}function he(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function X(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function _e(){return v(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function J(e){if(typeof window>"u")return e||"/";let t=v(window.__RSC_BASENAME),n=_e(),o=he(e||"/",t);return X(n,o)}function Q(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ce(){return typeof window>"u"?null:window[V]??null}function ye(e){typeof window>"u"||(window[V]=e)}function j(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),a=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(c))}return e}function q(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 Ee(){return s.default.useMemo(()=>({all:()=>j(),get:e=>j()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=q(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=q(e,"",{...t??{},maxAge:0}))}}),[])}function Ae(){let e=A?s.default.useContext(A):null;if(!e){let t=Ce();if(t)return t;if(typeof window>"u")return ge;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Te({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 G(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 Y(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function x(e){if(typeof document>"u")return;let t=S(e)??e;ee(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(we))n.remove();t.description&&G({name:"description",content:t.description}),t.favicon&&Y({rel:"icon",href:t.favicon});for(let n of t.meta??[])G(n);for(let n of t.links??[])Y(n)}function ee(e){if(typeof window>"u")return;let t=S(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=X(r,"/rsc"))}function Pe(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Se(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,g.createFromReadableStream)(Pe(e)))}function Ne(e){let t=Q(e),n=J(window.location.pathname);return Se()??(0,g.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function xe(e,t){return function(){let o=s.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,c]=(0,s.useState)(o.model),[m,f]=(0,s.useState)(o.contextModel),[p,w]=(0,s.useState)(o.pageModel),[b,I]=(0,s.useState)(o.head),[te,h]=(0,s.useState)(!1),[ne,oe]=(0,s.useState)(!1),[re,T]=(0,s.useState)(r);async function O(i){let C=Q(t),l=J(i.pathname);return await(0,g.createFromFetch)(fetch(`${C}?path=${encodeURIComponent(l)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}async function _(i,C="push"){h(!0);try{let l=await O(i);x(l.head),I(l.head),c(l.model),f(l.contextModel),w(l.pageModel),T(!0);let P=`${i.pathname}${i.search}`;C==="replace"?(history.replaceState(null,"",P),F()):C==="push"&&(history.pushState(null,"",P),F())}catch(l){console.error("[webframez-react] Failed to render route",l),c((0,d.jsx)("p",{children:"Failed to load route."}))}finally{h(!1)}}async function ie(){h(!0);try{let i=await O(new URL(window.location.href));if(x(i.head),I(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){f(i.contextModel),T(!0);return}c(i.model),T(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i)}finally{h(!1)}}(0,s.useEffect)(()=>{x(b)},[b]),(0,s.useEffect)(()=>{oe(!0);let i=()=>{_(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let k=s.default.useMemo(()=>({push:i=>{_(new URL(i,window.location.origin),"push")},replace:i=>{_(new URL(i,window.location.origin),"replace")},refresh:()=>{_(new URL(window.location.href),"none")},refreshContext:()=>{ie()}}),[]);ye(k);let ae=re&&typeof p<"u"?m?(0,d.jsx)(K.RouteChildrenSlotProvider,{page:p,children:E(m,p)}):p:a,B=(0,d.jsxs)(d.Fragment,{children:[ne?(0,d.jsx)(Te,{active:te}):null,ae??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return A?(0,d.jsx)(A.Provider,{value:k,children:B}):B}}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",a=Promise.resolve(Ne(r)).then(f=>(f?.head&&ee(f.head),f)),c=xe(a,r);return(0,Z.hydrateRoot)(n,(0,d.jsx)(c,{}))}
1
+ var se=Object.create;var y=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var fe=(e,t)=>{for(var n in t)y(e,n,{get:t[n],enumerable:!0})},L=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of de(t))!le.call(e,r)&&r!==n&&y(e,r,{get:()=>t[r],enumerable:!(o=ce(t,r))||o.enumerable});return e};var H=(e,t,n)=>(n=e!=null?se(ue(e)):{},L(t||!e||!e.__esModule?y(n,"default",{value:e,enumerable:!0}):n,e)),pe=e=>L(y({},"__esModule",{value:!0}),e);var be={};fe(be,{mountWebframezClient:()=>ve,useCookie:()=>Ee,useRouter:()=>Ae});module.exports=pe(be);var s=H(require("react"),1),Z=require("react-dom/client"),R=require("react-server-dom-webpack/client"),K=require("@webtypen/webframez-react/route-slot");var me=/^(?:[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 U(e,t){let n=e.trim(),o=u(t);return!n||!o||me.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=u(e.basename)??u(t),o=u(e.routeBasePath),r=u(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=U(a.favicon,n)),a.links&&(a.links=a.links.map(c=>({...c,href:U(c.href,n)}))),a}var m=H(require("react"),1),$="webframez-route-children",W="__webframezRouteChildren",D="WebframezRouteChildren",N=()=>m.default.createElement($);N.displayName=D;N[W]=!0;var Re=N;function z(e){if(e===$||e===Re)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[W]===!0||t.displayName===D||t.name==="RouteChildren"}catch{return!1}}function M(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 l=!1,g=e.map(p=>{let w=E(p,t);return w!==p&&(l=!0),w});return l?g:e}if(M(e)&&z(e.type))return t;let n=m.default.isValidElement(e);if(!n&&!M(e))return e;if(n&&z(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)?m.default.cloneElement(e,void 0,...r):m.default.cloneElement(e,void 0,r);let a=e,c={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return m.default.createElement(a.type,c)}var d=require("react/jsx-runtime"),ge={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},A=typeof s.default.createContext=="function"?s.default.createContext(null):null,V="__WEBFRAMEZ_ROUTER__",we="[data-webframez-head='true']";function F(){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 v(e){return u(e)??""}function he(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function X(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function _e(){return v(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function J(e){if(typeof window>"u")return e||"/";let t=v(window.__RSC_BASENAME),n=_e(),o=he(e||"/",t);return X(n,o)}function Q(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function Ce(){return typeof window>"u"?null:window[V]??null}function ye(e){typeof window>"u"||(window[V]=e)}function j(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),a=r>=0?o.slice(0,r).trim():o,c=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(c))}return e}function q(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 Ee(){return s.default.useMemo(()=>({all:()=>j(),get:e=>j()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=q(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=q(e,"",{...t??{},maxAge:0}))}}),[])}function Ae(){let e=A?s.default.useContext(A):null;if(!e){let t=Ce();if(t)return t;if(typeof window>"u")return ge;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Te({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 G(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 Y(e){let t=document.createElement("link");t.setAttribute("data-webframez-head","true");let n=Object.entries(e).filter(([,o])=>!!o);for(let[o,r]of n)t.setAttribute(o,String(r));document.head.appendChild(t)}function x(e){if(typeof document>"u")return;let t=S(e)??e;ee(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(we))n.remove();t.description&&G({name:"description",content:t.description}),t.favicon&&Y({rel:"icon",href:t.favicon});for(let n of t.meta??[])G(n);for(let n of t.links??[])Y(n)}function ee(e){if(typeof window>"u")return;let t=S(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=X(r,"/rsc"))}function Pe(e){let t=new TextEncoder;return new ReadableStream({start(n){n.enqueue(t.encode(e)),n.close()}})}function Se(){if(typeof window>"u")return null;let e=window.__RSC_INITIAL_PAYLOAD;return typeof e!="string"||e===""?null:(delete window.__RSC_INITIAL_PAYLOAD,(0,R.createFromReadableStream)(Pe(e)))}function Ne(e){let t=Q(e),n=J(window.location.pathname);return Se()??(0,R.createFromFetch)(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function xe(e,t){return function(){let o=s.default.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,c]=(0,s.useState)(o.model),[l,g]=(0,s.useState)(o.contextModel),[p,w]=(0,s.useState)(o.pageModel),[b,I]=(0,s.useState)(o.head),[te,h]=(0,s.useState)(!1),[ne,oe]=(0,s.useState)(!1),[re,T]=(0,s.useState)(r);async function O(i){let C=Q(t),f=J(i.pathname);return await(0,R.createFromFetch)(fetch(`${C}?path=${encodeURIComponent(f)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}async function _(i,C="push"){h(!0);try{let f=await O(i);x(f.head),I(f.head),c(f.model),g(f.contextModel),w(f.pageModel),T(!0);let P=`${i.pathname}${i.search}`;C==="replace"?(history.replaceState(null,"",P),F()):C==="push"&&(history.pushState(null,"",P),F())}catch(f){console.error("[webframez-react] Failed to render route",f),c((0,d.jsx)("p",{children:"Failed to load route."}))}finally{h(!1)}}async function ie(){h(!0);try{let i=await O(new URL(window.location.href));if(x(i.head),I(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){g(i.contextModel),T(!0);return}c(i.model),T(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i)}finally{h(!1)}}(0,s.useEffect)(()=>{x(b)},[b]),(0,s.useEffect)(()=>{oe(!0);let i=()=>{_(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let k=s.default.useMemo(()=>({push:i=>{_(new URL(i,window.location.origin),"push")},replace:i=>{_(new URL(i,window.location.origin),"replace")},refresh:()=>{_(new URL(window.location.href),"none")},refreshContext:()=>{ie()}}),[]);ye(k);let ae=re&&typeof p<"u"?l?(0,d.jsx)(K.RouteChildrenSlotProvider,{page:p,children:E(l,p)}):p:a,B=(0,d.jsxs)(d.Fragment,{children:[ne?(0,d.jsx)(Te,{active:te}):null,ae??(0,d.jsx)("p",{style:{padding:24},children:"Loading..."})]});return A?(0,d.jsx)(A.Provider,{value:k,children:B}):B}}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",a=Promise.resolve(Ne(r)).then(l=>(l?.head&&ee(l.head),l)),c=xe(a,r);return(0,Z.hydrateRoot)(n,(0,d.jsx)(c,{}))}
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import R,{useEffect as $,useState as f}from"react";import{hydrateRoot as ae}from"react-dom/client";import{createFromFetch as G,createFromReadableStream as se}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as ce}from"@webtypen/webframez-react/route-slot";var re=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function c(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function B(e,t){let n=e.trim(),o=c(t);return!n||!o||re.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=c(e.basename)??c(t),o=c(e.routeBasePath),r=c(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=B(a.favicon,n)),a.links&&(a.links=a.links.map(s=>({...s,href:B(s.href,n)}))),a}import g from"react";var U="webframez-route-children",z="__webframezRouteChildren",M="WebframezRouteChildren",S=()=>g.createElement(U);S.displayName=M;S[z]=!0;var ie=S;function L(e){if(e===U||e===ie)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[z]===!0||t.displayName===M||t.name==="RouteChildren"}catch{return!1}}function H(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function y(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let m=!1,u=e.map(l=>{let w=y(l,t);return w!==l&&(m=!0),w});return m?u:e}if(H(e)&&L(e.type))return t;let n=g.isValidElement(e);if(!n&&!H(e))return e;if(n&&L(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=y(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?g.cloneElement(e,void 0,...r):g.cloneElement(e,void 0,r);let a=e,s={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return g.createElement(a.type,s)}import{Fragment as Ce,jsx as p,jsxs as ye}from"react/jsx-runtime";var de={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},E=typeof R.createContext=="function"?R.createContext(null):null,Y="__WEBFRAMEZ_ROUTER__",ue="[data-webframez-head='true']";function W(){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 c(e)??""}function le(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function Z(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function fe(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function K(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=fe(),o=le(e||"/",t);return Z(n,o)}function V(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function pe(){return typeof window>"u"?null:window[Y]??null}function me(e){typeof window>"u"||(window[Y]=e)}function D(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),a=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(s))}return e}function F(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 Ie(){return R.useMemo(()=>({all:()=>D(),get:e=>D()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=F(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=F(e,"",{...t??{},maxAge:0}))}}),[])}function Oe(){let e=E?R.useContext(E):null;if(!e){let t=pe();if(t)return t;if(typeof window>"u")return de;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Re({active:e}){return p("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function j(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 q(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 N(e){if(typeof document>"u")return;let t=P(e)??e;X(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(ue))n.remove();t.description&&j({name:"description",content:t.description}),t.favicon&&q({rel:"icon",href:t.favicon});for(let n of t.meta??[])j(n);for(let n of t.links??[])q(n)}function X(e){if(typeof window>"u")return;let t=P(e)??e,n=c(t.basename),o=c(t.routeBasePath),r=c(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=Z(r,"/rsc"))}function ge(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,se(ge(e)))}function he(e){let t=V(e),n=K(window.location.pathname);return we()??G(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function _e(e,t){return function(){let o=R.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,s]=f(o.model),[m,u]=f(o.contextModel),[l,w]=f(o.pageModel),[v,b]=f(o.head),[J,h]=f(!1),[Q,ee]=f(!1),[te,A]=f(r);async function I(i){let C=V(t),d=K(i.pathname);return await G(fetch(`${C}?path=${encodeURIComponent(d)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}async function _(i,C="push"){h(!0);try{let d=await I(i);N(d.head),b(d.head),s(d.model),u(d.contextModel),w(d.pageModel),A(!0);let T=`${i.pathname}${i.search}`;C==="replace"?(history.replaceState(null,"",T),W()):C==="push"&&(history.pushState(null,"",T),W())}catch(d){console.error("[webframez-react] Failed to render route",d),s(p("p",{children:"Failed to load route."}))}finally{h(!1)}}async function ne(){h(!0);try{let i=await I(new URL(window.location.href));if(N(i.head),b(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){u(i.contextModel),A(!0);return}s(i.model),A(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i)}finally{h(!1)}}$(()=>{N(v)},[v]),$(()=>{ee(!0);let i=()=>{_(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let O=R.useMemo(()=>({push:i=>{_(new URL(i,window.location.origin),"push")},replace:i=>{_(new URL(i,window.location.origin),"replace")},refresh:()=>{_(new URL(window.location.href),"none")},refreshContext:()=>{ne()}}),[]);me(O);let oe=te&&typeof l<"u"?m?p(ce,{page:l,children:y(m,l)}):l:a,k=ye(Ce,{children:[Q?p(Re,{active:J}):null,oe??p("p",{style:{padding:24},children:"Loading..."})]});return E?p(E.Provider,{value:O,children:k}):k}}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",a=Promise.resolve(he(r)).then(u=>(u?.head&&X(u.head),u)),s=_e(a,r);return ae(n,p(s,{}))}export{ke as mountWebframezClient,Ie as useCookie,Oe as useRouter};
1
+ import m,{useEffect as $,useState as f}from"react";import{hydrateRoot as ae}from"react-dom/client";import{createFromFetch as G,createFromReadableStream as se}from"react-server-dom-webpack/client";import{RouteChildrenSlotProvider as ce}from"@webtypen/webframez-react/route-slot";var re=/^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;function c(e){if(typeof e!="string")return;let t=e.trim();return!t||t==="/"?"":t.replace(/\/+$/,"")}function B(e,t){let n=e.trim(),o=c(t);return!n||!o||re.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=c(e.basename)??c(t),o=c(e.routeBasePath),r=c(e.transportBasePath),a={...e,...n!==void 0?{basename:n}:{},...o!==void 0?{routeBasePath:o}:{},...r!==void 0?{transportBasePath:r}:{}};return a.favicon&&(a.favicon=B(a.favicon,n)),a.links&&(a.links=a.links.map(s=>({...s,href:B(s.href,n)}))),a}import R from"react";var U="webframez-route-children",z="__webframezRouteChildren",M="WebframezRouteChildren",S=()=>R.createElement(U);S.displayName=M;S[z]=!0;var ie=S;function L(e){if(e===U||e===ie)return!0;if(!e||typeof e!="function"&&typeof e!="object")return!1;try{let t=e;return t[z]===!0||t.displayName===M||t.name==="RouteChildren"}catch{return!1}}function H(e){if(!e||typeof e!="object")return!1;try{return"type"in e&&"props"in e}catch{return!1}}function y(e,t){if(e==null||typeof e=="boolean")return e;if(Array.isArray(e)){let d=!1,g=e.map(l=>{let w=y(l,t);return w!==l&&(d=!0),w});return d?g:e}if(H(e)&&L(e.type))return t;let n=R.isValidElement(e);if(!n&&!H(e))return e;if(n&&L(e.type))return t;let o=e.props??{};if(!("children"in o))return e;let r=y(o.children,t);if(r===o.children)return e;if(n)return Array.isArray(r)?R.cloneElement(e,void 0,...r):R.cloneElement(e,void 0,r);let a=e,s={...a.props??{},children:r,...a.key!==void 0&&a.key!==null?{key:a.key}:{}};return R.createElement(a.type,s)}import{Fragment as Ce,jsx as p,jsxs as ye}from"react/jsx-runtime";var de={push:()=>{},replace:()=>{},refresh:()=>{},refreshContext:()=>{}},E=typeof m.createContext=="function"?m.createContext(null):null,Y="__WEBFRAMEZ_ROUTER__",ue="[data-webframez-head='true']";function W(){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 c(e)??""}function le(e,t){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length)||"/":e||"/":e||"/"}function Z(e,t){let n=!t||t==="/"?"/":t.startsWith("/")?t:`/${t}`;return e?n==="/"?e:`${e}${n}`:n}function fe(){return x(typeof window>"u"?globalThis.__RSC_ROUTE_BASE_PATH:window.__RSC_ROUTE_BASE_PATH)}function K(e){if(typeof window>"u")return e||"/";let t=x(window.__RSC_BASENAME),n=fe(),o=le(e||"/",t);return Z(n,o)}function V(e){if(typeof window>"u")return e;let t=window.__RSC_ENDPOINT;return typeof t=="string"&&t.trim()!==""?t:e}function pe(){return typeof window>"u"?null:window[Y]??null}function me(e){typeof window>"u"||(window[Y]=e)}function D(){let e={},t=typeof document>"u"?"":document.cookie;if(!t||t.trim()==="")return e;for(let n of t.split(";")){let o=n.trim();if(!o)continue;let r=o.indexOf("="),a=r>=0?o.slice(0,r).trim():o,s=r>=0?o.slice(r+1):"";a&&(e[a]=decodeURIComponent(s))}return e}function F(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 Ie(){return m.useMemo(()=>({all:()=>D(),get:e=>D()[e],set:(e,t,n)=>{typeof document>"u"||(document.cookie=F(e,t,n))},remove:(e,t)=>{typeof document>"u"||(document.cookie=F(e,"",{...t??{},maxAge:0}))}}),[])}function Oe(){let e=E?m.useContext(E):null;if(!e){let t=pe();if(t)return t;if(typeof window>"u")return de;throw new Error("useRouter must be used inside mountWebframezClient()")}return e}function Re({active:e}){return p("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:3,zIndex:9999,transformOrigin:"left",transform:e?"scaleX(1)":"scaleX(0)",transition:"transform 180ms ease",background:"linear-gradient(90deg, #0ea5e9, #22c55e)"}})}function j(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 q(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 N(e){if(typeof document>"u")return;let t=P(e)??e;X(t),document.title=t.title||"Webframez React";for(let n of document.head.querySelectorAll(ue))n.remove();t.description&&j({name:"description",content:t.description}),t.favicon&&q({rel:"icon",href:t.favicon});for(let n of t.meta??[])j(n);for(let n of t.links??[])q(n)}function X(e){if(typeof window>"u")return;let t=P(e)??e,n=c(t.basename),o=c(t.routeBasePath),r=c(t.transportBasePath);window.__RSC_BASENAME=n??"",window.__RSC_ROUTE_BASE_PATH=o??"",r!==void 0&&(window.__RSC_ENDPOINT=Z(r,"/rsc"))}function ge(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,se(ge(e)))}function he(e){let t=V(e),n=K(window.location.pathname);return we()??G(fetch(`${t}?path=${encodeURIComponent(n)}&search=${encodeURIComponent(window.location.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}function _e(e,t){return function(){let o=m.use(e),r=typeof o.contextModel<"u"&&typeof o.pageModel<"u",[a,s]=f(o.model),[d,g]=f(o.contextModel),[l,w]=f(o.pageModel),[v,b]=f(o.head),[J,h]=f(!1),[Q,ee]=f(!1),[te,A]=f(r);async function I(i){let C=V(t),u=K(i.pathname);return await G(fetch(`${C}?path=${encodeURIComponent(u)}&search=${encodeURIComponent(i.search)}`,{cache:"no-store",credentials:"same-origin",headers:{Accept:"text/x-component"}}))}async function _(i,C="push"){h(!0);try{let u=await I(i);N(u.head),b(u.head),s(u.model),g(u.contextModel),w(u.pageModel),A(!0);let T=`${i.pathname}${i.search}`;C==="replace"?(history.replaceState(null,"",T),W()):C==="push"&&(history.pushState(null,"",T),W())}catch(u){console.error("[webframez-react] Failed to render route",u),s(p("p",{children:"Failed to load route."}))}finally{h(!1)}}async function ne(){h(!0);try{let i=await I(new URL(window.location.href));if(N(i.head),b(i.head),Object.prototype.hasOwnProperty.call(i,"contextModel")){g(i.contextModel),A(!0);return}s(i.model),A(!1)}catch(i){console.error("[webframez-react] Failed to refresh route context",i)}finally{h(!1)}}$(()=>{N(v)},[v]),$(()=>{ee(!0);let i=()=>{_(new URL(window.location.href),"none")};return window.addEventListener("popstate",i),()=>{window.removeEventListener("popstate",i)}},[]);let O=m.useMemo(()=>({push:i=>{_(new URL(i,window.location.origin),"push")},replace:i=>{_(new URL(i,window.location.origin),"replace")},refresh:()=>{_(new URL(window.location.href),"none")},refreshContext:()=>{ne()}}),[]);me(O);let oe=te&&typeof l<"u"?d?p(ce,{page:l,children:y(d,l)}):l:a,k=ye(Ce,{children:[Q?p(Re,{active:J}):null,oe??p("p",{style:{padding:24},children:"Loading..."})]});return E?p(E.Provider,{value:O,children:k}):k}}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",a=Promise.resolve(he(r)).then(d=>(d?.head&&X(d.head),d)),s=_e(a,r);return ae(n,p(s,{}))}export{ke as mountWebframezClient,Ie as useCookie,Oe as useRouter};
package/dist/http.cjs CHANGED
@@ -36,6 +36,7 @@ var import_node_fs2 = __toESM(require("node:fs"), 1);
36
36
  var import_node_path3 = __toESM(require("node:path"), 1);
37
37
  var import_node_url = require("node:url");
38
38
  var import_node_child_process = require("node:child_process");
39
+ var import_node_zlib = require("node:zlib");
39
40
 
40
41
  // src/server.ts
41
42
  var import_node_path = __toESM(require("node:path"), 1);
@@ -792,7 +793,77 @@ function parseSearchParams(query) {
792
793
  function createInitialHtmlErrorMarkup(message) {
793
794
  return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
794
795
  }
796
+ function createClientAssetVersion(distRootDir) {
797
+ try {
798
+ const stat = import_node_fs2.default.statSync(import_node_path3.default.join(distRootDir, "client.js"));
799
+ return `${Math.floor(stat.mtimeMs)}-${stat.size}`;
800
+ } catch {
801
+ return "";
802
+ }
803
+ }
804
+ function appendAssetVersion(url, version) {
805
+ if (!version) {
806
+ return url;
807
+ }
808
+ const separator = url.includes("?") ? "&" : "?";
809
+ return `${url}${separator}v=${encodeURIComponent(version)}`;
810
+ }
811
+ function isWithinDirectory(filePath, directory) {
812
+ return filePath === directory || filePath.startsWith(`${directory}${import_node_path3.default.sep}`);
813
+ }
814
+ function isCompressibleAsset(ext) {
815
+ return [".js", ".mjs", ".json", ".css", ".svg", ".txt", ".html"].includes(ext);
816
+ }
817
+ function isHashedAssetPath(filePath) {
818
+ return /-[a-f0-9]{12,}\.[cm]?js$/i.test(import_node_path3.default.basename(filePath));
819
+ }
820
+ function setAssetContentType(res, ext) {
821
+ if (ext === ".js" || ext === ".mjs") {
822
+ res.setHeader("Content-Type", "text/javascript; charset=utf-8");
823
+ } else if (ext === ".json") {
824
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
825
+ } else if (ext === ".css") {
826
+ res.setHeader("Content-Type", "text/css; charset=utf-8");
827
+ } else if (ext === ".svg") {
828
+ res.setHeader("Content-Type", "image/svg+xml; charset=utf-8");
829
+ }
830
+ }
831
+ function getPreferredContentEncoding(req, ext, fileSize) {
832
+ if (!isCompressibleAsset(ext) || fileSize < 1024) {
833
+ return "";
834
+ }
835
+ const acceptEncoding = String(req.headers["accept-encoding"] || "");
836
+ if (/\bbr\b/.test(acceptEncoding)) {
837
+ return "br";
838
+ }
839
+ if (/\bgzip\b/.test(acceptEncoding)) {
840
+ return "gzip";
841
+ }
842
+ return "";
843
+ }
844
+ function sendTextResponse(req, res, body, options) {
845
+ const bodyBuffer = Buffer.from(body);
846
+ const contentEncoding = options.compress === false ? "" : getPreferredContentEncoding(req, ".html", bodyBuffer.length);
847
+ res.statusCode = options.statusCode ?? 200;
848
+ res.setHeader("Content-Type", options.contentType);
849
+ if (options.cacheControl) {
850
+ res.setHeader("Cache-Control", options.cacheControl);
851
+ }
852
+ res.setHeader("Vary", "Accept-Encoding");
853
+ if (contentEncoding === "br") {
854
+ res.setHeader("Content-Encoding", "br");
855
+ res.end((0, import_node_zlib.brotliCompressSync)(bodyBuffer));
856
+ return;
857
+ }
858
+ if (contentEncoding === "gzip") {
859
+ res.setHeader("Content-Encoding", "gzip");
860
+ res.end((0, import_node_zlib.gzipSync)(bodyBuffer));
861
+ return;
862
+ }
863
+ res.end(bodyBuffer);
864
+ }
795
865
  var INITIAL_HTML_WORKER_SCRIPT = `
866
+ const fs = require("node:fs");
796
867
  const path = require("node:path");
797
868
  const Module = require("node:module");
798
869
  const { Readable, Writable } = require("node:stream");
@@ -842,11 +913,42 @@ const reactDomServer = require(path.join(path.dirname(reactDomPkg), "server.node
842
913
  globalThis.__webpack_chunk_load__ = function __webframezNoopChunkLoad() {
843
914
  return Promise.resolve();
844
915
  };
916
+ function normalizeWebframezRequireCandidate(candidate) {
917
+ const stagingMarker = path.join(".webframez-build", "");
918
+ const appMarker = path.join("app", "");
919
+ const stagingIndex = candidate.indexOf(stagingMarker);
920
+ const appIndex = candidate.indexOf(appMarker, stagingIndex >= 0 ? stagingIndex : 0);
921
+ if (stagingIndex >= 0 && appIndex >= 0) {
922
+ const runtimeCandidate = path.resolve(process.cwd(), candidate.slice(appIndex));
923
+ if (fs.existsSync(runtimeCandidate)) {
924
+ return runtimeCandidate;
925
+ }
926
+ }
927
+
928
+ const frameworkDistDir = path.join("node_modules", "@webtypen", "webframez-react", "dist");
929
+ const shouldUseCjs =
930
+ candidate.includes(frameworkDistDir) &&
931
+ (candidate.endsWith(path.join("dist", "navigation.js")) ||
932
+ candidate.endsWith(path.join("dist", "route-slot.js")));
933
+
934
+ if (!shouldUseCjs) {
935
+ return candidate;
936
+ }
937
+
938
+ const cjsCandidate = candidate.slice(0, -3) + ".cjs";
939
+ return fs.existsSync(cjsCandidate) ? cjsCandidate : candidate;
940
+ }
941
+
845
942
  globalThis.__webpack_require__ = function __webframezNodeRequire(id) {
846
943
  if (typeof id !== "string") {
847
944
  return require(id);
848
945
  }
849
946
 
947
+ const directRequireTarget = normalizeWebframezRequireCandidate(id);
948
+ if (directRequireTarget !== id) {
949
+ return require(directRequireTarget);
950
+ }
951
+
850
952
  if (id.startsWith("./")) {
851
953
  const relativeId = id.slice(2);
852
954
  const candidates = [
@@ -854,10 +956,16 @@ globalThis.__webpack_require__ = function __webframezNodeRequire(id) {
854
956
  path.resolve(process.cwd(), "..", relativeId)
855
957
  ];
856
958
  for (const candidate of candidates) {
959
+ const requireTarget = normalizeWebframezRequireCandidate(candidate);
857
960
  try {
858
- return require(candidate);
961
+ return require(requireTarget);
859
962
  } catch (error) {
860
- const missingCandidate = error && error.code === "MODULE_NOT_FOUND" && typeof error.message === "string" && error.message.includes("'" + candidate + "'");
963
+ const missingCandidate =
964
+ error &&
965
+ error.code === "MODULE_NOT_FOUND" &&
966
+ typeof error.message === "string" &&
967
+ (error.message.includes("'" + candidate + "'") ||
968
+ error.message.includes("'" + requireTarget + "'"));
861
969
  if (!missingCandidate) {
862
970
  throw error;
863
971
  }
@@ -1079,6 +1187,14 @@ function joinRuntimeBasePath(basePath, pathname) {
1079
1187
  }
1080
1188
  return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1081
1189
  }
1190
+ function joinRuntimeAssetPath(basePath, pathname) {
1191
+ const normalizedBasePath = normalizeRuntimeBasePath(basePath) ?? "";
1192
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1193
+ if (normalizedBasePath && (normalizedPath === normalizedBasePath || normalizedPath.startsWith(`${normalizedBasePath}/`))) {
1194
+ return normalizedPath;
1195
+ }
1196
+ return joinRuntimeBasePath(normalizedBasePath, normalizedPath);
1197
+ }
1082
1198
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1083
1199
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1084
1200
  return "";
@@ -1273,6 +1389,18 @@ function createServerConsumerManifest(manifest) {
1273
1389
  const consumerManifest = {};
1274
1390
  const normalizeWorkerModuleId = (requestKey, rawModuleId) => {
1275
1391
  if (typeof rawModuleId === "string" && rawModuleId.trim() !== "") {
1392
+ const isStagingModuleId = rawModuleId.startsWith("./.webframez-build/") || rawModuleId.includes(`${import_node_path3.default.sep}.webframez-build${import_node_path3.default.sep}`);
1393
+ const isRuntimeBuildKey = requestKey.startsWith("file://") || requestKey.startsWith("/") && requestKey.includes(`${import_node_path3.default.sep}build${import_node_path3.default.sep}app${import_node_path3.default.sep}`);
1394
+ if (isStagingModuleId && isRuntimeBuildKey) {
1395
+ if (requestKey.startsWith("file://")) {
1396
+ try {
1397
+ return (0, import_node_url.fileURLToPath)(requestKey);
1398
+ } catch {
1399
+ return rawModuleId;
1400
+ }
1401
+ }
1402
+ return requestKey;
1403
+ }
1276
1404
  return rawModuleId;
1277
1405
  }
1278
1406
  if (typeof rawModuleId !== "number" || !Number.isFinite(rawModuleId)) {
@@ -1354,6 +1482,14 @@ function createServerConsumerManifest(manifest) {
1354
1482
  name: exportName
1355
1483
  });
1356
1484
  }
1485
+ } else if (typeof entry.id === "string" && entry.id.trim() !== "") {
1486
+ addReference(entry.id, "*", reference);
1487
+ for (const exportName of exportNames) {
1488
+ addReference(entry.id, exportName, {
1489
+ ...reference,
1490
+ name: exportName
1491
+ });
1492
+ }
1357
1493
  }
1358
1494
  }
1359
1495
  return consumerManifest;
@@ -1468,24 +1604,49 @@ function createNodeRequestHandler(options) {
1468
1604
  if (url.pathname.startsWith(assetsPrefix)) {
1469
1605
  const relative = url.pathname.slice(assetsPrefix.length);
1470
1606
  const filePath = import_node_path3.default.resolve(distRootDir, relative);
1471
- if (!filePath.startsWith(distRootDir)) {
1607
+ if (!isWithinDirectory(filePath, distRootDir)) {
1472
1608
  res.statusCode = 400;
1473
1609
  res.end("Invalid path");
1474
1610
  return;
1475
1611
  }
1476
1612
  const ext = import_node_path3.default.extname(filePath);
1477
- if (ext === ".js" || ext === ".mjs") {
1478
- res.setHeader("Content-Type", "text/javascript; charset=utf-8");
1479
- } else if (ext === ".json") {
1480
- res.setHeader("Content-Type", "application/json; charset=utf-8");
1613
+ let stat;
1614
+ try {
1615
+ stat = import_node_fs2.default.statSync(filePath);
1616
+ if (!stat.isFile()) {
1617
+ throw new Error("Asset path is not a file");
1618
+ }
1619
+ } catch {
1620
+ res.statusCode = 404;
1621
+ res.end("Not found");
1622
+ return;
1481
1623
  }
1482
- res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
1624
+ setAssetContentType(res, ext);
1625
+ const isDevelopmentAsset = nodeEnv !== "production";
1626
+ const isVersionedClientAsset = import_node_path3.default.basename(filePath) === "client.js" && url.searchParams.has("v");
1627
+ const canCacheLongTerm = !isDevelopmentAsset && (isHashedAssetPath(filePath) || isVersionedClientAsset);
1628
+ res.setHeader(
1629
+ "Cache-Control",
1630
+ canCacheLongTerm ? "public, max-age=31536000, immutable" : "no-store, no-cache, must-revalidate, proxy-revalidate"
1631
+ );
1632
+ res.setHeader("Vary", "Accept-Encoding");
1633
+ const contentEncoding = !isDevelopmentAsset ? getPreferredContentEncoding(req, ext, stat.size) : "";
1483
1634
  const stream = import_node_fs2.default.createReadStream(filePath);
1484
1635
  stream.on("error", () => {
1485
- res.statusCode = 404;
1636
+ if (!res.headersSent) {
1637
+ res.statusCode = 404;
1638
+ }
1486
1639
  res.end("Not found");
1487
1640
  });
1488
- stream.pipe(res);
1641
+ if (contentEncoding === "br") {
1642
+ res.setHeader("Content-Encoding", "br");
1643
+ stream.pipe((0, import_node_zlib.createBrotliCompress)()).pipe(res);
1644
+ } else if (contentEncoding === "gzip") {
1645
+ res.setHeader("Content-Encoding", "gzip");
1646
+ stream.pipe((0, import_node_zlib.createGzip)()).pipe(res);
1647
+ } else {
1648
+ stream.pipe(res);
1649
+ }
1489
1650
  return;
1490
1651
  }
1491
1652
  const resolved = await withRequestBasename(
@@ -1503,22 +1664,23 @@ function createNodeRequestHandler(options) {
1503
1664
  );
1504
1665
  const initialPayload = {
1505
1666
  model: resolved.model,
1506
- contextModel: resolved.contextModel,
1507
- pageModel: resolved.pageModel,
1508
1667
  head: resolved.head
1509
1668
  };
1510
1669
  const initialFlightData = await renderRSCToString(initialPayload, {
1511
1670
  moduleMap
1512
1671
  });
1513
1672
  const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1514
- const shellClientScriptUrl = joinRuntimeBasePath(
1515
- transportBasePath,
1516
- "/assets/client.js"
1673
+ const shellClientScriptUrl = appendAssetVersion(
1674
+ joinRuntimeAssetPath(
1675
+ transportBasePath,
1676
+ clientScriptUrl
1677
+ ),
1678
+ createClientAssetVersion(distRootDir)
1517
1679
  );
1518
1680
  const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1519
1681
  const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1520
1682
  const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1521
- let rootHtml = "";
1683
+ let rootHtml;
1522
1684
  try {
1523
1685
  rootHtml = await initialHtmlWorker.renderFromFlightData({
1524
1686
  flightData: initialFlightData,
@@ -1542,29 +1704,23 @@ function createNodeRequestHandler(options) {
1542
1704
  });
1543
1705
  } catch (flightRenderError) {
1544
1706
  console.error("[webframez-react] Flight-to-HTML render failed", flightRenderError);
1545
- res.statusCode = 500;
1546
- res.setHeader("Content-Type", "text/html");
1547
- res.end(
1548
- createHTMLShell({
1549
- title: "500 - Initial HTML render failed",
1550
- headTags: "",
1551
- clientScriptUrl: shellClientScriptUrl,
1552
- rscEndpoint: shellRscEndpoint,
1553
- rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1554
- initialFlightData,
1555
- basename: shellBasename,
1556
- routeBasePath: shellRouteBasePath,
1557
- liveReloadPath: liveReloadPath || void 0,
1558
- liveReloadServerId: liveReloadPath ? devServerId : void 0
1559
- })
1707
+ sendTextResponse(
1708
+ req,
1709
+ res,
1710
+ createInitialHtmlErrorMarkup("Failed to render initial React HTML."),
1711
+ {
1712
+ statusCode: 500,
1713
+ contentType: "text/html; charset=utf-8",
1714
+ compress: nodeEnv === "production"
1715
+ }
1560
1716
  );
1561
1717
  return;
1562
1718
  }
1563
1719
  }
1564
1720
  }
1565
- res.statusCode = resolved.statusCode;
1566
- res.setHeader("Content-Type", "text/html");
1567
- res.end(
1721
+ sendTextResponse(
1722
+ req,
1723
+ res,
1568
1724
  createHTMLShell({
1569
1725
  title: resolved.head.title || "Webframez React",
1570
1726
  headTags: renderHeadToString(resolved.head),
@@ -1576,7 +1732,13 @@ function createNodeRequestHandler(options) {
1576
1732
  routeBasePath: shellRouteBasePath,
1577
1733
  liveReloadPath: liveReloadPath || void 0,
1578
1734
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1579
- })
1735
+ }),
1736
+ {
1737
+ statusCode: resolved.statusCode,
1738
+ contentType: "text/html; charset=utf-8",
1739
+ cacheControl: "no-store, no-cache, must-revalidate, proxy-revalidate",
1740
+ compress: nodeEnv === "production"
1741
+ }
1580
1742
  );
1581
1743
  };
1582
1744
  }