what-server 0.13.8 → 0.13.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.min.js CHANGED
@@ -1,18 +1,18 @@
1
- import{h as re,_isAriaAttr as dt,_beginComponentSSR as ne,_endComponentSSR as oe,_mapArrayToArray as ae,getServerContext as ke,runWithServerContext as S,beginHeadCollection as ft,endHeadCollection as se}from"what-core";var Pe=new RegExp("[<>&\\u2028\\u2029]","g"),Ie={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function W(e){return JSON.stringify(e).replace(Pe,t=>Ie[t.charCodeAt(0)])}import{mount as Ot,hydrate as $t,signal as Pt,batch as It,getServerContext as ve}from"what-core";var xe=new Map;function Ne(e){let t=e||ve();return t&&t.islandStores instanceof Map?t.islandStores:null}function ye(e){let t=typeof document<"u"?xe:Ne(e),r={};for(let[n,s]of t||[])r[n]=s._getSnapshot();return r}import{signal as R,batch as G}from"what-core";var H=Symbol.for("what.revalidationHandler"),me=!(typeof process<"u");function z(e){globalThis[H]=e}function De(){return globalThis[H]??null}async function X(e,t){let r=globalThis[H];if(r&&r.revalidatePath)return r.revalidatePath(e,t);me&&console.warn(`[what] revalidatePath('${e}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function Y(e,t){let r=globalThis[H];if(r&&r.revalidateTag)return r.revalidateTag(e,t);me&&console.warn(`[what] revalidateTag('${e}') had no effect: no cache engine is bound.`)}var K=new Map;function He(){if(typeof document<"u"){let e=document.querySelector('meta[name="what-csrf-token"]');if(e)return e.getAttribute("content");let t=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(t)return decodeURIComponent(t[1])}return null}function Z(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function ge(e,t){if(!e||!t||e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e.charCodeAt(n)^t.charCodeAt(n);return r===0}function Q(e){return`<meta name="what-csrf-token" content="${String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var je=0,Le=!1;function Me(){return!Le&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),t=>t.toString(16).padStart(2,"0")).join(""):`c${(++je).toString(36)}_${Date.now().toString(36)}`}`}function Fe(e,t={}){let r=t.id||Me(),{onError:n,onSuccess:s,revalidate:a}=t;typeof window>"u"&&K.set(r,{fn:e,options:t});async function o(...i){if(typeof window>"u")return e(...i);let c=t.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=He(),l={"Content-Type":"application/json","X-What-Action":r};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let w=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(w.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),a)for(let w of a)be(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${r}" timed out after ${c}ms`);throw l.code="TIMEOUT",n&&n(l),l}throw n&&n(f),f}finally{clearTimeout(d)}}return o._actionId=r,o._isAction=!0,o}function we(e,t={}){let{onSuccess:r,onError:n,resetOnSuccess:s=!0}=t;return async a=>{let o,i;a instanceof Event?(a.preventDefault(),i=a.target,o=new FormData(i)):o=a;let c={},u=!1;for(let[d,f]of o.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await e(c,o):await e(c);return r&&r(d,i),s&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function Se(e){let t=R(!1),r=R(null),n=R(null);async function s(...a){t.set(!0),r.set(null);try{let o=await e(...a);return n.set(o),o}catch(o){throw r.set(o),o}finally{t.set(!1)}}return{trigger:s,isPending:()=>t(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function Ue(e,t={}){let{resetOnSuccess:r=!0}=t,n={current:null},s=Se(we(e,{resetOnSuccess:r}));function a(o){o.preventDefault();let i=new FormData(o.target);return n.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:n}}function Be(e,t){let r=R(e),n=R([]),s=R(e);function a(u){let d=t(r.peek(),u);G(()=>{n.set([...n.peek(),u]),r.set(d)})}function o(u,d){G(()=>{if(n.set(n.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of n.peek())f=t(f,l);r.set(f)}})}function i(u,d){G(()=>{let f=n.peek().filter(h=>h!==u);n.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=t(p,h);r.set(p)})}async function c(u,d){a(u);try{let f=await d();return o(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{r.set(u),s.set(u)}}}var x=new Map;function Je(e,t){return x.has(e)||x.set(e,new Set),x.get(e).add(t),()=>{x.get(e)?.delete(t)}}function be(e){let t=x.get(e);if(t)for(let r of t)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function j(e,t,r,n={}){let{csrfToken:s,skipCsrf:a=!1}=n;if(!a){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=e?.headers?.["x-csrf-token"]||e?.headers?.["X-CSRF-Token"];if(!ge(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=K.get(t);return o?Array.isArray(r)?o.fn(...r).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await X(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await Y(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${t}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Ve(){return[...K.keys()]}function We(e,t={}){let{onSuccess:r,onError:n,onSettled:s}=t,a={isPending:R(!1),error:R(null),data:R(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await e(...i);return a.data.set(c),r&&r(c,...i),c}catch(c){throw a.error.set(c),n&&n(c,...i),c}finally{a.isPending.set(!1),s&&s(a.data.peek(),a.error.peek(),...i)}}return{mutate:o,isPending:()=>a.isPending(),error:()=>a.error(),data:()=>a.data(),reset:()=>{a.error.set(null),a.data.set(null)}}}import{h as L}from"what-core";var _e="/__what_action";function ze(e){if(typeof e=="string")return e;if(typeof e=="function"){let t=e._actionId;if(t)return t;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function Xe(){if(typeof document>"u")return null;let e=document.querySelector('meta[name="what-csrf-token"]');if(e)return e.getAttribute("content");let t=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return t?decodeURIComponent(t[1]):null}function Ye({action:e,csrfToken:t,redirect:r,method:n="post",enhance:s=!0,children:a,...o}){let i=ze(e),c=t!==void 0?t:Xe();c==null&&typeof process<"u";let u=[L("input",{type:"hidden",name:"_action",value:i}),L("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(L("input",{type:"hidden",name:"_redirect",value:r}));let d={...o,method:n,action:o.action||_e,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return L("form",d,...u,...f)}var Ge="/__what_action",Ae=1024*1024;function Ke(e){if(!e)return{};if(typeof e.forEach=="function"&&typeof e.get=="function"){let r={};return e.forEach((n,s)=>{r[s.toLowerCase()]=n}),r}let t={};for(let r in e)t[r.toLowerCase()]=e[r];return t}function M(e,t){return{status:e,headers:{"content-type":"application/json"},body:JSON.stringify(t)}}function q(e,t){return{status:e,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${e}</h1><p>${String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</p></body></html>`}}function Re(e){if(typeof e!="string"||!e.startsWith("/")||/^[/\\]{2}/.test(e)||e.includes("\\"))return null;try{let t=new URL(e,"http://localhost");return t.origin!=="http://localhost"?null:t.pathname+t.search}catch{return null}}function Ze(e,t){let r=Re(e&&e._redirect);if(r)return r;let n=t.referer||t.referrer;if(n)try{let s=new URL(n,"http://localhost"),a=Re(s.pathname+s.search);if(a)return a}catch{}return"/"}var Qe=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function N(e={}){let{getCsrfToken:t,skipCsrf:r=!1}=e;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return M(405,{message:"Method Not Allowed"});let o=Ke(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=r?void 0:t?await t(s):void 0;if(u){let h=s.body||{},w=h._action||h["data-action"]||s.query&&s.query.action;if(!w)return q(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let _={...o},C=h._csrf??h["what-csrf-token"];if(C&&!_["x-csrf-token"]&&(_["x-csrf-token"]=String(C)),!r&&t&&!d)return q(403,"Missing CSRF token");let O={};for(let[$,B]of Object.entries(h))Qe.has($)||(O[$]=B);let k=await j({headers:_},w,[O],{csrfToken:d,skipCsrf:r});return k.status===200?{status:303,headers:{location:Ze(h,o)},body:""}:q(k.status,k.body&&k.body.message||"Action failed")}if(!i)return M(400,{message:"Missing X-What-Action header"});if(!r&&t&&!d)return M(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await j({headers:o},i,l,{csrfToken:d,skipCsrf:r});return M(p.status,p.body)}}function qe(e={}){let t=e.basePath||Ge,r=N(e);return async function(s,a,o){let[i,c]=(s.url||"").split("?");if(i!==t||(s.method||"").toUpperCase()!=="POST")return o?o():void 0;let u;try{let l=await et(s);u=F(l,s.headers["content-type"]||"")}catch(l){a.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),a.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await r({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function F(e,t){if((t||"").includes("application/x-www-form-urlencoded")){let r={};for(let[n,s]of new URLSearchParams(String(e)))r[n]===void 0?r[n]=s:Array.isArray(r[n])?r[n].push(s):r[n]=[r[n],s];return r}return e==null||e===""?{}:JSON.parse(String(e))}async function U(e,t=Ae){let r=Number(e.headers.get("content-length"));if(Number.isFinite(r)&&r>t)return{tooLarge:!0};let n=e.body;if(!n||typeof n.getReader!="function"){let i=await e.text();return Buffer.byteLength(i,"utf8")>t?{tooLarge:!0}:{raw:i}}let s=n.getReader(),a=[],o=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(o+=c.byteLength,o>t){try{await s.cancel()}catch{}return{tooLarge:!0}}a.push(c)}}return{raw:Buffer.concat(a.map(i=>Buffer.from(i))).toString("utf8")}}function et(e){return new Promise((t,r)=>{let n=0,s=[];e.on("data",a=>{if(n+=a.length,n>Ae){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",r(o),e.destroy?.();return}s.push(a)}),e.on("end",()=>{if(s.length===0)return t("");t(Buffer.concat(s).toString("utf8"))}),e.on("error",r)})}function tt(e={}){let t=N(e);return async function(r){let n={};try{let o=await U(r);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=F(o.raw,r.headers.get("content-type")||"")}catch{n={}}let s={};try{s=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let a=await t({method:r.method,headers:r.headers,body:n,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as rt,parseQuery as nt}from"what-router/match";var ot="/__what_action",at="/__what_revalidate",ee="what-csrf";function D(e){let t={};return e&&typeof e.forEach=="function"&&e.forEach((r,n)=>{t[n.toLowerCase()]=r}),t}function Ee(e,t){if(!e)return null;let r=String(e).match(new RegExp(`(?:^|;\\s*)${t}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function st(e){try{let t=await U(e);return t.tooLarge?{tooLarge:!0}:F(t.raw,e.headers.get("content-type")||"")}catch{return{}}}async function it(e){let t;try{t=await U(e)}catch{return{json:{}}}if(t.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(t.raw??"")}}catch{return{json:{}}}}function ct(e){return async function(r){let{route:n,params:s,query:a,request:o,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:s,query:a,request:o,csrfToken:i}:{params:s,query:a,request:o},d=i?{...e,csrfToken:i}:e;return{html:await Te(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function te(e={}){let{routes:t=[],cache:r,render:n,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=e,u=c!==!1&&!e.actionHandler,d=e.actionHandler||N(u?{getCsrfToken:l=>Ee(l.headers&&l.headers.cookie,ee)}:{skipCsrf:!0}),f=n||ct(a);return r&&(r.revalidatePath||r.revalidateTag)&&z({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),w=h.pathname;if(i&&w.startsWith(i)&&(w=w.slice(i.length)||"/"),p.method==="POST"&&w===ot){let m=await st(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await d({method:"POST",headers:D(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(E.body,{status:E.status,headers:E.headers})}let _=null,C=null;if(u&&(_=Ee(D(p.headers).cookie,ee),!_)){_=Z();let E=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${ee}=${encodeURIComponent(_)}; Path=/; SameSite=Lax`+(E?"; Secure":"")}let O=m=>(C&&(m["set-cookie"]=C),m);if(p.method==="POST"&&w===at&&s){let m=await it(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await s({headers:D(p.headers),body:m.json});return new Response(JSON.stringify(E.body),{status:E.status,headers:{"content-type":"application/json"}})}let k=rt(w,t);if(!k){let m=o?o():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(m,{status:404,headers:O({"content-type":"text/html; charset=utf-8"})})}let{route:$,params:B}=k,J=$.page||{mode:$.mode||"client"},v={path:w,query:nt(h.search),config:J,route:$,params:B,request:p};if(r&&J.mode!=="server"){v.varyHeaders=D(p.headers);let m=await r.handle(v,()=>f(v));return new Response(m.html,{status:m.status||200,headers:O({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}_&&(v.csrfToken=_);let V=await f(v),he=O({"content-type":"text/html; charset=utf-8",...V.headers||{}});return J.mode==="server"&&(he["Cache-Control"]="private, no-store"),new Response(V.html,{status:V.status||200,headers:he})}}function ut(e={}){let t=te(e);return{async fetch(r,n,s){return n&&(r.__env=n),s&&(r.__ctx=s),t(r)}}}function T(e){return{head:ft(),loaderData:e,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var Ce=0;function lt(){Ce=0}function pt(){return"h"+Ce++}function ht(e){if(!ke()){let t=T(void 0);return S(t,()=>ht(e))}return lt(),A(e)}var Oe=new Set(["__errorBoundary","__suspense"]),ie=new Set(["__portal"]);function ce(e){let t=e.children;return!t||t.length===0?{...e.props}:{...e.props,children:t}}function ue(e,t){let r=e.props&&e.props.fallback;if(typeof r!="function")return r;let n=e.props&&e.props.reset||(()=>{});try{return r({error:t,reset:n})}catch(s){return b(s),I&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function A(e){if(e==null||e===!1||e===!0)return"";if(typeof e=="string"||typeof e=="number")return g(String(e));if(typeof e=="function"&&e._signal)return`<!--$-->${A(e())}<!--/$-->`;if(typeof e=="function"&&e._mapArray)try{return`<!--$-->${A(ae(e))}<!--/$-->`}catch(c){return b(c),typeof process<"u","<!--$--><!--/$-->"}if(typeof e=="function")try{return`<!--$-->${A(e())}<!--/$-->`}catch(c){return b(c),typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(e))return`<!--[]-->${e.map(A).join("")}<!--/[]-->`;if(ie.has(e.tag))return"";if(Oe.has(e.tag))try{return(e.children||[]).map(A).join("")}catch(c){b(c);let u=c&&typeof c.then=="function";if(u&&e.tag==="__errorBoundary"||!u&&e.tag==="__suspense")throw c;return A(ue(e,u?null:c))}if(typeof e.tag=="function"){let c=pt(),u=ne(e.tag),d;try{d=A(e.tag(ce(e)))}finally{oe(u)}return yt(d,c)}let{tag:t,props:r,children:n}=e;fe(t,e);let s=le(r||{}),a=`<${t}${s}>`;if(pe.has(t))return a;let o=de(r),i=o!=null?String(o):n.map(A).join("");return`${a}${i}</${t}>`}function yt(e,t){let r=e.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],s=r[2],a=n.length+1+s.length,o=e.indexOf(">",a),i=e.slice(a,o===-1?void 0:o);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?e:e.slice(0,a)+` data-hk="${t}"`+e.slice(a)}return e}function y(e){if(!ke()){let c=T(void 0);return S(c,()=>y(e))}if(e==null||e===!1||e===!0)return"";if(typeof e=="string"||typeof e=="number")return g(String(e));if(typeof e=="function"&&e._signal)return y(e());if(typeof e=="function"&&e._mapArray)try{return y(ae(e))}catch(c){return b(c),typeof process<"u",""}if(typeof e=="function")try{return y(e())}catch(c){return b(c),typeof process<"u",""}if(Array.isArray(e))return e.map(y).join("");if(ie.has(e.tag))return"";if(Oe.has(e.tag))try{return(e.children||[]).map(y).join("")}catch(c){b(c);let u=c&&typeof c.then=="function";if(u&&e.tag==="__errorBoundary"||!u&&e.tag==="__suspense")throw c;return y(ue(e,u?null:c))}if(typeof e.tag=="function"){let c=ne(e.tag);try{return y(e.tag(ce(e)))}finally{oe(c)}}let{tag:t,props:r,children:n}=e;fe(t,e);let s=le(r||{}),a=`<${t}${s}>`;if(pe.has(t))return a;let o=de(r),i=o!=null?String(o):n.map(y).join("");return`${a}${i}</${t}>`}function qt(e){let t=T(void 0);return{body:S(t,()=>y(e)),head:se(t.head)}}async function er(e,t={}){let r=e.default||e,n=typeof e.loader=="function"?await e.loader(t):void 0,s=T(n),a=t.params||{};return{body:S(s,()=>y(re(r,{...a,loaderData:n}))),head:se(s.head),loaderData:n}}var $e=12;async function mt(e,t){t||(t=T(void 0));let r="",n=t.resourceCounter;for(let a=0;a<$e;a++){t.resourceCounter=n,r=S(t,()=>y(e));let o=[...t.resources.values()].filter(i=>i.status==="pending").map(i=>i.promise);if(o.length===0)break;await Promise.all(o)}let s={};for(let[a,o]of t.resources)o.status==="ready"&&(s[a]=o.value);return{body:r,head:se(t.head),loaderData:t.loaderData,resources:s,ctx:t}}async function Te(e,t={},r={}){let n=e.default||e,s=typeof e.loader=="function"?await e.loader(t):void 0,a=T(s),o=t.params||{},{body:i,head:c,resources:u}=await mt(re(n,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:ye(a)};return gt({body:i,head:c,payload:d,options:r})}function gt({body:e,head:t,payload:r,options:n={}}){let s=n.lang||"en",a=`<script id="__what_data" type="application/json">${W(r)}<\/script>`,o=n.clientEntry?`<script type="module" src="${g(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?Q(n.csrfToken):"")+(n.head||""),u=n.bodyClass?` class="${g(n.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${t||""}${c}</head><body${u}>${e}${a}${o}</body></html>`}async function*P(e,t){if(t===void 0&&(t=T(void 0)),e==null||e===!1||e===!0)return;if(typeof e=="string"||typeof e=="number"){yield g(String(e));return}if(typeof e=="function"&&e._signal){let o=S(t,()=>e());yield*P(o,t);return}if(typeof e=="function"&&e._mapArray){let o=null;try{o=S(t,()=>ae(e))}catch(i){b(i),typeof process<"u"}o&&(yield*P(o,t));return}if(typeof e=="function"){try{let o=S(t,()=>e());yield*P(o,t)}catch(o){b(o),typeof process<"u"}return}if(Array.isArray(e)){for(let o of e)yield*P(o,t);return}if(ie.has(e.tag))return;if(e.tag==="__errorBoundary"){let o;try{o=S(t,()=>(e.children||[]).map(y).join(""))}catch(i){if(b(i),i&&typeof i.then=="function")throw i;o=S(t,()=>y(ue(e,i)))}yield o;return}if(e.tag==="__suspense"){let o=null,i=t.resourceCounter;for(let c=0;c<$e&&o===null;c++){t.resourceCounter=i;let u=null;try{o=S(t,()=>(e.children||[]).map(y).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(o===null){let d=[...t.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}o===null&&(o=S(t,()=>y(e.props&&e.props.fallback))),yield o;return}if(typeof e.tag=="function"){let o=ne(e.tag);try{let i=S(t,()=>e.tag(ce(e))),c=i instanceof Promise?await i:i;yield*P(c,t)}catch(i){b(i),typeof process<"u",yield I?`<!-- SSR Error: ${g(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{oe(o)}return}let{tag:r,props:n,children:s}=e;fe(r,e);let a=le(n||{});if(yield`<${r}${a}>`,!pe.has(r)){let o=de(n);if(o!=null)yield String(o);else for(let i of s)yield*P(i,t);yield`</${r}>`}}function tr(e){return{mode:"static",...e}}function rr(e,t={}){let r=T(t),n=S(r,()=>y(re(e.component,t))),s=e.islands||[];return wt({title:e.title||"",meta:e.meta||{},body:n,islands:s,scripts:e.mode==="static"?[]:e.scripts||[],styles:e.styles||[],mode:e.mode})}function wt({title:e,meta:t,body:r,islands:n,scripts:s,styles:a,mode:o}){let i=Object.entries(t).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
2
- `),c=a.map(l=>`<link rel="stylesheet" href="${g(l)}">`).join(`
3
- `),u=n.length>0?`
1
+ import{h as rt,_isAriaAttr as de,_beginComponentSSR as nt,_endComponentSSR as ot,_mapArrayToArray as at,getServerContext as kt,runWithServerContext as S,beginHeadCollection as fe,endHeadCollection as st}from"what-core";var It=new RegExp("[<>&\\u2028\\u2029]","g"),Pt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function W(t){return JSON.stringify(t).replace(It,e=>Pt[e.charCodeAt(0)])}import{mount as $e,hydrate as Ie,signal as Pe,batch as ve,getServerContext as vt}from"what-core";var xt=new Map;function Nt(t){let e=t||vt();return e&&e.islandStores instanceof Map?e.islandStores:null}function yt(t){let e=typeof document<"u"?xt:Nt(t),r={};for(let[a,o]of e||[])r[a]=o._getSnapshot();return r}import{signal as R,batch as G}from"what-core";var H=Symbol.for("what.revalidationHandler"),mt=!(typeof process<"u");function z(t){globalThis[H]=t}function Dt(){return globalThis[H]??null}async function X(t,e){let r=globalThis[H];if(r&&r.revalidatePath)return r.revalidatePath(t,e);mt&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function Y(t,e){let r=globalThis[H];if(r&&r.revalidateTag)return r.revalidateTag(t,e);mt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var K=new Map;function Ht(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function Z(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function gt(t,e){if(!t||!e||t.length!==e.length)return!1;let r=0;for(let a=0;a<t.length;a++)r|=t.charCodeAt(a)^e.charCodeAt(a);return r===0}function Q(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Lt=0,jt=!1;function Mt(){return!jt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Lt).toString(36)}_${Date.now().toString(36)}`}`}function Ft(t,e={}){let r=e.id||Mt(),{onError:a,onSuccess:o,revalidate:i}=e;typeof window>"u"&&K.set(r,{fn:t,options:e});async function n(...s){if(typeof window>"u")return t(...s);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Ht(),l={"Content-Type":"application/json","X-What-Action":r};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:s})});if(!p.ok){let w=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(w.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(o&&o(h),i)for(let w of i)bt(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${r}" timed out after ${c}ms`);throw l.code="TIMEOUT",a&&a(l),l}throw a&&a(f),f}finally{clearTimeout(d)}}return n._actionId=r,n._isAction=!0,n}function wt(t,e={}){let{onSuccess:r,onError:a,resetOnSuccess:o=!0}=e;return async i=>{let n,s;i instanceof Event?(i.preventDefault(),s=i.target,n=new FormData(s)):n=i;let c={},u=!1;for(let[d,f]of n.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,n):await t(c);return r&&r(d,s),o&&s&&s.reset(),d}catch(d){throw a&&a(d,s),d}}}function St(t){let e=R(!1),r=R(null),a=R(null);async function o(...i){e.set(!0),r.set(null);try{let n=await t(...i);return a.set(n),n}catch(n){throw r.set(n),n}finally{e.set(!1)}}return{trigger:o,isPending:()=>e(),error:()=>r(),data:()=>a(),reset:()=>{r.set(null),a.set(null)}}}function Ut(t,e={}){let{resetOnSuccess:r=!0}=e,a={current:null},o=St(wt(t,{resetOnSuccess:r}));function i(n){n.preventDefault();let s=new FormData(n.target);return a.current=n.target,o.trigger(s)}return{...o,handleSubmit:i,formRef:a}}function Bt(t,e){let r=R(t),a=R([]),o=R(t);function i(u){let d=e(r.peek(),u);G(()=>{a.set([...a.peek(),u]),r.set(d)})}function n(u,d){G(()=>{if(a.set(a.peek().filter(f=>f!==u)),d!==void 0){o.set(d);let f=d;for(let l of a.peek())f=e(f,l);r.set(f)}})}function s(u,d){G(()=>{let f=a.peek().filter(h=>h!==u);a.set(f);let l=d!==void 0?d:o.peek();o.set(l);let p=l;for(let h of f)p=e(p,h);r.set(p)})}async function c(u,d){i(u);try{let f=await d();return n(u,f),f}catch(f){throw s(u),f}}return{value:()=>r(),isPending:()=>a().length>0,addOptimistic:i,resolve:n,rollback:s,withOptimistic:c,set:u=>{r.set(u),o.set(u)}}}var x=new Map;function Jt(t,e){return x.has(t)||x.set(t,new Set),x.get(t).add(e),()=>{x.get(t)?.delete(e)}}function bt(t){let e=x.get(t);if(e)for(let r of e)try{r()}catch(a){console.error("[what] Revalidation error:",a)}}function L(t,e,r,a={}){let{csrfToken:o,skipCsrf:i=!1}=a;if(!i){if(!o)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let s=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!gt(s,o))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let n=K.get(e);return n?Array.isArray(r)?n.fn(...r).then(async s=>{let c=n.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await X(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await Y(u);return{status:200,body:s}}).catch(s=>(console.error(`[what] Action "${e}" error:`,s),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Vt(){return[...K.keys()]}function Wt(t,e={}){let{onSuccess:r,onError:a,onSettled:o}=e,i={isPending:R(!1),error:R(null),data:R(null)};async function n(...s){i.isPending.set(!0),i.error.set(null);try{let c=await t(...s);return i.data.set(c),r&&r(c,...s),c}catch(c){throw i.error.set(c),a&&a(c,...s),c}finally{i.isPending.set(!1),o&&o(i.data.peek(),i.error.peek(),...s)}}return{mutate:n,isPending:()=>i.isPending(),error:()=>i.error(),data:()=>i.data(),reset:()=>{i.error.set(null),i.data.set(null)}}}import{h as j}from"what-core";var _t="/__what_action";function zt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function Xt(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function Yt({action:t,csrfToken:e,redirect:r,method:a="post",enhance:o=!0,children:i,...n}){let s=zt(t),c=e!==void 0?e:Xt();c==null&&typeof process<"u";let u=[j("input",{type:"hidden",name:"_action",value:s}),j("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(j("input",{type:"hidden",name:"_redirect",value:r}));let d={...n,method:a,action:n.action||_t,"data-action":s};o&&(d["data-enhance"]="");let f=i==null?[]:Array.isArray(i)?i:[i];return j("form",d,...u,...f)}var Gt="/__what_action",At=1024*1024;function Kt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let r={};return t.forEach((a,o)=>{r[o.toLowerCase()]=a}),r}let e={};for(let r in t)e[r.toLowerCase()]=t[r];return e}function M(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function q(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</p></body></html>`}}function Rt(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function Zt(t,e){let r=Rt(t&&t._redirect);if(r)return r;let a=e.referer||e.referrer;if(a)try{let o=new URL(a,"http://localhost"),i=Rt(o.pathname+o.search);if(i)return i}catch{}return"/"}var Qt=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function N(t={}){let{getCsrfToken:e,skipCsrf:r=!1}=t;return async function(o){if((o.method||"POST").toUpperCase()!=="POST")return M(405,{message:"Method Not Allowed"});let n=Kt(o.headers),s=n["x-what-action"],c=n["content-type"]||"",u=!s&&c.includes("application/x-www-form-urlencoded"),d=r?void 0:e?await e(o):void 0;if(u){let h=o.body||{},w=h._action||h["data-action"]||o.query&&o.query.action;if(!w)return q(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let _={...n},C=h._csrf??h["what-csrf-token"];if(C&&!_["x-csrf-token"]&&(_["x-csrf-token"]=String(C)),!r&&e&&!d)return q(403,"Missing CSRF token");let O={};for(let[$,B]of Object.entries(h))Qt.has($)||(O[$]=B);let k=await L({headers:_},w,[O],{csrfToken:d,skipCsrf:r});return k.status===200?{status:303,headers:{location:Zt(h,n)},body:""}:q(k.status,k.body&&k.body.message||"Action failed")}if(!s)return M(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return M(403,{message:"Missing CSRF token"});let l=(o.body||{}).args,p=await L({headers:n},s,l,{csrfToken:d,skipCsrf:r});return M(p.status,p.body)}}function qt(t={}){let e=t.basePath||Gt,r=N(t);return async function(o,i,n){let[s,c]=(o.url||"").split("?");if(s!==e||(o.method||"").toUpperCase()!=="POST")return n?n():void 0;let u;try{let l=await te(o);u=F(l,o.headers["content-type"]||"")}catch(l){i.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),i.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await r({method:o.method,headers:o.headers,body:u,query:d});i.writeHead(f.status,f.headers),i.end(f.body)}}function F(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let r={};for(let[a,o]of new URLSearchParams(String(t)))r[a]===void 0?r[a]=o:Array.isArray(r[a])?r[a].push(o):r[a]=[r[a],o];return r}return t==null||t===""?{}:JSON.parse(String(t))}async function U(t,e=At){let r=Number(t.headers.get("content-length"));if(Number.isFinite(r)&&r>e)return{tooLarge:!0};let a=t.body;if(!a||typeof a.getReader!="function"){let s=await t.text();return Buffer.byteLength(s,"utf8")>e?{tooLarge:!0}:{raw:s}}let o=a.getReader(),i=[],n=0;for(;;){let{done:s,value:c}=await o.read();if(s)break;if(c){if(n+=c.byteLength,n>e){try{await o.cancel()}catch{}return{tooLarge:!0}}i.push(c)}}return{raw:Buffer.concat(i.map(s=>Buffer.from(s))).toString("utf8")}}function te(t){return new Promise((e,r)=>{let a=0,o=[];t.on("data",i=>{if(a+=i.length,a>At){let n=new Error("Body too large");n.code="BODY_TOO_LARGE",r(n),t.destroy?.();return}o.push(i)}),t.on("end",()=>{if(o.length===0)return e("");e(Buffer.concat(o).toString("utf8"))}),t.on("error",r)})}function ee(t={}){let e=N(t);return async function(r){let a={};try{let n=await U(r);if(n.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});a=F(n.raw,r.headers.get("content-type")||"")}catch{a={}}let o={};try{o=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let i=await e({method:r.method,headers:r.headers,body:a,query:o});return new Response(i.body,{status:i.status,headers:i.headers})}}import{matchRoute as re,parseQuery as ne}from"what-router/match";var oe="/__what_action",ae="/__what_revalidate",tt="what-csrf";function D(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((r,a)=>{e[a.toLowerCase()]=r}),e}function Et(t,e){if(!t)return null;let r=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function se(t){try{let e=await U(t);return e.tooLarge?{tooLarge:!0}:F(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function ie(t){let e;try{e=await U(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ce(t){return async function(r){let{route:a,params:o,query:i,request:n,csrfToken:s}=r,c={default:a.component,loader:a.loader},u=s?{params:o,query:i,request:n,csrfToken:s}:{params:o,query:i,request:n},d=s?{...t,csrfToken:s}:t;return{html:await Tt(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function et(t={}){let{routes:e=[],cache:r,render:a,revalidateWebhook:o,document:i={},notFound:n,basePath:s="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||N(u?{getCsrfToken:l=>Et(l.headers&&l.headers.cookie,tt)}:{skipCsrf:!0}),f=a||ce(i);return r&&(r.revalidatePath||r.revalidateTag)&&z({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),w=h.pathname;if(s&&w.startsWith(s)&&(w=w.slice(s.length)||"/"),p.method==="POST"&&w===oe){let m=await se(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await d({method:"POST",headers:D(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(E.body,{status:E.status,headers:E.headers})}let _=null,C=null;if(u&&(_=Et(D(p.headers).cookie,tt),!_)){_=Z();let E=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${tt}=${encodeURIComponent(_)}; Path=/; SameSite=Lax`+(E?"; Secure":"")}let O=m=>(C&&(m["set-cookie"]=C),m);if(p.method==="POST"&&w===ae&&o){let m=await ie(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await o({headers:D(p.headers),body:m.json});return new Response(JSON.stringify(E.body),{status:E.status,headers:{"content-type":"application/json"}})}let k=re(w,e);if(!k){let m=n?n():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(m,{status:404,headers:O({"content-type":"text/html; charset=utf-8"})})}let{route:$,params:B}=k,J=$.page||{mode:$.mode||"client"},v={path:w,query:ne(h.search),config:J,route:$,params:B,request:p};if(r&&J.mode!=="server"){v.varyHeaders=D(p.headers);let m=await r.handle(v,()=>f(v));return new Response(m.html,{status:m.status||200,headers:O({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}_&&(v.csrfToken=_);let V=await f(v),ht=O({"content-type":"text/html; charset=utf-8",...V.headers||{}});return J.mode==="server"&&(ht["Cache-Control"]="private, no-store"),new Response(V.html,{status:V.status||200,headers:ht})}}function ue(t={}){let e=et(t);return{async fetch(r,a,o){return a&&(r.__env=a),o&&(r.__ctx=o),e(r)}}}function T(t){return{head:fe(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var Ct=0;function le(){Ct=0}function pe(){return"h"+Ct++}function he(t){if(!kt()){let e=T(void 0);return S(e,()=>he(t))}return le(),A(t)}var Ot=new Set(["__errorBoundary","__suspense"]),it=new Set(["__portal"]);function ct(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function ut(t,e){let r=t.props&&t.props.fallback;if(typeof r!="function")return r;let a=t.props&&t.props.reset||(()=>{});try{return r({error:e,reset:a})}catch(o){return b(o),P&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${o.message}`),null}}function A(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${A(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${A(at(t))}<!--/$-->`}catch(c){return b(c),typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${A(t())}<!--/$-->`}catch(c){return b(c),typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(A).join("")}<!--/[]-->`;if(it.has(t.tag))return"";if(Ot.has(t.tag))try{return(t.children||[]).map(A).join("")}catch(c){b(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return A(ut(t,u?null:c))}if(typeof t.tag=="function"){let c=pe(),u=nt(t.tag),d;try{d=A(t.tag(ct(t)))}finally{ot(u)}return ye(d,c)}let{tag:e,props:r,children:a}=t;ft(e,t);let o=lt(r||{}),i=`<${e}${o}>`;if(pt.has(e))return i;let n=dt(r),s=n!=null?String(n):a.map(A).join("");return`${i}${s}</${e}>`}function ye(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let a=r[1],o=r[2],i=a.length+1+o.length,n=t.indexOf(">",i),s=t.slice(i,n===-1?void 0:n);return/[\s"']data-hk\s*=/.test(s)||/^\s*data-hk\s*=/.test(s)?t:t.slice(0,i)+` data-hk="${e}"`+t.slice(i)}return t}function y(t){if(!kt()){let c=T(void 0);return S(c,()=>y(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return g(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function"&&t._mapArray)try{return y(at(t))}catch(c){return b(c),typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch(c){return b(c),typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(it.has(t.tag))return"";if(Ot.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){b(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(ut(t,u?null:c))}if(typeof t.tag=="function"){let c=nt(t.tag);try{return y(t.tag(ct(t)))}finally{ot(c)}}let{tag:e,props:r,children:a}=t;ft(e,t);let o=lt(r||{}),i=`<${e}${o}>`;if(pt.has(e))return i;let n=dt(r),s=n!=null?String(n):a.map(y).join("");return`${i}${s}</${e}>`}function tr(t){let e=T(void 0);return{body:S(e,()=>y(t)),head:st(e.head)}}async function er(t,e={}){let r=t.default||t,a=typeof t.loader=="function"?await t.loader(e):void 0,o=T(a),i=e.params||{};return{body:S(o,()=>y(rt(r,{...i,loaderData:a}))),head:st(o.head),loaderData:a}}var $t=12;async function me(t,e){e||(e=T(void 0));let r="",a=e.resourceCounter;for(let i=0;i<$t;i++){e.resourceCounter=a,r=S(e,()=>y(t));let n=[...e.resources.values()].filter(s=>s.status==="pending").map(s=>s.promise);if(n.length===0)break;await Promise.all(n)}let o={};for(let[i,n]of e.resources)n.status==="ready"&&(o[i]=n.value);return{body:r,head:st(e.head),loaderData:e.loaderData,resources:o,ctx:e}}async function Tt(t,e={},r={}){let a=t.default||t,o=typeof t.loader=="function"?await t.loader(e):void 0,i=T(o),n=e.params||{},{body:s,head:c,resources:u}=await me(rt(a,{...n,loaderData:o}),i),d={loaderData:o??null,resources:u,islandStores:yt(i)};return ge({body:s,head:c,payload:d,options:r})}function ge({body:t,head:e,payload:r,options:a={}}){let o=a.lang||"en",i=`<script id="__what_data" type="application/json">${W(r)}<\/script>`,n=a.clientEntry?`<script type="module" src="${g(a.clientEntry)}"><\/script>`:"",c=(a.csrfToken?Q(a.csrfToken):"")+(a.head||""),u=a.bodyClass?` class="${g(a.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(o)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${i}${n}</body></html>`}async function*I(t,e){if(e===void 0&&(e=T(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield g(String(t));return}if(typeof t=="function"&&t._signal){let n=S(e,()=>t());yield*I(n,e);return}if(typeof t=="function"&&t._mapArray){let n=null;try{n=S(e,()=>at(t))}catch(s){b(s),typeof process<"u"}n&&(yield*I(n,e));return}if(typeof t=="function"){try{let n=S(e,()=>t());yield*I(n,e)}catch(n){b(n),typeof process<"u"}return}if(Array.isArray(t)){for(let n of t)yield*I(n,e);return}if(it.has(t.tag))return;if(t.tag==="__errorBoundary"){let n;try{n=S(e,()=>(t.children||[]).map(y).join(""))}catch(s){if(b(s),s&&typeof s.then=="function")throw s;n=S(e,()=>y(ut(t,s)))}yield n;return}if(t.tag==="__suspense"){let n=null,s=e.resourceCounter;for(let c=0;c<$t&&n===null;c++){e.resourceCounter=s;let u=null;try{n=S(e,()=>(t.children||[]).map(y).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(n===null){let d=[...e.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}n===null&&(n=S(e,()=>y(t.props&&t.props.fallback))),yield n;return}if(typeof t.tag=="function"){let n=nt(t.tag);try{let s=S(e,()=>t.tag(ct(t))),c=s instanceof Promise?await s:s;yield*I(c,e)}catch(s){b(s),typeof process<"u",yield P?`<!-- SSR Error: ${g(s.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{ot(n)}return}let{tag:r,props:a,children:o}=t;ft(r,t);let i=lt(a||{});if(yield`<${r}${i}>`,!pt.has(r)){let n=dt(a);if(n!=null)yield String(n);else for(let s of o)yield*I(s,e);yield`</${r}>`}}function rr(t){return{mode:"static",...t}}function nr(t,e={}){let r=T(e),a=S(r,()=>y(rt(t.component,e))),o=t.islands||[];return we({title:t.title||"",meta:t.meta||{},body:a,islands:o,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function we({title:t,meta:e,body:r,islands:a,scripts:o,styles:i,mode:n}){let s=Object.entries(e).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
2
+ `),c=i.map(l=>`<link rel="stylesheet" href="${g(l)}">`).join(`
3
+ `),u=a.length>0?`
4
4
  <script type="module">
5
5
  import { hydrateIslands } from '/@what/islands.js';
6
6
  hydrateIslands();
7
- <\/script>`:"",d=s.map(l=>`<script type="module" src="${g(l)}"><\/script>`).join(`
8
- `),f=o==="client"?`
7
+ <\/script>`:"",d=o.map(l=>`<script type="module" src="${g(l)}"><\/script>`).join(`
8
+ `),f=n==="client"?`
9
9
  <script type="module" src="/@what/client.js"><\/script>`:"";return`<!DOCTYPE html>
10
10
  <html lang="en">
11
11
  <head>
12
12
  <meta charset="UTF-8">
13
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
- ${i}
15
- <title>${g(e)}</title>
14
+ ${s}
15
+ <title>${g(t)}</title>
16
16
  ${c}
17
17
  </head>
18
18
  <body>
@@ -21,4 +21,4 @@ import{h as re,_isAriaAttr as dt,_beginComponentSSR as ne,_endComponentSSR as oe
21
21
  ${d}
22
22
  ${f}
23
23
  </body>
24
- </html>`}function nr(e){return e._server=!0,e}var I=!(typeof process<"u");function de(e){return e?e.dangerouslySetInnerHTML?e.dangerouslySetInnerHTML.__html??null:e.innerHTML&&typeof e.innerHTML=="object"&&"__html"in e.innerHTML?e.innerHTML.__html??null:(e.innerHTML!=null&&typeof e.innerHTML=="string"&&I&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var St=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,bt=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function b(e){if(e&&e.code==="ERR_COMPILED_JSX_IN_SSR")throw e}function _t(e){return!!e&&typeof e=="object"&&typeof e.nodeType=="number"}function fe(e,t){if(!(typeof e=="string"&&bt.test(e)))throw _t(t)?Object.assign(new Error('[what-server] Cannot server-render a DOM node. A component compiled by what-compiler returns a cloned template (finished DOM), not a vnode, so it has no server-rendered form. Author server-rendered views with h(), or compile them with the automatic JSX runtime (jsxImportSource: "what-framework") instead of what-compiler.'),{code:"ERR_COMPILED_JSX_IN_SSR"}):Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(e)}`),{code:"ERR_INVALID_SSR_TAG"})}function le(e){let t="";for(let[r,n]of Object.entries(e)){if(r==="key"||r==="ref"||r==="children"||r==="dangerouslySetInnerHTML"||r==="innerHTML")continue;let s=r.toLowerCase();if(s.startsWith("on")&&r.length>2)continue;let a=n;if(typeof a=="function"){try{a=a()}catch(o){I&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(r)}: its value threw during SSR: ${o.message}`);continue}if(typeof a=="function")continue}if(a===!1&&(dt(r)||r.startsWith("data-"))){t+=` ${r}="false"`;continue}if(!(a===!1||a==null)){if(!St.test(r)){I&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(r)}`);continue}if(Et.has(s)){I&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(r)}`);continue}if(r==="className"||r==="class")t+=` class="${g(String(a))}"`;else if(r==="style"&&typeof a=="object"){let o=Object.entries(a).map(([i,c])=>`${Tt(i)}:${c}`).join(";");t+=` style="${g(o)}"`}else if(a===!0)r.startsWith("aria-")||r==="role"||r.startsWith("data-")?t+=` ${r}="true"`:t+=` ${r}`;else{if(Rt(r,a))continue;t+=` ${r}="${g(String(a))}"`}}}return t}function Rt(e,t){let r=e.toLowerCase();if(!At.has(r))return!1;let n=String(t).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return n.startsWith("javascript:")||n.startsWith("vbscript:")||n.startsWith("data:")}var At=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Et=new Set(["srcdoc"]);function g(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Tt(e){return e.startsWith("--")?e:e.replace(/([A-Z])/g,"-$1").toLowerCase()}var pe=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{_e as ACTION_ENDPOINT,Ye as Form,Fe as action,N as createActionHandler,ut as createCloudflareHandler,te as createRequestHandler,Q as csrfMetaTag,tr as definePage,tt as fetchActionHandler,we as formAction,Z as generateCsrfToken,rr as generateStaticPage,Ve as getRegisteredActions,De as getRevalidationHandler,j as handleActionRequest,be as invalidatePath,qe as nodeActionMiddleware,Je as onRevalidate,Te as renderDocument,er as renderPage,ht as renderToHydratableString,P as renderToStream,y as renderToString,mt as renderToStringAsync,qt as renderToStringWithHead,X as revalidatePath,Y as revalidateTag,W as serializeState,nr as server,z as setRevalidationHandler,Se as useAction,Ue as useFormAction,We as useMutation,Be as useOptimistic,ge as validateCsrfToken};
24
+ </html>`}function or(t){return t._server=!0,t}var P=!(typeof process<"u");function dt(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&P&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var Se=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,be=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function b(t){if(t&&t.code==="ERR_COMPILED_JSX_IN_SSR")throw t}function _e(t){return!!t&&typeof t=="object"&&typeof t.nodeType=="number"}function ft(t,e){if(!(typeof t=="string"&&be.test(t)))throw _e(e)?Object.assign(new Error('[what-server] Cannot server-render a DOM node. A component compiled by what-compiler returns a cloned template (finished DOM), not a vnode, so it has no server-rendered form. Author server-rendered views with h(), or compile them with the automatic JSX runtime (jsxImportSource: "what-framework") instead of what-compiler.'),{code:"ERR_COMPILED_JSX_IN_SSR"}):Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}var Re=new Map([["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"],["acceptCharset","accept-charset"]]);function lt(t){let e="";for(let[r,a]of Object.entries(t)){if(r==="key"||r==="ref"||r==="children"||r==="dangerouslySetInnerHTML"||r==="innerHTML")continue;let o=Re.get(r)||r,i=o.toLowerCase();if(i.startsWith("on")&&o.length>2)continue;let n=a;if(typeof n=="function"){try{n=n()}catch(s){P&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(o)}: its value threw during SSR: ${s.message}`);continue}if(typeof n=="function")continue}if(n===!1&&(de(o)||o.startsWith("data-"))){e+=` ${o}="false"`;continue}if(!(n===!1||n==null)){if(!Se.test(o)){P&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(o)}`);continue}if(Te.has(i)){P&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(o)}`);continue}if(o==="class")e+=` class="${g(String(n))}"`;else if(o==="style"&&typeof n=="object"){let s=Object.entries(n).map(([c,u])=>`${ke(c)}:${u}`).join(";");e+=` style="${g(s)}"`}else if(n===!0)o.startsWith("aria-")||o==="role"||o.startsWith("data-")?e+=` ${o}="true"`:e+=` ${o}`;else{if(Ae(o,n))continue;e+=` ${o}="${g(String(n))}"`}}}return e}function Ae(t,e){let r=t.toLowerCase();if(!Ee.has(r))return!1;let a=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return a.startsWith("javascript:")||a.startsWith("vbscript:")||a.startsWith("data:")}var Ee=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Te=new Set(["srcdoc"]);function g(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ke(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var pt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{_t as ACTION_ENDPOINT,Yt as Form,Ft as action,N as createActionHandler,ue as createCloudflareHandler,et as createRequestHandler,Q as csrfMetaTag,rr as definePage,ee as fetchActionHandler,wt as formAction,Z as generateCsrfToken,nr as generateStaticPage,Vt as getRegisteredActions,Dt as getRevalidationHandler,L as handleActionRequest,bt as invalidatePath,qt as nodeActionMiddleware,Jt as onRevalidate,Tt as renderDocument,er as renderPage,he as renderToHydratableString,I as renderToStream,y as renderToString,me as renderToStringAsync,tr as renderToStringWithHead,X as revalidatePath,Y as revalidateTag,W as serializeState,or as server,z as setRevalidationHandler,St as useAction,Ut as useFormAction,Wt as useMutation,Bt as useOptimistic,gt as validateCsrfToken};
package/dist/node.min.js CHANGED
@@ -1,10 +1,10 @@
1
- import{AsyncLocalStorage as ze}from"node:async_hooks";import{__installServerContextStorage as Ge}from"what-core";import{h as at,_isAriaAttr as we,_beginComponentSSR as st,_endComponentSSR as it,_mapArrayToArray as ct,getServerContext as vt,runWithServerContext as S,beginHeadCollection as Se,endHeadCollection as ut}from"what-core";var Lt=new RegExp("[<>&\\u2028\\u2029]","g"),Mt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function N(t){return JSON.stringify(t).replace(Lt,e=>Mt[e.charCodeAt(0)])}import{mount as Ke,hydrate as Ze,signal as Qe,batch as qe,getServerContext as Ft}from"what-core";var Ut=new Map;function Bt(t){let e=t||Ft();return e&&e.islandStores instanceof Map?e.islandStores:null}function bt(t){let e=typeof document<"u"?Ut:Bt(t),r={};for(let[n,s]of e||[])r[n]=s._getSnapshot();return r}import{signal as R,batch as q}from"what-core";var M=Symbol.for("what.revalidationHandler"),_t=!(typeof process<"u");function K(t){globalThis[M]=t}function Jt(){return globalThis[M]??null}async function Z(t,e){let r=globalThis[M];if(r&&r.revalidatePath)return r.revalidatePath(t,e);_t&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function Q(t,e){let r=globalThis[M];if(r&&r.revalidateTag)return r.revalidateTag(t,e);_t&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var tt=new Map;function Vt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function et(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function Rt(t,e){if(!t||!e||t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t.charCodeAt(n)^e.charCodeAt(n);return r===0}function rt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Wt=0,zt=!1;function Gt(){return!zt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Wt).toString(36)}_${Date.now().toString(36)}`}`}function Xt(t,e={}){let r=e.id||Gt(),{onError:n,onSuccess:s,revalidate:a}=e;typeof window>"u"&&tt.set(r,{fn:t,options:e});async function o(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Vt(),l={"Content-Type":"application/json","X-What-Action":r};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let m=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(m.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),a)for(let m of a)Tt(m);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${r}" timed out after ${c}ms`);throw l.code="TIMEOUT",n&&n(l),l}throw n&&n(f),f}finally{clearTimeout(d)}}return o._actionId=r,o._isAction=!0,o}function Et(t,e={}){let{onSuccess:r,onError:n,resetOnSuccess:s=!0}=e;return async a=>{let o,i;a instanceof Event?(a.preventDefault(),i=a.target,o=new FormData(i)):o=a;let c={},u=!1;for(let[d,f]of o.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,o):await t(c);return r&&r(d,i),s&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function At(t){let e=R(!1),r=R(null),n=R(null);async function s(...a){e.set(!0),r.set(null);try{let o=await t(...a);return n.set(o),o}catch(o){throw r.set(o),o}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function Yt(t,e={}){let{resetOnSuccess:r=!0}=e,n={current:null},s=At(Et(t,{resetOnSuccess:r}));function a(o){o.preventDefault();let i=new FormData(o.target);return n.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:n}}function Kt(t,e){let r=R(t),n=R([]),s=R(t);function a(u){let d=e(r.peek(),u);q(()=>{n.set([...n.peek(),u]),r.set(d)})}function o(u,d){q(()=>{if(n.set(n.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of n.peek())f=e(f,l);r.set(f)}})}function i(u,d){q(()=>{let f=n.peek().filter(h=>h!==u);n.set(f);let l=d!==void 0?d:s.peek();s.set(l);let p=l;for(let h of f)p=e(p,h);r.set(p)})}async function c(u,d){a(u);try{let f=await d();return o(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{r.set(u),s.set(u)}}}var j=new Map;function Zt(t,e){return j.has(t)||j.set(t,new Set),j.get(t).add(e),()=>{j.get(t)?.delete(e)}}function Tt(t){let e=j.get(t);if(e)for(let r of e)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function F(t,e,r,n={}){let{csrfToken:s,skipCsrf:a=!1}=n;if(!a){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!Rt(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=tt.get(e);return o?Array.isArray(r)?o.fn(...r).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await Z(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await Q(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function Qt(){return[...tt.keys()]}function qt(t,e={}){let{onSuccess:r,onError:n,onSettled:s}=e,a={isPending:R(!1),error:R(null),data:R(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await t(...i);return a.data.set(c),r&&r(c,...i),c}catch(c){throw a.error.set(c),n&&n(c,...i),c}finally{a.isPending.set(!1),s&&s(a.data.peek(),a.error.peek(),...i)}}return{mutate:o,isPending:()=>a.isPending(),error:()=>a.error(),data:()=>a.data(),reset:()=>{a.error.set(null),a.data.set(null)}}}import{h as U}from"what-core";var kt="/__what_action";function te(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function ee(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function re({action:t,csrfToken:e,redirect:r,method:n="post",enhance:s=!0,children:a,...o}){let i=te(t),c=e!==void 0?e:ee();c==null&&typeof process<"u";let u=[U("input",{type:"hidden",name:"_action",value:i}),U("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(U("input",{type:"hidden",name:"_redirect",value:r}));let d={...o,method:n,action:o.action||kt,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return U("form",d,...u,...f)}var ne="/__what_action",H=1024*1024;function oe(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let r={};return t.forEach((n,s)=>{r[s.toLowerCase()]=n}),r}let e={};for(let r in t)e[r.toLowerCase()]=t[r];return e}function B(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function nt(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</p></body></html>`}}function Ot(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function ae(t,e){let r=Ot(t&&t._redirect);if(r)return r;let n=e.referer||e.referrer;if(n)try{let s=new URL(n,"http://localhost"),a=Ot(s.pathname+s.search);if(a)return a}catch{}return"/"}var se=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function D(t={}){let{getCsrfToken:e,skipCsrf:r=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return B(405,{message:"Method Not Allowed"});let o=oe(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=r?void 0:e?await e(s):void 0;if(u){let h=s.body||{},m=h._action||h["data-action"]||s.query&&s.query.action;if(!m)return nt(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...o},C=h._csrf??h["what-csrf-token"];if(C&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(C)),!r&&e&&!d)return nt(403,"Missing CSRF token");let v={};for(let[x,G]of Object.entries(h))se.has(x)||(v[x]=G);let O=await F({headers:b},m,[v],{csrfToken:d,skipCsrf:r});return O.status===200?{status:303,headers:{location:ae(h,o)},body:""}:nt(O.status,O.body&&O.body.message||"Action failed")}if(!i)return B(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return B(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await F({headers:o},i,l,{csrfToken:d,skipCsrf:r});return B(p.status,p.body)}}function ie(t={}){let e=t.basePath||ne,r=D(t);return async function(s,a,o){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return o?o():void 0;let u;try{let l=await ce(s);u=J(l,s.headers["content-type"]||"")}catch(l){a.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),a.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await r({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function J(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let r={};for(let[n,s]of new URLSearchParams(String(t)))r[n]===void 0?r[n]=s:Array.isArray(r[n])?r[n].push(s):r[n]=[r[n],s];return r}return t==null||t===""?{}:JSON.parse(String(t))}async function V(t,e=H){let r=Number(t.headers.get("content-length"));if(Number.isFinite(r)&&r>e)return{tooLarge:!0};let n=t.body;if(!n||typeof n.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=n.getReader(),a=[],o=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(o+=c.byteLength,o>e){try{await s.cancel()}catch{}return{tooLarge:!0}}a.push(c)}}return{raw:Buffer.concat(a.map(i=>Buffer.from(i))).toString("utf8")}}function ce(t){return new Promise((e,r)=>{let n=0,s=[];t.on("data",a=>{if(n+=a.length,n>H){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",r(o),t.destroy?.();return}s.push(a)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",r)})}function ue(t={}){let e=D(t);return async function(r){let n={};try{let o=await V(r);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=J(o.raw,r.headers.get("content-type")||"")}catch{n={}}let s={};try{s=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let a=await e({method:r.method,headers:r.headers,body:n,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as de,parseQuery as fe}from"what-router/match";var le="/__what_action",pe="/__what_revalidate",ot="what-csrf";function L(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((r,n)=>{e[n.toLowerCase()]=r}),e}function Ct(t,e){if(!t)return null;let r=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function he(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:J(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function me(t){let e;try{e=await V(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ye(t){return async function(r){let{route:n,params:s,query:a,request:o,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:s,query:a,request:o,csrfToken:i}:{params:s,query:a,request:o},d=i?{...t,csrfToken:i}:t;return{html:await W(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function T(t={}){let{routes:e=[],cache:r,render:n,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||D(u?{getCsrfToken:l=>Ct(l.headers&&l.headers.cookie,ot)}:{skipCsrf:!0}),f=n||ye(a);return r&&(r.revalidatePath||r.revalidateTag)&&K({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),m=h.pathname;if(i&&m.startsWith(i)&&(m=m.slice(i.length)||"/"),p.method==="POST"&&m===le){let g=await he(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await d({method:"POST",headers:L(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(A.body,{status:A.status,headers:A.headers})}let b=null,C=null;if(u&&(b=Ct(L(p.headers).cookie,ot),!b)){b=et();let A=L(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${ot}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(A?"; Secure":"")}let v=g=>(C&&(g["set-cookie"]=C),g);if(p.method==="POST"&&m===pe&&s){let g=await me(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await s({headers:L(p.headers),body:g.json});return new Response(JSON.stringify(A.body),{status:A.status,headers:{"content-type":"application/json"}})}let O=de(m,e);if(!O){let g=o?o():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:v({"content-type":"text/html; charset=utf-8"})})}let{route:x,params:G}=O,X=x.page||{mode:x.mode||"client"},I={path:m,query:fe(h.search),config:X,route:x,params:G,request:p};if(r&&X.mode!=="server"){I.varyHeaders=L(p.headers);let g=await r.handle(I,()=>f(I));return new Response(g.html,{status:g.status||200,headers:v({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}b&&(I.csrfToken=b);let Y=await f(I),St=v({"content-type":"text/html; charset=utf-8",...Y.headers||{}});return X.mode==="server"&&(St["Cache-Control"]="private, no-store"),new Response(Y.html,{status:Y.status||200,headers:St})}}function ge(t={}){let e=T(t);return{async fetch(r,n,s){return n&&(r.__env=n),s&&(r.__ctx=s),e(r)}}}function k(t){return{head:Se(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var xt=0;function be(){xt=0}function _e(){return"h"+xt++}function Re(t){if(!vt()){let e=k(void 0);return S(e,()=>Re(t))}return be(),E(t)}var Pt=new Set(["__errorBoundary","__suspense"]),dt=new Set(["__portal"]);function ft(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function lt(t,e){let r=t.props&&t.props.fallback;if(typeof r!="function")return r;let n=t.props&&t.props.reset||(()=>{});try{return r({error:e,reset:n})}catch(s){return _(s),$&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function E(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${E(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${E(ct(t))}<!--/$-->`}catch(c){return _(c),typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${E(t())}<!--/$-->`}catch(c){return _(c),typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(E).join("")}<!--/[]-->`;if(dt.has(t.tag))return"";if(Pt.has(t.tag))try{return(t.children||[]).map(E).join("")}catch(c){_(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return E(lt(t,u?null:c))}if(typeof t.tag=="function"){let c=_e(),u=st(t.tag),d;try{d=E(t.tag(ft(t)))}finally{it(u)}return Ee(d,c)}let{tag:e,props:r,children:n}=t;ht(e,t);let s=mt(r||{}),a=`<${e}${s}>`;if(yt.has(e))return a;let o=pt(r),i=o!=null?String(o):n.map(E).join("");return`${a}${i}</${e}>`}function Ee(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],s=r[2],a=n.length+1+s.length,o=t.indexOf(">",a),i=t.slice(a,o===-1?void 0:o);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,a)+` data-hk="${e}"`+t.slice(a)}return t}function y(t){if(!vt()){let c=k(void 0);return S(c,()=>y(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return w(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function"&&t._mapArray)try{return y(ct(t))}catch(c){return _(c),typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch(c){return _(c),typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(dt.has(t.tag))return"";if(Pt.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){_(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(lt(t,u?null:c))}if(typeof t.tag=="function"){let c=st(t.tag);try{return y(t.tag(ft(t)))}finally{it(c)}}let{tag:e,props:r,children:n}=t;ht(e,t);let s=mt(r||{}),a=`<${e}${s}>`;if(yt.has(e))return a;let o=pt(r),i=o!=null?String(o):n.map(y).join("");return`${a}${i}</${e}>`}function _r(t){let e=k(void 0);return{body:S(e,()=>y(t)),head:ut(e.head)}}async function Rr(t,e={}){let r=t.default||t,n=typeof t.loader=="function"?await t.loader(e):void 0,s=k(n),a=e.params||{};return{body:S(s,()=>y(at(r,{...a,loaderData:n}))),head:ut(s.head),loaderData:n}}var $t=12;async function Ae(t,e){e||(e=k(void 0));let r="",n=e.resourceCounter;for(let a=0;a<$t;a++){e.resourceCounter=n,r=S(e,()=>y(t));let o=[...e.resources.values()].filter(i=>i.status==="pending").map(i=>i.promise);if(o.length===0)break;await Promise.all(o)}let s={};for(let[a,o]of e.resources)o.status==="ready"&&(s[a]=o.value);return{body:r,head:ut(e.head),loaderData:e.loaderData,resources:s,ctx:e}}async function W(t,e={},r={}){let n=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,a=k(s),o=e.params||{},{body:i,head:c,resources:u}=await Ae(at(n,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:bt(a)};return Te({body:i,head:c,payload:d,options:r})}function Te({body:t,head:e,payload:r,options:n={}}){let s=n.lang||"en",a=`<script id="__what_data" type="application/json">${N(r)}<\/script>`,o=n.clientEntry?`<script type="module" src="${w(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?rt(n.csrfToken):"")+(n.head||""),u=n.bodyClass?` class="${w(n.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${w(s)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${a}${o}</body></html>`}async function*P(t,e){if(e===void 0&&(e=k(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield w(String(t));return}if(typeof t=="function"&&t._signal){let o=S(e,()=>t());yield*P(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=S(e,()=>ct(t))}catch(i){_(i),typeof process<"u"}o&&(yield*P(o,e));return}if(typeof t=="function"){try{let o=S(e,()=>t());yield*P(o,e)}catch(o){_(o),typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*P(o,e);return}if(dt.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(_(i),i&&typeof i.then=="function")throw i;o=S(e,()=>y(lt(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null,i=e.resourceCounter;for(let c=0;c<$t&&o===null;c++){e.resourceCounter=i;let u=null;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(o===null){let d=[...e.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}o===null&&(o=S(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=st(t.tag);try{let i=S(e,()=>t.tag(ft(t))),c=i instanceof Promise?await i:i;yield*P(c,e)}catch(i){_(i),typeof process<"u",yield $?`<!-- SSR Error: ${w(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{it(o)}return}let{tag:r,props:n,children:s}=t;ht(r,t);let a=mt(n||{});if(yield`<${r}${a}>`,!yt.has(r)){let o=pt(n);if(o!=null)yield String(o);else for(let i of s)yield*P(i,e);yield`</${r}>`}}function Er(t){return{mode:"static",...t}}function Ar(t,e={}){let r=k(e),n=S(r,()=>y(at(t.component,e))),s=t.islands||[];return ke({title:t.title||"",meta:t.meta||{},body:n,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ke({title:t,meta:e,body:r,islands:n,scripts:s,styles:a,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${w(l)}" content="${w(p)}">`).join(`
2
- `),c=a.map(l=>`<link rel="stylesheet" href="${w(l)}">`).join(`
1
+ import{AsyncLocalStorage as Ge}from"node:async_hooks";import{__installServerContextStorage as Xe}from"what-core";import{h as at,_isAriaAttr as we,_beginComponentSSR as st,_endComponentSSR as it,_mapArrayToArray as ct,getServerContext as vt,runWithServerContext as b,beginHeadCollection as Se,endHeadCollection as ut}from"what-core";var Lt=new RegExp("[<>&\\u2028\\u2029]","g"),Mt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function N(t){return JSON.stringify(t).replace(Lt,e=>Mt[e.charCodeAt(0)])}import{mount as Ze,hydrate as qe,signal as Qe,batch as tr,getServerContext as Ft}from"what-core";var Ut=new Map;function Bt(t){let e=t||Ft();return e&&e.islandStores instanceof Map?e.islandStores:null}function bt(t){let e=typeof document<"u"?Ut:Bt(t),r={};for(let[n,a]of e||[])r[n]=a._getSnapshot();return r}import{signal as E,batch as Q}from"what-core";var M=Symbol.for("what.revalidationHandler"),_t=!(typeof process<"u");function K(t){globalThis[M]=t}function Jt(){return globalThis[M]??null}async function Z(t,e){let r=globalThis[M];if(r&&r.revalidatePath)return r.revalidatePath(t,e);_t&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-isr engine and bind it in your adapter (setRevalidationHandler).`)}async function q(t,e){let r=globalThis[M];if(r&&r.revalidateTag)return r.revalidateTag(t,e);_t&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var tt=new Map;function Vt(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function et(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw Object.assign(new Error("[what] No secure random source available for CSRF token generation"),{code:"ERR_NO_SECURE_RANDOM"})}function Rt(t,e){if(!t||!e||t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t.charCodeAt(n)^e.charCodeAt(n);return r===0}function rt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Wt=0,zt=!1;function Gt(){return!zt&&typeof process<"u",`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++Wt).toString(36)}_${Date.now().toString(36)}`}`}function Xt(t,e={}){let r=e.id||Gt(),{onError:n,onSuccess:a,revalidate:s}=e;typeof window>"u"&&tt.set(r,{fn:t,options:e});async function o(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let f=Vt(),l={"Content-Type":"application/json","X-What-Action":r};f&&(l["X-CSRF-Token"]=f);let p=await fetch("/__what_action",{method:"POST",headers:l,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let m=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(m.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(a&&a(h),s)for(let m of s)Tt(m);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${r}" timed out after ${c}ms`);throw l.code="TIMEOUT",n&&n(l),l}throw n&&n(f),f}finally{clearTimeout(d)}}return o._actionId=r,o._isAction=!0,o}function Et(t,e={}){let{onSuccess:r,onError:n,resetOnSuccess:a=!0}=e;return async s=>{let o,i;s instanceof Event?(s.preventDefault(),i=s.target,o=new FormData(i)):o=s;let c={},u=!1;for(let[d,f]of o.entries())typeof File<"u"&&f instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(f):c[d]=[c[d],f]:c[d]=f;try{let d=u?await t(c,o):await t(c);return r&&r(d,i),a&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function At(t){let e=E(!1),r=E(null),n=E(null);async function a(...s){e.set(!0),r.set(null);try{let o=await t(...s);return n.set(o),o}catch(o){throw r.set(o),o}finally{e.set(!1)}}return{trigger:a,isPending:()=>e(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function Yt(t,e={}){let{resetOnSuccess:r=!0}=e,n={current:null},a=At(Et(t,{resetOnSuccess:r}));function s(o){o.preventDefault();let i=new FormData(o.target);return n.current=o.target,a.trigger(i)}return{...a,handleSubmit:s,formRef:n}}function Kt(t,e){let r=E(t),n=E([]),a=E(t);function s(u){let d=e(r.peek(),u);Q(()=>{n.set([...n.peek(),u]),r.set(d)})}function o(u,d){Q(()=>{if(n.set(n.peek().filter(f=>f!==u)),d!==void 0){a.set(d);let f=d;for(let l of n.peek())f=e(f,l);r.set(f)}})}function i(u,d){Q(()=>{let f=n.peek().filter(h=>h!==u);n.set(f);let l=d!==void 0?d:a.peek();a.set(l);let p=l;for(let h of f)p=e(p,h);r.set(p)})}async function c(u,d){s(u);try{let f=await d();return o(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:s,resolve:o,rollback:i,withOptimistic:c,set:u=>{r.set(u),a.set(u)}}}var j=new Map;function Zt(t,e){return j.has(t)||j.set(t,new Set),j.get(t).add(e),()=>{j.get(t)?.delete(e)}}function Tt(t){let e=j.get(t);if(e)for(let r of e)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function F(t,e,r,n={}){let{csrfToken:a,skipCsrf:s=!1}=n;if(!s){if(!a)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!Rt(i,a))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=tt.get(e);return o?Array.isArray(r)?o.fn(...r).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await Z(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await q(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function qt(){return[...tt.keys()]}function Qt(t,e={}){let{onSuccess:r,onError:n,onSettled:a}=e,s={isPending:E(!1),error:E(null),data:E(null)};async function o(...i){s.isPending.set(!0),s.error.set(null);try{let c=await t(...i);return s.data.set(c),r&&r(c,...i),c}catch(c){throw s.error.set(c),n&&n(c,...i),c}finally{s.isPending.set(!1),a&&a(s.data.peek(),s.error.peek(),...i)}}return{mutate:o,isPending:()=>s.isPending(),error:()=>s.error(),data:()=>s.data(),reset:()=>{s.error.set(null),s.data.set(null)}}}import{h as U}from"what-core";var kt="/__what_action";function te(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw Object.assign(new Error("[what] <Form action={fn}>: that function is not a server action. Wrap it with action() from what-server, or pass the action id as a string."),{code:"ERR_FORM_ACTION_NOT_REGISTERED"})}throw Object.assign(new Error("[what] <Form> requires an `action` prop: a server action or its id."),{code:"ERR_FORM_ACTION_MISSING"})}function ee(){if(typeof document>"u")return null;let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return e?decodeURIComponent(e[1]):null}function re({action:t,csrfToken:e,redirect:r,method:n="post",enhance:a=!0,children:s,...o}){let i=te(t),c=e!==void 0?e:ee();c==null&&typeof process<"u";let u=[U("input",{type:"hidden",name:"_action",value:i}),U("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(U("input",{type:"hidden",name:"_redirect",value:r}));let d={...o,method:n,action:o.action||kt,"data-action":i};a&&(d["data-enhance"]="");let f=s==null?[]:Array.isArray(s)?s:[s];return U("form",d,...u,...f)}var ne="/__what_action",H=1024*1024;function oe(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let r={};return t.forEach((n,a)=>{r[a.toLowerCase()]=n}),r}let e={};for(let r in t)e[r.toLowerCase()]=t[r];return e}function B(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function nt(t,e){return{status:t,headers:{"content-type":"text/html; charset=utf-8"},body:`<!DOCTYPE html><html><body><h1>${t}</h1><p>${String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</p></body></html>`}}function Ot(t){if(typeof t!="string"||!t.startsWith("/")||/^[/\\]{2}/.test(t)||t.includes("\\"))return null;try{let e=new URL(t,"http://localhost");return e.origin!=="http://localhost"?null:e.pathname+e.search}catch{return null}}function ae(t,e){let r=Ot(t&&t._redirect);if(r)return r;let n=e.referer||e.referrer;if(n)try{let a=new URL(n,"http://localhost"),s=Ot(a.pathname+a.search);if(s)return s}catch{}return"/"}var se=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function D(t={}){let{getCsrfToken:e,skipCsrf:r=!1}=t;return async function(a){if((a.method||"POST").toUpperCase()!=="POST")return B(405,{message:"Method Not Allowed"});let o=oe(a.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=r?void 0:e?await e(a):void 0;if(u){let h=a.body||{},m=h._action||h["data-action"]||a.query&&a.query.action;if(!m)return nt(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let w={...o},T=h._csrf??h["what-csrf-token"];if(T&&!w["x-csrf-token"]&&(w["x-csrf-token"]=String(T)),!r&&e&&!d)return nt(403,"Missing CSRF token");let k={};for(let[O,G]of Object.entries(h))se.has(O)||(k[O]=G);let R=await F({headers:w},m,[k],{csrfToken:d,skipCsrf:r});return R.status===200?{status:303,headers:{location:ae(h,o)},body:""}:nt(R.status,R.body&&R.body.message||"Action failed")}if(!i)return B(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return B(403,{message:"Missing CSRF token"});let l=(a.body||{}).args,p=await F({headers:o},i,l,{csrfToken:d,skipCsrf:r});return B(p.status,p.body)}}function ie(t={}){let e=t.basePath||ne,r=D(t);return async function(a,s,o){let[i,c]=(a.url||"").split("?");if(i!==e||(a.method||"").toUpperCase()!=="POST")return o?o():void 0;let u;try{let l=await ce(a);u=J(l,a.headers["content-type"]||"")}catch(l){s.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),s.end(JSON.stringify({message:l.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid request body"}));return}let d=Object.fromEntries(new URLSearchParams(c||"")),f=await r({method:a.method,headers:a.headers,body:u,query:d});s.writeHead(f.status,f.headers),s.end(f.body)}}function J(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let r={};for(let[n,a]of new URLSearchParams(String(t)))r[n]===void 0?r[n]=a:Array.isArray(r[n])?r[n].push(a):r[n]=[r[n],a];return r}return t==null||t===""?{}:JSON.parse(String(t))}async function V(t,e=H){let r=Number(t.headers.get("content-length"));if(Number.isFinite(r)&&r>e)return{tooLarge:!0};let n=t.body;if(!n||typeof n.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let a=n.getReader(),s=[],o=0;for(;;){let{done:i,value:c}=await a.read();if(i)break;if(c){if(o+=c.byteLength,o>e){try{await a.cancel()}catch{}return{tooLarge:!0}}s.push(c)}}return{raw:Buffer.concat(s.map(i=>Buffer.from(i))).toString("utf8")}}function ce(t){return new Promise((e,r)=>{let n=0,a=[];t.on("data",s=>{if(n+=s.length,n>H){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",r(o),t.destroy?.();return}a.push(s)}),t.on("end",()=>{if(a.length===0)return e("");e(Buffer.concat(a).toString("utf8"))}),t.on("error",r)})}function ue(t={}){let e=D(t);return async function(r){let n={};try{let o=await V(r);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=J(o.raw,r.headers.get("content-type")||"")}catch{n={}}let a={};try{a=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let s=await e({method:r.method,headers:r.headers,body:n,query:a});return new Response(s.body,{status:s.status,headers:s.headers})}}import{matchRoute as de,parseQuery as fe}from"what-router/match";var le="/__what_action",pe="/__what_revalidate",ot="what-csrf";function L(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((r,n)=>{e[n.toLowerCase()]=r}),e}function Ct(t,e){if(!t)return null;let r=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function he(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:J(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function me(t){let e;try{e=await V(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ye(t){return async function(r){let{route:n,params:a,query:s,request:o,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:a,query:s,request:o,csrfToken:i}:{params:a,query:s,request:o},d=i?{...t,csrfToken:i}:t;return{html:await W(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function v(t={}){let{routes:e=[],cache:r,render:n,revalidateWebhook:a,document:s={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||D(u?{getCsrfToken:l=>Ct(l.headers&&l.headers.cookie,ot)}:{skipCsrf:!0}),f=n||ye(s);return r&&(r.revalidatePath||r.revalidateTag)&&K({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),m=h.pathname;if(i&&m.startsWith(i)&&(m=m.slice(i.length)||"/"),p.method==="POST"&&m===le){let g=await he(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let C=await d({method:"POST",headers:L(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(C.body,{status:C.status,headers:C.headers})}let w=null,T=null;if(u&&(w=Ct(L(p.headers).cookie,ot),!w)){w=et();let C=L(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;T=`${ot}=${encodeURIComponent(w)}; Path=/; SameSite=Lax`+(C?"; Secure":"")}let k=g=>(T&&(g["set-cookie"]=T),g);if(p.method==="POST"&&m===pe&&a){let g=await me(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let C=await a({headers:L(p.headers),body:g.json});return new Response(JSON.stringify(C.body),{status:C.status,headers:{"content-type":"application/json"}})}let R=de(m,e);if(!R){let g=o?o():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:k({"content-type":"text/html; charset=utf-8"})})}let{route:O,params:G}=R,X=O.page||{mode:O.mode||"client"},I={path:m,query:fe(h.search),config:X,route:O,params:G,request:p};if(r&&X.mode!=="server"){I.varyHeaders=L(p.headers);let g=await r.handle(I,()=>f(I));return new Response(g.html,{status:g.status||200,headers:k({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}w&&(I.csrfToken=w);let Y=await f(I),St=k({"content-type":"text/html; charset=utf-8",...Y.headers||{}});return X.mode==="server"&&(St["Cache-Control"]="private, no-store"),new Response(Y.html,{status:Y.status||200,headers:St})}}function ge(t={}){let e=v(t);return{async fetch(r,n,a){return n&&(r.__env=n),a&&(r.__ctx=a),e(r)}}}function x(t){return{head:Se(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var xt=0;function be(){xt=0}function _e(){return"h"+xt++}function Re(t){if(!vt()){let e=x(void 0);return b(e,()=>Re(t))}return be(),A(t)}var Pt=new Set(["__errorBoundary","__suspense"]),dt=new Set(["__portal"]);function ft(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function lt(t,e){let r=t.props&&t.props.fallback;if(typeof r!="function")return r;let n=t.props&&t.props.reset||(()=>{});try{return r({error:e,reset:n})}catch(a){return _(a),$&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${a.message}`),null}}function A(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return S(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${A(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${A(ct(t))}<!--/$-->`}catch(c){return _(c),typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${A(t())}<!--/$-->`}catch(c){return _(c),typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(A).join("")}<!--/[]-->`;if(dt.has(t.tag))return"";if(Pt.has(t.tag))try{return(t.children||[]).map(A).join("")}catch(c){_(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return A(lt(t,u?null:c))}if(typeof t.tag=="function"){let c=_e(),u=st(t.tag),d;try{d=A(t.tag(ft(t)))}finally{it(u)}return Ee(d,c)}let{tag:e,props:r,children:n}=t;ht(e,t);let a=mt(r||{}),s=`<${e}${a}>`;if(yt.has(e))return s;let o=pt(r),i=o!=null?String(o):n.map(A).join("");return`${s}${i}</${e}>`}function Ee(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],a=r[2],s=n.length+1+a.length,o=t.indexOf(">",s),i=t.slice(s,o===-1?void 0:o);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,s)+` data-hk="${e}"`+t.slice(s)}return t}function y(t){if(!vt()){let c=x(void 0);return b(c,()=>y(t))}if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return S(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function"&&t._mapArray)try{return y(ct(t))}catch(c){return _(c),typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch(c){return _(c),typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(dt.has(t.tag))return"";if(Pt.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){_(c);let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(lt(t,u?null:c))}if(typeof t.tag=="function"){let c=st(t.tag);try{return y(t.tag(ft(t)))}finally{it(c)}}let{tag:e,props:r,children:n}=t;ht(e,t);let a=mt(r||{}),s=`<${e}${a}>`;if(yt.has(e))return s;let o=pt(r),i=o!=null?String(o):n.map(y).join("");return`${s}${i}</${e}>`}function Rr(t){let e=x(void 0);return{body:b(e,()=>y(t)),head:ut(e.head)}}async function Er(t,e={}){let r=t.default||t,n=typeof t.loader=="function"?await t.loader(e):void 0,a=x(n),s=e.params||{};return{body:b(a,()=>y(at(r,{...s,loaderData:n}))),head:ut(a.head),loaderData:n}}var $t=12;async function Ae(t,e){e||(e=x(void 0));let r="",n=e.resourceCounter;for(let s=0;s<$t;s++){e.resourceCounter=n,r=b(e,()=>y(t));let o=[...e.resources.values()].filter(i=>i.status==="pending").map(i=>i.promise);if(o.length===0)break;await Promise.all(o)}let a={};for(let[s,o]of e.resources)o.status==="ready"&&(a[s]=o.value);return{body:r,head:ut(e.head),loaderData:e.loaderData,resources:a,ctx:e}}async function W(t,e={},r={}){let n=t.default||t,a=typeof t.loader=="function"?await t.loader(e):void 0,s=x(a),o=e.params||{},{body:i,head:c,resources:u}=await Ae(at(n,{...o,loaderData:a}),s),d={loaderData:a??null,resources:u,islandStores:bt(s)};return Te({body:i,head:c,payload:d,options:r})}function Te({body:t,head:e,payload:r,options:n={}}){let a=n.lang||"en",s=`<script id="__what_data" type="application/json">${N(r)}<\/script>`,o=n.clientEntry?`<script type="module" src="${S(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?rt(n.csrfToken):"")+(n.head||""),u=n.bodyClass?` class="${S(n.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${S(a)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${c}</head><body${u}>${t}${s}${o}</body></html>`}async function*P(t,e){if(e===void 0&&(e=x(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield S(String(t));return}if(typeof t=="function"&&t._signal){let o=b(e,()=>t());yield*P(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=b(e,()=>ct(t))}catch(i){_(i),typeof process<"u"}o&&(yield*P(o,e));return}if(typeof t=="function"){try{let o=b(e,()=>t());yield*P(o,e)}catch(o){_(o),typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*P(o,e);return}if(dt.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=b(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(_(i),i&&typeof i.then=="function")throw i;o=b(e,()=>y(lt(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null,i=e.resourceCounter;for(let c=0;c<$t&&o===null;c++){e.resourceCounter=i;let u=null;try{o=b(e,()=>(t.children||[]).map(y).join(""))}catch(d){if(d&&typeof d.then=="function")u=d;else throw d}if(o===null){let d=[...e.resources.values()].filter(f=>f.status==="pending").map(f=>f.promise);await Promise.all([u,...d].filter(Boolean))}}o===null&&(o=b(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=st(t.tag);try{let i=b(e,()=>t.tag(ft(t))),c=i instanceof Promise?await i:i;yield*P(c,e)}catch(i){_(i),typeof process<"u",yield $?`<!-- SSR Error: ${S(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{it(o)}return}let{tag:r,props:n,children:a}=t;ht(r,t);let s=mt(n||{});if(yield`<${r}${s}>`,!yt.has(r)){let o=pt(n);if(o!=null)yield String(o);else for(let i of a)yield*P(i,e);yield`</${r}>`}}function Ar(t){return{mode:"static",...t}}function Tr(t,e={}){let r=x(e),n=b(r,()=>y(at(t.component,e))),a=t.islands||[];return ke({title:t.title||"",meta:t.meta||{},body:n,islands:a,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ke({title:t,meta:e,body:r,islands:n,scripts:a,styles:s,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${S(l)}" content="${S(p)}">`).join(`
2
+ `),c=s.map(l=>`<link rel="stylesheet" href="${S(l)}">`).join(`
3
3
  `),u=n.length>0?`
4
4
  <script type="module">
5
5
  import { hydrateIslands } from '/@what/islands.js';
6
6
  hydrateIslands();
7
- <\/script>`:"",d=s.map(l=>`<script type="module" src="${w(l)}"><\/script>`).join(`
7
+ <\/script>`:"",d=a.map(l=>`<script type="module" src="${S(l)}"><\/script>`).join(`
8
8
  `),f=o==="client"?`
9
9
  <script type="module" src="/@what/client.js"><\/script>`:"";return`<!DOCTYPE html>
10
10
  <html lang="en">
@@ -12,7 +12,7 @@ import{AsyncLocalStorage as ze}from"node:async_hooks";import{__installServerCont
12
12
  <meta charset="UTF-8">
13
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
14
  ${i}
15
- <title>${w(t)}</title>
15
+ <title>${S(t)}</title>
16
16
  ${c}
17
17
  </head>
18
18
  <body>
@@ -21,4 +21,4 @@ import{AsyncLocalStorage as ze}from"node:async_hooks";import{__installServerCont
21
21
  ${d}
22
22
  ${f}
23
23
  </body>
24
- </html>`}function Tr(t){return t._server=!0,t}var $=!(typeof process<"u");function pt(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&$&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var Oe=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Ce=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function _(t){if(t&&t.code==="ERR_COMPILED_JSX_IN_SSR")throw t}function ve(t){return!!t&&typeof t=="object"&&typeof t.nodeType=="number"}function ht(t,e){if(!(typeof t=="string"&&Ce.test(t)))throw ve(e)?Object.assign(new Error('[what-server] Cannot server-render a DOM node. A component compiled by what-compiler returns a cloned template (finished DOM), not a vnode, so it has no server-rendered form. Author server-rendered views with h(), or compile them with the automatic JSX runtime (jsxImportSource: "what-framework") instead of what-compiler.'),{code:"ERR_COMPILED_JSX_IN_SSR"}):Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}function mt(t){let e="";for(let[r,n]of Object.entries(t)){if(r==="key"||r==="ref"||r==="children"||r==="dangerouslySetInnerHTML"||r==="innerHTML")continue;let s=r.toLowerCase();if(s.startsWith("on")&&r.length>2)continue;let a=n;if(typeof a=="function"){try{a=a()}catch(o){$&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(r)}: its value threw during SSR: ${o.message}`);continue}if(typeof a=="function")continue}if(a===!1&&(we(r)||r.startsWith("data-"))){e+=` ${r}="false"`;continue}if(!(a===!1||a==null)){if(!Oe.test(r)){$&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(r)}`);continue}if($e.has(s)){$&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(r)}`);continue}if(r==="className"||r==="class")e+=` class="${w(String(a))}"`;else if(r==="style"&&typeof a=="object"){let o=Object.entries(a).map(([i,c])=>`${Ie(i)}:${c}`).join(";");e+=` style="${w(o)}"`}else if(a===!0)r.startsWith("aria-")||r==="role"||r.startsWith("data-")?e+=` ${r}="true"`:e+=` ${r}`;else{if(xe(r,a))continue;e+=` ${r}="${w(String(a))}"`}}}return e}function xe(t,e){let r=t.toLowerCase();if(!Pe.has(r))return!1;let n=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return n.startsWith("javascript:")||n.startsWith("vbscript:")||n.startsWith("data:")}var Pe=new Set(["href","src","action","formaction","data","ping","xlink:href"]),$e=new Set(["srcdoc"]);function w(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Ie(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var yt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);import Ne from"node:http";var gt=Symbol("what.bodyTooLarge"),It=()=>new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});async function Nt(t){let r=`http://${t.headers.host||"localhost"}${t.url}`,n=new Headers;for(let[a,o]of Object.entries(t.headers))o!=null&&n.set(a,Array.isArray(o)?o.join(", "):String(o));let s;if(t.method!=="GET"&&t.method!=="HEAD"){let a=Number(t.headers["content-length"]),o=Number.isFinite(a)&&a>H,i=[],c=0;for await(let u of t)if(!o){if(c+=u.length,c>H){o=!0,i.length=0;continue}i.push(u)}if(o)return gt;i.length&&(s=Buffer.concat(i))}return new Request(r,{method:t.method,headers:n,body:s})}async function z(t,e){t.statusCode=e.status,e.headers.forEach((n,s)=>t.setHeader(s,n));let r=await e.text();t.end(r)}function jt(t){return async function(r,n){try{let s=await Nt(r);if(s===gt)return await z(n,It());let a=await t(s);await z(n,a)}catch(s){n.headersSent||n.writeHead(500,{"content-type":"text/html; charset=utf-8"}),n.end("<!DOCTYPE html><html><body><h1>500 \u2014 Server Error</h1></body></html>"),console.error("[what-server] request error:",s)}}}function je(t={}){let e=T(t);return async function(n,s,a){let o=await Nt(n);if(o===gt)return await z(s,It());let i=await e(o);if(i.status===404&&typeof a=="function")return a();await z(s,i)}}function He(t={}){let e=T(t),r=Ne.createServer(jt(e)),{scheduler:n}=t;if(n){n.start();let s=()=>{try{n.stop()}catch{}r.close()};process.once("SIGTERM",s),process.once("SIGINT",s)}return r}import{mkdir as De,writeFile as Ht}from"node:fs/promises";import{join as wt,resolve as Dt,sep as Le}from"node:path";import{matchRoute as Me}from"what-router/match";function Fe(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Ue(t,e){return t.replace(/\[\.\.\.(\w+)\]/g,(r,n)=>e[n]??"").replace(/\[(\w+)\]/g,(r,n)=>e[n]??"").replace(/[:*](\w+)/g,(r,n)=>e[n]??"")}function Be(t,e){let r=Dt(t),n=Dt(wt(t,e==="/"?"":e));if(n!==r&&!n.startsWith(r+Le))throw Object.assign(new Error(`[what-server] Refusing to write outside outDir: ${e}`),{code:"ERR_STATIC_WRITE_ESCAPE"});return n}async function Je({routes:t=[],outDir:e,render:r,documentOptions:n={}}={}){let s=[];for(let a of t){let o=a.page&&a.page.mode||a.mode;if(o!=="static"&&o!=="hybrid")continue;let i={default:a.component,loader:a.loader},c=[a.path];if(Fe(a.path)){if(typeof a.getStaticPaths!="function")continue;c=((await a.getStaticPaths()).paths||[]).map(d=>Ue(a.path,d.params||{}))}for(let u of c){let d=Be(e,u),f=Me(u,[a]),p={params:f?f.params:{},query:{}},h=r?await r(i,p):await W(i,p,n);if(await De(d,{recursive:!0}),await Ht(wt(d,"index.html"),h),typeof a.loader=="function"){let m=await a.loader(p);await Ht(wt(d,"__what_data.json"),N({loaderData:m}))}s.push(u)}}return{pages:s}}function Ve(t={}){return T(t)}async function We({outDir:t=".vercel/output",functionName:e="render",runtime:r="nodejs22.x",files:n=null,handler:s="index.mjs",staticDir:a=null}={}){let{mkdir:o,writeFile:i,cp:c}=await import("node:fs/promises"),{join:u,dirname:d}=await import("node:path");await o(t,{recursive:!0});let f={version:3,routes:[{handle:"filesystem"},{src:"/.*",dest:`/${e}`}]};await i(u(t,"config.json"),JSON.stringify(f,null,2)),a&&await c(a,u(t,"static"),{recursive:!0});let l=null;if(n&&typeof n=="object"){l=u(t,"functions",`${e}.func`),await o(l,{recursive:!0});let p={runtime:r,handler:s,launcherType:"Nodejs",shouldAddHelpers:!1,supportsResponseStreaming:!0};await i(u(l,".vc-config.json"),JSON.stringify(p,null,2));for(let[h,m]of Object.entries(n)){let b=u(l,h);await o(d(b),{recursive:!0}),await i(b,m)}s in n||console.warn(`[what-server] buildVercelOutput: files does not include the handler entry "${s}" \u2014 the deploy will 500 until your build emits it.`)}return{config:f,outDir:t,functionDir:l}}Ge(new ze);export{kt as ACTION_ENDPOINT,re as Form,Xt as action,We as buildVercelOutput,D as createActionHandler,ge as createCloudflareHandler,T as createRequestHandler,He as createServer,Ve as createVercelHandler,rt as csrfMetaTag,Er as definePage,Je as exportStatic,ue as fetchActionHandler,Et as formAction,et as generateCsrfToken,Ar as generateStaticPage,Qt as getRegisteredActions,Jt as getRevalidationHandler,F as handleActionRequest,Tt as invalidatePath,ie as nodeActionMiddleware,Zt as onRevalidate,W as renderDocument,Rr as renderPage,Re as renderToHydratableString,P as renderToStream,y as renderToString,Ae as renderToStringAsync,_r as renderToStringWithHead,Z as revalidatePath,Q as revalidateTag,N as serializeState,Tr as server,K as setRevalidationHandler,jt as toNodeListener,At as useAction,Yt as useFormAction,qt as useMutation,Kt as useOptimistic,Rt as validateCsrfToken,je as whatMiddleware};
24
+ </html>`}function kr(t){return t._server=!0,t}var $=!(typeof process<"u");function pt(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&$&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}var Oe=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Ce=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function _(t){if(t&&t.code==="ERR_COMPILED_JSX_IN_SSR")throw t}function ve(t){return!!t&&typeof t=="object"&&typeof t.nodeType=="number"}function ht(t,e){if(!(typeof t=="string"&&Ce.test(t)))throw ve(e)?Object.assign(new Error('[what-server] Cannot server-render a DOM node. A component compiled by what-compiler returns a cloned template (finished DOM), not a vnode, so it has no server-rendered form. Author server-rendered views with h(), or compile them with the automatic JSX runtime (jsxImportSource: "what-framework") instead of what-compiler.'),{code:"ERR_COMPILED_JSX_IN_SSR"}):Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}var xe=new Map([["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"],["acceptCharset","accept-charset"]]);function mt(t){let e="";for(let[r,n]of Object.entries(t)){if(r==="key"||r==="ref"||r==="children"||r==="dangerouslySetInnerHTML"||r==="innerHTML")continue;let a=xe.get(r)||r,s=a.toLowerCase();if(s.startsWith("on")&&a.length>2)continue;let o=n;if(typeof o=="function"){try{o=o()}catch(i){$&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(a)}: its value threw during SSR: ${i.message}`);continue}if(typeof o=="function")continue}if(o===!1&&(we(a)||a.startsWith("data-"))){e+=` ${a}="false"`;continue}if(!(o===!1||o==null)){if(!Oe.test(a)){$&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(a)}`);continue}if(Ie.has(s)){$&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(a)}`);continue}if(a==="class")e+=` class="${S(String(o))}"`;else if(a==="style"&&typeof o=="object"){let i=Object.entries(o).map(([c,u])=>`${Ne(c)}:${u}`).join(";");e+=` style="${S(i)}"`}else if(o===!0)a.startsWith("aria-")||a==="role"||a.startsWith("data-")?e+=` ${a}="true"`:e+=` ${a}`;else{if(Pe(a,o))continue;e+=` ${a}="${S(String(o))}"`}}}return e}function Pe(t,e){let r=t.toLowerCase();if(!$e.has(r))return!1;let n=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return n.startsWith("javascript:")||n.startsWith("vbscript:")||n.startsWith("data:")}var $e=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Ie=new Set(["srcdoc"]);function S(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Ne(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var yt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);import je from"node:http";var gt=Symbol("what.bodyTooLarge"),It=()=>new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});async function Nt(t){let r=`http://${t.headers.host||"localhost"}${t.url}`,n=new Headers;for(let[s,o]of Object.entries(t.headers))o!=null&&n.set(s,Array.isArray(o)?o.join(", "):String(o));let a;if(t.method!=="GET"&&t.method!=="HEAD"){let s=Number(t.headers["content-length"]),o=Number.isFinite(s)&&s>H,i=[],c=0;for await(let u of t)if(!o){if(c+=u.length,c>H){o=!0,i.length=0;continue}i.push(u)}if(o)return gt;i.length&&(a=Buffer.concat(i))}return new Request(r,{method:t.method,headers:n,body:a})}async function z(t,e){t.statusCode=e.status,e.headers.forEach((n,a)=>t.setHeader(a,n));let r=await e.text();t.end(r)}function jt(t){return async function(r,n){try{let a=await Nt(r);if(a===gt)return await z(n,It());let s=await t(a);await z(n,s)}catch(a){n.headersSent||n.writeHead(500,{"content-type":"text/html; charset=utf-8"}),n.end("<!DOCTYPE html><html><body><h1>500 \u2014 Server Error</h1></body></html>"),console.error("[what-server] request error:",a)}}}function He(t={}){let e=v(t);return async function(n,a,s){let o=await Nt(n);if(o===gt)return await z(a,It());let i=await e(o);if(i.status===404&&typeof s=="function")return s();await z(a,i)}}function De(t={}){let e=v(t),r=je.createServer(jt(e)),{scheduler:n}=t;if(n){n.start();let a=()=>{try{n.stop()}catch{}r.close()};process.once("SIGTERM",a),process.once("SIGINT",a)}return r}import{mkdir as Le,writeFile as Ht}from"node:fs/promises";import{join as wt,resolve as Dt,sep as Me}from"node:path";import{matchRoute as Fe}from"what-router/match";function Ue(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Be(t,e){return t.replace(/\[\.\.\.(\w+)\]/g,(r,n)=>e[n]??"").replace(/\[(\w+)\]/g,(r,n)=>e[n]??"").replace(/[:*](\w+)/g,(r,n)=>e[n]??"")}function Je(t,e){let r=Dt(t),n=Dt(wt(t,e==="/"?"":e));if(n!==r&&!n.startsWith(r+Me))throw Object.assign(new Error(`[what-server] Refusing to write outside outDir: ${e}`),{code:"ERR_STATIC_WRITE_ESCAPE"});return n}async function Ve({routes:t=[],outDir:e,render:r,documentOptions:n={}}={}){let a=[];for(let s of t){let o=s.page&&s.page.mode||s.mode;if(o!=="static"&&o!=="hybrid")continue;let i=[s.path];if(Ue(s.path)){if(typeof s.getStaticPaths!="function")continue;i=((await s.getStaticPaths()).paths||[]).map(u=>Be(s.path,u.params||{}))}for(let c of i){let u=Je(e,c),d=Fe(c,[s]),l={params:d?d.params:{},query:{}},p={default:s.component,loader:s.loader},h=typeof p.loader=="function";if(h){let T=p.loader,k;p.loader=R=>k??=new Promise(O=>{O(T.call(p,R))})}let m=r?await r(p,l):await W(p,l,n),w=h?await p.loader(l):void 0;await Le(u,{recursive:!0}),await Ht(wt(u,"index.html"),m),h&&await Ht(wt(u,"__what_data.json"),N({loaderData:w})),a.push(c)}}return{pages:a}}function We(t={}){return v(t)}async function ze({outDir:t=".vercel/output",functionName:e="render",runtime:r="nodejs22.x",files:n=null,handler:a="index.mjs",staticDir:s=null}={}){let{mkdir:o,writeFile:i,cp:c}=await import("node:fs/promises"),{join:u,dirname:d}=await import("node:path");await o(t,{recursive:!0});let f={version:3,routes:[{handle:"filesystem"},{src:"/.*",dest:`/${e}`}]};await i(u(t,"config.json"),JSON.stringify(f,null,2)),s&&await c(s,u(t,"static"),{recursive:!0});let l=null;if(n&&typeof n=="object"){l=u(t,"functions",`${e}.func`),await o(l,{recursive:!0});let p={runtime:r,handler:a,launcherType:"Nodejs",shouldAddHelpers:!1,supportsResponseStreaming:!0};await i(u(l,".vc-config.json"),JSON.stringify(p,null,2));for(let[h,m]of Object.entries(n)){let w=u(l,h);await o(d(w),{recursive:!0}),await i(w,m)}a in n||console.warn(`[what-server] buildVercelOutput: files does not include the handler entry "${a}" \u2014 the deploy will 500 until your build emits it.`)}return{config:f,outDir:t,functionDir:l}}Xe(new Ge);export{kt as ACTION_ENDPOINT,re as Form,Xt as action,ze as buildVercelOutput,D as createActionHandler,ge as createCloudflareHandler,v as createRequestHandler,De as createServer,We as createVercelHandler,rt as csrfMetaTag,Ar as definePage,Ve as exportStatic,ue as fetchActionHandler,Et as formAction,et as generateCsrfToken,Tr as generateStaticPage,qt as getRegisteredActions,Jt as getRevalidationHandler,F as handleActionRequest,Tt as invalidatePath,ie as nodeActionMiddleware,Zt as onRevalidate,W as renderDocument,Er as renderPage,Re as renderToHydratableString,P as renderToStream,y as renderToString,Ae as renderToStringAsync,Rr as renderToStringWithHead,Z as revalidatePath,q as revalidateTag,N as serializeState,kr as server,K as setRevalidationHandler,jt as toNodeListener,At as useAction,Yt as useFormAction,Qt as useMutation,Kt as useOptimistic,Rt as validateCsrfToken,He as whatMiddleware};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "what-server",
3
- "version": "0.13.8",
3
+ "version": "0.13.10",
4
4
  "description": "What Framework - SSR, islands architecture, static generation",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -51,8 +51,8 @@
51
51
  "author": "ZVN DEV (https://zvndev.com)",
52
52
  "license": "MIT",
53
53
  "peerDependencies": {
54
- "what-core": "^0.13.8",
55
- "what-router": "^0.13.8"
54
+ "what-core": "^0.13.10",
55
+ "what-router": "^0.13.10"
56
56
  },
57
57
  "peerDependenciesMeta": {
58
58
  "what-router": {
@@ -50,8 +50,6 @@ export async function exportStatic({ routes = [], outDir, render, documentOption
50
50
  const mode = (route.page && route.page.mode) || route.mode;
51
51
  if (mode !== 'static' && mode !== 'hybrid') continue;
52
52
 
53
- const pageModule = { default: route.component, loader: route.loader };
54
-
55
53
  let concrete = [route.path];
56
54
  if (isDynamic(route.path)) {
57
55
  if (typeof route.getStaticPaths !== 'function') continue; // can't enumerate
@@ -64,18 +62,29 @@ export async function exportStatic({ routes = [], outDir, render, documentOption
64
62
  const matched = matchRoute(urlPath, [route]);
65
63
  const params = matched ? matched.params : {};
66
64
  const reqCtx = { params, query: {} };
65
+ const pageModule = { default: route.component, loader: route.loader };
66
+ const hasLoader = typeof pageModule.loader === 'function';
67
+ // One snapshot per concrete page, shared with default/custom renderers
68
+ // and client navigation. Custom renderers may prepare the context first.
69
+ if (hasLoader) {
70
+ const loader = pageModule.loader;
71
+ let snapshot;
72
+ pageModule.loader = (context) => snapshot ??= new Promise((resolve) => {
73
+ resolve(loader.call(pageModule, context));
74
+ });
75
+ }
67
76
 
68
77
  const html = render
69
78
  ? await render(pageModule, reqCtx)
70
79
  : await renderDocument(pageModule, reqCtx, documentOptions);
80
+ const loaderData = hasLoader ? await pageModule.loader(reqCtx) : undefined;
71
81
 
72
82
  await mkdir(dirPath, { recursive: true });
73
83
  await writeFile(join(dirPath, 'index.html'), html);
74
84
 
75
85
  // data.json for client-side navigation (loader data without a round-trip)
76
- if (typeof route.loader === 'function') {
77
- const data = await route.loader(reqCtx);
78
- await writeFile(join(dirPath, '__what_data.json'), serializeState({ loaderData: data }));
86
+ if (hasLoader) {
87
+ await writeFile(join(dirPath, '__what_data.json'), serializeState({ loaderData }));
79
88
  }
80
89
 
81
90
  written.push(urlPath);
package/src/index.js CHANGED
@@ -848,10 +848,28 @@ function assertSafeTag(tag, vnode) {
848
848
  );
849
849
  }
850
850
 
851
+ // Prop names whose HTML attribute is not just the prop name in another case.
852
+ // The client reaches the right attribute through the element's reflected DOM
853
+ // property (`label.htmlFor = x` writes `for`), and the compiler and head.js
854
+ // rename the same props. Markup has no properties, so the server must rename
855
+ // them itself: an unrenamed `htmlFor="x"` parses as a meaningless `htmlfor`
856
+ // attribute, and hydration never corrects a static attribute.
857
+ //
858
+ // Names that differ from their attribute only by case (tabIndex, readOnly,
859
+ // maxLength, contentEditable) need no entry. HTML attribute names are
860
+ // case-insensitive and the parser lowercases them.
861
+ const ATTRIBUTE_ALIASES = new Map([
862
+ ['className', 'class'],
863
+ ['htmlFor', 'for'],
864
+ ['httpEquiv', 'http-equiv'],
865
+ ['acceptCharset', 'accept-charset'],
866
+ ]);
867
+
851
868
  function renderAttrs(props) {
852
869
  let out = '';
853
- for (const [key, rawVal] of Object.entries(props)) {
854
- if (key === 'key' || key === 'ref' || key === 'children' || key === 'dangerouslySetInnerHTML' || key === 'innerHTML') continue;
870
+ for (const [propKey, rawVal] of Object.entries(props)) {
871
+ if (propKey === 'key' || propKey === 'ref' || propKey === 'children' || propKey === 'dangerouslySetInnerHTML' || propKey === 'innerHTML') continue;
872
+ const key = ATTRIBUTE_ALIASES.get(propKey) || propKey;
855
873
  const lowerKey = key.toLowerCase();
856
874
  if (lowerKey.startsWith('on') && key.length > 2) continue; // Skip event handlers in SSR
857
875
 
@@ -907,7 +925,7 @@ function renderAttrs(props) {
907
925
  continue;
908
926
  }
909
927
 
910
- if (key === 'className' || key === 'class') {
928
+ if (key === 'class') {
911
929
  out += ` class="${escapeHtml(String(val))}"`;
912
930
  } else if (key === 'style' && typeof val === 'object') {
913
931
  const css = Object.entries(val)