what-server 0.12.4 → 0.13.0

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.
@@ -1 +1 @@
1
- import{signal as p,batch as v}from"what-core";var m=null,k=!(typeof process<"u");async function b(e,t){if(m&&m.revalidatePath)return m.revalidatePath(e,t);k&&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 S(e,t){if(m&&m.revalidateTag)return m.revalidateTag(e,t);k&&console.warn(`[what] revalidateTag('${e}') had no effect: no cache engine is bound.`)}var A=new Map;function P(){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 U(){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 new Error("[what] No secure random source available for CSRF token generation")}function R(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 O(e){return`<meta name="what-csrf-token" content="${String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var T=0,x=!1;function C(){return!x&&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${(++T).toString(36)}_${Date.now().toString(36)}`}`}function N(e,t={}){let r=t.id||C(),{onError:n,onSuccess:f,revalidate:o}=t;typeof window>"u"&&A.set(r,{fn:e,options:t});async function a(...s){if(typeof window>"u")return e(...s);let i=t.timeout||3e4,u=new AbortController,c=setTimeout(()=>u.abort(),i);try{let l=P(),d={"Content-Type":"application/json","X-What-Action":r};l&&(d["X-CSRF-Token"]=l);let g=await fetch("/__what_action",{method:"POST",headers:d,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:s})});if(!g.ok){let w=await g.json().catch(()=>({message:"Action failed"}));throw new Error(w.message||"Action failed")}let h=await g.json();if(f&&f(h),o)for(let w of o)D(w);return h}catch(l){if(l.name==="AbortError"){let d=new Error(`Action "${r}" timed out after ${i}ms`);throw d.code="TIMEOUT",n&&n(d),d}throw n&&n(l),l}finally{clearTimeout(c)}}return a._actionId=r,a._isAction=!0,a}function _(e,t={}){let{onSuccess:r,onError:n,resetOnSuccess:f=!0}=t;return async o=>{let a,s;o instanceof Event?(o.preventDefault(),s=o.target,a=new FormData(s)):a=o;let i={},u=!1;for(let[c,l]of a.entries())typeof File<"u"&&l instanceof File&&(u=!0),i[c]?Array.isArray(i[c])?i[c].push(l):i[c]=[i[c],l]:i[c]=l;try{let c=u?await e(i,a):await e(i);return r&&r(c,s),f&&s&&s.reset(),c}catch(c){throw n&&n(c,s),c}}}function E(e){let t=p(!1),r=p(null),n=p(null);async function f(...o){t.set(!0),r.set(null);try{let a=await e(...o);return n.set(a),a}catch(a){throw r.set(a),a}finally{t.set(!1)}}return{trigger:f,isPending:()=>t(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function j(e,t={}){let{resetOnSuccess:r=!0}=t,n={current:null},f=E(_(e,{resetOnSuccess:r}));function o(a){a.preventDefault();let s=new FormData(a.target);return n.current=a.target,f.trigger(s)}return{...f,handleSubmit:o,formRef:n}}function M(e,t){let r=p(e),n=p([]),f=p(e);function o(u){let c=t(r.peek(),u);v(()=>{n.set([...n.peek(),u]),r.set(c)})}function a(u,c){v(()=>{if(n.set(n.peek().filter(l=>l!==u)),c!==void 0){f.set(c);let l=c;for(let d of n.peek())l=t(l,d);r.set(l)}})}function s(u,c){v(()=>{let l=n.peek().filter(h=>h!==u);n.set(l);let d=c!==void 0?c:f.peek();f.set(d);let g=d;for(let h of l)g=t(g,h);r.set(g)})}async function i(u,c){o(u);try{let l=await c();return a(u,l),l}catch(l){throw s(u),l}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:o,resolve:a,rollback:s,withOptimistic:i,set:u=>{r.set(u),f.set(u)}}}var y=new Map;function V(e,t){return y.has(e)||y.set(e,new Set),y.get(e).add(t),()=>{y.get(e)?.delete(t)}}function D(e){let t=y.get(e);if(t)for(let r of t)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function H(e,t,r,n={}){let{csrfToken:f,skipCsrf:o=!1}=n;if(!o){if(!f)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=e?.headers?.["x-csrf-token"]||e?.headers?.["X-CSRF-Token"];if(!R(s,f))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=A.get(t);return a?Array.isArray(r)?a.fn(...r).then(async s=>{let i=a.options||{};if(Array.isArray(i.revalidate))for(let u of i.revalidate)await b(u);if(Array.isArray(i.revalidateTags))for(let u of i.revalidateTags)await S(u);return{status:200,body:s}}).catch(s=>(console.error(`[what] Action "${t}" 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 W(){return[...A.keys()]}function X(e,t={}){let{onSuccess:r,onError:n,onSettled:f}=t,o={isPending:p(!1),error:p(null),data:p(null)};async function a(...s){o.isPending.set(!0),o.error.set(null);try{let i=await e(...s);return o.data.set(i),r&&r(i,...s),i}catch(i){throw o.error.set(i),n&&n(i,...s),i}finally{o.isPending.set(!1),f&&f(o.data.peek(),o.error.peek(),...s)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}export{N as action,O as csrfMetaTag,_ as formAction,U as generateCsrfToken,W as getRegisteredActions,H as handleActionRequest,D as invalidatePath,V as onRevalidate,E as useAction,j as useFormAction,X as useMutation,M as useOptimistic,R as validateCsrfToken};
1
+ import{signal as p,batch as v}from"what-core";var m=null,k=!(typeof process<"u");async function b(e,t){if(m&&m.revalidatePath)return m.revalidatePath(e,t);k&&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 R(e,t){if(m&&m.revalidateTag)return m.revalidateTag(e,t);k&&console.warn(`[what] revalidateTag('${e}') had no effect: no cache engine is bound.`)}var A=new Map;function S(){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 N(){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 C(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 U(e){return`<meta name="what-csrf-token" content="${String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var P=0,T=!1;function x(){return!T&&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${(++P).toString(36)}_${Date.now().toString(36)}`}`}function $(e,t={}){let r=t.id||x(),{onError:n,onSuccess:f,revalidate:o}=t;typeof window>"u"&&A.set(r,{fn:e,options:t});async function a(...s){if(typeof window>"u")return e(...s);let i=t.timeout||3e4,u=new AbortController,c=setTimeout(()=>u.abort(),i);try{let l=S(),d={"Content-Type":"application/json","X-What-Action":r};l&&(d["X-CSRF-Token"]=l);let g=await fetch("/__what_action",{method:"POST",headers:d,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:s})});if(!g.ok){let w=await g.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(w.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await g.json();if(f&&f(h),o)for(let w of o)D(w);return h}catch(l){if(l.name==="AbortError"){let d=new Error(`Action "${r}" timed out after ${i}ms`);throw d.code="TIMEOUT",n&&n(d),d}throw n&&n(l),l}finally{clearTimeout(c)}}return a._actionId=r,a._isAction=!0,a}function _(e,t={}){let{onSuccess:r,onError:n,resetOnSuccess:f=!0}=t;return async o=>{let a,s;o instanceof Event?(o.preventDefault(),s=o.target,a=new FormData(s)):a=o;let i={},u=!1;for(let[c,l]of a.entries())typeof File<"u"&&l instanceof File&&(u=!0),i[c]?Array.isArray(i[c])?i[c].push(l):i[c]=[i[c],l]:i[c]=l;try{let c=u?await e(i,a):await e(i);return r&&r(c,s),f&&s&&s.reset(),c}catch(c){throw n&&n(c,s),c}}}function E(e){let t=p(!1),r=p(null),n=p(null);async function f(...o){t.set(!0),r.set(null);try{let a=await e(...o);return n.set(a),a}catch(a){throw r.set(a),a}finally{t.set(!1)}}return{trigger:f,isPending:()=>t(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function j(e,t={}){let{resetOnSuccess:r=!0}=t,n={current:null},f=E(_(e,{resetOnSuccess:r}));function o(a){a.preventDefault();let s=new FormData(a.target);return n.current=a.target,f.trigger(s)}return{...f,handleSubmit:o,formRef:n}}function M(e,t){let r=p(e),n=p([]),f=p(e);function o(u){let c=t(r.peek(),u);v(()=>{n.set([...n.peek(),u]),r.set(c)})}function a(u,c){v(()=>{if(n.set(n.peek().filter(l=>l!==u)),c!==void 0){f.set(c);let l=c;for(let d of n.peek())l=t(l,d);r.set(l)}})}function s(u,c){v(()=>{let l=n.peek().filter(h=>h!==u);n.set(l);let d=c!==void 0?c:f.peek();f.set(d);let g=d;for(let h of l)g=t(g,h);r.set(g)})}async function i(u,c){o(u);try{let l=await c();return a(u,l),l}catch(l){throw s(u),l}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:o,resolve:a,rollback:s,withOptimistic:i,set:u=>{r.set(u),f.set(u)}}}var y=new Map;function V(e,t){return y.has(e)||y.set(e,new Set),y.get(e).add(t),()=>{y.get(e)?.delete(t)}}function D(e){let t=y.get(e);if(t)for(let r of t)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function H(e,t,r,n={}){let{csrfToken:f,skipCsrf:o=!1}=n;if(!o){if(!f)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=e?.headers?.["x-csrf-token"]||e?.headers?.["X-CSRF-Token"];if(!C(s,f))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=A.get(t);return a?Array.isArray(r)?a.fn(...r).then(async s=>{let i=a.options||{};if(Array.isArray(i.revalidate))for(let u of i.revalidate)await b(u);if(Array.isArray(i.revalidateTags))for(let u of i.revalidateTags)await R(u);return{status:200,body:s}}).catch(s=>(console.error(`[what] Action "${t}" 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 W(){return[...A.keys()]}function X(e,t={}){let{onSuccess:r,onError:n,onSettled:f}=t,o={isPending:p(!1),error:p(null),data:p(null)};async function a(...s){o.isPending.set(!0),o.error.set(null);try{let i=await e(...s);return o.data.set(i),r&&r(i,...s),i}catch(i){throw o.error.set(i),n&&n(i,...s),i}finally{o.isPending.set(!1),f&&f(o.data.peek(),o.error.peek(),...s)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}export{$ as action,U as csrfMetaTag,_ as formAction,N as generateCsrfToken,W as getRegisteredActions,H as handleActionRequest,D as invalidatePath,V as onRevalidate,E as useAction,j as useFormAction,X as useMutation,M as useOptimistic,C as validateCsrfToken};
package/dist/index.min.js CHANGED
@@ -1,4 +1,4 @@
1
- import{h as tt,_isAriaAttr as ue,_beginComponentSSR as et,_endComponentSSR as nt,_mapArrayToArray as rt,getServerContext as Et,runWithServerContext as S,beginHeadCollection as de,endHeadCollection as ot}from"what-core";var $t=new RegExp("[<>&\\u2028\\u2029]","g"),Pt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function J(t){return JSON.stringify(t).replace($t,e=>Pt[e.charCodeAt(0)])}import{mount as Re,hydrate as Ce,signal as Oe,batch as $e,getServerContext as xt}from"what-core";var vt=new Map;function It(t){let e=t||xt();return e&&e.islandStores instanceof Map?e.islandStores:null}function ht(t){let e=typeof document<"u"?vt:It(t),n={};for(let[r,s]of e||[])n[r]=s._getSnapshot();return n}import{signal as _,batch as X}from"what-core";var T=null,yt=!(typeof process<"u");function V(t){T=t}function Nt(){return T}async function W(t,e){if(T&&T.revalidatePath)return T.revalidatePath(t,e);yt&&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 z(t,e){if(T&&T.revalidateTag)return T.revalidateTag(t,e);yt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var Y=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 K(){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 new Error("[what] No secure random source available for CSRF token generation")}function mt(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function G(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Dt=0,Lt=!1;function jt(){return!Lt&&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${(++Dt).toString(36)}_${Date.now().toString(36)}`}`}function Mt(t,e={}){let n=e.id||jt(),{onError:r,onSuccess:s,revalidate:a}=e;typeof window>"u"&&Y.set(n,{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=Ht(),l={"Content-Type":"application/json","X-What-Action":n};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 new Error(w.message||"Action failed")}let h=await p.json();if(s&&s(h),a)for(let w of a)St(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${n}" timed out after ${c}ms`);throw l.code="TIMEOUT",r&&r(l),l}throw r&&r(f),f}finally{clearTimeout(d)}}return o._actionId=n,o._isAction=!0,o}function gt(t,e={}){let{onSuccess:n,onError:r,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 n&&n(d,i),s&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function wt(t){let e=_(!1),n=_(null),r=_(null);async function s(...a){e.set(!0),n.set(null);try{let o=await t(...a);return r.set(o),o}catch(o){throw n.set(o),o}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function Ft(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},s=wt(gt(t,{resetOnSuccess:n}));function a(o){o.preventDefault();let i=new FormData(o.target);return r.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:r}}function Ut(t,e){let n=_(t),r=_([]),s=_(t);function a(u){let d=e(n.peek(),u);X(()=>{r.set([...r.peek(),u]),n.set(d)})}function o(u,d){X(()=>{if(r.set(r.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of r.peek())f=e(f,l);n.set(f)}})}function i(u,d){X(()=>{let f=r.peek().filter(h=>h!==u);r.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);n.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:()=>n(),isPending:()=>r().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{n.set(u),s.set(u)}}}var I=new Map;function Bt(t,e){return I.has(t)||I.set(t,new Set),I.get(t).add(e),()=>{I.get(t)?.delete(e)}}function St(t){let e=I.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function D(t,e,n,r={}){let{csrfToken:s,skipCsrf:a=!1}=r;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(!mt(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=Y.get(e);return o?Array.isArray(n)?o.fn(...n).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await W(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await z(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 Jt(){return[...Y.keys()]}function Vt(t,e={}){let{onSuccess:n,onError:r,onSettled:s}=e,a={isPending:_(!1),error:_(null),data:_(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await t(...i);return a.data.set(c),n&&n(c,...i),c}catch(c){throw a.error.set(c),r&&r(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 bt="/__what_action";function Wt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw 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.")}throw new Error("[what] <Form> requires an `action` prop: a server action or its id.")}function zt(){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 Xt({action:t,csrfToken:e,redirect:n,method:r="post",enhance:s=!0,children:a,...o}){let i=Wt(t),c=e!==void 0?e:zt();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||""})];n&&u.push(L("input",{type:"hidden",name:"_redirect",value:n}));let d={...o,method:r,action:o.action||bt,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return L("form",d,...u,...f)}var Yt="/__what_action",At=1024*1024;function Kt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,s)=>{n[s.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function j(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function Z(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 _t(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 Gt(t,e){let n=_t(t&&t._redirect);if(n)return n;let r=e.referer||e.referrer;if(r)try{let s=new URL(r,"http://localhost"),a=_t(s.pathname+s.search);if(a)return a}catch{}return"/"}var Zt=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function N(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return j(405,{message:"Method Not Allowed"});let o=Kt(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=n?void 0:e?await e(s):void 0;if(u){let h=s.body||{},w=h._action||h["data-action"]||s.query&&s.query.action;if(!w)return Z(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)),!n&&e&&!d)return Z(403,"Missing CSRF token");let O={};for(let[$,U]of Object.entries(h))Zt.has($)||(O[$]=U);let R=await D({headers:b},w,[O],{csrfToken:d,skipCsrf:n});return R.status===200?{status:303,headers:{location:Gt(h,o)},body:""}:Z(R.status,R.body&&R.body.message||"Action failed")}if(!i)return j(400,{message:"Missing X-What-Action header"});if(!n&&e&&!d)return j(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await D({headers:o},i,l,{csrfToken:d,skipCsrf:n});return j(p.status,p.body)}}function Qt(t={}){let e=t.basePath||Yt,n=N(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 qt(s);u=M(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 n({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function M(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let n={};for(let[r,s]of new URLSearchParams(String(t)))n[r]===void 0?n[r]=s:Array.isArray(n[r])?n[r].push(s):n[r]=[n[r],s];return n}return t==null||t===""?{}:JSON.parse(String(t))}async function F(t,e=At){let n=Number(t.headers.get("content-length"));if(Number.isFinite(n)&&n>e)return{tooLarge:!0};let r=t.body;if(!r||typeof r.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=r.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 qt(t){return new Promise((e,n)=>{let r=0,s=[];t.on("data",a=>{if(r+=a.length,r>At){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",n(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",n)})}function te(t={}){let e=N(t);return async function(n){let r={};try{let o=await F(n);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});r=M(o.raw,n.headers.get("content-type")||"")}catch{r={}}let s={};try{s=Object.fromEntries(new URL(n.url,"http://localhost").searchParams)}catch{}let a=await e({method:n.method,headers:n.headers,body:r,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as ee,parseQuery as ne}from"what-router/match";var re="/__what_action",oe="/__what_revalidate",Q="what-csrf";function H(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}function kt(t,e){if(!t)return null;let n=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return n?decodeURIComponent(n[1]):null}async function ae(t){try{let e=await F(t);return e.tooLarge?{tooLarge:!0}:M(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function se(t){let e;try{e=await F(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw)}}catch{return{json:{}}}}function ie(t){return async function(n){let{route:r,params:s,query:a,request:o,csrfToken:i}=n,c={default:r.component,loader:r.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 Tt(c,u,d),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function q(t={}){let{routes:e=[],cache:n,render:r,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||N(u?{getCsrfToken:l=>kt(l.headers&&l.headers.cookie,Q)}:{skipCsrf:!0}),f=r||ie(a);return n&&(n.revalidatePath||n.revalidateTag)&&V({revalidatePath:n.revalidatePath,revalidateTag:n.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===re){let m=await ae(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let k=await d({method:"POST",headers:H(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(k.body,{status:k.status,headers:k.headers})}let b=null,C=null;if(u&&(b=kt(H(p.headers).cookie,Q),!b)){b=K();let k=H(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${Q}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(k?"; Secure":"")}let O=m=>(C&&(m["set-cookie"]=C),m);if(p.method==="POST"&&w===oe&&s){let m=await se(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let k=await s({headers:H(p.headers),body:m.json});return new Response(JSON.stringify(k.body),{status:k.status,headers:{"content-type":"application/json"}})}let R=ee(w,e);if(!R){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:U}=R,B=$.page||{mode:$.mode||"client"},v={path:w,query:ne(h.search),config:B,route:$,params:U,request:p};if(n&&B.mode!=="server"){v.varyHeaders=H(p.headers);let m=await n.handle(v,()=>f(v));return new Response(m.html,{status:m.status||200,headers:O({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}b&&(v.csrfToken=b);let lt=await f(v),pt=O({"content-type":"text/html; charset=utf-8"});return B.mode==="server"&&(pt["Cache-Control"]="private, no-store"),new Response(lt.html,{status:lt.status||200,headers:pt})}}function ce(t={}){let e=q(t);return{async fetch(n,r,s){return r&&(n.__env=r),s&&(n.__ctx=s),e(n)}}}function E(t){return{head:de(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var Rt=0;function fe(){Rt=0}function le(){return"h"+Rt++}function pe(t){if(!Et()){let e=E(void 0);return S(e,()=>pe(t))}return fe(),A(t)}var Ct=new Set(["__errorBoundary","__suspense"]),at=new Set(["__portal"]);function st(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function it(t,e){let n=t.props&&t.props.fallback;if(typeof n!="function")return n;let r=t.props&&t.props.reset||(()=>{});try{return n({error:e,reset:r})}catch(s){return x&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.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(rt(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${A(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(A).join("")}<!--/[]-->`;if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(A).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return A(it(t,u?null:c))}if(typeof t.tag=="function"){let c=le(),u=et(t.tag),d;try{d=A(t.tag(st(t)))}finally{nt(u)}return he(d,c)}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(A).join("");return`${a}${i}</${e}>`}function he(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],s=n[2],a=r.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(!Et()){let c=E(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(rt(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(it(t,u?null:c))}if(typeof t.tag=="function"){let c=et(t.tag);try{return y(t.tag(st(t)))}finally{nt(c)}}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(y).join("");return`${a}${i}</${e}>`}function Ze(t){let e=E(void 0);return{body:S(e,()=>y(t)),head:ot(e.head)}}async function Qe(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,s=E(r),a=e.params||{};return{body:S(s,()=>y(tt(n,{...a,loaderData:r}))),head:ot(s.head),loaderData:r}}var Ot=12;async function ye(t,e){e||(e=E(void 0));let n="";for(let s=0;s<Ot;s++){n=S(e,()=>y(t));let a=[...e.resources.values()].filter(o=>o.status==="pending").map(o=>o.promise);if(a.length===0)break;await Promise.all(a)}let r={};for(let[s,a]of e.resources)a.status==="ready"&&(r[s]=a.value);return{body:n,head:ot(e.head),loaderData:e.loaderData,resources:r,ctx:e}}async function Tt(t,e={},n={}){let r=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,a=E(s),o=e.params||{},{body:i,head:c,resources:u}=await ye(tt(r,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:ht(a)};return me({body:i,head:c,payload:d,options:n})}function me({body:t,head:e,payload:n,options:r={}}){let s=r.lang||"en",a=`<script id="__what_data" type="application/json">${J(n)}<\/script>`,o=r.clientEntry?`<script type="module" src="${g(r.clientEntry)}"><\/script>`:"",c=(r.csrfToken?G(r.csrfToken):"")+(r.head||""),u=r.bodyClass?` class="${g(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(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=E(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 o=S(e,()=>t());yield*P(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=S(e,()=>rt(t))}catch{typeof process<"u"}o&&(yield*P(o,e));return}if(typeof t=="function"){try{let o=S(e,()=>t());yield*P(o,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*P(o,e);return}if(at.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;o=S(e,()=>y(it(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null;for(let i=0;i<Ot&&o===null;i++){let c=null;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(o===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}o===null&&(o=S(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=et(t.tag);try{let i=S(e,()=>t.tag(st(t))),c=i instanceof Promise?await i:i;yield*P(c,e)}catch(i){typeof process<"u",yield x?`<!-- SSR Error: ${g(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{nt(o)}return}let{tag:n,props:r,children:s}=t;ut(n);let a=dt(r||{});if(yield`<${n}${a}>`,!ft.has(n)){let o=ct(r);if(o!=null)yield String(o);else for(let i of s)yield*P(i,e);yield`</${n}>`}}function qe(t){return{mode:"static",...t}}function tn(t,e={}){let n=E(e),r=S(n,()=>y(tt(t.component,e))),s=t.islands||[];return ge({title:t.title||"",meta:t.meta||{},body:r,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ge({title:t,meta:e,body:n,islands:r,scripts:s,styles:a,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
1
+ import{h as tt,_isAriaAttr as ue,_beginComponentSSR as et,_endComponentSSR as nt,_mapArrayToArray as rt,getServerContext as Tt,runWithServerContext as S,beginHeadCollection as de,endHeadCollection as ot}from"what-core";var $t=new RegExp("[<>&\\u2028\\u2029]","g"),Pt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function J(t){return JSON.stringify(t).replace($t,e=>Pt[e.charCodeAt(0)])}import{mount as ke,hydrate as Ce,signal as Oe,batch as $e,getServerContext as xt}from"what-core";var vt=new Map;function It(t){let e=t||xt();return e&&e.islandStores instanceof Map?e.islandStores:null}function ht(t){let e=typeof document<"u"?vt:It(t),n={};for(let[r,s]of e||[])n[r]=s._getSnapshot();return n}import{signal as _,batch as G}from"what-core";var E=null,yt=!(typeof process<"u");function V(t){E=t}function Nt(){return E}async function W(t,e){if(E&&E.revalidatePath)return E.revalidatePath(t,e);yt&&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 z(t,e){if(E&&E.revalidateTag)return E.revalidateTag(t,e);yt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var X=new Map;function Dt(){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 Y(){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 mt(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function K(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Ht=0,Lt=!1;function jt(){return!Lt&&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${(++Ht).toString(36)}_${Date.now().toString(36)}`}`}function Mt(t,e={}){let n=e.id||jt(),{onError:r,onSuccess:s,revalidate:a}=e;typeof window>"u"&&X.set(n,{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=Dt(),l={"Content-Type":"application/json","X-What-Action":n};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)St(w);return h}catch(f){if(f.name==="AbortError"){let l=new Error(`Action "${n}" timed out after ${c}ms`);throw l.code="TIMEOUT",r&&r(l),l}throw r&&r(f),f}finally{clearTimeout(d)}}return o._actionId=n,o._isAction=!0,o}function gt(t,e={}){let{onSuccess:n,onError:r,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 n&&n(d,i),s&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function wt(t){let e=_(!1),n=_(null),r=_(null);async function s(...a){e.set(!0),n.set(null);try{let o=await t(...a);return r.set(o),o}catch(o){throw n.set(o),o}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function Ft(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},s=wt(gt(t,{resetOnSuccess:n}));function a(o){o.preventDefault();let i=new FormData(o.target);return r.current=o.target,s.trigger(i)}return{...s,handleSubmit:a,formRef:r}}function Ut(t,e){let n=_(t),r=_([]),s=_(t);function a(u){let d=e(n.peek(),u);G(()=>{r.set([...r.peek(),u]),n.set(d)})}function o(u,d){G(()=>{if(r.set(r.peek().filter(f=>f!==u)),d!==void 0){s.set(d);let f=d;for(let l of r.peek())f=e(f,l);n.set(f)}})}function i(u,d){G(()=>{let f=r.peek().filter(h=>h!==u);r.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);n.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:()=>n(),isPending:()=>r().length>0,addOptimistic:a,resolve:o,rollback:i,withOptimistic:c,set:u=>{n.set(u),s.set(u)}}}var I=new Map;function Bt(t,e){return I.has(t)||I.set(t,new Set),I.get(t).add(e),()=>{I.get(t)?.delete(e)}}function St(t){let e=I.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function H(t,e,n,r={}){let{csrfToken:s,skipCsrf:a=!1}=r;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(!mt(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let o=X.get(e);return o?Array.isArray(n)?o.fn(...n).then(async i=>{let c=o.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await W(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await z(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 Jt(){return[...X.keys()]}function Vt(t,e={}){let{onSuccess:n,onError:r,onSettled:s}=e,a={isPending:_(!1),error:_(null),data:_(null)};async function o(...i){a.isPending.set(!0),a.error.set(null);try{let c=await t(...i);return a.data.set(c),n&&n(c,...i),c}catch(c){throw a.error.set(c),r&&r(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 bt="/__what_action";function Wt(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 zt(){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 Gt({action:t,csrfToken:e,redirect:n,method:r="post",enhance:s=!0,children:a,...o}){let i=Wt(t),c=e!==void 0?e:zt();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||""})];n&&u.push(L("input",{type:"hidden",name:"_redirect",value:n}));let d={...o,method:r,action:o.action||bt,"data-action":i};s&&(d["data-enhance"]="");let f=a==null?[]:Array.isArray(a)?a:[a];return L("form",d,...u,...f)}var Xt="/__what_action",Rt=1024*1024;function Yt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,s)=>{n[s.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function j(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function Z(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 _t(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 Kt(t,e){let n=_t(t&&t._redirect);if(n)return n;let r=e.referer||e.referrer;if(r)try{let s=new URL(r,"http://localhost"),a=_t(s.pathname+s.search);if(a)return a}catch{}return"/"}var Zt=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function N(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return j(405,{message:"Method Not Allowed"});let o=Yt(s.headers),i=o["x-what-action"],c=o["content-type"]||"",u=!i&&c.includes("application/x-www-form-urlencoded"),d=n?void 0:e?await e(s):void 0;if(u){let h=s.body||{},w=h._action||h["data-action"]||s.query&&s.query.action;if(!w)return Z(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)),!n&&e&&!d)return Z(403,"Missing CSRF token");let O={};for(let[$,U]of Object.entries(h))Zt.has($)||(O[$]=U);let k=await H({headers:b},w,[O],{csrfToken:d,skipCsrf:n});return k.status===200?{status:303,headers:{location:Kt(h,o)},body:""}:Z(k.status,k.body&&k.body.message||"Action failed")}if(!i)return j(400,{message:"Missing X-What-Action header"});if(!n&&e&&!d)return j(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await H({headers:o},i,l,{csrfToken:d,skipCsrf:n});return j(p.status,p.body)}}function Qt(t={}){let e=t.basePath||Xt,n=N(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 qt(s);u=M(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 n({method:s.method,headers:s.headers,body:u,query:d});a.writeHead(f.status,f.headers),a.end(f.body)}}function M(t,e){if((e||"").includes("application/x-www-form-urlencoded")){let n={};for(let[r,s]of new URLSearchParams(String(t)))n[r]===void 0?n[r]=s:Array.isArray(n[r])?n[r].push(s):n[r]=[n[r],s];return n}return t==null||t===""?{}:JSON.parse(String(t))}async function F(t,e=Rt){let n=Number(t.headers.get("content-length"));if(Number.isFinite(n)&&n>e)return{tooLarge:!0};let r=t.body;if(!r||typeof r.getReader!="function"){let i=await t.text();return Buffer.byteLength(i,"utf8")>e?{tooLarge:!0}:{raw:i}}let s=r.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 qt(t){return new Promise((e,n)=>{let r=0,s=[];t.on("data",a=>{if(r+=a.length,r>Rt){let o=new Error("Body too large");o.code="BODY_TOO_LARGE",n(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",n)})}function te(t={}){let e=N(t);return async function(n){let r={};try{let o=await F(n);if(o.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});r=M(o.raw,n.headers.get("content-type")||"")}catch{r={}}let s={};try{s=Object.fromEntries(new URL(n.url,"http://localhost").searchParams)}catch{}let a=await e({method:n.method,headers:n.headers,body:r,query:s});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as ee,parseQuery as ne}from"what-router/match";var re="/__what_action",oe="/__what_revalidate",Q="what-csrf";function D(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}function At(t,e){if(!t)return null;let n=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return n?decodeURIComponent(n[1]):null}async function ae(t){try{let e=await F(t);return e.tooLarge?{tooLarge:!0}:M(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function se(t){let e;try{e=await F(t)}catch{return{json:{}}}if(e.tooLarge)return{tooLarge:!0};try{return{json:JSON.parse(e.raw??"")}}catch{return{json:{}}}}function ie(t){return async function(n){let{route:r,params:s,query:a,request:o,csrfToken:i}=n,c={default:r.component,loader:r.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 Et(c,u,d),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function q(t={}){let{routes:e=[],cache:n,render:r,revalidateWebhook:s,document:a={},notFound:o,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||N(u?{getCsrfToken:l=>At(l.headers&&l.headers.cookie,Q)}:{skipCsrf:!0}),f=r||ie(a);return n&&(n.revalidatePath||n.revalidateTag)&&V({revalidatePath:n.revalidatePath,revalidateTag:n.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===re){let m=await ae(p);if(m&&m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await d({method:"POST",headers:D(p.headers),body:m,query:Object.fromEntries(h.searchParams)});return new Response(A.body,{status:A.status,headers:A.headers})}let b=null,C=null;if(u&&(b=At(D(p.headers).cookie,Q),!b)){b=Y();let A=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${Q}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(A?"; Secure":"")}let O=m=>(C&&(m["set-cookie"]=C),m);if(p.method==="POST"&&w===oe&&s){let m=await se(p);if(m.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let A=await s({headers:D(p.headers),body:m.json});return new Response(JSON.stringify(A.body),{status:A.status,headers:{"content-type":"application/json"}})}let k=ee(w,e);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:U}=k,B=$.page||{mode:$.mode||"client"},v={path:w,query:ne(h.search),config:B,route:$,params:U,request:p};if(n&&B.mode!=="server"){v.varyHeaders=D(p.headers);let m=await n.handle(v,()=>f(v));return new Response(m.html,{status:m.status||200,headers:O({"content-type":"text/html; charset=utf-8",...m.headers||{}})})}b&&(v.csrfToken=b);let lt=await f(v),pt=O({"content-type":"text/html; charset=utf-8"});return B.mode==="server"&&(pt["Cache-Control"]="private, no-store"),new Response(lt.html,{status:lt.status||200,headers:pt})}}function ce(t={}){let e=q(t);return{async fetch(n,r,s){return r&&(n.__env=r),s&&(n.__ctx=s),e(n)}}}function T(t){return{head:de(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var kt=0;function fe(){kt=0}function le(){return"h"+kt++}function pe(t){if(!Tt()){let e=T(void 0);return S(e,()=>pe(t))}return fe(),R(t)}var Ct=new Set(["__errorBoundary","__suspense"]),at=new Set(["__portal"]);function st(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function it(t,e){let n=t.props&&t.props.fallback;if(typeof n!="function")return n;let r=t.props&&t.props.reset||(()=>{});try{return n({error:e,reset:r})}catch(s){return x&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function R(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`<!--$-->${R(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${R(rt(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${R(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(R).join("")}<!--/[]-->`;if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(R).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return R(it(t,u?null:c))}if(typeof t.tag=="function"){let c=le(),u=et(t.tag),d;try{d=R(t.tag(st(t)))}finally{nt(u)}return he(d,c)}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(R).join("");return`${a}${i}</${e}>`}function he(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],s=n[2],a=r.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(!Tt()){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(rt(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return y(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(at.has(t.tag))return"";if(Ct.has(t.tag))try{return(t.children||[]).map(y).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return y(it(t,u?null:c))}if(typeof t.tag=="function"){let c=et(t.tag);try{return y(t.tag(st(t)))}finally{nt(c)}}let{tag:e,props:n,children:r}=t;ut(e);let s=dt(n||{}),a=`<${e}${s}>`;if(ft.has(e))return a;let o=ct(n),i=o!=null?String(o):r.map(y).join("");return`${a}${i}</${e}>`}function Ze(t){let e=T(void 0);return{body:S(e,()=>y(t)),head:ot(e.head)}}async function Qe(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,s=T(r),a=e.params||{};return{body:S(s,()=>y(tt(n,{...a,loaderData:r}))),head:ot(s.head),loaderData:r}}var Ot=12;async function ye(t,e){e||(e=T(void 0));let n="";for(let s=0;s<Ot;s++){n=S(e,()=>y(t));let a=[...e.resources.values()].filter(o=>o.status==="pending").map(o=>o.promise);if(a.length===0)break;await Promise.all(a)}let r={};for(let[s,a]of e.resources)a.status==="ready"&&(r[s]=a.value);return{body:n,head:ot(e.head),loaderData:e.loaderData,resources:r,ctx:e}}async function Et(t,e={},n={}){let r=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,a=T(s),o=e.params||{},{body:i,head:c,resources:u}=await ye(tt(r,{...o,loaderData:s}),a),d={loaderData:s??null,resources:u,islandStores:ht(a)};return me({body:i,head:c,payload:d,options:n})}function me({body:t,head:e,payload:n,options:r={}}){let s=r.lang||"en",a=`<script id="__what_data" type="application/json">${J(n)}<\/script>`,o=r.clientEntry?`<script type="module" src="${g(r.clientEntry)}"><\/script>`:"",c=(r.csrfToken?K(r.csrfToken):"")+(r.head||""),u=r.bodyClass?` class="${g(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${g(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=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 o=S(e,()=>t());yield*P(o,e);return}if(typeof t=="function"&&t._mapArray){let o=null;try{o=S(e,()=>rt(t))}catch{typeof process<"u"}o&&(yield*P(o,e));return}if(typeof t=="function"){try{let o=S(e,()=>t());yield*P(o,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*P(o,e);return}if(at.has(t.tag))return;if(t.tag==="__errorBoundary"){let o;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;o=S(e,()=>y(it(t,i)))}yield o;return}if(t.tag==="__suspense"){let o=null;for(let i=0;i<Ot&&o===null;i++){let c=null;try{o=S(e,()=>(t.children||[]).map(y).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(o===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}o===null&&(o=S(e,()=>y(t.props&&t.props.fallback))),yield o;return}if(typeof t.tag=="function"){let o=et(t.tag);try{let i=S(e,()=>t.tag(st(t))),c=i instanceof Promise?await i:i;yield*P(c,e)}catch(i){typeof process<"u",yield x?`<!-- SSR Error: ${g(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{nt(o)}return}let{tag:n,props:r,children:s}=t;ut(n);let a=dt(r||{});if(yield`<${n}${a}>`,!ft.has(n)){let o=ct(r);if(o!=null)yield String(o);else for(let i of s)yield*P(i,e);yield`</${n}>`}}function qe(t){return{mode:"static",...t}}function tn(t,e={}){let n=T(e),r=S(n,()=>y(tt(t.component,e))),s=t.islands||[];return ge({title:t.title||"",meta:t.meta||{},body:r,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function ge({title:t,meta:e,body:n,islands:r,scripts:s,styles:a,mode:o}){let i=Object.entries(e).map(([l,p])=>`<meta name="${g(l)}" content="${g(p)}">`).join(`
2
2
  `),c=a.map(l=>`<link rel="stylesheet" href="${g(l)}">`).join(`
3
3
  `),u=r.length>0?`
4
4
  <script type="module">
@@ -21,4 +21,4 @@ import{h as tt,_isAriaAttr as ue,_beginComponentSSR as et,_endComponentSSR as nt
21
21
  ${d}
22
22
  ${f}
23
23
  </body>
24
- </html>`}function en(t){return t._server=!0,t}var x=!(typeof process<"u");function ct(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"&&x&&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 we=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Se=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function ut(t){if(typeof t!="string"||!Se.test(t))throw new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`)}function dt(t){let e="";for(let[n,r]of Object.entries(t)){if(n==="key"||n==="ref"||n==="children"||n==="dangerouslySetInnerHTML"||n==="innerHTML")continue;let s=n.toLowerCase();if(s.startsWith("on")&&n.length>2)continue;let a=r;if(typeof a=="function"){try{a=a()}catch(o){x&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(n)}: its value threw during SSR: ${o.message}`);continue}if(typeof a=="function")continue}if(a===!1&&ue(n)){e+=` ${n}="false"`;continue}if(!(a===!1||a==null)){if(!we.test(n)){x&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(n)}`);continue}if(Ae.has(s)){x&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(n)}`);continue}if(n==="className"||n==="class")e+=` class="${g(String(a))}"`;else if(n==="style"&&typeof a=="object"){let o=Object.entries(a).map(([i,c])=>`${ke(i)}:${c}`).join(";");e+=` style="${g(o)}"`}else if(a===!0)n.startsWith("aria-")||n==="role"?e+=` ${n}="true"`:e+=` ${n}`;else{if(be(n,a))continue;e+=` ${n}="${g(String(a))}"`}}}return e}function be(t,e){let n=t.toLowerCase();if(!_e.has(n))return!1;let r=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return r.startsWith("javascript:")||r.startsWith("vbscript:")||r.startsWith("data:")}var _e=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Ae=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 ft=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{bt as ACTION_ENDPOINT,Xt as Form,Mt as action,N as createActionHandler,ce as createCloudflareHandler,q as createRequestHandler,G as csrfMetaTag,qe as definePage,te as fetchActionHandler,gt as formAction,K as generateCsrfToken,tn as generateStaticPage,Jt as getRegisteredActions,Nt as getRevalidationHandler,D as handleActionRequest,St as invalidatePath,Qt as nodeActionMiddleware,Bt as onRevalidate,Tt as renderDocument,Qe as renderPage,pe as renderToHydratableString,P as renderToStream,y as renderToString,ye as renderToStringAsync,Ze as renderToStringWithHead,W as revalidatePath,z as revalidateTag,J as serializeState,en as server,V as setRevalidationHandler,wt as useAction,Ft as useFormAction,Vt as useMutation,Ut as useOptimistic,mt as validateCsrfToken};
24
+ </html>`}function en(t){return t._server=!0,t}var x=!(typeof process<"u");function ct(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"&&x&&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 we=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Se=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function ut(t){if(typeof t!="string"||!Se.test(t))throw Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}function dt(t){let e="";for(let[n,r]of Object.entries(t)){if(n==="key"||n==="ref"||n==="children"||n==="dangerouslySetInnerHTML"||n==="innerHTML")continue;let s=n.toLowerCase();if(s.startsWith("on")&&n.length>2)continue;let a=r;if(typeof a=="function"){try{a=a()}catch(o){x&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(n)}: its value threw during SSR: ${o.message}`);continue}if(typeof a=="function")continue}if(a===!1&&ue(n)){e+=` ${n}="false"`;continue}if(!(a===!1||a==null)){if(!we.test(n)){x&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(n)}`);continue}if(Re.has(s)){x&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(n)}`);continue}if(n==="className"||n==="class")e+=` class="${g(String(a))}"`;else if(n==="style"&&typeof a=="object"){let o=Object.entries(a).map(([i,c])=>`${Ae(i)}:${c}`).join(";");e+=` style="${g(o)}"`}else if(a===!0)n.startsWith("aria-")||n==="role"?e+=` ${n}="true"`:e+=` ${n}`;else{if(be(n,a))continue;e+=` ${n}="${g(String(a))}"`}}}return e}function be(t,e){let n=t.toLowerCase();if(!_e.has(n))return!1;let r=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return r.startsWith("javascript:")||r.startsWith("vbscript:")||r.startsWith("data:")}var _e=new Set(["href","src","action","formaction","data","ping","xlink:href"]),Re=new Set(["srcdoc"]);function g(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Ae(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var ft=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{bt as ACTION_ENDPOINT,Gt as Form,Mt as action,N as createActionHandler,ce as createCloudflareHandler,q as createRequestHandler,K as csrfMetaTag,qe as definePage,te as fetchActionHandler,gt as formAction,Y as generateCsrfToken,tn as generateStaticPage,Jt as getRegisteredActions,Nt as getRevalidationHandler,H as handleActionRequest,St as invalidatePath,Qt as nodeActionMiddleware,Bt as onRevalidate,Et as renderDocument,Qe as renderPage,pe as renderToHydratableString,P as renderToStream,y as renderToString,ye as renderToStringAsync,Ze as renderToStringWithHead,W as revalidatePath,z as revalidateTag,J as serializeState,en as server,V as setRevalidationHandler,wt as useAction,Ft as useFormAction,Vt as useMutation,Ut as useOptimistic,mt as validateCsrfToken};
@@ -1,2 +1,2 @@
1
- import{mount as L,hydrate as N,signal as T,batch as O,getServerContext as j}from"what-core";var q=new RegExp("[<>&\\u2028\\u2029]","g"),F={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function I(e){return JSON.stringify(e).replace(q,n=>F[n.charCodeAt(0)])}var x=new Map,v=new Set,f=[],C=!1,E=new Map,g=new Map;function k(e){if(typeof structuredClone=="function")try{return structuredClone(e)}catch{}return Array.isArray(e)?e.map(k):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,t])=>[n,k(t)])):e}function b(e,n,t){if(e.has(n))return e.get(n);let r={},s={};for(let[o,a]of Object.entries(k(t)))s[o]=T(a),Object.defineProperty(r,o,{get:()=>s[o](),set:i=>s[o].set(i),enumerable:!0});return r._signals=s,r._subscribe=(o,a)=>{if(s[o])return s[o].subscribe(a)},r._batch=o=>O(o),r._getSnapshot=()=>{let o={};for(let[a,i]of Object.entries(s))o[a]=i.peek();return o},r._hydrate=o=>{O(()=>{for(let[a,i]of Object.entries(o))s[a]&&s[a].set(i)})},e.set(n,r),r}function w(e){let n=e||j();return n&&n.islandStores instanceof Map?n.islandStores:null}function M(e,n){if(g.has(e))return g.get(e).handle;let t={initialState:k(n),handle:null},r=()=>{let s=w();if(!s)throw new Error(`[what-server] Island store "${e}" was accessed outside an active server render. Read or write module-scoped island stores from a component rendered by renderDocument/renderPage.`);return b(s,e,t.initialState)};return t.handle=new Proxy({},{get(s,o){return Reflect.get(r(),o)},set(s,o,a){return Reflect.set(r(),o,a)},has(s,o){return Reflect.has(r(),o)},ownKeys(){return Reflect.ownKeys(r())},getOwnPropertyDescriptor(s,o){let a=Reflect.getOwnPropertyDescriptor(r(),o);return a?{...a,configurable:!0}:void 0}}),g.set(e,t),t.handle}function W(e,n){if(typeof document<"u")return b(E,e,n);let t=w();if(t){let r=g.get(e);return b(t,e,r?.initialState??n)}return M(e,n)}function R(e,n={}){if(typeof document<"u")return b(E,e,n);let t=w();if(t){let r=g.get(e);return b(t,e,r?.initialState??n)}return M(e,n)}function V(){return I(D())}function D(e){let n=typeof document<"u"?E:w(e),t={};for(let[r,s]of n||[])t[r]=s._getSnapshot();return t}function J(e){try{let n=typeof e=="string"?JSON.parse(e):e;for(let[t,r]of Object.entries(n))R(t,r)._hydrate(r)}catch(n){console.warn("[what] Failed to hydrate island stores:",n)}}function U(e,n,t={}){x.set(e,{loader:n,mode:t.mode||"idle",media:t.media||null,priority:t.priority||0,stores:t.stores||[]})}function Y({name:e,props:n={},children:t,mode:r,priority:s,stores:o}){let a=x.get(e),i=r||a?.mode||"idle",c=s??a?.priority??0,d=o||a?.stores||[];return{tag:"div",props:{"data-island":e,"data-island-mode":i,"data-island-props":JSON.stringify(n),"data-island-priority":c,"data-island-stores":JSON.stringify(d)},children:t||[],key:null,_vnode:!0}}function h(e){let n=!1;for(let t=0;t<f.length;t++)if(e.priority>f[t].priority){f.splice(t,0,e),n=!0;break}n||f.push(e),_()}function _(){if(C||f.length===0)return;C=!0;let e=f.shift();Promise.resolve(e.hydrate()).catch(n=>console.error("[what] Island hydration failed:",e.name,n)).finally(()=>{C=!1,queueMicrotask(_)})}function Z(e,n=100){for(let t of f)if(t.name===e){t.priority=n,f.sort((r,s)=>s.priority-r.priority);break}}function A(){let e=document.getElementById("__what_data");if(e)try{let t=JSON.parse(e.textContent||"{}");t&&t.islandStores&&J(t.islandStores)}catch(t){console.warn("[what] Failed to parse hydration payload:",t)}let n=document.querySelectorAll("[data-island]");for(let t of n){if(t.dataset.islandSelf)continue;let r=t.dataset.island,s=t.dataset.islandMode||"idle",o=JSON.parse(t.dataset.islandProps||"{}"),a=parseInt(t.dataset.islandPriority||"0",10),i=JSON.parse(t.dataset.islandStores||"[]"),c=x.get(r);if(!c){console.warn(`[what] Island "${r}" not registered`);continue}v.has(t)||H(t,c,o,s,a,r,i)}}function H(e,n,t,r,s,o,a){let i=async()=>{if(v.has(e))return;v.add(e);let c=await n.loader(),d=c.default||c,u={};for(let y of a)u[y]=R(y);let p=d({...t,...u});e.childNodes.length>0?N(p,e):L(p,e),e.removeAttribute("data-island"),e.removeAttribute("data-island-mode"),e.removeAttribute("data-island-props"),e.removeAttribute("data-island-priority"),e.removeAttribute("data-island-stores"),e.dispatchEvent(new CustomEvent("island:hydrated",{bubbles:!0,detail:{name:o,mode:r}}))};switch(r){case"load":h({name:o,priority:s+1e3,hydrate:i});break;case"idle":"requestIdleCallback"in window?requestIdleCallback(()=>{h({name:o,priority:s,hydrate:i})}):setTimeout(()=>{h({name:o,priority:s,hydrate:i})},200);break;case"visible":{new IntersectionObserver((d,u)=>{for(let p of d)if(p.isIntersecting){u.disconnect(),h({name:o,priority:s,hydrate:i});break}},{rootMargin:"200px"}).observe(e);break}case"media":{let c=window.matchMedia(n.media||"(max-width: 768px)");c.matches?h({name:o,priority:s,hydrate:i}):c.addEventListener("change",d=>{d.matches&&h({name:o,priority:s,hydrate:i})},{once:!0});break}case"action":{let c=["click","focus","mouseover","touchstart"],d=()=>{c.forEach(u=>e.removeEventListener(u,d)),h({name:o,priority:s+500,hydrate:i})};c.forEach(u=>e.addEventListener(u,d,{once:!0,passive:!0}));break}case"static":break;default:h({name:o,priority:s,hydrate:i})}}function ee(e){for(let[n,t]of Object.entries(e))U(n,t.loader||t,{mode:t.mode||"idle",media:t.media,priority:t.priority||0,stores:t.stores||[]});typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",A):A())}function $(e,n){if(typeof document>"u")return;let t=document.querySelectorAll(e);for(let r of t)r.dataset.enhanced||(r.dataset.enhanced="true",n(r))}function Q(e){let n=document.querySelector('meta[name="csrf-token"]')||document.querySelector('meta[name="what-csrf-token"]');if(n)return n.getAttribute("content");let t=e.querySelector('input[name="what-csrf-token"], input[name="_csrf"]');if(t&&t.value)return t.value;let r=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return r?decodeURIComponent(r[1]):null}function X(e,n,t){let r=new FormData(e);if(n&&n.name&&r.append(n.name,n.value??""),t)return r;let s=new URLSearchParams,o=null;for(let[a,i]of r)typeof i=="string"?s.append(a,i.replace(/\r\n|\r|\n/g,`\r
2
- `)):(o=o||a,s.append(a,i.name??""));return o&&typeof console<"u"&&console.warn(`[what] Form field "${o}" holds a file, but the form is not enctype="multipart/form-data", so only the file NAME is sent. This is what a plain HTML submit does too. Add enctype="multipart/form-data" to upload the bytes.`),s}function te(e="form[data-enhance]"){$(e,n=>{n.addEventListener("submit",async t=>{t.preventDefault();try{let r=t.submitter||null,s=l=>r&&r.getAttribute(`form${l}`)||n.getAttribute(l),o=(s("method")||"get").toUpperCase(),a=new URL(s("action")||location.href,location.href),c=(s("enctype")||"").toLowerCase()==="multipart/form-data",d=X(n,r,c),u=a.origin===location.origin,p={"X-Requested-With":"XMLHttpRequest"};if(u){let l=Q(n),S=n.getAttribute("data-no-csrf")==="true";if(!l&&!S){console.warn('[what] Form submission blocked: no CSRF token found. Add a <meta name="what-csrf-token"> tag (csrfMetaTag() emits it) or set data-no-csrf="true" on the form to opt out.'),n.dispatchEvent(new CustomEvent("form:error",{bubbles:!0,detail:{error:new Error("Missing CSRF token")}}));return}l&&(p["X-CSRF-Token"]=l)}let y;o==="GET"?a.search=String(d):c?y=d:(y=d,p["Content-Type"]="application/x-www-form-urlencoded;charset=UTF-8");let m=await fetch(a.href,{method:o,body:y,headers:p,credentials:"same-origin"}),P=new CustomEvent("form:response",{bubbles:!0,cancelable:!0,detail:{response:m,ok:m.ok,redirected:m.redirected}});if(n.dispatchEvent(P)&&m.ok&&m.redirected){let l=null;try{let S=new URL(m.url,location.href);S.origin===location.origin&&(l=S.href)}catch{}l&&location.assign(l)}}catch(r){n.dispatchEvent(new CustomEvent("form:error",{bubbles:!0,detail:{error:r}}))}})})}function ne(){let e=typeof document<"u"?[...E.keys()]:[...w()?.keys()||g.keys()];return{registered:[...x.keys()],hydrated:v.size,pending:f.length,queue:f.map(t=>({name:t.name,priority:t.priority})),stores:e}}export{Y as Island,ee as autoIslands,Z as boostIslandPriority,W as createIslandStore,$ as enhance,te as enhanceForms,ne as getIslandStatus,D as getIslandStoresSnapshot,J as hydrateIslandStores,A as hydrateIslands,U as island,V as serializeIslandStores,R as useIslandStore};
1
+ import{mount as L,hydrate as N,signal as T,batch as O,getServerContext as D}from"what-core";var q=new RegExp("[<>&\\u2028\\u2029]","g"),F={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function I(e){return JSON.stringify(e).replace(q,n=>F[n.charCodeAt(0)])}var E=new Map,v=new Set,f=[],C=!1,x=new Map,g=new Map;function k(e){if(typeof structuredClone=="function")try{return structuredClone(e)}catch{}return Array.isArray(e)?e.map(k):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,t])=>[n,k(t)])):e}function b(e,n,t){if(e.has(n))return e.get(n);let r={},s={};for(let[o,a]of Object.entries(k(t)))s[o]=T(a),Object.defineProperty(r,o,{get:()=>s[o](),set:i=>s[o].set(i),enumerable:!0});return r._signals=s,r._subscribe=(o,a)=>{if(s[o])return s[o].subscribe(a)},r._batch=o=>O(o),r._getSnapshot=()=>{let o={};for(let[a,i]of Object.entries(s))o[a]=i.peek();return o},r._hydrate=o=>{O(()=>{for(let[a,i]of Object.entries(o))s[a]&&s[a].set(i)})},e.set(n,r),r}function w(e){let n=e||D();return n&&n.islandStores instanceof Map?n.islandStores:null}function _(e,n){if(g.has(e))return g.get(e).handle;let t={initialState:k(n),handle:null},r=()=>{let s=w();if(!s)throw Object.assign(new Error(`[what-server] Island store "${e}" was accessed outside an active server render. Read or write module-scoped island stores from a component rendered by renderDocument/renderPage.`),{code:"ERR_ISLAND_STORE_OUTSIDE_RENDER"});return b(s,e,t.initialState)};return t.handle=new Proxy({},{get(s,o){return Reflect.get(r(),o)},set(s,o,a){return Reflect.set(r(),o,a)},has(s,o){return Reflect.has(r(),o)},ownKeys(){return Reflect.ownKeys(r())},getOwnPropertyDescriptor(s,o){let a=Reflect.getOwnPropertyDescriptor(r(),o);return a?{...a,configurable:!0}:void 0}}),g.set(e,t),t.handle}function W(e,n){if(typeof document<"u")return b(x,e,n);let t=w();if(t){let r=g.get(e);return b(t,e,r?.initialState??n)}return _(e,n)}function A(e,n={}){if(typeof document<"u")return b(x,e,n);let t=w();if(t){let r=g.get(e);return b(t,e,r?.initialState??n)}return _(e,n)}function V(){return I(j())}function j(e){let n=typeof document<"u"?x:w(e),t={};for(let[r,s]of n||[])t[r]=s._getSnapshot();return t}function U(e){try{let n=typeof e=="string"?JSON.parse(e):e;for(let[t,r]of Object.entries(n))A(t,r)._hydrate(r)}catch(n){console.warn("[what] Failed to hydrate island stores:",n)}}function J(e,n,t={}){E.set(e,{loader:n,mode:t.mode||"idle",media:t.media||null,priority:t.priority||0,stores:t.stores||[]})}function Y({name:e,props:n={},children:t,mode:r,priority:s,stores:o}){let a=E.get(e),i=r||a?.mode||"idle",c=s??a?.priority??0,d=o||a?.stores||[];return{tag:"div",props:{"data-island":e,"data-island-mode":i,"data-island-props":JSON.stringify(n),"data-island-priority":c,"data-island-stores":JSON.stringify(d)},children:t||[],key:null,_vnode:!0}}function h(e){let n=!1;for(let t=0;t<f.length;t++)if(e.priority>f[t].priority){f.splice(t,0,e),n=!0;break}n||f.push(e),M()}function M(){if(C||f.length===0)return;C=!0;let e=f.shift();Promise.resolve(e.hydrate()).catch(n=>console.error("[what] Island hydration failed:",e.name,n)).finally(()=>{C=!1,queueMicrotask(M)})}function Z(e,n=100){for(let t of f)if(t.name===e){t.priority=n,f.sort((r,s)=>s.priority-r.priority);break}}function R(){let e=document.getElementById("__what_data");if(e)try{let t=JSON.parse(e.textContent||"{}");t&&t.islandStores&&U(t.islandStores)}catch(t){console.warn("[what] Failed to parse hydration payload:",t)}let n=document.querySelectorAll("[data-island]");for(let t of n){if(t.dataset.islandSelf)continue;let r=t.dataset.island,s=t.dataset.islandMode||"idle",o=JSON.parse(t.dataset.islandProps||"{}"),a=parseInt(t.dataset.islandPriority||"0",10),i=JSON.parse(t.dataset.islandStores||"[]"),c=E.get(r);if(!c){console.warn(`[what] Island "${r}" not registered`);continue}v.has(t)||H(t,c,o,s,a,r,i)}}function H(e,n,t,r,s,o,a){let i=async()=>{if(v.has(e))return;v.add(e);let c=await n.loader(),d=c.default||c,u={};for(let y of a)u[y]=A(y);let p=d({...t,...u});e.childNodes.length>0?N(p,e):L(p,e),e.removeAttribute("data-island"),e.removeAttribute("data-island-mode"),e.removeAttribute("data-island-props"),e.removeAttribute("data-island-priority"),e.removeAttribute("data-island-stores"),e.dispatchEvent(new CustomEvent("island:hydrated",{bubbles:!0,detail:{name:o,mode:r}}))};switch(r){case"load":h({name:o,priority:s+1e3,hydrate:i});break;case"idle":"requestIdleCallback"in window?requestIdleCallback(()=>{h({name:o,priority:s,hydrate:i})}):setTimeout(()=>{h({name:o,priority:s,hydrate:i})},200);break;case"visible":{new IntersectionObserver((d,u)=>{for(let p of d)if(p.isIntersecting){u.disconnect(),h({name:o,priority:s,hydrate:i});break}},{rootMargin:"200px"}).observe(e);break}case"media":{let c=window.matchMedia(n.media||"(max-width: 768px)");c.matches?h({name:o,priority:s,hydrate:i}):c.addEventListener("change",d=>{d.matches&&h({name:o,priority:s,hydrate:i})},{once:!0});break}case"action":{let c=["click","focus","mouseover","touchstart"],d=()=>{c.forEach(u=>e.removeEventListener(u,d)),h({name:o,priority:s+500,hydrate:i})};c.forEach(u=>e.addEventListener(u,d,{once:!0,passive:!0}));break}case"static":break;default:h({name:o,priority:s,hydrate:i})}}function ee(e){for(let[n,t]of Object.entries(e))J(n,t.loader||t,{mode:t.mode||"idle",media:t.media,priority:t.priority||0,stores:t.stores||[]});typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",R):R())}function $(e,n){if(typeof document>"u")return;let t=document.querySelectorAll(e);for(let r of t)r.dataset.enhanced||(r.dataset.enhanced="true",n(r))}function Q(e){let n=document.querySelector('meta[name="csrf-token"]')||document.querySelector('meta[name="what-csrf-token"]');if(n)return n.getAttribute("content");let t=e.querySelector('input[name="what-csrf-token"], input[name="_csrf"]');if(t&&t.value)return t.value;let r=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);return r?decodeURIComponent(r[1]):null}function X(e,n,t){let r=new FormData(e);if(n&&n.name&&r.append(n.name,n.value??""),t)return r;let s=new URLSearchParams,o=null;for(let[a,i]of r)typeof i=="string"?s.append(a,i.replace(/\r\n|\r|\n/g,`\r
2
+ `)):(o=o||a,s.append(a,i.name??""));return o&&typeof console<"u"&&console.warn(`[what] Form field "${o}" holds a file, but the form is not enctype="multipart/form-data", so only the file NAME is sent. This is what a plain HTML submit does too. Add enctype="multipart/form-data" to upload the bytes.`),s}function te(e="form[data-enhance]"){$(e,n=>{n.addEventListener("submit",async t=>{t.preventDefault();try{let r=t.submitter||null,s=l=>r&&r.getAttribute(`form${l}`)||n.getAttribute(l),o=(s("method")||"get").toUpperCase(),a=new URL(s("action")||location.href,location.href),c=(s("enctype")||"").toLowerCase()==="multipart/form-data",d=X(n,r,c),u=a.origin===location.origin,p={"X-Requested-With":"XMLHttpRequest"};if(u){let l=Q(n),S=n.getAttribute("data-no-csrf")==="true";if(!l&&!S){console.warn('[what] Form submission blocked: no CSRF token found. Add a <meta name="what-csrf-token"> tag (csrfMetaTag() emits it) or set data-no-csrf="true" on the form to opt out.'),n.dispatchEvent(new CustomEvent("form:error",{bubbles:!0,detail:{error:new Error("Missing CSRF token")}}));return}l&&(p["X-CSRF-Token"]=l)}let y;o==="GET"?a.search=String(d):c?y=d:(y=d,p["Content-Type"]="application/x-www-form-urlencoded;charset=UTF-8");let m=await fetch(a.href,{method:o,body:y,headers:p,credentials:"same-origin"}),P=new CustomEvent("form:response",{bubbles:!0,cancelable:!0,detail:{response:m,ok:m.ok,redirected:m.redirected}});if(n.dispatchEvent(P)&&m.ok&&m.redirected){let l=null;try{let S=new URL(m.url,location.href);S.origin===location.origin&&(l=S.href)}catch{}l&&location.assign(l)}}catch(r){n.dispatchEvent(new CustomEvent("form:error",{bubbles:!0,detail:{error:r}}))}})})}function ne(){let e=typeof document<"u"?[...x.keys()]:[...w()?.keys()||g.keys()];return{registered:[...E.keys()],hydrated:v.size,pending:f.length,queue:f.map(t=>({name:t.name,priority:t.priority})),stores:e}}export{Y as Island,ee as autoIslands,Z as boostIslandPriority,W as createIslandStore,$ as enhance,te as enhanceForms,ne as getIslandStatus,j as getIslandStoresSnapshot,U as hydrateIslandStores,R as hydrateIslands,J as island,V as serializeIslandStores,A as useIslandStore};
package/dist/node.min.js CHANGED
@@ -1,4 +1,4 @@
1
- import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerContextStorage as We}from"what-core";import{h as nt,_isAriaAttr as ge,_beginComponentSSR as ot,_endComponentSSR as at,_mapArrayToArray as st,getServerContext as Ot,runWithServerContext as S,beginHeadCollection as we,endHeadCollection as it}from"what-core";var Lt=new RegExp("[<>&\\u2028\\u2029]","g"),Dt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function H(t){return JSON.stringify(t).replace(Lt,e=>Dt[e.charCodeAt(0)])}import{mount as Ge,hydrate as Xe,signal as Ke,batch as Ze,getServerContext as Mt}from"what-core";var Ft=new Map;function Ut(t){let e=t||Mt();return e&&e.islandStores instanceof Map?e.islandStores:null}function St(t){let e=typeof document<"u"?Ft:Ut(t),r={};for(let[n,s]of e||[])r[n]=s._getSnapshot();return r}import{signal as _,batch as Z}from"what-core";var T=null,bt=!(typeof process<"u");function G(t){T=t}function Bt(){return T}async function X(t,e){if(T&&T.revalidatePath)return T.revalidatePath(t,e);bt&&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 K(t,e){if(T&&T.revalidateTag)return T.revalidateTag(t,e);bt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var Q=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 q(){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 new Error("[what] No secure random source available for CSRF token generation")}function _t(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 tt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Jt=0,Wt=!1;function zt(){return!Wt&&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${(++Jt).toString(36)}_${Date.now().toString(36)}`}`}function Yt(t,e={}){let r=e.id||zt(),{onError:n,onSuccess:s,revalidate:o}=e;typeof window>"u"&&Q.set(r,{fn:t,options:e});async function a(...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 y=await p.json().catch(()=>({message:"Action failed"}));throw new Error(y.message||"Action failed")}let h=await p.json();if(s&&s(h),o)for(let y of o)Tt(y);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 a._actionId=r,a._isAction=!0,a}function At(t,e={}){let{onSuccess:r,onError:n,resetOnSuccess:s=!0}=e;return async o=>{let a,i;o instanceof Event?(o.preventDefault(),i=o.target,a=new FormData(i)):a=o;let c={},u=!1;for(let[d,f]of a.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,a):await t(c);return r&&r(d,i),s&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function Rt(t){let e=_(!1),r=_(null),n=_(null);async function s(...o){e.set(!0),r.set(null);try{let a=await t(...o);return n.set(a),a}catch(a){throw r.set(a),a}finally{e.set(!1)}}return{trigger:s,isPending:()=>e(),error:()=>r(),data:()=>n(),reset:()=>{r.set(null),n.set(null)}}}function Gt(t,e={}){let{resetOnSuccess:r=!0}=e,n={current:null},s=Rt(At(t,{resetOnSuccess:r}));function o(a){a.preventDefault();let i=new FormData(a.target);return n.current=a.target,s.trigger(i)}return{...s,handleSubmit:o,formRef:n}}function Xt(t,e){let r=_(t),n=_([]),s=_(t);function o(u){let d=e(r.peek(),u);Z(()=>{n.set([...n.peek(),u]),r.set(d)})}function a(u,d){Z(()=>{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){Z(()=>{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){o(u);try{let f=await d();return a(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:o,resolve:a,rollback:i,withOptimistic:c,set:u=>{r.set(u),s.set(u)}}}var I=new Map;function Kt(t,e){return I.has(t)||I.set(t,new Set),I.get(t).add(e),()=>{I.get(t)?.delete(e)}}function Tt(t){let e=I.get(t);if(e)for(let r of e)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function M(t,e,r,n={}){let{csrfToken:s,skipCsrf:o=!1}=n;if(!o){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(!_t(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=Q.get(e);return a?Array.isArray(r)?a.fn(...r).then(async i=>{let c=a.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 K(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 Zt(){return[...Q.keys()]}function Qt(t,e={}){let{onSuccess:r,onError:n,onSettled:s}=e,o={isPending:_(!1),error:_(null),data:_(null)};async function a(...i){o.isPending.set(!0),o.error.set(null);try{let c=await t(...i);return o.data.set(c),r&&r(c,...i),c}catch(c){throw o.error.set(c),n&&n(c,...i),c}finally{o.isPending.set(!1),s&&s(o.data.peek(),o.error.peek(),...i)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}import{h as F}from"what-core";var kt="/__what_action";function qt(t){if(typeof t=="string")return t;if(typeof t=="function"){let e=t._actionId;if(e)return e;throw 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.")}throw new Error("[what] <Form> requires an `action` prop: a server action or its id.")}function te(){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 ee({action:t,csrfToken:e,redirect:r,method:n="post",enhance:s=!0,children:o,...a}){let i=qt(t),c=e!==void 0?e:te();c==null&&typeof process<"u";let u=[F("input",{type:"hidden",name:"_action",value:i}),F("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(F("input",{type:"hidden",name:"_redirect",value:r}));let d={...a,method:n,action:a.action||kt,"data-action":i};s&&(d["data-enhance"]="");let f=o==null?[]:Array.isArray(o)?o:[o];return F("form",d,...u,...f)}var re="/__what_action",j=1024*1024;function ne(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 U(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function et(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 Et(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 oe(t,e){let r=Et(t&&t._redirect);if(r)return r;let n=e.referer||e.referrer;if(n)try{let s=new URL(n,"http://localhost"),o=Et(s.pathname+s.search);if(o)return o}catch{}return"/"}var ae=new Set(["_action","data-action","_csrf","what-csrf-token","_redirect"]);function L(t={}){let{getCsrfToken:e,skipCsrf:r=!1}=t;return async function(s){if((s.method||"POST").toUpperCase()!=="POST")return U(405,{message:"Method Not Allowed"});let a=ne(s.headers),i=a["x-what-action"],c=a["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||{},y=h._action||h["data-action"]||s.query&&s.query.action;if(!y)return et(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...a},O=h._csrf??h["what-csrf-token"];if(O&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(O)),!r&&e&&!d)return et(403,"Missing CSRF token");let x={};for(let[v,z]of Object.entries(h))ae.has(v)||(x[v]=z);let C=await M({headers:b},y,[x],{csrfToken:d,skipCsrf:r});return C.status===200?{status:303,headers:{location:oe(h,a)},body:""}:et(C.status,C.body&&C.body.message||"Action failed")}if(!i)return U(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return U(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await M({headers:a},i,l,{csrfToken:d,skipCsrf:r});return U(p.status,p.body)}}function se(t={}){let e=t.basePath||re,r=L(t);return async function(s,o,a){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return a?a():void 0;let u;try{let l=await ie(s);u=B(l,s.headers["content-type"]||"")}catch(l){o.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),o.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});o.writeHead(f.status,f.headers),o.end(f.body)}}function B(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=j){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(),o=[],a=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(a+=c.byteLength,a>e){try{await s.cancel()}catch{}return{tooLarge:!0}}o.push(c)}}return{raw:Buffer.concat(o.map(i=>Buffer.from(i))).toString("utf8")}}function ie(t){return new Promise((e,r)=>{let n=0,s=[];t.on("data",o=>{if(n+=o.length,n>j){let a=new Error("Body too large");a.code="BODY_TOO_LARGE",r(a),t.destroy?.();return}s.push(o)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",r)})}function ce(t={}){let e=L(t);return async function(r){let n={};try{let a=await V(r);if(a.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=B(a.raw,r.headers.get("content-type")||"")}catch{n={}}let s={};try{s=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let o=await e({method:r.method,headers:r.headers,body:n,query:s});return new Response(o.body,{status:o.status,headers:o.headers})}}import{matchRoute as ue,parseQuery as de}from"what-router/match";var fe="/__what_action",le="/__what_revalidate",rt="what-csrf";function D(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 pe(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:B(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function he(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:o,request:a,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:s,query:o,request:a,csrfToken:i}:{params:s,query:o,request:a},d=i?{...t,csrfToken:i}:t;return{html:await J(c,u,d),status:200,tags:r.config&&r.config.tags||[],path:r.path}}}function k(t={}){let{routes:e=[],cache:r,render:n,revalidateWebhook:s,document:o={},notFound:a,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||L(u?{getCsrfToken:l=>Ct(l.headers&&l.headers.cookie,rt)}:{skipCsrf:!0}),f=n||ye(o);return r&&(r.revalidatePath||r.revalidateTag)&&G({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),y=h.pathname;if(i&&y.startsWith(i)&&(y=y.slice(i.length)||"/"),p.method==="POST"&&y===fe){let g=await pe(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let R=await d({method:"POST",headers:D(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(R.body,{status:R.status,headers:R.headers})}let b=null,O=null;if(u&&(b=Ct(D(p.headers).cookie,rt),!b)){b=q();let R=D(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;O=`${rt}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(R?"; Secure":"")}let x=g=>(O&&(g["set-cookie"]=O),g);if(p.method==="POST"&&y===le&&s){let g=await he(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let R=await s({headers:D(p.headers),body:g.json});return new Response(JSON.stringify(R.body),{status:R.status,headers:{"content-type":"application/json"}})}let C=ue(y,e);if(!C){let g=a?a():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:x({"content-type":"text/html; charset=utf-8"})})}let{route:v,params:z}=C,Y=v.page||{mode:v.mode||"client"},N={path:y,query:de(h.search),config:Y,route:v,params:z,request:p};if(r&&Y.mode!=="server"){N.varyHeaders=D(p.headers);let g=await r.handle(N,()=>f(N));return new Response(g.html,{status:g.status||200,headers:x({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}b&&(N.csrfToken=b);let gt=await f(N),wt=x({"content-type":"text/html; charset=utf-8"});return Y.mode==="server"&&(wt["Cache-Control"]="private, no-store"),new Response(gt.html,{status:gt.status||200,headers:wt})}}function me(t={}){let e=k(t);return{async fetch(r,n,s){return n&&(r.__env=n),s&&(r.__ctx=s),e(r)}}}function E(t){return{head:we(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var xt=0;function Se(){xt=0}function be(){return"h"+xt++}function _e(t){if(!Ot()){let e=E(void 0);return S(e,()=>_e(t))}return Se(),A(t)}var vt=new Set(["__errorBoundary","__suspense"]),ct=new Set(["__portal"]);function ut(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function dt(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 P&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function A(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`<!--$-->${A(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${A(st(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${A(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(A).join("")}<!--/[]-->`;if(ct.has(t.tag))return"";if(vt.has(t.tag))try{return(t.children||[]).map(A).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return A(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=be(),u=ot(t.tag),d;try{d=A(t.tag(ut(t)))}finally{at(u)}return Ae(d,c)}let{tag:e,props:r,children:n}=t;lt(e);let s=pt(r||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(r),i=a!=null?String(a):n.map(A).join("");return`${o}${i}</${e}>`}function Ae(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],s=r[2],o=n.length+1+s.length,a=t.indexOf(">",o),i=t.slice(o,a===-1?void 0:a);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,o)+` data-hk="${e}"`+t.slice(o)}return t}function m(t){if(!Ot()){let c=E(void 0);return S(c,()=>m(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 m(t());if(typeof t=="function"&&t._mapArray)try{return m(st(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return m(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(m).join("");if(ct.has(t.tag))return"";if(vt.has(t.tag))try{return(t.children||[]).map(m).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return m(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=ot(t.tag);try{return m(t.tag(ut(t)))}finally{at(c)}}let{tag:e,props:r,children:n}=t;lt(e);let s=pt(r||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(r),i=a!=null?String(a):n.map(m).join("");return`${o}${i}</${e}>`}function Sr(t){let e=E(void 0);return{body:S(e,()=>m(t)),head:it(e.head)}}async function br(t,e={}){let r=t.default||t,n=typeof t.loader=="function"?await t.loader(e):void 0,s=E(n),o=e.params||{};return{body:S(s,()=>m(nt(r,{...o,loaderData:n}))),head:it(s.head),loaderData:n}}var $t=12;async function Re(t,e){e||(e=E(void 0));let r="";for(let s=0;s<$t;s++){r=S(e,()=>m(t));let o=[...e.resources.values()].filter(a=>a.status==="pending").map(a=>a.promise);if(o.length===0)break;await Promise.all(o)}let n={};for(let[s,o]of e.resources)o.status==="ready"&&(n[s]=o.value);return{body:r,head:it(e.head),loaderData:e.loaderData,resources:n,ctx:e}}async function J(t,e={},r={}){let n=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,o=E(s),a=e.params||{},{body:i,head:c,resources:u}=await Re(nt(n,{...a,loaderData:s}),o),d={loaderData:s??null,resources:u,islandStores:St(o)};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",o=`<script id="__what_data" type="application/json">${H(r)}<\/script>`,a=n.clientEntry?`<script type="module" src="${w(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?tt(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}${o}${a}</body></html>`}async function*$(t,e){if(e===void 0&&(e=E(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 a=S(e,()=>t());yield*$(a,e);return}if(typeof t=="function"&&t._mapArray){let a=null;try{a=S(e,()=>st(t))}catch{typeof process<"u"}a&&(yield*$(a,e));return}if(typeof t=="function"){try{let a=S(e,()=>t());yield*$(a,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let a of t)yield*$(a,e);return}if(ct.has(t.tag))return;if(t.tag==="__errorBoundary"){let a;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;a=S(e,()=>m(dt(t,i)))}yield a;return}if(t.tag==="__suspense"){let a=null;for(let i=0;i<$t&&a===null;i++){let c=null;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(a===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}a===null&&(a=S(e,()=>m(t.props&&t.props.fallback))),yield a;return}if(typeof t.tag=="function"){let a=ot(t.tag);try{let i=S(e,()=>t.tag(ut(t))),c=i instanceof Promise?await i:i;yield*$(c,e)}catch(i){typeof process<"u",yield P?`<!-- SSR Error: ${w(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{at(a)}return}let{tag:r,props:n,children:s}=t;lt(r);let o=pt(n||{});if(yield`<${r}${o}>`,!ht.has(r)){let a=ft(n);if(a!=null)yield String(a);else for(let i of s)yield*$(i,e);yield`</${r}>`}}function _r(t){return{mode:"static",...t}}function Ar(t,e={}){let r=E(e),n=S(r,()=>m(nt(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:o,mode:a}){let i=Object.entries(e).map(([l,p])=>`<meta name="${w(l)}" content="${w(p)}">`).join(`
1
+ import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerContextStorage as We}from"what-core";import{h as nt,_isAriaAttr as ge,_beginComponentSSR as ot,_endComponentSSR as at,_mapArrayToArray as st,getServerContext as Ct,runWithServerContext as S,beginHeadCollection as we,endHeadCollection as it}from"what-core";var Dt=new RegExp("[<>&\\u2028\\u2029]","g"),Lt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function I(t){return JSON.stringify(t).replace(Dt,e=>Lt[e.charCodeAt(0)])}import{mount as Ye,hydrate as Xe,signal as Ke,batch as Ze,getServerContext as Mt}from"what-core";var Ft=new Map;function Ut(t){let e=t||Mt();return e&&e.islandStores instanceof Map?e.islandStores:null}function St(t){let e=typeof document<"u"?Ft:Ut(t),r={};for(let[n,s]of e||[])r[n]=s._getSnapshot();return r}import{signal as _,batch as Z}from"what-core";var A=null,bt=!(typeof process<"u");function Y(t){A=t}function Bt(){return A}async function X(t,e){if(A&&A.revalidatePath)return A.revalidatePath(t,e);bt&&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 K(t,e){if(A&&A.revalidateTag)return A.revalidateTag(t,e);bt&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var Q=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 q(){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 _t(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 tt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}">`}var Jt=0,Wt=!1;function zt(){return!Wt&&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${(++Jt).toString(36)}_${Date.now().toString(36)}`}`}function Gt(t,e={}){let r=e.id||zt(),{onError:n,onSuccess:s,revalidate:o}=e;typeof window>"u"&&Q.set(r,{fn:t,options:e});async function a(...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 y=await p.json().catch(()=>({message:"Action failed"}));throw Object.assign(new Error(y.message||"Action failed"),{code:"ERR_ACTION_FAILED"})}let h=await p.json();if(s&&s(h),o)for(let y of o)At(y);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 a._actionId=r,a._isAction=!0,a}function Rt(t,e={}){let{onSuccess:r,onError:n,resetOnSuccess:s=!0}=e;return async o=>{let a,i;o instanceof Event?(o.preventDefault(),i=o.target,a=new FormData(i)):a=o;let c={},u=!1;for(let[d,f]of a.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,a):await t(c);return r&&r(d,i),s&&i&&i.reset(),d}catch(d){throw n&&n(d,i),d}}}function Et(t){let e=_(!1),r=_(null),n=_(null);async function s(...o){e.set(!0),r.set(null);try{let a=await t(...o);return n.set(a),a}catch(a){throw r.set(a),a}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=Et(Rt(t,{resetOnSuccess:r}));function o(a){a.preventDefault();let i=new FormData(a.target);return n.current=a.target,s.trigger(i)}return{...s,handleSubmit:o,formRef:n}}function Xt(t,e){let r=_(t),n=_([]),s=_(t);function o(u){let d=e(r.peek(),u);Z(()=>{n.set([...n.peek(),u]),r.set(d)})}function a(u,d){Z(()=>{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){Z(()=>{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){o(u);try{let f=await d();return a(u,f),f}catch(f){throw i(u),f}}return{value:()=>r(),isPending:()=>n().length>0,addOptimistic:o,resolve:a,rollback:i,withOptimistic:c,set:u=>{r.set(u),s.set(u)}}}var j=new Map;function Kt(t,e){return j.has(t)||j.set(t,new Set),j.get(t).add(e),()=>{j.get(t)?.delete(e)}}function At(t){let e=j.get(t);if(e)for(let r of e)try{r()}catch(n){console.error("[what] Revalidation error:",n)}}function M(t,e,r,n={}){let{csrfToken:s,skipCsrf:o=!1}=n;if(!o){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(!_t(i,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let a=Q.get(e);return a?Array.isArray(r)?a.fn(...r).then(async i=>{let c=a.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 K(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 Zt(){return[...Q.keys()]}function Qt(t,e={}){let{onSuccess:r,onError:n,onSettled:s}=e,o={isPending:_(!1),error:_(null),data:_(null)};async function a(...i){o.isPending.set(!0),o.error.set(null);try{let c=await t(...i);return o.data.set(c),r&&r(c,...i),c}catch(c){throw o.error.set(c),n&&n(c,...i),c}finally{o.isPending.set(!1),s&&s(o.data.peek(),o.error.peek(),...i)}}return{mutate:a,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}import{h as F}from"what-core";var Tt="/__what_action";function qt(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 te(){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 ee({action:t,csrfToken:e,redirect:r,method:n="post",enhance:s=!0,children:o,...a}){let i=qt(t),c=e!==void 0?e:te();c==null&&typeof process<"u";let u=[F("input",{type:"hidden",name:"_action",value:i}),F("input",{type:"hidden",name:"what-csrf-token",value:c||""})];r&&u.push(F("input",{type:"hidden",name:"_redirect",value:r}));let d={...a,method:n,action:a.action||Tt,"data-action":i};s&&(d["data-enhance"]="");let f=o==null?[]:Array.isArray(o)?o:[o];return F("form",d,...u,...f)}var re="/__what_action",H=1024*1024;function ne(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 U(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function et(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 kt(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 oe(t,e){let r=kt(t&&t._redirect);if(r)return r;let n=e.referer||e.referrer;if(n)try{let s=new URL(n,"http://localhost"),o=kt(s.pathname+s.search);if(o)return o}catch{}return"/"}var ae=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 U(405,{message:"Method Not Allowed"});let a=ne(s.headers),i=a["x-what-action"],c=a["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||{},y=h._action||h["data-action"]||s.query&&s.query.action;if(!y)return et(400,'Missing action name (add a hidden "_action" field or ?action= query param)');let b={...a},C=h._csrf??h["what-csrf-token"];if(C&&!b["x-csrf-token"]&&(b["x-csrf-token"]=String(C)),!r&&e&&!d)return et(403,"Missing CSRF token");let x={};for(let[v,z]of Object.entries(h))ae.has(v)||(x[v]=z);let O=await M({headers:b},y,[x],{csrfToken:d,skipCsrf:r});return O.status===200?{status:303,headers:{location:oe(h,a)},body:""}:et(O.status,O.body&&O.body.message||"Action failed")}if(!i)return U(400,{message:"Missing X-What-Action header"});if(!r&&e&&!d)return U(403,{message:"Missing CSRF token"});let l=(s.body||{}).args,p=await M({headers:a},i,l,{csrfToken:d,skipCsrf:r});return U(p.status,p.body)}}function se(t={}){let e=t.basePath||re,r=D(t);return async function(s,o,a){let[i,c]=(s.url||"").split("?");if(i!==e||(s.method||"").toUpperCase()!=="POST")return a?a():void 0;let u;try{let l=await ie(s);u=B(l,s.headers["content-type"]||"")}catch(l){o.writeHead(l.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),o.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});o.writeHead(f.status,f.headers),o.end(f.body)}}function B(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(),o=[],a=0;for(;;){let{done:i,value:c}=await s.read();if(i)break;if(c){if(a+=c.byteLength,a>e){try{await s.cancel()}catch{}return{tooLarge:!0}}o.push(c)}}return{raw:Buffer.concat(o.map(i=>Buffer.from(i))).toString("utf8")}}function ie(t){return new Promise((e,r)=>{let n=0,s=[];t.on("data",o=>{if(n+=o.length,n>H){let a=new Error("Body too large");a.code="BODY_TOO_LARGE",r(a),t.destroy?.();return}s.push(o)}),t.on("end",()=>{if(s.length===0)return e("");e(Buffer.concat(s).toString("utf8"))}),t.on("error",r)})}function ce(t={}){let e=D(t);return async function(r){let n={};try{let a=await V(r);if(a.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});n=B(a.raw,r.headers.get("content-type")||"")}catch{n={}}let s={};try{s=Object.fromEntries(new URL(r.url,"http://localhost").searchParams)}catch{}let o=await e({method:r.method,headers:r.headers,body:n,query:s});return new Response(o.body,{status:o.status,headers:o.headers})}}import{matchRoute as ue,parseQuery as de}from"what-router/match";var fe="/__what_action",le="/__what_revalidate",rt="what-csrf";function L(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((r,n)=>{e[n.toLowerCase()]=r}),e}function Ot(t,e){if(!t)return null;let r=String(t).match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return r?decodeURIComponent(r[1]):null}async function pe(t){try{let e=await V(t);return e.tooLarge?{tooLarge:!0}:B(e.raw,t.headers.get("content-type")||"")}catch{return{}}}async function he(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:o,request:a,csrfToken:i}=r,c={default:n.component,loader:n.loader},u=i?{params:s,query:o,request:a,csrfToken:i}:{params:s,query:o,request:a},d=i?{...t,csrfToken:i}:t;return{html:await J(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:o={},notFound:a,basePath:i="",csrf:c=!0}=t,u=c!==!1&&!t.actionHandler,d=t.actionHandler||D(u?{getCsrfToken:l=>Ot(l.headers&&l.headers.cookie,rt)}:{skipCsrf:!0}),f=n||ye(o);return r&&(r.revalidatePath||r.revalidateTag)&&Y({revalidatePath:r.revalidatePath,revalidateTag:r.revalidateTag}),async function(p){let h=new URL(p.url,"http://localhost"),y=h.pathname;if(i&&y.startsWith(i)&&(y=y.slice(i.length)||"/"),p.method==="POST"&&y===fe){let g=await pe(p);if(g&&g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await d({method:"POST",headers:L(p.headers),body:g,query:Object.fromEntries(h.searchParams)});return new Response(E.body,{status:E.status,headers:E.headers})}let b=null,C=null;if(u&&(b=Ot(L(p.headers).cookie,rt),!b)){b=q();let E=L(p.headers)["x-forwarded-proto"]==="https"||h.protocol==="https:"||!0;C=`${rt}=${encodeURIComponent(b)}; Path=/; SameSite=Lax`+(E?"; Secure":"")}let x=g=>(C&&(g["set-cookie"]=C),g);if(p.method==="POST"&&y===le&&s){let g=await he(p);if(g.tooLarge)return new Response(JSON.stringify({message:"Payload too large"}),{status:413,headers:{"content-type":"application/json"}});let E=await s({headers:L(p.headers),body:g.json});return new Response(JSON.stringify(E.body),{status:E.status,headers:{"content-type":"application/json"}})}let O=ue(y,e);if(!O){let g=a?a():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(g,{status:404,headers:x({"content-type":"text/html; charset=utf-8"})})}let{route:v,params:z}=O,G=v.page||{mode:v.mode||"client"},N={path:y,query:de(h.search),config:G,route:v,params:z,request:p};if(r&&G.mode!=="server"){N.varyHeaders=L(p.headers);let g=await r.handle(N,()=>f(N));return new Response(g.html,{status:g.status||200,headers:x({"content-type":"text/html; charset=utf-8",...g.headers||{}})})}b&&(N.csrfToken=b);let gt=await f(N),wt=x({"content-type":"text/html; charset=utf-8"});return G.mode==="server"&&(wt["Cache-Control"]="private, no-store"),new Response(gt.html,{status:gt.status||200,headers:wt})}}function me(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:we(),loaderData:t,resources:new Map,islandStores:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var xt=0;function Se(){xt=0}function be(){return"h"+xt++}function _e(t){if(!Ct()){let e=k(void 0);return S(e,()=>_e(t))}return Se(),R(t)}var vt=new Set(["__errorBoundary","__suspense"]),ct=new Set(["__portal"]);function ut(t){let e=t.children;return!e||e.length===0?{...t.props}:{...t.props,children:e}}function dt(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 P&&console.warn(`[what-server] <ErrorBoundary> fallback threw during SSR: ${s.message}`),null}}function R(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`<!--$-->${R(t())}<!--/$-->`;if(typeof t=="function"&&t._mapArray)try{return`<!--$-->${R(st(t))}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(typeof t=="function")try{return`<!--$-->${R(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(R).join("")}<!--/[]-->`;if(ct.has(t.tag))return"";if(vt.has(t.tag))try{return(t.children||[]).map(R).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return R(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=be(),u=ot(t.tag),d;try{d=R(t.tag(ut(t)))}finally{at(u)}return Re(d,c)}let{tag:e,props:r,children:n}=t;lt(e);let s=pt(r||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(r),i=a!=null?String(a):n.map(R).join("");return`${o}${i}</${e}>`}function Re(t,e){let r=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(r){let n=r[1],s=r[2],o=n.length+1+s.length,a=t.indexOf(">",o),i=t.slice(o,a===-1?void 0:a);return/[\s"']data-hk\s*=/.test(i)||/^\s*data-hk\s*=/.test(i)?t:t.slice(0,o)+` data-hk="${e}"`+t.slice(o)}return t}function m(t){if(!Ct()){let c=k(void 0);return S(c,()=>m(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 m(t());if(typeof t=="function"&&t._mapArray)try{return m(st(t))}catch{return typeof process<"u",""}if(typeof t=="function")try{return m(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(m).join("");if(ct.has(t.tag))return"";if(vt.has(t.tag))try{return(t.children||[]).map(m).join("")}catch(c){let u=c&&typeof c.then=="function";if(u&&t.tag==="__errorBoundary"||!u&&t.tag==="__suspense")throw c;return m(dt(t,u?null:c))}if(typeof t.tag=="function"){let c=ot(t.tag);try{return m(t.tag(ut(t)))}finally{at(c)}}let{tag:e,props:r,children:n}=t;lt(e);let s=pt(r||{}),o=`<${e}${s}>`;if(ht.has(e))return o;let a=ft(r),i=a!=null?String(a):n.map(m).join("");return`${o}${i}</${e}>`}function Sr(t){let e=k(void 0);return{body:S(e,()=>m(t)),head:it(e.head)}}async function br(t,e={}){let r=t.default||t,n=typeof t.loader=="function"?await t.loader(e):void 0,s=k(n),o=e.params||{};return{body:S(s,()=>m(nt(r,{...o,loaderData:n}))),head:it(s.head),loaderData:n}}var $t=12;async function Ee(t,e){e||(e=k(void 0));let r="";for(let s=0;s<$t;s++){r=S(e,()=>m(t));let o=[...e.resources.values()].filter(a=>a.status==="pending").map(a=>a.promise);if(o.length===0)break;await Promise.all(o)}let n={};for(let[s,o]of e.resources)o.status==="ready"&&(n[s]=o.value);return{body:r,head:it(e.head),loaderData:e.loaderData,resources:n,ctx:e}}async function J(t,e={},r={}){let n=t.default||t,s=typeof t.loader=="function"?await t.loader(e):void 0,o=k(s),a=e.params||{},{body:i,head:c,resources:u}=await Ee(nt(n,{...a,loaderData:s}),o),d={loaderData:s??null,resources:u,islandStores:St(o)};return Ae({body:i,head:c,payload:d,options:r})}function Ae({body:t,head:e,payload:r,options:n={}}){let s=n.lang||"en",o=`<script id="__what_data" type="application/json">${I(r)}<\/script>`,a=n.clientEntry?`<script type="module" src="${w(n.clientEntry)}"><\/script>`:"",c=(n.csrfToken?tt(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}${o}${a}</body></html>`}async function*$(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 a=S(e,()=>t());yield*$(a,e);return}if(typeof t=="function"&&t._mapArray){let a=null;try{a=S(e,()=>st(t))}catch{typeof process<"u"}a&&(yield*$(a,e));return}if(typeof t=="function"){try{let a=S(e,()=>t());yield*$(a,e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let a of t)yield*$(a,e);return}if(ct.has(t.tag))return;if(t.tag==="__errorBoundary"){let a;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(i){if(i&&typeof i.then=="function")throw i;a=S(e,()=>m(dt(t,i)))}yield a;return}if(t.tag==="__suspense"){let a=null;for(let i=0;i<$t&&a===null;i++){let c=null;try{a=S(e,()=>(t.children||[]).map(m).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(a===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}a===null&&(a=S(e,()=>m(t.props&&t.props.fallback))),yield a;return}if(typeof t.tag=="function"){let a=ot(t.tag);try{let i=S(e,()=>t.tag(ut(t))),c=i instanceof Promise?await i:i;yield*$(c,e)}catch(i){typeof process<"u",yield P?`<!-- SSR Error: ${w(i.message||"Component error")} -->`:"<!-- SSR Error -->"}finally{at(a)}return}let{tag:r,props:n,children:s}=t;lt(r);let o=pt(n||{});if(yield`<${r}${o}>`,!ht.has(r)){let a=ft(n);if(a!=null)yield String(a);else for(let i of s)yield*$(i,e);yield`</${r}>`}}function _r(t){return{mode:"static",...t}}function Rr(t,e={}){let r=k(e),n=S(r,()=>m(nt(t.component,e))),s=t.islands||[];return Te({title:t.title||"",meta:t.meta||{},body:n,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function Te({title:t,meta:e,body:r,islands:n,scripts:s,styles:o,mode:a}){let i=Object.entries(e).map(([l,p])=>`<meta name="${w(l)}" content="${w(p)}">`).join(`
2
2
  `),c=o.map(l=>`<link rel="stylesheet" href="${w(l)}">`).join(`
3
3
  `),u=n.length>0?`
4
4
  <script type="module">
@@ -21,4 +21,4 @@ import{AsyncLocalStorage as Je}from"node:async_hooks";import{__installServerCont
21
21
  ${d}
22
22
  ${f}
23
23
  </body>
24
- </html>`}function Rr(t){return t._server=!0,t}var P=!(typeof process<"u");function ft(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 Ee=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Ce=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function lt(t){if(typeof t!="string"||!Ce.test(t))throw new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`)}function pt(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 o=n;if(typeof o=="function"){try{o=o()}catch(a){P&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(r)}: its value threw during SSR: ${a.message}`);continue}if(typeof o=="function")continue}if(o===!1&&ge(r)){e+=` ${r}="false"`;continue}if(!(o===!1||o==null)){if(!Ee.test(r)){P&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(r)}`);continue}if(ve.has(s)){P&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(r)}`);continue}if(r==="className"||r==="class")e+=` class="${w(String(o))}"`;else if(r==="style"&&typeof o=="object"){let a=Object.entries(o).map(([i,c])=>`${$e(i)}:${c}`).join(";");e+=` style="${w(a)}"`}else if(o===!0)r.startsWith("aria-")||r==="role"?e+=` ${r}="true"`:e+=` ${r}`;else{if(Oe(r,o))continue;e+=` ${r}="${w(String(o))}"`}}}return e}function Oe(t,e){let r=t.toLowerCase();if(!xe.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 xe=new Set(["href","src","action","formaction","data","ping","xlink:href"]),ve=new Set(["srcdoc"]);function w(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function $e(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var ht=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);import Pe from"node:http";var yt=Symbol("what.bodyTooLarge"),Pt=()=>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[o,a]of Object.entries(t.headers))a!=null&&n.set(o,Array.isArray(a)?a.join(", "):String(a));let s;if(t.method!=="GET"&&t.method!=="HEAD"){let o=Number(t.headers["content-length"]),a=Number.isFinite(o)&&o>j,i=[],c=0;for await(let u of t)if(!a){if(c+=u.length,c>j){a=!0,i.length=0;continue}i.push(u)}if(a)return yt;i.length&&(s=Buffer.concat(i))}return new Request(r,{method:t.method,headers:n,body:s})}async function W(t,e){t.statusCode=e.status,e.headers.forEach((n,s)=>t.setHeader(s,n));let r=await e.text();t.end(r)}function Ht(t){return async function(r,n){try{let s=await Nt(r);if(s===yt)return await W(n,Pt());let o=await t(s);await W(n,o)}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 Ne(t={}){let e=k(t);return async function(n,s,o){let a=await Nt(n);if(a===yt)return await W(s,Pt());let i=await e(a);if(i.status===404&&typeof o=="function")return o();await W(s,i)}}function He(t={}){let e=k(t),r=Pe.createServer(Ht(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 Ie,writeFile as It}from"node:fs/promises";import{join as mt,resolve as jt,sep as je}from"node:path";import{matchRoute as Le}from"what-router/match";function De(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Me(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 Fe(t,e){let r=jt(t),n=jt(mt(t,e==="/"?"":e));if(n!==r&&!n.startsWith(r+je))throw new Error(`[what-server] Refusing to write outside outDir: ${e}`);return n}async function Ue({routes:t=[],outDir:e,render:r,documentOptions:n={}}={}){let s=[];for(let o of t){let a=o.page&&o.page.mode||o.mode;if(a!=="static"&&a!=="hybrid")continue;let i={default:o.component,loader:o.loader},c=[o.path];if(De(o.path)){if(typeof o.getStaticPaths!="function")continue;c=((await o.getStaticPaths()).paths||[]).map(d=>Me(o.path,d.params||{}))}for(let u of c){let d=Fe(e,u),f=Le(u,[o]),p={params:f?f.params:{},query:{}},h=r?await r(i,p):await J(i,p,n);if(await Ie(d,{recursive:!0}),await It(mt(d,"index.html"),h),typeof o.loader=="function"){let y=await o.loader(p);await It(mt(d,"__what_data.json"),H({loaderData:y}))}s.push(u)}}return{pages:s}}function Be(t={}){return k(t)}async function Ve({outDir:t=".vercel/output",functionName:e="render",runtime:r="nodejs22.x",files:n=null,handler:s="index.mjs",staticDir:o=null}={}){let{mkdir:a,writeFile:i,cp:c}=await import("node:fs/promises"),{join:u,dirname:d}=await import("node:path");await a(t,{recursive:!0});let f={version:3,routes:[{handle:"filesystem"},{src:"/.*",dest:`/${e}`}]};await i(u(t,"config.json"),JSON.stringify(f,null,2)),o&&await c(o,u(t,"static"),{recursive:!0});let l=null;if(n&&typeof n=="object"){l=u(t,"functions",`${e}.func`),await a(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,y]of Object.entries(n)){let b=u(l,h);await a(d(b),{recursive:!0}),await i(b,y)}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}}We(new Je);export{kt as ACTION_ENDPOINT,ee as Form,Yt as action,Ve as buildVercelOutput,L as createActionHandler,me as createCloudflareHandler,k as createRequestHandler,He as createServer,Be as createVercelHandler,tt as csrfMetaTag,_r as definePage,Ue as exportStatic,ce as fetchActionHandler,At as formAction,q as generateCsrfToken,Ar as generateStaticPage,Zt as getRegisteredActions,Bt as getRevalidationHandler,M as handleActionRequest,Tt as invalidatePath,se as nodeActionMiddleware,Kt as onRevalidate,J as renderDocument,br as renderPage,_e as renderToHydratableString,$ as renderToStream,m as renderToString,Re as renderToStringAsync,Sr as renderToStringWithHead,X as revalidatePath,K as revalidateTag,H as serializeState,Rr as server,G as setRevalidationHandler,Ht as toNodeListener,Rt as useAction,Gt as useFormAction,Qt as useMutation,Xt as useOptimistic,_t as validateCsrfToken,Ne as whatMiddleware};
24
+ </html>`}function Er(t){return t._server=!0,t}var P=!(typeof process<"u");function ft(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 ke=/^[a-zA-Z_:][a-zA-Z0-9:._-]*$/,Oe=/^[a-zA-Z_][a-zA-Z0-9._:-]*$/;function lt(t){if(typeof t!="string"||!Oe.test(t))throw Object.assign(new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(t)}`),{code:"ERR_INVALID_SSR_TAG"})}function pt(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 o=n;if(typeof o=="function"){try{o=o()}catch(a){P&&console.warn(`[what-server] Skipping attribute ${JSON.stringify(r)}: its value threw during SSR: ${a.message}`);continue}if(typeof o=="function")continue}if(o===!1&&ge(r)){e+=` ${r}="false"`;continue}if(!(o===!1||o==null)){if(!ke.test(r)){P&&console.warn(`[what-server] Skipping invalid attribute name in SSR: ${JSON.stringify(r)}`);continue}if(ve.has(s)){P&&console.warn(`[what-server] Skipping unsafe attribute in SSR: ${JSON.stringify(r)}`);continue}if(r==="className"||r==="class")e+=` class="${w(String(o))}"`;else if(r==="style"&&typeof o=="object"){let a=Object.entries(o).map(([i,c])=>`${$e(i)}:${c}`).join(";");e+=` style="${w(a)}"`}else if(o===!0)r.startsWith("aria-")||r==="role"?e+=` ${r}="true"`:e+=` ${r}`;else{if(Ce(r,o))continue;e+=` ${r}="${w(String(o))}"`}}}return e}function Ce(t,e){let r=t.toLowerCase();if(!xe.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 xe=new Set(["href","src","action","formaction","data","ping","xlink:href"]),ve=new Set(["srcdoc"]);function w(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function $e(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var ht=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);import Pe from"node:http";var yt=Symbol("what.bodyTooLarge"),Pt=()=>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[o,a]of Object.entries(t.headers))a!=null&&n.set(o,Array.isArray(a)?a.join(", "):String(a));let s;if(t.method!=="GET"&&t.method!=="HEAD"){let o=Number(t.headers["content-length"]),a=Number.isFinite(o)&&o>H,i=[],c=0;for await(let u of t)if(!a){if(c+=u.length,c>H){a=!0,i.length=0;continue}i.push(u)}if(a)return yt;i.length&&(s=Buffer.concat(i))}return new Request(r,{method:t.method,headers:n,body:s})}async function W(t,e){t.statusCode=e.status,e.headers.forEach((n,s)=>t.setHeader(s,n));let r=await e.text();t.end(r)}function It(t){return async function(r,n){try{let s=await Nt(r);if(s===yt)return await W(n,Pt());let o=await t(s);await W(n,o)}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 Ne(t={}){let e=T(t);return async function(n,s,o){let a=await Nt(n);if(a===yt)return await W(s,Pt());let i=await e(a);if(i.status===404&&typeof o=="function")return o();await W(s,i)}}function Ie(t={}){let e=T(t),r=Pe.createServer(It(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 je,writeFile as jt}from"node:fs/promises";import{join as mt,resolve as Ht,sep as He}from"node:path";import{matchRoute as De}from"what-router/match";function Le(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Me(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 Fe(t,e){let r=Ht(t),n=Ht(mt(t,e==="/"?"":e));if(n!==r&&!n.startsWith(r+He))throw Object.assign(new Error(`[what-server] Refusing to write outside outDir: ${e}`),{code:"ERR_STATIC_WRITE_ESCAPE"});return n}async function Ue({routes:t=[],outDir:e,render:r,documentOptions:n={}}={}){let s=[];for(let o of t){let a=o.page&&o.page.mode||o.mode;if(a!=="static"&&a!=="hybrid")continue;let i={default:o.component,loader:o.loader},c=[o.path];if(Le(o.path)){if(typeof o.getStaticPaths!="function")continue;c=((await o.getStaticPaths()).paths||[]).map(d=>Me(o.path,d.params||{}))}for(let u of c){let d=Fe(e,u),f=De(u,[o]),p={params:f?f.params:{},query:{}},h=r?await r(i,p):await J(i,p,n);if(await je(d,{recursive:!0}),await jt(mt(d,"index.html"),h),typeof o.loader=="function"){let y=await o.loader(p);await jt(mt(d,"__what_data.json"),I({loaderData:y}))}s.push(u)}}return{pages:s}}function Be(t={}){return T(t)}async function Ve({outDir:t=".vercel/output",functionName:e="render",runtime:r="nodejs22.x",files:n=null,handler:s="index.mjs",staticDir:o=null}={}){let{mkdir:a,writeFile:i,cp:c}=await import("node:fs/promises"),{join:u,dirname:d}=await import("node:path");await a(t,{recursive:!0});let f={version:3,routes:[{handle:"filesystem"},{src:"/.*",dest:`/${e}`}]};await i(u(t,"config.json"),JSON.stringify(f,null,2)),o&&await c(o,u(t,"static"),{recursive:!0});let l=null;if(n&&typeof n=="object"){l=u(t,"functions",`${e}.func`),await a(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,y]of Object.entries(n)){let b=u(l,h);await a(d(b),{recursive:!0}),await i(b,y)}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}}We(new Je);export{Tt as ACTION_ENDPOINT,ee as Form,Gt as action,Ve as buildVercelOutput,D as createActionHandler,me as createCloudflareHandler,T as createRequestHandler,Ie as createServer,Be as createVercelHandler,tt as csrfMetaTag,_r as definePage,Ue as exportStatic,ce as fetchActionHandler,Rt as formAction,q as generateCsrfToken,Rr as generateStaticPage,Zt as getRegisteredActions,Bt as getRevalidationHandler,M as handleActionRequest,At as invalidatePath,se as nodeActionMiddleware,Kt as onRevalidate,J as renderDocument,br as renderPage,_e as renderToHydratableString,$ as renderToStream,m as renderToString,Ee as renderToStringAsync,Sr as renderToStringWithHead,X as revalidatePath,K as revalidateTag,I as serializeState,Er as server,Y as setRevalidationHandler,It as toNodeListener,Et as useAction,Yt as useFormAction,Qt as useMutation,Xt as useOptimistic,_t as validateCsrfToken,Ne as whatMiddleware};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "what-server",
3
- "version": "0.12.4",
3
+ "version": "0.13.0",
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.12.4",
55
- "what-router": "^0.12.4"
54
+ "what-core": "^0.13.0",
55
+ "what-router": "^0.13.0"
56
56
  },
57
57
  "peerDependenciesMeta": {
58
58
  "what-router": {
@@ -299,6 +299,7 @@ function readRawBody(req) {
299
299
  req.on('data', (chunk) => {
300
300
  size += chunk.length;
301
301
  if (size > MAX_BODY_BYTES) {
302
+ /** @type {Error & { code?: string }} */
302
303
  const e = new Error('Body too large');
303
304
  e.code = 'BODY_TOO_LARGE';
304
305
  reject(e);
package/src/actions.js CHANGED
@@ -53,7 +53,11 @@ export function generateCsrfToken() {
53
53
  return Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');
54
54
  }
55
55
  // Last resort — should not be reached in modern environments
56
- throw new Error('[what] No secure random source available for CSRF token generation');
56
+ // ERROR_CODES.NO_SECURE_RANDOM
57
+ throw Object.assign(
58
+ new Error('[what] No secure random source available for CSRF token generation'),
59
+ { code: 'ERR_NO_SECURE_RANDOM' },
60
+ );
57
61
  }
58
62
 
59
63
  // Server: validate CSRF token from request header against session token
@@ -141,7 +145,10 @@ export function action(fn, options = {}) {
141
145
 
142
146
  if (!response.ok) {
143
147
  const error = await response.json().catch(() => ({ message: 'Action failed' }));
144
- throw new Error(error.message || 'Action failed');
148
+ // ERROR_CODES.ACTION_FAILED
149
+ throw Object.assign(new Error(error.message || 'Action failed'), {
150
+ code: 'ERR_ACTION_FAILED',
151
+ });
145
152
  }
146
153
 
147
154
  const result = await response.json();
@@ -157,6 +164,7 @@ export function action(fn, options = {}) {
157
164
  return result;
158
165
  } catch (error) {
159
166
  if (error.name === 'AbortError') {
167
+ /** @type {Error & { code?: string }} */
160
168
  const timeoutError = new Error(`Action "${id}" timed out after ${timeout}ms`);
161
169
  timeoutError.code = 'TIMEOUT';
162
170
  if (onError) onError(timeoutError);
@@ -187,7 +195,7 @@ export function formAction(actionFn, options = {}) {
187
195
 
188
196
  if (formDataOrEvent instanceof Event) {
189
197
  formDataOrEvent.preventDefault();
190
- form = formDataOrEvent.target;
198
+ form = /** @type {HTMLFormElement} */ (formDataOrEvent.target);
191
199
  formData = new FormData(form);
192
200
  } else {
193
201
  formData = formDataOrEvent;
@@ -290,7 +298,7 @@ export function useFormAction(actionFn, options = {}) {
290
298
 
291
299
  export function useOptimistic(initialValue, reducer) {
292
300
  const value = signal(initialValue);
293
- const pending = signal([]);
301
+ const pending = signal(/** @type {any[]} */ ([]));
294
302
  const baseValue = signal(initialValue); // Track the confirmed server value
295
303
 
296
304
  function addOptimistic(action) {
@@ -46,7 +46,9 @@ async function readJsonBody(request) {
46
46
  let read;
47
47
  try { read = await readFetchBodyCapped(request); } catch { return { json: {} }; }
48
48
  if (read.tooLarge) return { tooLarge: true };
49
- try { return { json: JSON.parse(read.raw) }; } catch { return { json: {} }; }
49
+ // `raw` is absent on the tooLarge branch, which returned above; `?? ''` keeps
50
+ // the parse throwing into the same catch it always did.
51
+ try { return { json: JSON.parse(read.raw ?? '') }; } catch { return { json: {} }; }
50
52
  }
51
53
 
52
54
  function defaultRenderRoute(documentOptions) {
@@ -27,11 +27,22 @@ function resolveInsideOutDir(outDir, urlPath) {
27
27
  const root = resolve(outDir);
28
28
  const dirPath = resolve(join(outDir, urlPath === '/' ? '' : urlPath));
29
29
  if (dirPath !== root && !dirPath.startsWith(root + sep)) {
30
- throw new Error(`[what-server] Refusing to write outside outDir: ${urlPath}`);
30
+ // ERROR_CODES.STATIC_WRITE_ESCAPE
31
+ throw Object.assign(
32
+ new Error(`[what-server] Refusing to write outside outDir: ${urlPath}`),
33
+ { code: 'ERR_STATIC_WRITE_ESCAPE' },
34
+ );
31
35
  }
32
36
  return dirPath;
33
37
  }
34
38
 
39
+ /**
40
+ * @param {object} [options]
41
+ * @param {any[]} [options.routes]
42
+ * @param {string} [options.outDir]
43
+ * @param {(route: any, documentOptions: any) => any} [options.render]
44
+ * @param {Record<string, any>} [options.documentOptions]
45
+ */
35
46
  export async function exportStatic({ routes = [], outDir, render, documentOptions = {} } = {}) {
36
47
  const written = [];
37
48
 
package/src/form.js CHANGED
@@ -27,12 +27,20 @@ function resolveActionId(action) {
27
27
  if (typeof action === 'function') {
28
28
  const id = action._actionId;
29
29
  if (id) return id;
30
- throw new Error(
31
- '[what] <Form action={fn}>: that function is not a server action. ' +
32
- 'Wrap it with action() from what-server, or pass the action id as a string.'
30
+ // ERROR_CODES.FORM_ACTION_NOT_REGISTERED
31
+ throw Object.assign(
32
+ new Error(
33
+ '[what] <Form action={fn}>: that function is not a server action. ' +
34
+ 'Wrap it with action() from what-server, or pass the action id as a string.'
35
+ ),
36
+ { code: 'ERR_FORM_ACTION_NOT_REGISTERED' },
33
37
  );
34
38
  }
35
- throw new Error('[what] <Form> requires an `action` prop: a server action or its id.');
39
+ // ERROR_CODES.FORM_ACTION_MISSING
40
+ throw Object.assign(
41
+ new Error('[what] <Form> requires an `action` prop: a server action or its id.'),
42
+ { code: 'ERR_FORM_ACTION_MISSING' },
43
+ );
36
44
  }
37
45
 
38
46
  // On the server there is no document, so the per-request token must be handed
package/src/index.js CHANGED
@@ -442,6 +442,13 @@ export async function renderDocument(pageModule, reqCtx = {}, options = {}) {
442
442
  return wrapHtmlDocument({ body, head, payload, options });
443
443
  }
444
444
 
445
+ /**
446
+ * @param {object} args
447
+ * @param {string} args.body
448
+ * @param {string} args.head
449
+ * @param {any} args.payload
450
+ * @param {{ lang?: string, clientEntry?: string, csrfToken?: string, head?: string, bodyClass?: string }} [args.options]
451
+ */
445
452
  function wrapHtmlDocument({ body, head, payload, options = {} }) {
446
453
  const lang = options.lang || 'en';
447
454
  const dataScript = `<script id="__what_data" type="application/json">${serializeState(payload)}</script>`;
@@ -747,7 +754,11 @@ const SAFE_TAG_NAME = /^[a-zA-Z_][a-zA-Z0-9._:-]*$/;
747
754
 
748
755
  function assertSafeTag(tag) {
749
756
  if (typeof tag !== 'string' || !SAFE_TAG_NAME.test(tag)) {
750
- throw new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(tag)}`);
757
+ // ERROR_CODES.INVALID_SSR_TAG
758
+ throw Object.assign(
759
+ new Error(`[what-server] Invalid tag name in SSR: ${JSON.stringify(tag)}`),
760
+ { code: 'ERR_INVALID_SSR_TAG' },
761
+ );
751
762
  }
752
763
  }
753
764
 
package/src/islands.js CHANGED
@@ -115,15 +115,19 @@ function serverStoreHandle(name, initialState) {
115
115
  const resolve = () => {
116
116
  const storeMap = activeServerStoreMap();
117
117
  if (!storeMap) {
118
- throw new Error(
119
- `[what-server] Island store "${name}" was accessed outside an active server render. ` +
120
- 'Read or write module-scoped island stores from a component rendered by renderDocument/renderPage.'
118
+ // ERROR_CODES.ISLAND_STORE_OUTSIDE_RENDER
119
+ throw Object.assign(
120
+ new Error(
121
+ `[what-server] Island store "${name}" was accessed outside an active server render. ` +
122
+ 'Read or write module-scoped island stores from a component rendered by renderDocument/renderPage.'
123
+ ),
124
+ { code: 'ERR_ISLAND_STORE_OUTSIDE_RENDER' },
121
125
  );
122
126
  }
123
127
  return createConcreteStore(storeMap, name, definition.initialState);
124
128
  };
125
129
 
126
- definition.handle = new Proxy({}, {
130
+ definition.handle = /** @type {any} */ (new Proxy({}, {
127
131
  get(_target, property) {
128
132
  return Reflect.get(resolve(), property);
129
133
  },
@@ -140,7 +144,7 @@ function serverStoreHandle(name, initialState) {
140
144
  const descriptor = Reflect.getOwnPropertyDescriptor(resolve(), property);
141
145
  return descriptor ? { ...descriptor, configurable: true } : undefined;
142
146
  },
143
- });
147
+ }));
144
148
 
145
149
  serverStoreDefinitions.set(name, definition);
146
150
  return definition.handle;
@@ -310,7 +314,7 @@ export function hydrateIslands() {
310
314
 
311
315
  const islands = document.querySelectorAll('[data-island]');
312
316
 
313
- for (const el of islands) {
317
+ for (const el of /** @type {NodeListOf<HTMLElement>} */ (islands)) {
314
318
  // Compiler-emitted islands (`<Counter client:idle />`) carry a direct
315
319
  // component reference and schedule their own hydration, so they are not in
316
320
  // the registry and must not be claimed here.