@getforma/core 0.9.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -5
- package/dist/chunk-DCTOXHPF.cjs +399 -0
- package/dist/chunk-DCTOXHPF.cjs.map +1 -0
- package/dist/chunk-OUVOAYIO.js +359 -0
- package/dist/chunk-OUVOAYIO.js.map +1 -0
- package/dist/{chunk-GDULJFJO.cjs → chunk-V732ZBCU.cjs} +119 -511
- package/dist/chunk-V732ZBCU.cjs.map +1 -0
- package/dist/{chunk-CN56FSDT.js → chunk-VTPFK5TJ.js} +89 -442
- package/dist/chunk-VTPFK5TJ.js.map +1 -0
- package/dist/forma-runtime-csp.js +3400 -1
- package/dist/forma-runtime.js +3572 -1
- package/dist/formajs-runtime-hardened.global.js +3400 -1
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +3572 -1
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/formajs.global.js +3443 -1
- package/dist/formajs.global.js.map +1 -1
- package/dist/http.cjs +225 -0
- package/dist/http.cjs.map +1 -0
- package/dist/http.d.cts +108 -0
- package/dist/http.d.ts +108 -0
- package/dist/http.js +220 -0
- package/dist/http.js.map +1 -0
- package/dist/index.cjs +71 -607
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -456
- package/dist/index.d.ts +2 -456
- package/dist/index.js +7 -523
- package/dist/index.js.map +1 -1
- package/dist/resource-Cd0cGOxS.d.ts +62 -0
- package/dist/resource-DK98lW5e.d.cts +62 -0
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +23 -22
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +2 -1
- package/dist/runtime.js.map +1 -1
- package/dist/server.cjs +179 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +217 -0
- package/dist/server.d.ts +217 -0
- package/dist/server.js +166 -0
- package/dist/server.js.map +1 -0
- package/dist/storage.cjs +151 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +77 -0
- package/dist/storage.d.ts +77 -0
- package/dist/storage.js +147 -0
- package/dist/storage.js.map +1 -0
- package/package.json +31 -1
- package/dist/chunk-CN56FSDT.js.map +0 -1
- package/dist/chunk-GDULJFJO.cjs.map +0 -1
package/dist/formajs.global.js
CHANGED
|
@@ -1,2 +1,3444 @@
|
|
|
1
|
-
"use strict";var FormaJS=(()=>{var ke=Object.defineProperty;var Yn=Object.getOwnPropertyDescriptor;var Xn=Object.getOwnPropertyNames;var Zn=Object.prototype.hasOwnProperty;var Qn=(e,t)=>{for(var n in t)ke(e,n,{get:t[n],enumerable:!0})},eo=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Xn(t))!Zn.call(e,r)&&r!==n&&ke(e,r,{get:()=>t[r],enumerable:!(o=Yn(t,r))||o.enumerable});return e};var to=e=>eo(ke({},"__esModule",{value:!0}),e);var Ko={};Qn(Ko,{$:()=>Dt,$$:()=>Ht,$$serverFunction:()=>dn,Fragment:()=>ce,activateIslands:()=>mt,addClass:()=>_t,applyRevalidation:()=>we,batch:()=>_,children:()=>Vt,cleanup:()=>st,closest:()=>$t,createAction:()=>sn,createBus:()=>Lt,createComputed:()=>ee,createContext:()=>bt,createEffect:()=>Q,createErrorBoundary:()=>dt,createFetch:()=>tn,createHistory:()=>kt,createIndexedDB:()=>en,createList:()=>te,createLocalStorage:()=>Xt,createMemo:()=>ze,createPortal:()=>ft,createRPCMiddleware:()=>hn,createReducer:()=>Ye,createRef:()=>Je,createResource:()=>Xe,createRoot:()=>H,createSSE:()=>on,createSessionStorage:()=>Zt,createShow:()=>ne,createSignal:()=>w,createStore:()=>Rt,createSuspense:()=>pt,createSwitch:()=>ut,createText:()=>ct,createWebSocket:()=>rn,deactivateAllIslands:()=>gt,deactivateIsland:()=>be,defineComponent:()=>Tt,delegate:()=>At,disposeComponent:()=>St,enableAutoRevalidation:()=>un,fetchJSON:()=>nn,fragment:()=>at,getBatchDepth:()=>Ae,getRegisteredEndpoints:()=>gn,getServerFunction:()=>mn,h:()=>se,handleRPC:()=>Ee,hydrateIsland:()=>V,inject:()=>wt,isComputed:()=>De,isEffect:()=>He,isEffectScope:()=>_e,isSignal:()=>Ne,mount:()=>lt,nextSibling:()=>Gt,on:()=>qe,onCleanup:()=>je,onError:()=>Ue,onIntersect:()=>Jt,onKey:()=>Nt,onMount:()=>ht,onMutation:()=>Yt,onResize:()=>qt,onUnmount:()=>yt,parent:()=>Wt,persist:()=>Mt,prevSibling:()=>zt,provide:()=>vt,reconcileList:()=>G,registerResource:()=>cn,registerServerFunction:()=>pn,removeClass:()=>Ot,setAttr:()=>Ft,setHTML:()=>Kt,setHTMLUnsafe:()=>jt,setStyle:()=>It,setText:()=>Bt,siblings:()=>Ut,toggleClass:()=>Pt,trackDisposer:()=>xt,trigger:()=>Pe,unprovide:()=>Ct,unregisterResource:()=>ln,untrack:()=>L,withRevalidation:()=>fn});function yn({update:e,notify:t,unwatched:n}){return{link:o,unlink:r,propagate:s,checkDirty:i,shallowPropagate:c};function o(u,a,d){let g=a.depsTail;if(g!==void 0&&g.dep===u)return;let p=g!==void 0?g.nextDep:a.deps;if(p!==void 0&&p.dep===u){p.version=d,a.depsTail=p;return}let h=u.subsTail;if(h!==void 0&&h.version===d&&h.sub===a)return;let T=a.depsTail=u.subsTail={version:d,dep:u,sub:a,prevDep:g,nextDep:p,prevSub:h,nextSub:void 0};p!==void 0&&(p.prevDep=T),g!==void 0?g.nextDep=T:a.deps=T,h!==void 0?h.nextSub=T:u.subs=T}function r(u,a=u.sub){let d=u.dep,g=u.prevDep,p=u.nextDep,h=u.nextSub,T=u.prevSub;return p!==void 0?p.prevDep=g:a.depsTail=g,g!==void 0?g.nextDep=p:a.deps=p,h!==void 0?h.prevSub=T:d.subsTail=T,T!==void 0?T.nextSub=h:(d.subs=h)===void 0&&n(d),p}function s(u){let a=u.nextSub,d;e:do{let g=u.sub,p=g.flags;if(p&60?p&12?p&4?!(p&48)&&f(u,g)?(g.flags=p|40,p&=1):p=0:g.flags=p&-9|32:p=0:g.flags=p|32,p&2&&t(g),p&1){let h=g.subs;if(h!==void 0){let T=(u=h).nextSub;T!==void 0&&(d={value:a,prev:d},a=T);continue}}if((u=a)!==void 0){a=u.nextSub;continue}for(;d!==void 0;)if(u=d.value,d=d.prev,u!==void 0){a=u.nextSub;continue e}break}while(!0)}function i(u,a){let d,g=0,p=!1;e:do{let h=u.dep,T=h.flags;if(a.flags&16)p=!0;else if((T&17)===17){if(e(h)){let b=h.subs;b.nextSub!==void 0&&c(b),p=!0}}else if((T&33)===33){(u.nextSub!==void 0||u.prevSub!==void 0)&&(d={value:u,prev:d}),u=h.deps,a=h,++g;continue}if(!p){let b=u.nextDep;if(b!==void 0){u=b;continue}}for(;g--;){let b=a.subs,y=b.nextSub!==void 0;if(y?(u=d.value,d=d.prev):u=b,p){if(e(a)){y&&c(b),a=u.sub;continue}p=!1}else a.flags&=-33;a=u.sub;let v=u.nextDep;if(v!==void 0){u=v;continue e}}return p}while(!0)}function c(u){do{let a=u.sub,d=a.flags;(d&48)===32&&(a.flags=d|16,(d&6)===2&&t(a))}while((u=u.nextSub)!==void 0)}function f(u,a){let d=a.depsTail;for(;d!==void 0;){if(d===u)return!0;d=d.prevDep}return!1}}var de=0,Z=0,$=0,X=0,I,B=[],{link:pe,unlink:Me,propagate:Tn,checkDirty:Sn,shallowPropagate:Le}=yn({update(e){return e.depsTail!==void 0?En(e):Rn(e)},notify(e){let t=X,n=t;do if(B[t++]=e,e.flags&=-3,e=e.subs?.sub,e===void 0||!(e.flags&2))break;while(!0);for(X=t;n<--t;){let o=B[n];B[n++]=B[t],B[t]=o}},unwatched(e){e.flags&1?e.depsTail!==void 0&&(e.depsTail=void 0,e.flags=17,ge(e)):me.call(e)}});function D(e){let t=I;return I=e,t}function Ae(){return Z}function xn(){++Z}function bn(){--Z||Ie()}function Ne(e){return e.name==="bound "+Mn.name}function De(e){return e.name==="bound "+kn.name}function He(e){return e.name==="bound "+Ln.name}function _e(e){return e.name==="bound "+me.name}function vn(e){return Mn.bind({currentValue:e,pendingValue:e,subs:void 0,subsTail:void 0,flags:1})}function wn(e){return kn.bind({value:void 0,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:0,getter:e})}function Oe(e){let t={fn:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:6},n=D(t);n!==void 0&&pe(t,n,0);try{t.fn()}finally{I=n,t.flags&=-5}return Ln.bind(t)}function Cn(e){let t={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:0},n=D(t);n!==void 0&&pe(t,n,0);try{e()}finally{I=n}return me.bind(t)}function Pe(e){let t={deps:void 0,depsTail:void 0,flags:2},n=D(t);try{e()}finally{I=n;let o=t.deps;for(;o!==void 0;){let r=o.dep;o=Me(o,t);let s=r.subs;s!==void 0&&(t.flags=0,Tn(s),Le(s))}Z||Ie()}}function En(e){++de,e.depsTail=void 0,e.flags=5;let t=D(e);try{let n=e.value;return n!==(e.value=e.getter(n))}finally{I=t,e.flags&=-5,ge(e)}}function Rn(e){return e.flags=1,e.currentValue!==(e.currentValue=e.pendingValue)}function no(e){let t=e.flags;if(t&16||t&32&&Sn(e.deps,e)){++de,e.depsTail=void 0,e.flags=6;let n=D(e);try{e.fn()}finally{I=n,e.flags&=-5,ge(e)}}else e.flags=2}function Ie(){try{for(;$<X;){let e=B[$];B[$++]=void 0,no(e)}}finally{for(;$<X;){let e=B[$];B[$++]=void 0,e.flags|=10}$=0,X=0}}function kn(){let e=this.flags;if(e&16||e&32&&(Sn(this.deps,this)||(this.flags=e&-33,!1))){if(En(this)){let n=this.subs;n!==void 0&&Le(n)}}else if(!e){this.flags=5;let n=D(this);try{this.value=this.getter()}finally{I=n,this.flags&=-5}}let t=I;return t!==void 0&&pe(this,t,de),this.value}function Mn(...e){if(e.length){if(this.pendingValue!==(this.pendingValue=e[0])){this.flags=17;let t=this.subs;t!==void 0&&(Tn(t),Z||Ie())}}else{if(this.flags&16&&Rn(this)){let n=this.subs;n!==void 0&&Le(n)}let t=I;for(;t!==void 0;){if(t.flags&3){pe(this,t,de);break}t=t.subs?.sub}return this.currentValue}}function Ln(){me.call(this)}function me(){this.depsTail=void 0,this.flags=0,ge(this);let e=this.subs;e!==void 0&&Me(e)}function ge(e){let t=e.depsTail,n=t!==void 0?t.nextDep:e.deps;for(;n!==void 0;)n=Me(n,e)}function oo(e,t,n){if(typeof t!="function"){if(n){let i=D(void 0),c=e();if(D(i),n(c,t))return}e(t);return}let o=D(void 0),r=e();D(o);let s=t(r);n&&n(r,s)||e(s)}function w(e,t){let n=vn(e),o=n,r=t?.equals;return[o,i=>oo(n,i,r)]}var W=null,An=[];function H(e){let t={disposers:[],scopeDispose:null};An.push(W),W=t;let n=()=>{if(t.scopeDispose){try{t.scopeDispose()}catch{}t.scopeDispose=null}for(let r of t.disposers)try{r()}catch{}t.disposers.length=0},o;try{t.scopeDispose=Cn(()=>{o=e(n)})}finally{W=An.pop()??null}return o}function Fe(e){W&&W.disposers.push(e)}function Be(){return W!==null}var Ke=null;function je(e){Ke?.(e)}function $e(e){let t=Ke;return Ke=e,t}var A=typeof process<"u"?process.env?.NODE_ENV!=="production":!0,Ve=null;function Ue(e){Ve=e}function F(e,t){if(Ve)try{Ve(e,t?{source:t}:{})}catch{}A&&console.error(`[forma] ${t??"Unknown"} error:`,e)}var We=32,Nn=100,Ge=[];for(let e=0;e<We;e++)Ge.push([]);var he=We;function ro(){if(he>0){let e=Ge[--he];return e.length=0,e}return[]}function Dn(e){e.length=0,he<We&&(Ge[he++]=e)}function Hn(e){if(e!==void 0)try{e()}catch(t){F(t,"effect cleanup")}}function _n(e){if(e!==void 0)for(let t=0;t<e.length;t++)try{e[t]()}catch(n){F(n,"effect cleanup")}}function C(e){let t=Oe(e);return Be()&&Fe(t),t}function Q(e){let t=Be(),n,o,r,s,i=b=>{if(s!==void 0){s.push(b);return}if(r!==void 0){let y=ro();y.push(r,b),r=void 0,s=y;return}r=b},c=!1,f=!0,u=!1,a=!1,d=()=>{if(n!==void 0&&(Hn(n),n=void 0),o!==void 0&&(_n(o),Dn(o),o=void 0),c){try{e()}catch(y){F(y,"effect")}return}r=void 0,s=void 0;let b=$e(i);try{let y=e();if(typeof y=="function"&&i(y),r===void 0&&s===void 0){f&&(c=!0);return}s!==void 0?o=s:n=r}catch(y){F(y,"effect"),s!==void 0?o=s:n=r}finally{$e(b),f=!1}},p=Oe(()=>{if(u){a=!0;return}u=!0;try{let b=0;do a=!1,d(),a&&(b++,b>=Nn&&(F(new Error(`createEffect exceeded ${Nn} re-entrant runs`),"effect"),a=!1));while(a)}finally{u=!1}}),h=!1,T=()=>{h||(h=!0,p(),n!==void 0&&(Hn(n),n=void 0),o!==void 0&&(_n(o),Dn(o),o=void 0))};return t&&Fe(T),T}function ee(e){return wn(e)}var ze=ee;function _(e){xn();try{e()}finally{bn()}}function L(e){let t=D(void 0);try{return e()}finally{D(t)}}function qe(e,t,n){let o,r=!0;return()=>{let s=e();if(n?.defer&&r){r=!1,o=s;return}let i=L(()=>t(s,o));return o=s,i}}function Je(e){return{current:e}}function Ye(e,t){let[n,o]=w(t);return[n,s=>{o(i=>e(i,s))}]}var ye=null,On=[];function Pn(e){On.push(ye),ye=e}function In(){ye=On.pop()??null}function Fn(){return ye}function Xe(e,t,n){let[o,r]=w(n?.initialValue),[s,i]=w(!1),[c,f]=w(void 0),u=Fn(),a=null,d=0,g=()=>{let h=L(e);a&&a.abort();let T=new AbortController;a=T;let b=++d,y=()=>b===d,v=!1;u&&(u.increment(),v=!0),i(!0),f(void 0),Promise.resolve(t(h)).then(S=>{y()&&!T.signal.aborted&&r(()=>S)}).catch(S=>{y()&&!T.signal.aborted&&S?.name!=="AbortError"&&f(S)}).finally(()=>{v&&u?.decrement(),y()&&(i(!1),a===T&&(a=null))})};C(()=>{e(),g()});let p=(()=>o());return p.loading=s,p.error=c,p.refetch=g,p.mutate=h=>r(()=>h),p}function tt(e){let t=e.length;if(t===0)return[];let n=new Int32Array(t),o=new Int32Array(t),r=new Int32Array(t).fill(-1),s=0;for(let f=0;f<t;f++){let u=e[f],a=0,d=s;for(;a<d;){let g=a+d>>1;n[g]<u?a=g+1:d=g}n[a]=u,o[a]=f,a>0&&(r[f]=o[a-1]),a>=s&&s++}let i=new Array(s),c=o[s-1];for(let f=s-1;f>=0;f--)i[f]=c,c=r[c];return i}var so=32,Ze=Symbol.for("forma-abort"),Qe=Symbol.for("forma-attr-cache"),et=Symbol.for("forma-dynamic-child");function io(e,t){return e instanceof HTMLElement&&t instanceof HTMLElement&&e.tagName===t.tagName&&!e[Ze]&&!e[Qe]&&!e[et]&&!t[Ze]&&!t[Qe]&&!t[et]}function ao(e,t){let n=new Set;for(let o of Array.from(t.attributes))n.add(o.name),e.getAttribute(o.name)!==o.value&&e.setAttribute(o.name,o.value);for(let o of Array.from(e.attributes))n.has(o.name)||e.removeAttribute(o.name);e.replaceChildren(...Array.from(t.childNodes))}function co(e,t,n,o,r,s,i,c,f){let u=t.length,a=n.length,d=new Array(u);for(let l=0;l<u;l++)d[l]=r(t[l]);let g=new Array(a),p=new Uint8Array(u);for(let l=0;l<a;l++){let m=r(n[l]),x=-1;for(let E=0;E<u;E++)if(!p[E]&&d[E]===m){x=E,p[E]=1;break}g[l]=x}for(let l=0;l<u;l++)if(!p[l])if(f?.onBeforeRemove){let m=o[l];f.onBeforeRemove(m,()=>{m.parentNode&&m.parentNode.removeChild(m)})}else e.removeChild(o[l]);if(u===a){let l=!0;for(let m=0;m<a;m++)if(g[m]!==m){l=!1;break}if(l){let m=new Array(a);for(let x=0;x<a;x++){let E=o[x];i(E,n[x]),m[x]=E}return{nodes:m,items:n}}}let h=[],T=[];for(let l=0;l<a;l++)g[l]!==-1&&(h.push(g[l]),T.push(l));let b=tt(h),y=new Uint8Array(a);for(let l of b)y[T[l]]=1;let v=new Array(a),S=c??null;for(let l=a-1;l>=0;l--){let m,x=!1;if(g[l]===-1)m=s(n[l]),x=!0;else if(m=o[g[l]],i(m,n[l]),y[l]){v[l]=m,S=m;continue}S?e.insertBefore(m,S):e.appendChild(m),x&&f?.onInsert?.(m),v[l]=m,S=m}return{nodes:v,items:n}}function G(e,t,n,o,r,s,i,c,f){let u=t.length,a=n.length;if(a===0){for(let l=0;l<u;l++)if(f?.onBeforeRemove){let m=o[l];f.onBeforeRemove(m,()=>{m.parentNode&&m.parentNode.removeChild(m)})}else e.removeChild(o[l]);return{nodes:[],items:[]}}if(u===0){let l=new Array(a);for(let m=0;m<a;m++){let x=s(n[m]);c?e.insertBefore(x,c):e.appendChild(x),f?.onInsert?.(x),l[m]=x}return{nodes:l,items:n}}if(u<so)return co(e,t,n,o,r,s,i,c,f);let d=new Map;for(let l=0;l<u;l++)d.set(r(t[l]),l);let g=new Array(a),p=new Uint8Array(u);for(let l=0;l<a;l++){let m=r(n[l]),x=d.get(m);x!==void 0?(g[l]=x,p[x]=1):g[l]=-1}for(let l=0;l<u;l++)if(!p[l])if(f?.onBeforeRemove){let m=o[l];f.onBeforeRemove(m,()=>{m.parentNode&&m.parentNode.removeChild(m)})}else e.removeChild(o[l]);if(u===a){let l=!0;for(let m=0;m<a;m++)if(g[m]!==m){l=!1;break}if(l){let m=new Array(a);for(let x=0;x<a;x++){let E=o[x];i(E,n[x]),m[x]=E}return{nodes:m,items:n}}}let h=[],T=[];for(let l=0;l<a;l++)g[l]!==-1&&(h.push(g[l]),T.push(l));let b=tt(h),y=new Uint8Array(a);for(let l of b)y[T[l]]=1;let v=new Array(a),S=c??null;for(let l=a-1;l>=0;l--){let m,x=!1;if(g[l]===-1)m=s(n[l]),x=!0;else if(m=o[g[l]],i(m,n[l]),y[l]){v[l]=m,S=m;continue}S?e.insertBefore(m,S):e.appendChild(m),x&&f?.onInsert?.(m),v[l]=m,S=m}return{nodes:v,items:n}}function te(e,t,n,o){if(k)return{type:"list",items:e,keyFn:t,renderFn:n,options:o};let r=document.createComment("forma-list-start"),s=document.createComment("forma-list-end"),i=document.createDocumentFragment();i.appendChild(r),i.appendChild(s);let c=new Map,f=[],u=[],a=o?.updateOnItemChange??"none";return C(()=>{let d=e(),g=r.parentNode;if(!g)return;if(!Array.isArray(d)){A&&console.warn("[forma] createList: value is not an array, treating as empty");for(let y of f)y.parentNode===g&&g.removeChild(y);c=new Map,f=[],u=[];return}let p=d;for(let y=0;y<d.length;y++)if(d[y]==null){p=d.filter(v=>v!=null);break}if(A){let y=new Set;for(let v of p){let S=t(v);y.has(S)&&console.warn("[forma] createList: duplicate key detected:",S),y.add(S)}}let T=G(g,u,p,f,t,y=>{let v=t(y),[S,l]=w(0),m=L(()=>n(y,S));return c.set(v,{element:m,item:y,getIndex:S,setIndex:l}),m},a==="rerender"?(y,v)=>{let S=t(v),l=c.get(S);if(!l||l.item===v||(l.item=v,!(y instanceof HTMLElement))||y[Ze]||y[Qe]||y[et])return;let m=L(()=>n(v,l.getIndex));io(y,m)&&(ao(y,m),l.element=y)}:(y,v)=>{let S=t(v),l=c.get(S);l&&(l.item=v)},s),b=new Map;for(let y=0;y<p.length;y++){let v=t(p[y]),S=c.get(v);S&&(S.setIndex(y),b.set(v,S))}c=b,f=T.nodes,u=T.items}),i}function ne(e,t,n){if(k){let a=e()?t():n?.()??null;return{type:"show",condition:e,whenTrue:t,whenFalse:n,initialBranch:a}}let o=document.createComment("forma-show"),r=document.createComment("/forma-show"),s=document.createDocumentFragment();s.appendChild(o),s.appendChild(r);let i=null,c=null,f=null,u=C(()=>{let a=!!e(),d=typeof globalThis.__FORMA_DEBUG__<"u",g=d?t.toString().slice(0,60):"";if(a===c){d&&console.log("[forma:show] skip (same)",a,g);return}d&&console.log("[forma:show]",c,"\u2192",a,g),c=a;let p=o.parentNode;if(!p){d&&console.warn("[forma:show] parentNode is null! skipping.",g);return}if(d&&console.log("[forma:show] parent:",p.nodeName,"inDoc:",document.contains(p)),f&&(f(),f=null),i)if(i.parentNode===p)p.removeChild(i);else for(;o.nextSibling&&o.nextSibling!==r;)p.removeChild(o.nextSibling);let h=a?t:n;if(h){let T;i=H(b=>(T=b,L(()=>h()))),f=T}else i=null;i&&p.insertBefore(i,r)});return s.__showDispose=()=>{u(),f&&(f(),f=null)},s}var Bn=Symbol.for("forma-abort"),k=!1;function Kn(e){k=e}function J(e){return e!=null&&typeof e=="object"&&"type"in e&&e.type==="element"}function Te(e){return e!=null&&typeof e=="object"&&"type"in e&&e.type==="show"}function ot(e){return e!=null&&typeof e=="object"&&"type"in e&&e.type==="list"}function lo(e,t){if(t)for(let n in t){let o=t[n];if(typeof o!="function")continue;if(n.charCodeAt(0)===111&&n.charCodeAt(1)===110&&n.length>2){let i=e[Bn];i||(i=new AbortController,e[Bn]=i),e.addEventListener(n.slice(2).toLowerCase(),o,{signal:i.signal});continue}let r=o,s=n;C(()=>{let i=r();i===!1||i==null?e.removeAttribute(s):i===!0?e.setAttribute(s,""):e.setAttribute(s,String(i))})}}function oe(e){if(e instanceof Node)return e;if(e==null||e===!1||e===!0)return null;if(typeof e=="string")return new Text(e);if(typeof e=="number")return new Text(String(e));if(J(e))return q(e);if(Te(e)){let t=k;k=!1;try{return ne(e.condition,()=>oe(e.whenTrue())??document.createComment("empty"),e.whenFalse?()=>oe(e.whenFalse())??document.createComment("empty"):void 0)}finally{k=t}}if(ot(e)){let t=k;k=!1;try{return te(e.items,e.keyFn,e.renderFn,e.options)}finally{k=t}}return null}function q(e){let t=k;k=!1;try{let n=e.children.map(o=>J(o)?q(o):Te(o)||ot(o)?oe(o):o);return se(e.tag,e.props,...n)}finally{k=t}}function uo(e){return e.length>=4&&e.charCodeAt(0)===102&&e.charCodeAt(1)===58&&e.charCodeAt(2)===105}function nt(e){return e.length>=4&&e.charCodeAt(0)===102&&e.charCodeAt(1)===58&&e.charCodeAt(2)===115}function fo(e){return e.length>=4&&e.charCodeAt(0)===102&&e.charCodeAt(1)===58&&e.charCodeAt(2)===116}function po(e){return e.length>=4&&e.charCodeAt(0)===102&&e.charCodeAt(1)===58&&e.charCodeAt(2)===108}function z(e){let t="/"+e.data,n=e.nextSibling;for(;n;){if(n.nodeType===8&&n.data===t)return n;n=n.nextSibling}return null}function mo(e,t){let n=e.nextSibling;for(;n&&n!==t;){if(n.nodeType===3)return n;n=n.nextSibling}return null}function go(e,t){let n=e.nextSibling;for(;n&&n!==t;){if(n.nodeType===1)return n;n=n.nextSibling}}function ho(e,t){let n=document.createDocumentFragment(),o=e.nextSibling;for(;o&&o!==t;){let r=o.nextSibling;n.appendChild(o),o=r}return n}function jn(e,t){let n=!!e.condition(),o=null,r=null;if(!(t.start.nextSibling!==t.end)&&n){A&&console.warn("[forma] Hydration: show condition mismatch \u2014 SSR empty but client condition is true");let i=e.whenTrue();i instanceof Node&&t.start.parentNode.insertBefore(i,t.end)}C(()=>{let i=!!e.condition();if(i===n)return;n=i;let c=t.start.parentNode;if(!c)return;let f=ho(t.start,t.end);i?r=f:o=f;let u=i?o??e.whenTrue():e.whenFalse?r??e.whenFalse():null;i&&o&&(o=null),!i&&r&&(r=null),u!=null&&!(u instanceof Node)&&(u=oe(u)),u instanceof Node&&c.insertBefore(u,t.end)})}function $n(e,t,n){if(J(e)){let o=go(t,n);o&&re(e,o)}else if(Te(e)){let o=t.nextSibling;for(;o&&o!==n;){if(o.nodeType===8&&nt(o.data)){let r=o,s=z(r);s&&(e.initialBranch&&$n(e.initialBranch,r,s),jn(e,{start:r,end:s,cachedContent:null}));break}o=o.nextSibling}}}function re(e,t){if(!t||t.tagName!==e.tag.toUpperCase()){A&&console.warn(`Hydration mismatch: expected <${e.tag}>, got <${t?.tagName?.toLowerCase()??"nothing"}>`);let o=q(e);t&&t.replaceWith(o);return}lo(t,e.props);let n=t.firstChild;for(let o of e.children)if(!(o===!1||o==null))if(J(o)){for(;n&&n.nodeType===3&&!n.data.trim();)n=n.nextSibling;for(;n&&n.nodeType===1&&n.hasAttribute("data-forma-island");)n=n.nextSibling;if(!n){t.appendChild(q(o));continue}if(n.nodeType===1){let r=n;n=n.nextSibling,re(o,r)}else if(n.nodeType===8&&uo(n.data)){let r=z(n),s=q(o);r?(r.parentNode.insertBefore(s,r),n=r.nextSibling):(t.appendChild(s),n=null)}else t.appendChild(q(o))}else if(Te(o)){for(;n&&!(n.nodeType===8&&nt(n.data));)n=n.nextSibling;if(n){let r=n,s=z(r);s&&(o.initialBranch&&$n(o.initialBranch,r,s),jn(o,{start:r,end:s,cachedContent:null}),n=s.nextSibling)}}else if(ot(o)){for(;n&&!(n.nodeType===8&&po(n.data));)n=n.nextSibling;if(n){let r=n,s=z(r);if(s){let i=new Map,c=[],f=r.nextSibling;for(;f&&f!==s;){if(f.nodeType===1){let l=f;c.push(l);let m=l.getAttribute("data-forma-key");m!=null&&i.set(m,l)}f=f.nextSibling}let u=L(()=>o.items()),a=o.keyFn,d=o.renderFn,g=i.size===0&&c.length>0,p=[],h=[],T=new Set;for(let l=0;l<u.length;l++){let m=u[l],x=a(m),E;if(g?l<c.length&&(E=c[l],T.add(l)):(E=i.get(String(x)),E&&i.delete(String(x))),E)p.push(E),h.push(m);else{A&&console.warn(`[FormaJS] Hydration: list item key "${x}" not found in SSR \u2014 rendering fresh`);let R=k;k=!1;try{let[M]=w(l),N=d(m,M);s.parentNode.insertBefore(N,s),p.push(N),h.push(m)}finally{k=R}}}if(g)for(let l=0;l<c.length;l++)!T.has(l)&&c[l].parentNode&&c[l].parentNode.removeChild(c[l]);else for(let[l,m]of i)A&&console.warn(`[FormaJS] Hydration: removing extra SSR list item with key "${l}"`),m.parentNode&&m.parentNode.removeChild(m);let b=r.parentNode;for(let l of p)b.insertBefore(l,s);let y=new Map;for(let l=0;l<h.length;l++){let m=h[l],x=a(m),[E,R]=w(l);y.set(x,{element:p[l],item:m,getIndex:E,setIndex:R})}let v=p.slice(),S=h.slice();C(()=>{let l=o.items(),m=r.parentNode;if(!m)return;let x=G(m,S,l,v,a,R=>{let M=k;k=!1;try{let N=a(R),[O,Re]=w(0),fe=L(()=>d(R,O));return y.set(N,{element:fe,item:R,getIndex:O,setIndex:Re}),fe}finally{k=M}},(R,M)=>{let N=a(M),O=y.get(N);O&&(O.item=M)},s),E=new Map;for(let R=0;R<l.length;R++){let M=a(l[R]),N=y.get(M);N&&(N.setIndex(R),E.set(M,N))}y=E,v=x.nodes,S=x.items}),n=s.nextSibling}}}else if(typeof o=="function"){for(;n&&n.nodeType===3&&!n.data.trim();)n=n.nextSibling;if(n&&n.nodeType===1){let r=o();if(J(r)){let s=n;n=n.nextSibling,re(r,s);continue}}if(n&&n.nodeType===8){let r=n.data;if(fo(r)){let s=z(n),i=n.nextSibling;if(!i||i.nodeType!==3){A&&console.warn(`[FormaJS] Hydration: created text node for marker ${r} \u2014 SSR walker should emit content between markers`);let c=document.createTextNode("");n.parentNode.insertBefore(c,s||n.nextSibling),i=c}C(()=>{i.data=String(o())}),n=s?s.nextSibling:i.nextSibling}else if(nt(r)){let s=n,i=z(s);if(i){let c=mo(s,i);c||(A&&console.warn(`[FormaJS] Hydration: created text node for show marker ${s.data} \u2014 SSR walker should emit content between markers`),c=document.createTextNode(""),s.parentNode.insertBefore(c,i)),C(()=>{c.data=String(o())}),n=i.nextSibling}else n=n.nextSibling}else n=n.nextSibling}else if(n&&n.nodeType===3){let r=n;n=n.nextSibling,C(()=>{r.data=String(o())})}else{A&&console.warn(`[FormaJS] Hydration: created text node in empty <${t.tagName.toLowerCase()}> \u2014 IR may not cover this component`);let r=document.createTextNode("");t.appendChild(r),C(()=>{r.data=String(o())})}}else(typeof o=="string"||typeof o=="number")&&n&&n.nodeType===3&&(n=n.nextSibling)}function V(e,t){if(!(t.childElementCount>0||t.childNodes.length>0&&Array.from(t.childNodes).some(r=>r.nodeType===1||r.nodeType===3&&r.data.trim()))){if(A){let s=t.getAttribute("data-forma-component")||"unknown";console.warn(`[forma] Island "${s}" has no SSR content \u2014 falling back to CSR. This means the IR walker did not render content between ISLAND_START and ISLAND_END.`)}let r=e();if(r instanceof Element){for(let s of Array.from(t.attributes))s.name.startsWith("data-forma-")&&r.setAttribute(s.name,s.value);return t.replaceWith(r),r}else r instanceof Node&&t.appendChild(r);return t}Kn(!0);let o;try{o=e()}finally{Kn(!1)}return!o||!J(o)?(t.removeAttribute("data-forma-ssr"),t):(t.hasAttribute("data-forma-island")?re(o,t):re(o,t.children[0]),t.removeAttribute("data-forma-ssr"),t)}var ce=Symbol.for("forma.fragment"),yo="http://www.w3.org/2000/svg",ie="http://www.w3.org/1999/xlink",To=new Set(["svg","path","circle","rect","line","polyline","polygon","ellipse","g","text","tspan","textPath","defs","use","symbol","clipPath","mask","pattern","marker","linearGradient","radialGradient","stop","filter","feGaussianBlur","feColorMatrix","feOffset","feBlend","feMerge","feMergeNode","feComposite","feFlood","feMorphology","feTurbulence","feDisplacementMap","feImage","foreignObject","animate","animateTransform","animateMotion","set","image","switch","desc","title","metadata"]),Un=new Set(["disabled","checked","readonly","required","autofocus","autoplay","controls","default","defer","formnovalidate","hidden","ismap","loop","multiple","muted","nomodule","novalidate","open","playsinline","reversed","selected","async"]),j=null;function So(e){if(!j){j=Object.create(null);for(let t of["div","span","p","a","li","ul","ol","button","input","label","h1","h2","h3","h4","h5","h6","section","header","footer","main","nav","table","tr","td","th","tbody","img","form","select","option","textarea","i","b","strong","em","small","article","aside","details","summary"])j[t]=document.createElement(t)}return j[e]??(j[e]=document.createElement(e))}var Vn=Object.create(null);function xo(e){return Vn[e]??(Vn[e]=e.slice(2).toLowerCase())}var Se=Symbol.for("forma-abort");function bo(e){let t=e[Se];return t||(t=new AbortController,e[Se]=t),t}function st(e){let t=e[Se];t&&(t.abort(),delete e[Se])}var rt=Symbol.for("forma-attr-cache"),vo=Symbol.for("forma-dynamic-child");function P(e){return e[rt]??(e[rt]=Object.create(null))}function it(e,t,n){if(typeof n=="function")C(()=>{let o=n(),r=P(e);r.class!==o&&(r.class=o,e instanceof HTMLElement?e.className=o:e.setAttribute("class",o))});else{let o=P(e);if(o.class===n)return;o.class=n,e instanceof HTMLElement?e.className=n:e.setAttribute("class",n)}}function wo(e,t,n){if(typeof n=="function"){let o=[];C(()=>{let r=n();if(typeof r=="string"){let s=P(e);if(s.style===r)return;s.style=r,o=[],e.style.cssText=r}else if(r&&typeof r=="object"){let s=e.style,i=Object.keys(r);for(let c of o)c in r||s.removeProperty(c.replace(/[A-Z]/g,f=>"-"+f.toLowerCase()));Object.assign(s,r),o=i}})}else if(typeof n=="string"){let o=P(e);if(o.style===n)return;o.style=n,e.style.cssText=n}else n&&typeof n=="object"&&Object.assign(e.style,n)}function Wn(e,t,n){let o=bo(e);e.addEventListener(xo(t),n,{signal:o.signal})}function Co(e,t,n){if(typeof n=="function")C(()=>{let o=n();if(o==null){e.innerHTML="";return}if(typeof o!="object"||!("__html"in o))throw new TypeError("dangerouslySetInnerHTML: expected { __html: string }, got "+typeof o);let r=o.__html;if(typeof r!="string")throw new TypeError("dangerouslySetInnerHTML: __html must be a string, got "+typeof r);let s=P(e);s.innerHTML!==r&&(s.innerHTML=r,e.innerHTML=r)});else{if(n==null){e.innerHTML="";return}if(typeof n!="object"||!("__html"in n))throw new TypeError("dangerouslySetInnerHTML: expected { __html: string }, got "+typeof n);let o=n.__html;if(typeof o!="string")throw new TypeError("dangerouslySetInnerHTML: __html must be a string, got "+typeof o);e.innerHTML=o}}function Eo(e,t,n){let o=t.slice(6);typeof n=="function"?C(()=>{let r=n();r==null||r===!1?e.removeAttributeNS(ie,o):e.setAttributeNS(ie,t,String(r))}):n==null||n===!1?e.removeAttributeNS(ie,o):e.setAttributeNS(ie,t,String(n))}function Ro(e,t,n){if(typeof n=="function")C(()=>{let o=n(),r=P(e);r[t]!==o&&(r[t]=o,o?e.setAttribute(t,""):e.removeAttribute(t))});else{let o=P(e);if(o[t]===n)return;o[t]=n,n?e.setAttribute(t,""):e.removeAttribute(t)}}function ko(e,t,n){if(typeof n=="function")C(()=>{let o=n();if(o==null||o===!1){let r=P(e);if(r[t]===null)return;r[t]=null,e.removeAttribute(t)}else{let r=String(o),s=P(e);if(s[t]===r)return;s[t]=r,e.setAttribute(t,r)}});else if(n==null||n===!1){let o=P(e);if(o[t]===null)return;o[t]=null,e.removeAttribute(t)}else{let o=String(n),r=P(e);if(r[t]===o)return;r[t]=o,e.setAttribute(t,o)}}var U=new Map;U.set("class",it);U.set("className",it);U.set("style",wo);U.set("ref",()=>{});U.set("dangerouslySetInnerHTML",Co);for(let e of Un)U.set(e,Ro);function Mo(e,t,n){if(t==="class"){it(e,t,n);return}if(t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&t.length>2){Wn(e,t,n);return}let o=U.get(t);if(o){o(e,t,n);return}if(t.charCodeAt(0)===120&&t.startsWith("xlink:")){Eo(e,t,n);return}ko(e,t,n)}function Lo(e,t,n){if(!(n==null||n===!1)){if(t==="class"||t==="className"){e.className=n;return}if(t==="style"){typeof n=="string"?e.style.cssText=n:n&&typeof n=="object"&&Object.assign(e.style,n);return}if(t==="dangerouslySetInnerHTML"){if(typeof n!="object"||!("__html"in n))throw new TypeError("dangerouslySetInnerHTML: expected { __html: string }, got "+typeof n);let o=n.__html;if(typeof o!="string")throw new TypeError("dangerouslySetInnerHTML: __html must be a string, got "+typeof o);e.innerHTML=o;return}if(t.charCodeAt(0)===120&&t.startsWith("xlink:")){e.setAttributeNS(ie,t,String(n));return}if(Un.has(t)){n&&e.setAttribute(t,"");return}n===!0?e.setAttribute(t,""):e.setAttribute(t,String(n))}}function ae(e,t){if(t instanceof Node){e.appendChild(t);return}if(typeof t=="string"){e.appendChild(new Text(t));return}if(!(t==null||t===!1||t===!0)){if(typeof t=="number"){e.appendChild(new Text(String(t)));return}if(typeof t=="function"){e instanceof Element&&(e[vo]=!0);let n=null;C(()=>{let o=t();if(o instanceof Node)n?e.replaceChild(o,n):e.appendChild(o),n=o;else{let r=String(typeof o=="symbol"?o:o??"");if(!n)n=new Text(r),e.appendChild(n);else if(n.nodeType===3)n.data=r;else{let s=new Text(r);e.replaceChild(s,n),n=s}}});return}if(Array.isArray(t)){for(let n of t)ae(e,n);return}}}function se(e,t,...n){if(typeof e=="function"&&e!==ce){let i={...t??{},children:n};return e(i)}if(e===ce){let i=document.createDocumentFragment();for(let c of n)ae(i,c);return i}let o=e;if(k)return{type:"element",tag:o,props:t??null,children:n};let r;if(j&&j[o]?r=j[o].cloneNode(!1):To.has(o)?r=document.createElementNS(yo,o):r=So(o).cloneNode(!1),t){let i=!1;for(let c in t){if(c==="ref")continue;let f=t[c];if(c.charCodeAt(0)===111&&c.charCodeAt(1)===110&&c.length>2){Wn(r,c,f);continue}if(typeof f=="function"){i||(r[rt]=Object.create(null),i=!0),Mo(r,c,f);continue}Lo(r,c,f)}}let s=n.length;if(s===1){let i=n[0];typeof i=="string"?r.textContent=i:typeof i=="number"?r.textContent=String(i):ae(r,i)}else if(s>1)for(let i of n)ae(r,i);return t&&typeof t.ref=="function"&&t.ref(r),r}function at(...e){let t=document.createDocumentFragment();for(let n of e)ae(t,n);return t}function ct(e){if(typeof e=="function"){let t=new Text("");return C(()=>{t.data=e()}),t}return new Text(e)}function lt(e,t){let n=typeof t=="string"?document.querySelector(t):t;if(!n)throw new Error(`mount: container not found \u2014 "${t}"`);let o;if(n.hasAttribute("data-forma-ssr"))H(s=>{o=s,V(e,n)});else{let s=H(i=>(o=i,e()));n.innerHTML="",n.appendChild(s)}let r=!1;return()=>{r||(r=!0,o(),n.innerHTML="")}}function ut(e,t,n){let o=document.createComment("forma-switch"),r=document.createComment("/forma-switch"),s=document.createDocumentFragment();s.appendChild(o),s.appendChild(r);let i=new Map,c=null,f=Ao,u=C(()=>{let a=e();if(a===f)return;let d=typeof globalThis.__FORMA_DEBUG__<"u";d&&console.log("[forma:switch] transition",String(f),"\u2192",String(a)),f=a;let g=o.parentNode;if(!g){d&&console.warn("[forma:switch] markers not in DOM yet, skipping");return}if(c)if(c.parentNode===g)d&&console.log("[forma:switch] removing single node"),g.removeChild(c);else if(c.nodeType===11){d&&console.log("[forma:switch] scooping nodes back into fragment");let h=0;for(;o.nextSibling&&o.nextSibling!==r;)c.appendChild(o.nextSibling),h++;d&&console.log("[forma:switch] scooped",h,"nodes back into fragment")}else for(d&&console.log("[forma:switch] clearing detached node between markers");o.nextSibling&&o.nextSibling!==r;)g.removeChild(o.nextSibling);let p=t.find(h=>h.match===a);if(p){let h=i.get(a);if(h)d&&console.log("[forma:switch] reusing cached branch for",String(a),"\u2192",h.node.nodeName,"type",h.node.nodeType,"childNodes",h.node.childNodes?.length);else{let T,b=H(y=>(T=y,L(()=>p.render())));h={node:b,dispose:T},i.set(a,h),d&&console.log("[forma:switch] rendered new branch for",String(a),"\u2192",b.nodeName,"type",b.nodeType)}c=h.node}else c=n?.()??null,d&&console.log("[forma:switch] no match, using fallback");c&&(g.insertBefore(c,r),d&&console.log("[forma:switch] inserted",c.nodeName,"before end marker"))});return s.__switchDispose=()=>{u();for(let a of i.values())a.dispose();i.clear()},s}var Ao=Symbol("unset");function ft(e,t){let n=document.createComment("forma-portal"),o=typeof t=="string"?document.querySelector(t):t??document.body;if(!o)throw new Error(`createPortal: target not found: ${t}`);let r=null,s=()=>{r&&r.parentNode===o&&o.removeChild(r),r=null};return Q(()=>{let i=e();return s(),r=i,o.appendChild(i),()=>{s()}}),n}function dt(e,t){let n=document.createComment("forma-error-boundary"),o=document.createComment("/forma-error-boundary"),r=document.createDocumentFragment();r.appendChild(n),r.appendChild(o);let[s,i]=w(0),c=null;return C(()=>{s();let f=n.parentNode;if(f){c&&c.parentNode===f&&f.removeChild(c);try{c=e()}catch(u){let a=u instanceof Error?u:new Error(String(u));c=t(a,()=>i(g=>g+1))}c&&f.insertBefore(c,o)}}),r}function pt(e,t){let n=document.createComment("forma-suspense"),o=document.createComment("/forma-suspense"),r=document.createDocumentFragment();r.appendChild(n),r.appendChild(o);let[s,i]=w(0),c=null,f=null,u=null;Pn({increment(){i(d=>d+1)},decrement(){i(d=>Math.max(0,d-1))}});try{f=t()}finally{In()}return C(()=>{let d=n.parentNode;if(!d)return;let p=s()>0?u??=e():f;p!==c&&(c&&c.parentNode===d&&d.removeChild(c),p&&d.insertBefore(p,o),c=p)}),r}var No=new Set(["__proto__","constructor","prototype"]);function Gn(e){for(let t of No)t in e&&delete e[t];return e}function Do(e,t,n){let o=e.getAttribute("data-forma-props");return o?Gn(JSON.parse(o)):n&&String(t)in n?Gn(n[String(t)]):null}function mt(e){let t=document.getElementById("__forma_islands"),n=t?JSON.parse(t.textContent):null,o=document.querySelectorAll("[data-forma-island]");for(let r of o){let s=parseInt(r.getAttribute("data-forma-island"),10),i=r.getAttribute("data-forma-component"),c=e[i];if(!c){A&&console.warn(`[forma] No hydrate function for island "${i}" (id=${s})`),r.setAttribute("data-forma-status","error");continue}let f=r.getAttribute("data-forma-hydrate")||"load";if(f==="visible"){let u=new IntersectionObserver(a=>{for(let d of a)d.isIntersecting&&(u.disconnect(),xe(r,s,i,c,n))},{rootMargin:"200px"});u.observe(r)}else if(f==="idle"){let u=()=>xe(r,s,i,c,n);typeof requestIdleCallback=="function"?requestIdleCallback(u):setTimeout(u,200)}else if(f==="interaction"){let u=()=>{r.removeEventListener("pointerdown",u,!0),r.removeEventListener("focusin",u,!0),xe(r,s,i,c,n)};r.addEventListener("pointerdown",u,{capture:!0,once:!0}),r.addEventListener("focusin",u,{capture:!0,once:!0})}else xe(r,s,i,c,n)}}function be(e){let t=e.__formaDispose;typeof t=="function"&&(t(),delete e.__formaDispose,e.setAttribute("data-forma-status","disposed"))}function gt(e=document){let t=e.querySelectorAll('[data-forma-status="active"]');for(let n of t)be(n)}function xe(e,t,n,o,r){try{let s=Do(e,t,r);e.setAttribute("data-forma-status","hydrating");let i=e;H(c=>{i=V(()=>o(e,s),e),i.__formaDispose=c}),i.setAttribute("data-forma-status","active")}catch(s){A&&console.error(`[forma] Island "${n}" (id=${t}) failed:`,s),e.setAttribute("data-forma-status","error")}}var K=null,zn=[];function Ho(e){zn.push(K),K=e}function _o(){K=zn.pop()??null}function ht(e){if(K===null)throw new Error("onMount() must be called inside a component setup function");K.mountCallbacks.push(e)}function yt(e){if(K===null)throw new Error("onUnmount() must be called inside a component setup function");K.unmountCallbacks.push(e)}var ve=Symbol("forma:component:dispose");function Tt(e){let t=typeof e=="function"?e:e.setup,n=typeof e=="function"?void 0:e.name;return function(){let r={disposers:[],mountCallbacks:[],unmountCallbacks:[]};Ho(r);let s;try{s=t()}finally{_o()}let i=()=>{for(let c of r.unmountCallbacks)try{c()}catch(f){F(f,"onUnmount")}for(let c of r.disposers)try{c()}catch(f){F(f,"component disposer")}r.disposers.length=0,r.mountCallbacks.length=0,r.unmountCallbacks.length=0};s[ve]=i;for(let c of r.mountCallbacks)try{let f=c();typeof f=="function"&&r.unmountCallbacks.push(f)}catch(f){F(f,"onMount")}return s}}function St(e){let t=e;typeof t[ve]=="function"&&(t[ve](),delete t[ve])}function xt(e){K!==null&&K.disposers.push(e)}var le=new Map;function bt(e){return{id:Symbol("forma:context"),defaultValue:e}}function vt(e,t){let n=le.get(e.id);n===void 0&&(n=[],le.set(e.id,n)),n.push(t)}function wt(e){let t=le.get(e.id);return t===void 0||t.length===0?e.defaultValue:t[t.length-1]}function Ct(e){let t=le.get(e.id);t!==void 0&&t.length>0&&(t.pop(),t.length===0&&le.delete(e.id))}var ue=Symbol("forma-raw"),Jn=Symbol("forma-proxy"),Oo=new Set(["push","pop","shift","unshift","splice","sort","reverse","fill","copyWithin"]);function qn(e){return!(e==null||typeof e!="object"||e instanceof Date||e instanceof RegExp||e instanceof Map||e instanceof Set||e instanceof WeakMap||e instanceof WeakSet||e instanceof Error||e instanceof Promise||e[Jn])}function Et(e,t){if(e===null||typeof e!="object"||(t||(t=new WeakSet),t.has(e)))return e;if(t.add(e),Array.isArray(e))return e.map(o=>Et(o,t));let n={};for(let o of Object.keys(e))n[o]=Et(e[o],t);return n}function Rt(e){let t=new Map,n=new Map;function o(d){let g=d.lastIndexOf(".");if(g===-1)return;let p=d.substring(0,g),h=n.get(p);h||(h=new Set,n.set(p,h)),h.add(d)}function r(d,g){let p=t.get(d);return p||(p=w(g),t.set(d,p),o(d)),p}let s=new WeakMap;function i(d){let g=n.get(d);if(g){for(let p of g)i(p),t.delete(p),n.delete(p);g.clear()}}function c(d,g){if(!qn(d))return d;let p=s.get(d);if(p)return p;let h=Array.isArray(d),T=g?g+".":"",b="",y,v=new Proxy(d,{get(S,l,m){if(l===ue)return S;if(l===Jn)return!0;if(typeof l=="symbol")return Reflect.get(S,l,m);let x=String(l),E=T+x;if(h&&Oo.has(x))return(...N)=>{let O;return _(()=>{let Re=N.map(Y=>Y!=null&&typeof Y=="object"&&Y[ue]?Y[ue]:Y);O=S[x].apply(S,Re),i(g);let[,fe]=r(T+"length",S.length);fe(S.length)}),O};if(h&&x==="length"){let[N]=r(E,S.length);return N(),S.length}let R=Reflect.get(S,l),M;return x===b&&y?M=y:(M=r(E,R),b=x,y=M),M[0](),qn(R)?c(R,E):R},set(S,l,m){if(typeof l=="symbol")return Reflect.set(S,l,m);let x=String(l),E=T+x,R=m!=null&&typeof m=="object"&&m[ue]?m[ue]:m;if(Reflect.set(S,l,R),R!=null&&typeof R=="object"&&i(E),h&&x!=="length"){let N=T+"length",O=t.get(N);O&&O[1](S.length)}let[,M]=r(E,R);return M(R),!0},has(S,l){if(typeof l=="symbol")return Reflect.has(S,l);let m=String(l),x=T+m,[E]=r(x,Reflect.get(S,l));return E(),Reflect.has(S,l)},ownKeys(S){return Reflect.ownKeys(S)},getOwnPropertyDescriptor(S,l){return Object.getOwnPropertyDescriptor(S,l)},deleteProperty(S,l){if(typeof l=="symbol")return Reflect.deleteProperty(S,l);let m=String(l),x=T+m,E=Reflect.deleteProperty(S,l);i(x),t.delete(x);let R=g;if(R!==void 0){let M=n.get(R);M&&(M.delete(x),M.size===0&&n.delete(R))}return n.delete(x),E}});return s.set(d,v),v}let f=c(e,"");function u(){return L(()=>Et(e))}return[f,d=>{let g=typeof d=="function"?d(u()):d;_(()=>{for(let p of Object.keys(g))f[p]=g[p]})}]}function kt(e,t){let[n,o]=e,r=t?.maxLength??100,s=[n()],i=0,[c,f]=w([...s]),[u,a]=w(i),[d,g]=w(s.length);function p(){_(()=>{f([...s]),a(i),g(s.length)})}let h=!1,T=!0;return C(()=>{let m=n();if(T){T=!1;return}if(h){h=!1;return}s=s.slice(0,i+1),s.push(m),s.length>r&&s.splice(0,s.length-r),i=s.length-1,p()}),{undo:()=>{i<=0||(i--,h=!0,o(s[i]),p())},redo:()=>{i>=s.length-1||(i++,h=!0,o(s[i]),p())},canUndo:()=>u()>0,canRedo:()=>u()<d()-1,history:()=>c(),cursor:()=>u(),clear:()=>{s=[n()],i=0,p()}}}function Mt(e,t,n){let[o,r]=e,s=n?.storage??globalThis.localStorage,i=n?.serialize??JSON.stringify,c=n?.deserialize??JSON.parse,f=n?.validate;try{let u=s.getItem(t);if(u!==null){let a=c(u);(!f||f(a))&&r(a)}}catch{}C(()=>{let u=o();try{let a=i(u);s.setItem(t,a)}catch{}})}function Lt(){let e=new Map;function t(c){let f=e.get(c);return f||(f=new Set,e.set(c,f)),f}function n(c,f){let u=t(c);return u.add(f),()=>{u.delete(f)}}function o(c,f){let u=a=>{s(c,u),f(a)};return n(c,u)}function r(c,f){let u=e.get(c);if(u)for(let a of[...u])try{a(f)}catch(d){console.error(`[forma] Bus handler error on "${String(c)}":`,d)}}function s(c,f){let u=e.get(c);u&&u.delete(f)}function i(){e.clear()}return{on:n,once:o,emit:r,off:s,clear:i}}function At(e,t,n,o,r){let s=i=>{let c=i.target;if(!(c instanceof HTMLElement))return;let f=e instanceof Document?e.documentElement:e,u=c.closest(t);u instanceof HTMLElement&&f.contains(u)&&o(i,u)};return e.addEventListener(n,s,r),()=>{e.removeEventListener(n,s,r)}}function Po(e){let t=e.toLowerCase().split("+").map(o=>o.trim()),n={ctrl:!1,shift:!1,alt:!1,meta:!1,key:""};for(let o of t)switch(o){case"ctrl":case"control":n.ctrl=!0;break;case"shift":n.shift=!0;break;case"alt":n.alt=!0;break;case"meta":case"cmd":case"command":n.meta=!0;break;default:n.key=o}return n}function Io(e,t){return e.ctrlKey!==t.ctrl||e.shiftKey!==t.shift||e.altKey!==t.alt||e.metaKey!==t.meta?!1:e.key.toLowerCase()===t.key}function Nt(e,t,n){let o=n?.target??document,r=n?.preventDefault??!0,s=Po(e),i=c=>{c instanceof KeyboardEvent&&Io(c,s)&&(r&&c.preventDefault(),t(c))};return o.addEventListener("keydown",i),()=>{o.removeEventListener("keydown",i)}}function Dt(e,t){return(t??document).querySelector(e)}function Ht(e,t){return Array.from((t??document).querySelectorAll(e))}function _t(e,...t){e.classList.add(...t)}function Ot(e,...t){e.classList.remove(...t)}function Pt(e,t,n){return e.classList.toggle(t,n)}function It(e,t){for(let[n,o]of Object.entries(t))o!==void 0&&(e.style[n]=o)}function Ft(e,t){for(let[n,o]of Object.entries(t))o===!1||o===null?e.removeAttribute(n):o===!0?e.setAttribute(n,""):e.setAttribute(n,o)}function Bt(e,t){e.textContent=t}function Kt(e,t){e.innerHTML=t}function jt(e,t){e.innerHTML=t}function $t(e,t){return e.closest(t)}function Vt(e,t){let n=Array.from(e.children);return t?n.filter(o=>o.matches(t)):n}function Ut(e,t){let n=e.parentElement;if(!n)return[];let r=Array.from(n.children).filter(s=>s!==e);return t?r.filter(s=>s.matches(t)):r}function Wt(e){return e.parentElement}function Gt(e,t){let n=e.nextElementSibling;for(;n;){if(n instanceof HTMLElement&&(!t||n.matches(t)))return n;n=n.nextElementSibling}return null}function zt(e,t){let n=e.previousElementSibling;for(;n;){if(n instanceof HTMLElement&&(!t||n.matches(t)))return n;n=n.previousElementSibling}return null}function qt(e,t){let n=new ResizeObserver(o=>{for(let r of o)t(r)});return n.observe(e),()=>{n.disconnect()}}function Jt(e,t,n){let o=new IntersectionObserver(r=>{for(let s of r)t(s)},n);return o.observe(e),()=>{o.disconnect()}}function Yt(e,t,n){let o=new MutationObserver(r=>{t(r)});return o.observe(e,n??{childList:!0,subtree:!0}),()=>{o.disconnect()}}function Xt(e,t){let n=t?.serialize??JSON.stringify,o=t?.deserialize??JSON.parse,r=t?.validate;return{key:e,get(){try{let s=localStorage.getItem(e);if(s===null)return null;let i=o(s);return r&&!r(i)?null:i}catch{return null}},set(s){try{let i=n(s);localStorage.setItem(e,i)}catch{}},remove(){localStorage.removeItem(e)}}}function Zt(e,t){let n=t?.serialize??JSON.stringify,o=t?.deserialize??JSON.parse,r=t?.validate;return{key:e,get(){try{let s=sessionStorage.getItem(e);if(s===null)return null;let i=o(s);return r&&!r(i)?null:i}catch{return null}},set(s){try{let i=n(s);sessionStorage.setItem(e,i)}catch{}},remove(){sessionStorage.removeItem(e)}}}var Qt=new Map;function Fo(e,t){let n=`${e}::${t}`,o=Qt.get(n);if(o)return o;let r=new Promise((s,i)=>{let c=indexedDB.open(e);c.onerror=()=>i(c.error),c.onsuccess=()=>{let f=c.result;if(f.objectStoreNames.contains(t)){s(f);return}let u=f.version+1;f.close();let a=indexedDB.open(e,u);a.onerror=()=>i(a.error),a.onupgradeneeded=()=>{let d=a.result;d.objectStoreNames.contains(t)||d.createObjectStore(t)},a.onsuccess=()=>s(a.result)},c.onupgradeneeded=()=>{let f=c.result;f.objectStoreNames.contains(t)||f.createObjectStore(t)}});return Qt.set(n,r),r.catch(()=>{Qt.delete(n)}),r}function en(e,t="default"){function n(o,r){return Fo(e,t).then(s=>new Promise((i,c)=>{let u=s.transaction(t,o).objectStore(t),a=r(u);a.onsuccess=()=>i(a.result),a.onerror=()=>c(a.error)}))}return{get(o){return n("readonly",r=>r.get(o))},set(o,r){return n("readwrite",s=>s.put(r,o)).then(()=>{})},delete(o){return n("readwrite",r=>r.delete(o)).then(()=>{})},getAll(){return n("readonly",o=>o.getAll())},keys(){return n("readonly",o=>o.getAllKeys()).then(o=>o.map(String))},clear(){return n("readwrite",o=>o.clear()).then(()=>{})}}}function tn(e,t){let[n,o]=w(null),[r,s]=w(null),[i,c]=w(!1),f=null;function u(){let d=typeof e=="function"?e():e,g=t?.base??"",p=new URL(d,g||void 0);if(t?.params)for(let[h,T]of Object.entries(t.params))p.searchParams.set(h,T);return p.toString()}async function a(){f&&f.abort(),f=new AbortController;let d=f,g=t?.timeout??3e4,p=setTimeout(()=>d.abort(),g);c(!0),s(null);try{let h=u(),{base:T,params:b,timeout:y,transform:v,...S}=t??{},l=await fetch(h,{...S,signal:d.signal});if(!l.ok)throw new Error(`HTTP ${l.status}: ${l.statusText}`);let m=await l.json(),x=v?v(m):m;o(x)}catch(h){if(h instanceof Error&&h.name==="AbortError")return;s(h instanceof Error?h:new Error(String(h)))}finally{clearTimeout(p),f===d&&(f=null,c(!1))}}return typeof e=="function"?C(()=>{e(),a()}):a(),{data:n,error:r,loading:i,refetch:a,abort(){f&&f.abort()}}}async function nn(e,t){let n=await fetch(e,t);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);return await n.json()}function on(e,t){let[n,o]=w(null),[r,s]=w(null),[i,c]=w(!1),f=new EventSource(e,{withCredentials:t?.withCredentials??!1});f.onopen=()=>{c(!0),s(null)};let u=t?.parse??(a=>{try{return JSON.parse(a)}catch{return a}});return f.onmessage=a=>{o(u(a.data))},f.onerror=a=>{s(a),c(!1)},{data:n,error:r,connected:i,close(){f.close(),c(!1)},on(a,d){let g=t?.parse??(h=>{try{return JSON.parse(h)}catch{return h}}),p=h=>{d(g(h.data))};return f.addEventListener(a,p),()=>{f.removeEventListener(a,p)}}}}function rn(e,t){let n=t?.reconnect??!0,o=t?.reconnectInterval??1e3,r=t?.maxReconnects??5,[s,i]=w(null),[c,f]=w("connecting"),u=new Set,a=null,d=0,g=null,p=!1;function h(){if(p)return;f("connecting"),a=new WebSocket(e,t?.protocols),a.onopen=()=>{f("open"),d=0};let T=t?.parse??(b=>{try{return JSON.parse(b)}catch{return b}});a.onmessage=b=>{let y=T(b.data);i(y);for(let v of u)v(y)},a.onerror=()=>{f("error")},a.onclose=()=>{if(p){f("closed");return}if(f("closed"),n&&d<r){let b=o*Math.pow(2,d);d++,g=setTimeout(h,b)}}}return h(),{data:s,status:c,send(T){a&&a.readyState===WebSocket.OPEN&&a.send(JSON.stringify(T))},close(){p=!0,g!==null&&(clearTimeout(g),g=null),a&&(a.close(),a=null),f("closed")},on(T){return u.add(T),()=>{u.delete(T)}}}}function sn(e,t){let[n,o]=w(!1),[r,s]=w(void 0),c=async(...f)=>{if(o(!0),s(void 0),t?.optimistic)try{_(()=>t.optimistic(...f))}catch{}try{let u=await e(...f);if(t?.onSuccess&&_(()=>t.onSuccess(u,...f)),t?.invalidates)for(let a of t.invalidates)a.refetch();return o(!1),u}catch(u){if(t?.onError)try{_(()=>t.onError(u,...f))}catch{}throw s(u),o(!1),u}};return c.pending=n,c.error=r,c.clearError=()=>s(void 0),c}var an=new Map;function cn(e,t){an.set(e,t)}function ln(e){an.delete(e)}function we(e){for(let[t,n]of Object.entries(e)){let o=an.get(t);o&&o.mutate(n)}}function un(){if(typeof window>"u")return()=>{};let e=t=>{let n=t.detail;n&&typeof n=="object"&&we(n)};return window.addEventListener("forma:revalidate",e),()=>window.removeEventListener("forma:revalidate",e)}function fn(e,t){return{data:e,__revalidate:t}}function dn(e){return async(...n)=>{let o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Forma-RPC":"1"},body:JSON.stringify({args:n})});if(!o.ok){let s=await o.text();throw new Error(`Server function failed (${o.status}): ${s}`)}let r=await o.json();return r&&typeof r=="object"&&"__revalidate"in r?(typeof window<"u"&&window.dispatchEvent(new CustomEvent("forma:revalidate",{detail:r.__revalidate})),r.data):r}}var Ce=new Map;function pn(e,t){Ce.set(e,t)}function mn(e){return Ce.get(e)}function gn(){return[...Ce.keys()]}var Bo=new Set(["__proto__","constructor","prototype"]);async function Ee(e,t,n){let o=e.split("/").pop()??"";if(Bo.has(o))return{error:"Forbidden endpoint name"};let r=Ce.get(e);if(!r)return{error:`Unknown server function: ${e}`};try{let s=await r(...t.args);return n?{data:s,__revalidate:n}:{data:s}}catch(s){return{error:typeof process<"u"&&process.env?.NODE_ENV==="development"&&s instanceof Error?s.message:"Internal server error"}}}function hn(){return async(e,t)=>{if(e.method!=="POST"){t.status(405).json({error:"Method not allowed"});return}let n=e.body;if(!n||!Array.isArray(n.args)){t.status(400).json({error:"Invalid RPC request: missing args array"});return}let o=await Ee(e.url,n);o.error?t.status(500).json(o):t.json(o)}}return to(Ko);})();
|
|
1
|
+
"use strict";
|
|
2
|
+
var FormaJS = (() => {
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var src_exports = {};
|
|
23
|
+
__export(src_exports, {
|
|
24
|
+
$: () => $,
|
|
25
|
+
$$: () => $$,
|
|
26
|
+
Fragment: () => Fragment,
|
|
27
|
+
activateIslands: () => activateIslands,
|
|
28
|
+
addClass: () => addClass,
|
|
29
|
+
batch: () => batch,
|
|
30
|
+
children: () => children,
|
|
31
|
+
cleanup: () => cleanup,
|
|
32
|
+
closest: () => closest,
|
|
33
|
+
createBus: () => createBus,
|
|
34
|
+
createComputed: () => createComputed,
|
|
35
|
+
createContext: () => createContext,
|
|
36
|
+
createEffect: () => createEffect,
|
|
37
|
+
createErrorBoundary: () => createErrorBoundary,
|
|
38
|
+
createHistory: () => createHistory,
|
|
39
|
+
createList: () => createList,
|
|
40
|
+
createMemo: () => createMemo,
|
|
41
|
+
createPortal: () => createPortal,
|
|
42
|
+
createReducer: () => createReducer,
|
|
43
|
+
createRef: () => createRef,
|
|
44
|
+
createResource: () => createResource,
|
|
45
|
+
createRoot: () => createRoot,
|
|
46
|
+
createShow: () => createShow,
|
|
47
|
+
createSignal: () => createSignal,
|
|
48
|
+
createStore: () => createStore,
|
|
49
|
+
createSuspense: () => createSuspense,
|
|
50
|
+
createSwitch: () => createSwitch,
|
|
51
|
+
createText: () => createText,
|
|
52
|
+
deactivateAllIslands: () => deactivateAllIslands,
|
|
53
|
+
deactivateIsland: () => deactivateIsland,
|
|
54
|
+
defineComponent: () => defineComponent,
|
|
55
|
+
delegate: () => delegate,
|
|
56
|
+
disposeComponent: () => disposeComponent,
|
|
57
|
+
fragment: () => fragment,
|
|
58
|
+
getBatchDepth: () => getBatchDepth,
|
|
59
|
+
h: () => h,
|
|
60
|
+
hydrateIsland: () => hydrateIsland,
|
|
61
|
+
inject: () => inject,
|
|
62
|
+
isComputed: () => isComputed,
|
|
63
|
+
isEffect: () => isEffect,
|
|
64
|
+
isEffectScope: () => isEffectScope,
|
|
65
|
+
isSignal: () => isSignal,
|
|
66
|
+
mount: () => mount,
|
|
67
|
+
nextSibling: () => nextSibling,
|
|
68
|
+
on: () => on,
|
|
69
|
+
onCleanup: () => onCleanup,
|
|
70
|
+
onError: () => onError,
|
|
71
|
+
onIntersect: () => onIntersect,
|
|
72
|
+
onKey: () => onKey,
|
|
73
|
+
onMount: () => onMount,
|
|
74
|
+
onMutation: () => onMutation,
|
|
75
|
+
onResize: () => onResize,
|
|
76
|
+
onUnmount: () => onUnmount,
|
|
77
|
+
parent: () => parent,
|
|
78
|
+
persist: () => persist,
|
|
79
|
+
prevSibling: () => prevSibling,
|
|
80
|
+
provide: () => provide,
|
|
81
|
+
reconcileList: () => reconcileList,
|
|
82
|
+
removeClass: () => removeClass,
|
|
83
|
+
setAttr: () => setAttr,
|
|
84
|
+
setHTML: () => setHTML,
|
|
85
|
+
setHTMLUnsafe: () => setHTMLUnsafe,
|
|
86
|
+
setStyle: () => setStyle,
|
|
87
|
+
setText: () => setText,
|
|
88
|
+
siblings: () => siblings,
|
|
89
|
+
toggleClass: () => toggleClass,
|
|
90
|
+
trackDisposer: () => trackDisposer,
|
|
91
|
+
trigger: () => trigger,
|
|
92
|
+
unprovide: () => unprovide,
|
|
93
|
+
untrack: () => untrack
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// node_modules/alien-signals/esm/system.mjs
|
|
97
|
+
function createReactiveSystem({ update, notify, unwatched }) {
|
|
98
|
+
return {
|
|
99
|
+
link: link2,
|
|
100
|
+
unlink: unlink2,
|
|
101
|
+
propagate: propagate2,
|
|
102
|
+
checkDirty: checkDirty2,
|
|
103
|
+
shallowPropagate: shallowPropagate2
|
|
104
|
+
};
|
|
105
|
+
function link2(dep, sub, version) {
|
|
106
|
+
const prevDep = sub.depsTail;
|
|
107
|
+
if (prevDep !== void 0 && prevDep.dep === dep) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const nextDep = prevDep !== void 0 ? prevDep.nextDep : sub.deps;
|
|
111
|
+
if (nextDep !== void 0 && nextDep.dep === dep) {
|
|
112
|
+
nextDep.version = version;
|
|
113
|
+
sub.depsTail = nextDep;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const prevSub = dep.subsTail;
|
|
117
|
+
if (prevSub !== void 0 && prevSub.version === version && prevSub.sub === sub) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const newLink = sub.depsTail = dep.subsTail = {
|
|
121
|
+
version,
|
|
122
|
+
dep,
|
|
123
|
+
sub,
|
|
124
|
+
prevDep,
|
|
125
|
+
nextDep,
|
|
126
|
+
prevSub,
|
|
127
|
+
nextSub: void 0
|
|
128
|
+
};
|
|
129
|
+
if (nextDep !== void 0) {
|
|
130
|
+
nextDep.prevDep = newLink;
|
|
131
|
+
}
|
|
132
|
+
if (prevDep !== void 0) {
|
|
133
|
+
prevDep.nextDep = newLink;
|
|
134
|
+
} else {
|
|
135
|
+
sub.deps = newLink;
|
|
136
|
+
}
|
|
137
|
+
if (prevSub !== void 0) {
|
|
138
|
+
prevSub.nextSub = newLink;
|
|
139
|
+
} else {
|
|
140
|
+
dep.subs = newLink;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function unlink2(link3, sub = link3.sub) {
|
|
144
|
+
const dep = link3.dep;
|
|
145
|
+
const prevDep = link3.prevDep;
|
|
146
|
+
const nextDep = link3.nextDep;
|
|
147
|
+
const nextSub = link3.nextSub;
|
|
148
|
+
const prevSub = link3.prevSub;
|
|
149
|
+
if (nextDep !== void 0) {
|
|
150
|
+
nextDep.prevDep = prevDep;
|
|
151
|
+
} else {
|
|
152
|
+
sub.depsTail = prevDep;
|
|
153
|
+
}
|
|
154
|
+
if (prevDep !== void 0) {
|
|
155
|
+
prevDep.nextDep = nextDep;
|
|
156
|
+
} else {
|
|
157
|
+
sub.deps = nextDep;
|
|
158
|
+
}
|
|
159
|
+
if (nextSub !== void 0) {
|
|
160
|
+
nextSub.prevSub = prevSub;
|
|
161
|
+
} else {
|
|
162
|
+
dep.subsTail = prevSub;
|
|
163
|
+
}
|
|
164
|
+
if (prevSub !== void 0) {
|
|
165
|
+
prevSub.nextSub = nextSub;
|
|
166
|
+
} else if ((dep.subs = nextSub) === void 0) {
|
|
167
|
+
unwatched(dep);
|
|
168
|
+
}
|
|
169
|
+
return nextDep;
|
|
170
|
+
}
|
|
171
|
+
function propagate2(link3) {
|
|
172
|
+
let next = link3.nextSub;
|
|
173
|
+
let stack;
|
|
174
|
+
top: do {
|
|
175
|
+
const sub = link3.sub;
|
|
176
|
+
let flags = sub.flags;
|
|
177
|
+
if (!(flags & (4 | 8 | 16 | 32))) {
|
|
178
|
+
sub.flags = flags | 32;
|
|
179
|
+
} else if (!(flags & (4 | 8))) {
|
|
180
|
+
flags = 0;
|
|
181
|
+
} else if (!(flags & 4)) {
|
|
182
|
+
sub.flags = flags & ~8 | 32;
|
|
183
|
+
} else if (!(flags & (16 | 32)) && isValidLink(link3, sub)) {
|
|
184
|
+
sub.flags = flags | (8 | 32);
|
|
185
|
+
flags &= 1;
|
|
186
|
+
} else {
|
|
187
|
+
flags = 0;
|
|
188
|
+
}
|
|
189
|
+
if (flags & 2) {
|
|
190
|
+
notify(sub);
|
|
191
|
+
}
|
|
192
|
+
if (flags & 1) {
|
|
193
|
+
const subSubs = sub.subs;
|
|
194
|
+
if (subSubs !== void 0) {
|
|
195
|
+
const nextSub = (link3 = subSubs).nextSub;
|
|
196
|
+
if (nextSub !== void 0) {
|
|
197
|
+
stack = { value: next, prev: stack };
|
|
198
|
+
next = nextSub;
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if ((link3 = next) !== void 0) {
|
|
204
|
+
next = link3.nextSub;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
while (stack !== void 0) {
|
|
208
|
+
link3 = stack.value;
|
|
209
|
+
stack = stack.prev;
|
|
210
|
+
if (link3 !== void 0) {
|
|
211
|
+
next = link3.nextSub;
|
|
212
|
+
continue top;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
} while (true);
|
|
217
|
+
}
|
|
218
|
+
function checkDirty2(link3, sub) {
|
|
219
|
+
let stack;
|
|
220
|
+
let checkDepth = 0;
|
|
221
|
+
let dirty = false;
|
|
222
|
+
top: do {
|
|
223
|
+
const dep = link3.dep;
|
|
224
|
+
const flags = dep.flags;
|
|
225
|
+
if (sub.flags & 16) {
|
|
226
|
+
dirty = true;
|
|
227
|
+
} else if ((flags & (1 | 16)) === (1 | 16)) {
|
|
228
|
+
if (update(dep)) {
|
|
229
|
+
const subs = dep.subs;
|
|
230
|
+
if (subs.nextSub !== void 0) {
|
|
231
|
+
shallowPropagate2(subs);
|
|
232
|
+
}
|
|
233
|
+
dirty = true;
|
|
234
|
+
}
|
|
235
|
+
} else if ((flags & (1 | 32)) === (1 | 32)) {
|
|
236
|
+
if (link3.nextSub !== void 0 || link3.prevSub !== void 0) {
|
|
237
|
+
stack = { value: link3, prev: stack };
|
|
238
|
+
}
|
|
239
|
+
link3 = dep.deps;
|
|
240
|
+
sub = dep;
|
|
241
|
+
++checkDepth;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (!dirty) {
|
|
245
|
+
const nextDep = link3.nextDep;
|
|
246
|
+
if (nextDep !== void 0) {
|
|
247
|
+
link3 = nextDep;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
while (checkDepth--) {
|
|
252
|
+
const firstSub = sub.subs;
|
|
253
|
+
const hasMultipleSubs = firstSub.nextSub !== void 0;
|
|
254
|
+
if (hasMultipleSubs) {
|
|
255
|
+
link3 = stack.value;
|
|
256
|
+
stack = stack.prev;
|
|
257
|
+
} else {
|
|
258
|
+
link3 = firstSub;
|
|
259
|
+
}
|
|
260
|
+
if (dirty) {
|
|
261
|
+
if (update(sub)) {
|
|
262
|
+
if (hasMultipleSubs) {
|
|
263
|
+
shallowPropagate2(firstSub);
|
|
264
|
+
}
|
|
265
|
+
sub = link3.sub;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
dirty = false;
|
|
269
|
+
} else {
|
|
270
|
+
sub.flags &= ~32;
|
|
271
|
+
}
|
|
272
|
+
sub = link3.sub;
|
|
273
|
+
const nextDep = link3.nextDep;
|
|
274
|
+
if (nextDep !== void 0) {
|
|
275
|
+
link3 = nextDep;
|
|
276
|
+
continue top;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return dirty;
|
|
280
|
+
} while (true);
|
|
281
|
+
}
|
|
282
|
+
function shallowPropagate2(link3) {
|
|
283
|
+
do {
|
|
284
|
+
const sub = link3.sub;
|
|
285
|
+
const flags = sub.flags;
|
|
286
|
+
if ((flags & (32 | 16)) === 32) {
|
|
287
|
+
sub.flags = flags | 16;
|
|
288
|
+
if ((flags & (2 | 4)) === 2) {
|
|
289
|
+
notify(sub);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
} while ((link3 = link3.nextSub) !== void 0);
|
|
293
|
+
}
|
|
294
|
+
function isValidLink(checkLink, sub) {
|
|
295
|
+
let link3 = sub.depsTail;
|
|
296
|
+
while (link3 !== void 0) {
|
|
297
|
+
if (link3 === checkLink) {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
link3 = link3.prevDep;
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// node_modules/alien-signals/esm/index.mjs
|
|
307
|
+
var cycle = 0;
|
|
308
|
+
var batchDepth = 0;
|
|
309
|
+
var notifyIndex = 0;
|
|
310
|
+
var queuedLength = 0;
|
|
311
|
+
var activeSub;
|
|
312
|
+
var queued = [];
|
|
313
|
+
var { link, unlink, propagate, checkDirty, shallowPropagate } = createReactiveSystem({
|
|
314
|
+
update(node) {
|
|
315
|
+
if (node.depsTail !== void 0) {
|
|
316
|
+
return updateComputed(node);
|
|
317
|
+
} else {
|
|
318
|
+
return updateSignal(node);
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
notify(effect2) {
|
|
322
|
+
let insertIndex = queuedLength;
|
|
323
|
+
let firstInsertedIndex = insertIndex;
|
|
324
|
+
do {
|
|
325
|
+
queued[insertIndex++] = effect2;
|
|
326
|
+
effect2.flags &= ~2;
|
|
327
|
+
effect2 = effect2.subs?.sub;
|
|
328
|
+
if (effect2 === void 0 || !(effect2.flags & 2)) {
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
} while (true);
|
|
332
|
+
queuedLength = insertIndex;
|
|
333
|
+
while (firstInsertedIndex < --insertIndex) {
|
|
334
|
+
const left = queued[firstInsertedIndex];
|
|
335
|
+
queued[firstInsertedIndex++] = queued[insertIndex];
|
|
336
|
+
queued[insertIndex] = left;
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
unwatched(node) {
|
|
340
|
+
if (!(node.flags & 1)) {
|
|
341
|
+
effectScopeOper.call(node);
|
|
342
|
+
} else if (node.depsTail !== void 0) {
|
|
343
|
+
node.depsTail = void 0;
|
|
344
|
+
node.flags = 1 | 16;
|
|
345
|
+
purgeDeps(node);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
function setActiveSub(sub) {
|
|
350
|
+
const prevSub = activeSub;
|
|
351
|
+
activeSub = sub;
|
|
352
|
+
return prevSub;
|
|
353
|
+
}
|
|
354
|
+
function getBatchDepth() {
|
|
355
|
+
return batchDepth;
|
|
356
|
+
}
|
|
357
|
+
function startBatch() {
|
|
358
|
+
++batchDepth;
|
|
359
|
+
}
|
|
360
|
+
function endBatch() {
|
|
361
|
+
if (!--batchDepth) {
|
|
362
|
+
flush();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function isSignal(fn) {
|
|
366
|
+
return fn.name === "bound " + signalOper.name;
|
|
367
|
+
}
|
|
368
|
+
function isComputed(fn) {
|
|
369
|
+
return fn.name === "bound " + computedOper.name;
|
|
370
|
+
}
|
|
371
|
+
function isEffect(fn) {
|
|
372
|
+
return fn.name === "bound " + effectOper.name;
|
|
373
|
+
}
|
|
374
|
+
function isEffectScope(fn) {
|
|
375
|
+
return fn.name === "bound " + effectScopeOper.name;
|
|
376
|
+
}
|
|
377
|
+
function signal(initialValue) {
|
|
378
|
+
return signalOper.bind({
|
|
379
|
+
currentValue: initialValue,
|
|
380
|
+
pendingValue: initialValue,
|
|
381
|
+
subs: void 0,
|
|
382
|
+
subsTail: void 0,
|
|
383
|
+
flags: 1
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
function computed(getter) {
|
|
387
|
+
return computedOper.bind({
|
|
388
|
+
value: void 0,
|
|
389
|
+
subs: void 0,
|
|
390
|
+
subsTail: void 0,
|
|
391
|
+
deps: void 0,
|
|
392
|
+
depsTail: void 0,
|
|
393
|
+
flags: 0,
|
|
394
|
+
getter
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function effect(fn) {
|
|
398
|
+
const e = {
|
|
399
|
+
fn,
|
|
400
|
+
subs: void 0,
|
|
401
|
+
subsTail: void 0,
|
|
402
|
+
deps: void 0,
|
|
403
|
+
depsTail: void 0,
|
|
404
|
+
flags: 2 | 4
|
|
405
|
+
};
|
|
406
|
+
const prevSub = setActiveSub(e);
|
|
407
|
+
if (prevSub !== void 0) {
|
|
408
|
+
link(e, prevSub, 0);
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
e.fn();
|
|
412
|
+
} finally {
|
|
413
|
+
activeSub = prevSub;
|
|
414
|
+
e.flags &= ~4;
|
|
415
|
+
}
|
|
416
|
+
return effectOper.bind(e);
|
|
417
|
+
}
|
|
418
|
+
function effectScope(fn) {
|
|
419
|
+
const e = {
|
|
420
|
+
deps: void 0,
|
|
421
|
+
depsTail: void 0,
|
|
422
|
+
subs: void 0,
|
|
423
|
+
subsTail: void 0,
|
|
424
|
+
flags: 0
|
|
425
|
+
};
|
|
426
|
+
const prevSub = setActiveSub(e);
|
|
427
|
+
if (prevSub !== void 0) {
|
|
428
|
+
link(e, prevSub, 0);
|
|
429
|
+
}
|
|
430
|
+
try {
|
|
431
|
+
fn();
|
|
432
|
+
} finally {
|
|
433
|
+
activeSub = prevSub;
|
|
434
|
+
}
|
|
435
|
+
return effectScopeOper.bind(e);
|
|
436
|
+
}
|
|
437
|
+
function trigger(fn) {
|
|
438
|
+
const sub = {
|
|
439
|
+
deps: void 0,
|
|
440
|
+
depsTail: void 0,
|
|
441
|
+
flags: 2
|
|
442
|
+
};
|
|
443
|
+
const prevSub = setActiveSub(sub);
|
|
444
|
+
try {
|
|
445
|
+
fn();
|
|
446
|
+
} finally {
|
|
447
|
+
activeSub = prevSub;
|
|
448
|
+
let link2 = sub.deps;
|
|
449
|
+
while (link2 !== void 0) {
|
|
450
|
+
const dep = link2.dep;
|
|
451
|
+
link2 = unlink(link2, sub);
|
|
452
|
+
const subs = dep.subs;
|
|
453
|
+
if (subs !== void 0) {
|
|
454
|
+
sub.flags = 0;
|
|
455
|
+
propagate(subs);
|
|
456
|
+
shallowPropagate(subs);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (!batchDepth) {
|
|
460
|
+
flush();
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function updateComputed(c) {
|
|
465
|
+
++cycle;
|
|
466
|
+
c.depsTail = void 0;
|
|
467
|
+
c.flags = 1 | 4;
|
|
468
|
+
const prevSub = setActiveSub(c);
|
|
469
|
+
try {
|
|
470
|
+
const oldValue = c.value;
|
|
471
|
+
return oldValue !== (c.value = c.getter(oldValue));
|
|
472
|
+
} finally {
|
|
473
|
+
activeSub = prevSub;
|
|
474
|
+
c.flags &= ~4;
|
|
475
|
+
purgeDeps(c);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function updateSignal(s) {
|
|
479
|
+
s.flags = 1;
|
|
480
|
+
return s.currentValue !== (s.currentValue = s.pendingValue);
|
|
481
|
+
}
|
|
482
|
+
function run(e) {
|
|
483
|
+
const flags = e.flags;
|
|
484
|
+
if (flags & 16 || flags & 32 && checkDirty(e.deps, e)) {
|
|
485
|
+
++cycle;
|
|
486
|
+
e.depsTail = void 0;
|
|
487
|
+
e.flags = 2 | 4;
|
|
488
|
+
const prevSub = setActiveSub(e);
|
|
489
|
+
try {
|
|
490
|
+
e.fn();
|
|
491
|
+
} finally {
|
|
492
|
+
activeSub = prevSub;
|
|
493
|
+
e.flags &= ~4;
|
|
494
|
+
purgeDeps(e);
|
|
495
|
+
}
|
|
496
|
+
} else {
|
|
497
|
+
e.flags = 2;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function flush() {
|
|
501
|
+
try {
|
|
502
|
+
while (notifyIndex < queuedLength) {
|
|
503
|
+
const effect2 = queued[notifyIndex];
|
|
504
|
+
queued[notifyIndex++] = void 0;
|
|
505
|
+
run(effect2);
|
|
506
|
+
}
|
|
507
|
+
} finally {
|
|
508
|
+
while (notifyIndex < queuedLength) {
|
|
509
|
+
const effect2 = queued[notifyIndex];
|
|
510
|
+
queued[notifyIndex++] = void 0;
|
|
511
|
+
effect2.flags |= 2 | 8;
|
|
512
|
+
}
|
|
513
|
+
notifyIndex = 0;
|
|
514
|
+
queuedLength = 0;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function computedOper() {
|
|
518
|
+
const flags = this.flags;
|
|
519
|
+
if (flags & 16 || flags & 32 && (checkDirty(this.deps, this) || (this.flags = flags & ~32, false))) {
|
|
520
|
+
if (updateComputed(this)) {
|
|
521
|
+
const subs = this.subs;
|
|
522
|
+
if (subs !== void 0) {
|
|
523
|
+
shallowPropagate(subs);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
} else if (!flags) {
|
|
527
|
+
this.flags = 1 | 4;
|
|
528
|
+
const prevSub = setActiveSub(this);
|
|
529
|
+
try {
|
|
530
|
+
this.value = this.getter();
|
|
531
|
+
} finally {
|
|
532
|
+
activeSub = prevSub;
|
|
533
|
+
this.flags &= ~4;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
const sub = activeSub;
|
|
537
|
+
if (sub !== void 0) {
|
|
538
|
+
link(this, sub, cycle);
|
|
539
|
+
}
|
|
540
|
+
return this.value;
|
|
541
|
+
}
|
|
542
|
+
function signalOper(...value2) {
|
|
543
|
+
if (value2.length) {
|
|
544
|
+
if (this.pendingValue !== (this.pendingValue = value2[0])) {
|
|
545
|
+
this.flags = 1 | 16;
|
|
546
|
+
const subs = this.subs;
|
|
547
|
+
if (subs !== void 0) {
|
|
548
|
+
propagate(subs);
|
|
549
|
+
if (!batchDepth) {
|
|
550
|
+
flush();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
if (this.flags & 16) {
|
|
556
|
+
if (updateSignal(this)) {
|
|
557
|
+
const subs = this.subs;
|
|
558
|
+
if (subs !== void 0) {
|
|
559
|
+
shallowPropagate(subs);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
let sub = activeSub;
|
|
564
|
+
while (sub !== void 0) {
|
|
565
|
+
if (sub.flags & (1 | 2)) {
|
|
566
|
+
link(this, sub, cycle);
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
sub = sub.subs?.sub;
|
|
570
|
+
}
|
|
571
|
+
return this.currentValue;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function effectOper() {
|
|
575
|
+
effectScopeOper.call(this);
|
|
576
|
+
}
|
|
577
|
+
function effectScopeOper() {
|
|
578
|
+
this.depsTail = void 0;
|
|
579
|
+
this.flags = 0;
|
|
580
|
+
purgeDeps(this);
|
|
581
|
+
const sub = this.subs;
|
|
582
|
+
if (sub !== void 0) {
|
|
583
|
+
unlink(sub);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
function purgeDeps(sub) {
|
|
587
|
+
const depsTail = sub.depsTail;
|
|
588
|
+
let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps;
|
|
589
|
+
while (dep !== void 0) {
|
|
590
|
+
dep = unlink(dep, sub);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// src/reactive/signal.ts
|
|
595
|
+
function applySignalSet(s, v, equals) {
|
|
596
|
+
if (typeof v !== "function") {
|
|
597
|
+
if (equals) {
|
|
598
|
+
const prevSub2 = setActiveSub(void 0);
|
|
599
|
+
const prev2 = s();
|
|
600
|
+
setActiveSub(prevSub2);
|
|
601
|
+
if (equals(prev2, v)) return;
|
|
602
|
+
}
|
|
603
|
+
s(v);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
const prevSub = setActiveSub(void 0);
|
|
607
|
+
const prev = s();
|
|
608
|
+
setActiveSub(prevSub);
|
|
609
|
+
const next = v(prev);
|
|
610
|
+
if (equals && equals(prev, next)) return;
|
|
611
|
+
s(next);
|
|
612
|
+
}
|
|
613
|
+
function createSignal(initialValue, options) {
|
|
614
|
+
const s = signal(initialValue);
|
|
615
|
+
const getter = s;
|
|
616
|
+
const eq = options?.equals;
|
|
617
|
+
const setter = (v) => applySignalSet(s, v, eq);
|
|
618
|
+
return [getter, setter];
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// src/reactive/root.ts
|
|
622
|
+
var currentRoot = null;
|
|
623
|
+
var rootStack = [];
|
|
624
|
+
function createRoot(fn) {
|
|
625
|
+
const scope = { disposers: [], scopeDispose: null };
|
|
626
|
+
rootStack.push(currentRoot);
|
|
627
|
+
currentRoot = scope;
|
|
628
|
+
const dispose = () => {
|
|
629
|
+
if (scope.scopeDispose) {
|
|
630
|
+
try {
|
|
631
|
+
scope.scopeDispose();
|
|
632
|
+
} catch {
|
|
633
|
+
}
|
|
634
|
+
scope.scopeDispose = null;
|
|
635
|
+
}
|
|
636
|
+
for (const d of scope.disposers) {
|
|
637
|
+
try {
|
|
638
|
+
d();
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
scope.disposers.length = 0;
|
|
643
|
+
};
|
|
644
|
+
let result;
|
|
645
|
+
try {
|
|
646
|
+
scope.scopeDispose = effectScope(() => {
|
|
647
|
+
result = fn(dispose);
|
|
648
|
+
});
|
|
649
|
+
} finally {
|
|
650
|
+
currentRoot = rootStack.pop() ?? null;
|
|
651
|
+
}
|
|
652
|
+
return result;
|
|
653
|
+
}
|
|
654
|
+
function registerDisposer(dispose) {
|
|
655
|
+
if (currentRoot) {
|
|
656
|
+
currentRoot.disposers.push(dispose);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
function hasActiveRoot() {
|
|
660
|
+
return currentRoot !== null;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/reactive/cleanup.ts
|
|
664
|
+
var currentCleanupCollector = null;
|
|
665
|
+
function onCleanup(fn) {
|
|
666
|
+
currentCleanupCollector?.(fn);
|
|
667
|
+
}
|
|
668
|
+
function setCleanupCollector(collector) {
|
|
669
|
+
const prev = currentCleanupCollector;
|
|
670
|
+
currentCleanupCollector = collector;
|
|
671
|
+
return prev;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/reactive/dev.ts
|
|
675
|
+
var __DEV__ = typeof process !== "undefined" ? process.env?.NODE_ENV !== "production" : true;
|
|
676
|
+
var _errorHandler = null;
|
|
677
|
+
function onError(handler) {
|
|
678
|
+
_errorHandler = handler;
|
|
679
|
+
}
|
|
680
|
+
function reportError(error, source) {
|
|
681
|
+
if (_errorHandler) {
|
|
682
|
+
try {
|
|
683
|
+
_errorHandler(error, source ? { source } : {});
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (__DEV__) {
|
|
688
|
+
console.error(`[forma] ${source ?? "Unknown"} error:`, error);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// src/reactive/effect.ts
|
|
693
|
+
var POOL_SIZE = 32;
|
|
694
|
+
var MAX_REENTRANT_RUNS = 100;
|
|
695
|
+
var pool = [];
|
|
696
|
+
for (let i = 0; i < POOL_SIZE; i++) pool.push([]);
|
|
697
|
+
var poolIdx = POOL_SIZE;
|
|
698
|
+
function acquireArray() {
|
|
699
|
+
if (poolIdx > 0) {
|
|
700
|
+
const arr = pool[--poolIdx];
|
|
701
|
+
arr.length = 0;
|
|
702
|
+
return arr;
|
|
703
|
+
}
|
|
704
|
+
return [];
|
|
705
|
+
}
|
|
706
|
+
function releaseArray(arr) {
|
|
707
|
+
arr.length = 0;
|
|
708
|
+
if (poolIdx < POOL_SIZE) {
|
|
709
|
+
pool[poolIdx++] = arr;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function runCleanup(fn) {
|
|
713
|
+
if (fn === void 0) return;
|
|
714
|
+
try {
|
|
715
|
+
fn();
|
|
716
|
+
} catch (e) {
|
|
717
|
+
reportError(e, "effect cleanup");
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function runCleanups(bag) {
|
|
721
|
+
if (bag === void 0) return;
|
|
722
|
+
for (let i = 0; i < bag.length; i++) {
|
|
723
|
+
try {
|
|
724
|
+
bag[i]();
|
|
725
|
+
} catch (e) {
|
|
726
|
+
reportError(e, "effect cleanup");
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
function internalEffect(fn) {
|
|
731
|
+
const dispose = effect(fn);
|
|
732
|
+
if (hasActiveRoot()) {
|
|
733
|
+
registerDisposer(dispose);
|
|
734
|
+
}
|
|
735
|
+
return dispose;
|
|
736
|
+
}
|
|
737
|
+
function createEffect(fn) {
|
|
738
|
+
const shouldRegister = hasActiveRoot();
|
|
739
|
+
let cleanup2;
|
|
740
|
+
let cleanupBag;
|
|
741
|
+
let nextCleanup;
|
|
742
|
+
let nextCleanupBag;
|
|
743
|
+
const addCleanup = (cb) => {
|
|
744
|
+
if (nextCleanupBag !== void 0) {
|
|
745
|
+
nextCleanupBag.push(cb);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (nextCleanup !== void 0) {
|
|
749
|
+
const bag = acquireArray();
|
|
750
|
+
bag.push(nextCleanup, cb);
|
|
751
|
+
nextCleanup = void 0;
|
|
752
|
+
nextCleanupBag = bag;
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
nextCleanup = cb;
|
|
756
|
+
};
|
|
757
|
+
let skipCleanupInfra = false;
|
|
758
|
+
let firstRun = true;
|
|
759
|
+
let running = false;
|
|
760
|
+
let rerunRequested = false;
|
|
761
|
+
const runOnce = () => {
|
|
762
|
+
if (cleanup2 !== void 0) {
|
|
763
|
+
runCleanup(cleanup2);
|
|
764
|
+
cleanup2 = void 0;
|
|
765
|
+
}
|
|
766
|
+
if (cleanupBag !== void 0) {
|
|
767
|
+
runCleanups(cleanupBag);
|
|
768
|
+
releaseArray(cleanupBag);
|
|
769
|
+
cleanupBag = void 0;
|
|
770
|
+
}
|
|
771
|
+
if (skipCleanupInfra) {
|
|
772
|
+
try {
|
|
773
|
+
fn();
|
|
774
|
+
} catch (e) {
|
|
775
|
+
reportError(e, "effect");
|
|
776
|
+
}
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
nextCleanup = void 0;
|
|
780
|
+
nextCleanupBag = void 0;
|
|
781
|
+
const prevCollector = setCleanupCollector(addCleanup);
|
|
782
|
+
try {
|
|
783
|
+
const result = fn();
|
|
784
|
+
if (typeof result === "function") {
|
|
785
|
+
addCleanup(result);
|
|
786
|
+
}
|
|
787
|
+
if (nextCleanup === void 0 && nextCleanupBag === void 0) {
|
|
788
|
+
if (firstRun) skipCleanupInfra = true;
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (nextCleanupBag !== void 0) {
|
|
792
|
+
cleanupBag = nextCleanupBag;
|
|
793
|
+
} else {
|
|
794
|
+
cleanup2 = nextCleanup;
|
|
795
|
+
}
|
|
796
|
+
} catch (e) {
|
|
797
|
+
reportError(e, "effect");
|
|
798
|
+
if (nextCleanupBag !== void 0) {
|
|
799
|
+
cleanupBag = nextCleanupBag;
|
|
800
|
+
} else {
|
|
801
|
+
cleanup2 = nextCleanup;
|
|
802
|
+
}
|
|
803
|
+
} finally {
|
|
804
|
+
setCleanupCollector(prevCollector);
|
|
805
|
+
firstRun = false;
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
const safeFn = () => {
|
|
809
|
+
if (running) {
|
|
810
|
+
rerunRequested = true;
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
running = true;
|
|
814
|
+
try {
|
|
815
|
+
let reentrantRuns = 0;
|
|
816
|
+
do {
|
|
817
|
+
rerunRequested = false;
|
|
818
|
+
runOnce();
|
|
819
|
+
if (rerunRequested) {
|
|
820
|
+
reentrantRuns++;
|
|
821
|
+
if (reentrantRuns >= MAX_REENTRANT_RUNS) {
|
|
822
|
+
reportError(
|
|
823
|
+
new Error(`createEffect exceeded ${MAX_REENTRANT_RUNS} re-entrant runs`),
|
|
824
|
+
"effect"
|
|
825
|
+
);
|
|
826
|
+
rerunRequested = false;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
} while (rerunRequested);
|
|
830
|
+
} finally {
|
|
831
|
+
running = false;
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
const dispose = effect(safeFn);
|
|
835
|
+
let disposed = false;
|
|
836
|
+
const wrappedDispose = () => {
|
|
837
|
+
if (disposed) return;
|
|
838
|
+
disposed = true;
|
|
839
|
+
dispose();
|
|
840
|
+
if (cleanup2 !== void 0) {
|
|
841
|
+
runCleanup(cleanup2);
|
|
842
|
+
cleanup2 = void 0;
|
|
843
|
+
}
|
|
844
|
+
if (cleanupBag !== void 0) {
|
|
845
|
+
runCleanups(cleanupBag);
|
|
846
|
+
releaseArray(cleanupBag);
|
|
847
|
+
cleanupBag = void 0;
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
if (shouldRegister) {
|
|
851
|
+
registerDisposer(wrappedDispose);
|
|
852
|
+
}
|
|
853
|
+
return wrappedDispose;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// src/reactive/computed.ts
|
|
857
|
+
function createComputed(fn) {
|
|
858
|
+
return computed(fn);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// src/reactive/memo.ts
|
|
862
|
+
var createMemo = createComputed;
|
|
863
|
+
|
|
864
|
+
// src/reactive/batch.ts
|
|
865
|
+
function batch(fn) {
|
|
866
|
+
startBatch();
|
|
867
|
+
try {
|
|
868
|
+
fn();
|
|
869
|
+
} finally {
|
|
870
|
+
endBatch();
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// src/reactive/untrack.ts
|
|
875
|
+
function untrack(fn) {
|
|
876
|
+
const prev = setActiveSub(void 0);
|
|
877
|
+
try {
|
|
878
|
+
return fn();
|
|
879
|
+
} finally {
|
|
880
|
+
setActiveSub(prev);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// src/reactive/on.ts
|
|
885
|
+
function on(deps, fn, options) {
|
|
886
|
+
let prev;
|
|
887
|
+
let isFirst = true;
|
|
888
|
+
return () => {
|
|
889
|
+
const value2 = deps();
|
|
890
|
+
if (options?.defer && isFirst) {
|
|
891
|
+
isFirst = false;
|
|
892
|
+
prev = value2;
|
|
893
|
+
return void 0;
|
|
894
|
+
}
|
|
895
|
+
const result = untrack(() => fn(value2, prev));
|
|
896
|
+
prev = value2;
|
|
897
|
+
return result;
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// src/reactive/ref.ts
|
|
902
|
+
function createRef(initialValue) {
|
|
903
|
+
return { current: initialValue };
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/reactive/reducer.ts
|
|
907
|
+
function createReducer(reducer, initialState) {
|
|
908
|
+
const [state, setState] = createSignal(initialState);
|
|
909
|
+
const dispatch = (action) => {
|
|
910
|
+
setState((prev) => reducer(prev, action));
|
|
911
|
+
};
|
|
912
|
+
return [state, dispatch];
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// src/reactive/suspense-context.ts
|
|
916
|
+
var currentSuspenseContext = null;
|
|
917
|
+
var suspenseStack = [];
|
|
918
|
+
function pushSuspenseContext(ctx) {
|
|
919
|
+
suspenseStack.push(currentSuspenseContext);
|
|
920
|
+
currentSuspenseContext = ctx;
|
|
921
|
+
}
|
|
922
|
+
function popSuspenseContext() {
|
|
923
|
+
currentSuspenseContext = suspenseStack.pop() ?? null;
|
|
924
|
+
}
|
|
925
|
+
function getSuspenseContext() {
|
|
926
|
+
return currentSuspenseContext;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// src/reactive/resource.ts
|
|
930
|
+
function createResource(source, fetcher, options) {
|
|
931
|
+
const [data, setData] = createSignal(options?.initialValue);
|
|
932
|
+
const [loading, setLoading] = createSignal(false);
|
|
933
|
+
const [error, setError] = createSignal(void 0);
|
|
934
|
+
const suspenseCtx = getSuspenseContext();
|
|
935
|
+
let abortController = null;
|
|
936
|
+
let fetchVersion = 0;
|
|
937
|
+
const doFetch = () => {
|
|
938
|
+
const sourceValue = untrack(source);
|
|
939
|
+
if (abortController) {
|
|
940
|
+
abortController.abort();
|
|
941
|
+
}
|
|
942
|
+
const controller = new AbortController();
|
|
943
|
+
abortController = controller;
|
|
944
|
+
const version = ++fetchVersion;
|
|
945
|
+
const isLatest = () => version === fetchVersion;
|
|
946
|
+
let suspensePending = false;
|
|
947
|
+
if (suspenseCtx) {
|
|
948
|
+
suspenseCtx.increment();
|
|
949
|
+
suspensePending = true;
|
|
950
|
+
}
|
|
951
|
+
setLoading(true);
|
|
952
|
+
setError(void 0);
|
|
953
|
+
Promise.resolve(fetcher(sourceValue)).then((result) => {
|
|
954
|
+
if (isLatest() && !controller.signal.aborted) {
|
|
955
|
+
setData(() => result);
|
|
956
|
+
}
|
|
957
|
+
}).catch((err) => {
|
|
958
|
+
if (isLatest() && !controller.signal.aborted) {
|
|
959
|
+
if (err?.name !== "AbortError") {
|
|
960
|
+
setError(err);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}).finally(() => {
|
|
964
|
+
if (suspensePending) suspenseCtx?.decrement();
|
|
965
|
+
if (isLatest()) {
|
|
966
|
+
setLoading(false);
|
|
967
|
+
if (abortController === controller) {
|
|
968
|
+
abortController = null;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
};
|
|
973
|
+
internalEffect(() => {
|
|
974
|
+
source();
|
|
975
|
+
doFetch();
|
|
976
|
+
});
|
|
977
|
+
const resource = (() => data());
|
|
978
|
+
resource.loading = loading;
|
|
979
|
+
resource.error = error;
|
|
980
|
+
resource.refetch = doFetch;
|
|
981
|
+
resource.mutate = (value2) => setData(() => value2);
|
|
982
|
+
return resource;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// src/dom/list.ts
|
|
986
|
+
function longestIncreasingSubsequence(arr) {
|
|
987
|
+
const n = arr.length;
|
|
988
|
+
if (n === 0) return [];
|
|
989
|
+
const tails = new Int32Array(n);
|
|
990
|
+
const tailIndices = new Int32Array(n);
|
|
991
|
+
const predecessor = new Int32Array(n).fill(-1);
|
|
992
|
+
let tailsLen = 0;
|
|
993
|
+
for (let i = 0; i < n; i++) {
|
|
994
|
+
const val = arr[i];
|
|
995
|
+
let lo = 0, hi = tailsLen;
|
|
996
|
+
while (lo < hi) {
|
|
997
|
+
const mid = lo + hi >> 1;
|
|
998
|
+
if (tails[mid] < val) lo = mid + 1;
|
|
999
|
+
else hi = mid;
|
|
1000
|
+
}
|
|
1001
|
+
tails[lo] = val;
|
|
1002
|
+
tailIndices[lo] = i;
|
|
1003
|
+
if (lo > 0) predecessor[i] = tailIndices[lo - 1];
|
|
1004
|
+
if (lo >= tailsLen) tailsLen++;
|
|
1005
|
+
}
|
|
1006
|
+
const result = new Array(tailsLen);
|
|
1007
|
+
let idx = tailIndices[tailsLen - 1];
|
|
1008
|
+
for (let i = tailsLen - 1; i >= 0; i--) {
|
|
1009
|
+
result[i] = idx;
|
|
1010
|
+
idx = predecessor[idx];
|
|
1011
|
+
}
|
|
1012
|
+
return result;
|
|
1013
|
+
}
|
|
1014
|
+
var SMALL_LIST_THRESHOLD = 32;
|
|
1015
|
+
var ABORT_SYM = /* @__PURE__ */ Symbol.for("forma-abort");
|
|
1016
|
+
var CACHE_SYM = /* @__PURE__ */ Symbol.for("forma-attr-cache");
|
|
1017
|
+
var DYNAMIC_CHILD_SYM = /* @__PURE__ */ Symbol.for("forma-dynamic-child");
|
|
1018
|
+
function canPatchStaticElement(target, source) {
|
|
1019
|
+
return target instanceof HTMLElement && source instanceof HTMLElement && target.tagName === source.tagName && !target[ABORT_SYM] && !target[CACHE_SYM] && !target[DYNAMIC_CHILD_SYM] && !source[ABORT_SYM] && !source[CACHE_SYM] && !source[DYNAMIC_CHILD_SYM];
|
|
1020
|
+
}
|
|
1021
|
+
function patchStaticElement(target, source) {
|
|
1022
|
+
const sourceAttrNames = /* @__PURE__ */ new Set();
|
|
1023
|
+
for (const attr of Array.from(source.attributes)) {
|
|
1024
|
+
sourceAttrNames.add(attr.name);
|
|
1025
|
+
if (target.getAttribute(attr.name) !== attr.value) {
|
|
1026
|
+
target.setAttribute(attr.name, attr.value);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
for (const attr of Array.from(target.attributes)) {
|
|
1030
|
+
if (!sourceAttrNames.has(attr.name)) {
|
|
1031
|
+
target.removeAttribute(attr.name);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
target.replaceChildren(...Array.from(source.childNodes));
|
|
1035
|
+
}
|
|
1036
|
+
function reconcileSmall(parent2, oldItems, newItems, oldNodes, keyFn, createFn, updateFn, beforeNode, hooks) {
|
|
1037
|
+
const oldLen = oldItems.length;
|
|
1038
|
+
const newLen = newItems.length;
|
|
1039
|
+
const oldKeys = new Array(oldLen);
|
|
1040
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1041
|
+
oldKeys[i] = keyFn(oldItems[i]);
|
|
1042
|
+
}
|
|
1043
|
+
const oldIndices = new Array(newLen);
|
|
1044
|
+
const oldUsed = new Uint8Array(oldLen);
|
|
1045
|
+
for (let i = 0; i < newLen; i++) {
|
|
1046
|
+
const key = keyFn(newItems[i]);
|
|
1047
|
+
let found = -1;
|
|
1048
|
+
for (let j = 0; j < oldLen; j++) {
|
|
1049
|
+
if (!oldUsed[j] && oldKeys[j] === key) {
|
|
1050
|
+
found = j;
|
|
1051
|
+
oldUsed[j] = 1;
|
|
1052
|
+
break;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
oldIndices[i] = found;
|
|
1056
|
+
}
|
|
1057
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1058
|
+
if (!oldUsed[i]) {
|
|
1059
|
+
if (hooks?.onBeforeRemove) {
|
|
1060
|
+
const node = oldNodes[i];
|
|
1061
|
+
hooks.onBeforeRemove(node, () => {
|
|
1062
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
1063
|
+
});
|
|
1064
|
+
} else {
|
|
1065
|
+
parent2.removeChild(oldNodes[i]);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
if (oldLen === newLen) {
|
|
1070
|
+
let allSameOrder = true;
|
|
1071
|
+
for (let i = 0; i < newLen; i++) {
|
|
1072
|
+
if (oldIndices[i] !== i) {
|
|
1073
|
+
allSameOrder = false;
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
if (allSameOrder) {
|
|
1078
|
+
const nodes = new Array(newLen);
|
|
1079
|
+
for (let i = 0; i < newLen; i++) {
|
|
1080
|
+
const node = oldNodes[i];
|
|
1081
|
+
updateFn(node, newItems[i]);
|
|
1082
|
+
nodes[i] = node;
|
|
1083
|
+
}
|
|
1084
|
+
return { nodes, items: newItems };
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
const reusedIndices = [];
|
|
1088
|
+
const reusedPositions = [];
|
|
1089
|
+
for (let i = 0; i < newLen; i++) {
|
|
1090
|
+
if (oldIndices[i] !== -1) {
|
|
1091
|
+
reusedIndices.push(oldIndices[i]);
|
|
1092
|
+
reusedPositions.push(i);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
const lisOfReused = longestIncreasingSubsequence(reusedIndices);
|
|
1096
|
+
const lisFlags = new Uint8Array(newLen);
|
|
1097
|
+
for (const li of lisOfReused) {
|
|
1098
|
+
lisFlags[reusedPositions[li]] = 1;
|
|
1099
|
+
}
|
|
1100
|
+
const newNodes = new Array(newLen);
|
|
1101
|
+
let nextSibling2 = beforeNode ?? null;
|
|
1102
|
+
for (let i = newLen - 1; i >= 0; i--) {
|
|
1103
|
+
let node;
|
|
1104
|
+
let isNew = false;
|
|
1105
|
+
if (oldIndices[i] === -1) {
|
|
1106
|
+
node = createFn(newItems[i]);
|
|
1107
|
+
isNew = true;
|
|
1108
|
+
} else {
|
|
1109
|
+
node = oldNodes[oldIndices[i]];
|
|
1110
|
+
updateFn(node, newItems[i]);
|
|
1111
|
+
if (lisFlags[i]) {
|
|
1112
|
+
newNodes[i] = node;
|
|
1113
|
+
nextSibling2 = node;
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
if (nextSibling2) {
|
|
1118
|
+
parent2.insertBefore(node, nextSibling2);
|
|
1119
|
+
} else {
|
|
1120
|
+
parent2.appendChild(node);
|
|
1121
|
+
}
|
|
1122
|
+
if (isNew) hooks?.onInsert?.(node);
|
|
1123
|
+
newNodes[i] = node;
|
|
1124
|
+
nextSibling2 = node;
|
|
1125
|
+
}
|
|
1126
|
+
return { nodes: newNodes, items: newItems };
|
|
1127
|
+
}
|
|
1128
|
+
function reconcileList(parent2, oldItems, newItems, oldNodes, keyFn, createFn, updateFn, beforeNode, hooks) {
|
|
1129
|
+
const oldLen = oldItems.length;
|
|
1130
|
+
const newLen = newItems.length;
|
|
1131
|
+
if (newLen === 0) {
|
|
1132
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1133
|
+
if (hooks?.onBeforeRemove) {
|
|
1134
|
+
const node = oldNodes[i];
|
|
1135
|
+
hooks.onBeforeRemove(node, () => {
|
|
1136
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
1137
|
+
});
|
|
1138
|
+
} else {
|
|
1139
|
+
parent2.removeChild(oldNodes[i]);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return { nodes: [], items: [] };
|
|
1143
|
+
}
|
|
1144
|
+
if (oldLen === 0) {
|
|
1145
|
+
const nodes = new Array(newLen);
|
|
1146
|
+
for (let i = 0; i < newLen; i++) {
|
|
1147
|
+
const node = createFn(newItems[i]);
|
|
1148
|
+
if (beforeNode) {
|
|
1149
|
+
parent2.insertBefore(node, beforeNode);
|
|
1150
|
+
} else {
|
|
1151
|
+
parent2.appendChild(node);
|
|
1152
|
+
}
|
|
1153
|
+
hooks?.onInsert?.(node);
|
|
1154
|
+
nodes[i] = node;
|
|
1155
|
+
}
|
|
1156
|
+
return { nodes, items: newItems };
|
|
1157
|
+
}
|
|
1158
|
+
if (oldLen < SMALL_LIST_THRESHOLD) {
|
|
1159
|
+
return reconcileSmall(parent2, oldItems, newItems, oldNodes, keyFn, createFn, updateFn, beforeNode, hooks);
|
|
1160
|
+
}
|
|
1161
|
+
const oldKeyMap = /* @__PURE__ */ new Map();
|
|
1162
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1163
|
+
oldKeyMap.set(keyFn(oldItems[i]), i);
|
|
1164
|
+
}
|
|
1165
|
+
const oldIndices = new Array(newLen);
|
|
1166
|
+
const oldUsed = new Uint8Array(oldLen);
|
|
1167
|
+
for (let i = 0; i < newLen; i++) {
|
|
1168
|
+
const key = keyFn(newItems[i]);
|
|
1169
|
+
const oldIdx = oldKeyMap.get(key);
|
|
1170
|
+
if (oldIdx !== void 0) {
|
|
1171
|
+
oldIndices[i] = oldIdx;
|
|
1172
|
+
oldUsed[oldIdx] = 1;
|
|
1173
|
+
} else {
|
|
1174
|
+
oldIndices[i] = -1;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1178
|
+
if (!oldUsed[i]) {
|
|
1179
|
+
if (hooks?.onBeforeRemove) {
|
|
1180
|
+
const node = oldNodes[i];
|
|
1181
|
+
hooks.onBeforeRemove(node, () => {
|
|
1182
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
1183
|
+
});
|
|
1184
|
+
} else {
|
|
1185
|
+
parent2.removeChild(oldNodes[i]);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (oldLen === newLen) {
|
|
1190
|
+
let allSameOrder = true;
|
|
1191
|
+
for (let i = 0; i < newLen; i++) {
|
|
1192
|
+
if (oldIndices[i] !== i) {
|
|
1193
|
+
allSameOrder = false;
|
|
1194
|
+
break;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
if (allSameOrder) {
|
|
1198
|
+
const nodes = new Array(newLen);
|
|
1199
|
+
for (let i = 0; i < newLen; i++) {
|
|
1200
|
+
const node = oldNodes[i];
|
|
1201
|
+
updateFn(node, newItems[i]);
|
|
1202
|
+
nodes[i] = node;
|
|
1203
|
+
}
|
|
1204
|
+
return { nodes, items: newItems };
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
const reusedIndices = [];
|
|
1208
|
+
const reusedPositions = [];
|
|
1209
|
+
for (let i = 0; i < newLen; i++) {
|
|
1210
|
+
if (oldIndices[i] !== -1) {
|
|
1211
|
+
reusedIndices.push(oldIndices[i]);
|
|
1212
|
+
reusedPositions.push(i);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
const lisOfReused = longestIncreasingSubsequence(reusedIndices);
|
|
1216
|
+
const lisFlags = new Uint8Array(newLen);
|
|
1217
|
+
for (const li of lisOfReused) {
|
|
1218
|
+
lisFlags[reusedPositions[li]] = 1;
|
|
1219
|
+
}
|
|
1220
|
+
const newNodes = new Array(newLen);
|
|
1221
|
+
let nextSibling2 = beforeNode ?? null;
|
|
1222
|
+
for (let i = newLen - 1; i >= 0; i--) {
|
|
1223
|
+
let node;
|
|
1224
|
+
let isNew = false;
|
|
1225
|
+
if (oldIndices[i] === -1) {
|
|
1226
|
+
node = createFn(newItems[i]);
|
|
1227
|
+
isNew = true;
|
|
1228
|
+
} else {
|
|
1229
|
+
node = oldNodes[oldIndices[i]];
|
|
1230
|
+
updateFn(node, newItems[i]);
|
|
1231
|
+
if (lisFlags[i]) {
|
|
1232
|
+
newNodes[i] = node;
|
|
1233
|
+
nextSibling2 = node;
|
|
1234
|
+
continue;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
if (nextSibling2) {
|
|
1238
|
+
parent2.insertBefore(node, nextSibling2);
|
|
1239
|
+
} else {
|
|
1240
|
+
parent2.appendChild(node);
|
|
1241
|
+
}
|
|
1242
|
+
if (isNew) hooks?.onInsert?.(node);
|
|
1243
|
+
newNodes[i] = node;
|
|
1244
|
+
nextSibling2 = node;
|
|
1245
|
+
}
|
|
1246
|
+
return { nodes: newNodes, items: newItems };
|
|
1247
|
+
}
|
|
1248
|
+
function createList(items, keyFn, renderFn, options) {
|
|
1249
|
+
if (hydrating) {
|
|
1250
|
+
return { type: "list", items, keyFn, renderFn, options };
|
|
1251
|
+
}
|
|
1252
|
+
const startMarker = document.createComment("forma-list-start");
|
|
1253
|
+
const endMarker = document.createComment("forma-list-end");
|
|
1254
|
+
const fragment2 = document.createDocumentFragment();
|
|
1255
|
+
fragment2.appendChild(startMarker);
|
|
1256
|
+
fragment2.appendChild(endMarker);
|
|
1257
|
+
let cache = /* @__PURE__ */ new Map();
|
|
1258
|
+
let currentNodes = [];
|
|
1259
|
+
let currentItems = [];
|
|
1260
|
+
const updateOnItemChange = options?.updateOnItemChange ?? "none";
|
|
1261
|
+
internalEffect(() => {
|
|
1262
|
+
const newItems = items();
|
|
1263
|
+
const parent2 = startMarker.parentNode;
|
|
1264
|
+
if (!parent2) {
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1267
|
+
if (!Array.isArray(newItems)) {
|
|
1268
|
+
if (__DEV__) {
|
|
1269
|
+
console.warn("[forma] createList: value is not an array, treating as empty");
|
|
1270
|
+
}
|
|
1271
|
+
for (const node of currentNodes) {
|
|
1272
|
+
if (node.parentNode === parent2) parent2.removeChild(node);
|
|
1273
|
+
}
|
|
1274
|
+
cache = /* @__PURE__ */ new Map();
|
|
1275
|
+
currentNodes = [];
|
|
1276
|
+
currentItems = [];
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
let cleanItems = newItems;
|
|
1280
|
+
for (let i = 0; i < newItems.length; i++) {
|
|
1281
|
+
if (newItems[i] == null) {
|
|
1282
|
+
cleanItems = newItems.filter((item) => item != null);
|
|
1283
|
+
break;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
if (__DEV__) {
|
|
1287
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1288
|
+
for (const item of cleanItems) {
|
|
1289
|
+
const key = keyFn(item);
|
|
1290
|
+
if (seen.has(key)) {
|
|
1291
|
+
console.warn("[forma] createList: duplicate key detected:", key);
|
|
1292
|
+
}
|
|
1293
|
+
seen.add(key);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
const updateRow = updateOnItemChange === "rerender" ? (node, item) => {
|
|
1297
|
+
const key = keyFn(item);
|
|
1298
|
+
const cached = cache.get(key);
|
|
1299
|
+
if (!cached) return;
|
|
1300
|
+
if (cached.item === item) return;
|
|
1301
|
+
cached.item = item;
|
|
1302
|
+
if (!(node instanceof HTMLElement)) return;
|
|
1303
|
+
if (node[ABORT_SYM] || node[CACHE_SYM] || node[DYNAMIC_CHILD_SYM]) {
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
const next = untrack(() => renderFn(item, cached.getIndex));
|
|
1307
|
+
if (canPatchStaticElement(node, next)) {
|
|
1308
|
+
patchStaticElement(node, next);
|
|
1309
|
+
cached.element = node;
|
|
1310
|
+
}
|
|
1311
|
+
} : (_node, item) => {
|
|
1312
|
+
const key = keyFn(item);
|
|
1313
|
+
const cached = cache.get(key);
|
|
1314
|
+
if (cached) cached.item = item;
|
|
1315
|
+
};
|
|
1316
|
+
const result = reconcileList(
|
|
1317
|
+
parent2,
|
|
1318
|
+
currentItems,
|
|
1319
|
+
cleanItems,
|
|
1320
|
+
currentNodes,
|
|
1321
|
+
keyFn,
|
|
1322
|
+
// createFn: create element + cache entry
|
|
1323
|
+
(item) => {
|
|
1324
|
+
const key = keyFn(item);
|
|
1325
|
+
const [getIndex, setIndex] = createSignal(0);
|
|
1326
|
+
const element = untrack(() => renderFn(item, getIndex));
|
|
1327
|
+
cache.set(key, { element, item, getIndex, setIndex });
|
|
1328
|
+
return element;
|
|
1329
|
+
},
|
|
1330
|
+
updateRow,
|
|
1331
|
+
// beforeNode: insert items before the end marker
|
|
1332
|
+
endMarker
|
|
1333
|
+
);
|
|
1334
|
+
const newCache = /* @__PURE__ */ new Map();
|
|
1335
|
+
for (let i = 0; i < cleanItems.length; i++) {
|
|
1336
|
+
const key = keyFn(cleanItems[i]);
|
|
1337
|
+
const cached = cache.get(key);
|
|
1338
|
+
if (cached) {
|
|
1339
|
+
cached.setIndex(i);
|
|
1340
|
+
newCache.set(key, cached);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
cache = newCache;
|
|
1344
|
+
currentNodes = result.nodes;
|
|
1345
|
+
currentItems = result.items;
|
|
1346
|
+
});
|
|
1347
|
+
return fragment2;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
// src/dom/show.ts
|
|
1351
|
+
function createShow(when, thenFn, elseFn) {
|
|
1352
|
+
if (hydrating) {
|
|
1353
|
+
const branch = when() ? thenFn() : elseFn?.() ?? null;
|
|
1354
|
+
return {
|
|
1355
|
+
type: "show",
|
|
1356
|
+
condition: when,
|
|
1357
|
+
whenTrue: thenFn,
|
|
1358
|
+
whenFalse: elseFn,
|
|
1359
|
+
initialBranch: branch
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
const startMarker = document.createComment("forma-show");
|
|
1363
|
+
const endMarker = document.createComment("/forma-show");
|
|
1364
|
+
const fragment2 = document.createDocumentFragment();
|
|
1365
|
+
fragment2.appendChild(startMarker);
|
|
1366
|
+
fragment2.appendChild(endMarker);
|
|
1367
|
+
let currentNode = null;
|
|
1368
|
+
let lastTruthy = null;
|
|
1369
|
+
let currentDispose = null;
|
|
1370
|
+
const showDispose = internalEffect(() => {
|
|
1371
|
+
const truthy = !!when();
|
|
1372
|
+
const DEBUG = typeof globalThis.__FORMA_DEBUG__ !== "undefined";
|
|
1373
|
+
const DEBUG_LABEL = DEBUG ? thenFn.toString().slice(0, 60) : "";
|
|
1374
|
+
if (truthy === lastTruthy) {
|
|
1375
|
+
if (DEBUG) console.log("[forma:show] skip (same)", truthy, DEBUG_LABEL);
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
if (DEBUG) console.log("[forma:show]", lastTruthy, "\u2192", truthy, DEBUG_LABEL);
|
|
1379
|
+
lastTruthy = truthy;
|
|
1380
|
+
const parent2 = startMarker.parentNode;
|
|
1381
|
+
if (!parent2) {
|
|
1382
|
+
if (DEBUG) console.warn("[forma:show] parentNode is null! skipping.", DEBUG_LABEL);
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
if (DEBUG) console.log("[forma:show] parent:", parent2.nodeName, "inDoc:", document.contains(parent2));
|
|
1386
|
+
if (currentDispose) {
|
|
1387
|
+
currentDispose();
|
|
1388
|
+
currentDispose = null;
|
|
1389
|
+
}
|
|
1390
|
+
if (currentNode) {
|
|
1391
|
+
if (currentNode.parentNode === parent2) {
|
|
1392
|
+
parent2.removeChild(currentNode);
|
|
1393
|
+
} else {
|
|
1394
|
+
while (startMarker.nextSibling && startMarker.nextSibling !== endMarker) {
|
|
1395
|
+
parent2.removeChild(startMarker.nextSibling);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
const branchFn = truthy ? thenFn : elseFn;
|
|
1400
|
+
if (branchFn) {
|
|
1401
|
+
let branchDispose;
|
|
1402
|
+
currentNode = createRoot((dispose) => {
|
|
1403
|
+
branchDispose = dispose;
|
|
1404
|
+
return untrack(() => branchFn());
|
|
1405
|
+
});
|
|
1406
|
+
currentDispose = branchDispose;
|
|
1407
|
+
} else {
|
|
1408
|
+
currentNode = null;
|
|
1409
|
+
}
|
|
1410
|
+
if (currentNode) {
|
|
1411
|
+
parent2.insertBefore(currentNode, endMarker);
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
fragment2.__showDispose = () => {
|
|
1415
|
+
showDispose();
|
|
1416
|
+
if (currentDispose) {
|
|
1417
|
+
currentDispose();
|
|
1418
|
+
currentDispose = null;
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
return fragment2;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// src/dom/hydrate.ts
|
|
1425
|
+
var ABORT_SYM2 = /* @__PURE__ */ Symbol.for("forma-abort");
|
|
1426
|
+
var hydrating = false;
|
|
1427
|
+
function setHydrating(value2) {
|
|
1428
|
+
hydrating = value2;
|
|
1429
|
+
}
|
|
1430
|
+
function isDescriptor(v) {
|
|
1431
|
+
return v != null && typeof v === "object" && "type" in v && v.type === "element";
|
|
1432
|
+
}
|
|
1433
|
+
function isShowDescriptor(v) {
|
|
1434
|
+
return v != null && typeof v === "object" && "type" in v && v.type === "show";
|
|
1435
|
+
}
|
|
1436
|
+
function isListDescriptor(v) {
|
|
1437
|
+
return v != null && typeof v === "object" && "type" in v && v.type === "list";
|
|
1438
|
+
}
|
|
1439
|
+
function applyDynamicProps(el, props) {
|
|
1440
|
+
if (!props) return;
|
|
1441
|
+
for (const key in props) {
|
|
1442
|
+
const value2 = props[key];
|
|
1443
|
+
if (typeof value2 !== "function") continue;
|
|
1444
|
+
if (key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.length > 2) {
|
|
1445
|
+
let ac = el[ABORT_SYM2];
|
|
1446
|
+
if (!ac) {
|
|
1447
|
+
ac = new AbortController();
|
|
1448
|
+
el[ABORT_SYM2] = ac;
|
|
1449
|
+
}
|
|
1450
|
+
el.addEventListener(key.slice(2).toLowerCase(), value2, { signal: ac.signal });
|
|
1451
|
+
continue;
|
|
1452
|
+
}
|
|
1453
|
+
const fn = value2;
|
|
1454
|
+
const attrKey = key;
|
|
1455
|
+
internalEffect(() => {
|
|
1456
|
+
const v = fn();
|
|
1457
|
+
if (v === false || v == null) {
|
|
1458
|
+
el.removeAttribute(attrKey);
|
|
1459
|
+
} else if (v === true) {
|
|
1460
|
+
el.setAttribute(attrKey, "");
|
|
1461
|
+
} else {
|
|
1462
|
+
el.setAttribute(attrKey, String(v));
|
|
1463
|
+
}
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
function ensureNode(value2) {
|
|
1468
|
+
if (value2 instanceof Node) return value2;
|
|
1469
|
+
if (value2 == null || value2 === false || value2 === true) return null;
|
|
1470
|
+
if (typeof value2 === "string") return new Text(value2);
|
|
1471
|
+
if (typeof value2 === "number") return new Text(String(value2));
|
|
1472
|
+
if (isDescriptor(value2)) return descriptorToElement(value2);
|
|
1473
|
+
if (isShowDescriptor(value2)) {
|
|
1474
|
+
const prevH = hydrating;
|
|
1475
|
+
hydrating = false;
|
|
1476
|
+
try {
|
|
1477
|
+
return createShow(
|
|
1478
|
+
value2.condition,
|
|
1479
|
+
() => ensureNode(value2.whenTrue()) ?? document.createComment("empty"),
|
|
1480
|
+
value2.whenFalse ? () => ensureNode(value2.whenFalse()) ?? document.createComment("empty") : void 0
|
|
1481
|
+
);
|
|
1482
|
+
} finally {
|
|
1483
|
+
hydrating = prevH;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
if (isListDescriptor(value2)) {
|
|
1487
|
+
const prevH = hydrating;
|
|
1488
|
+
hydrating = false;
|
|
1489
|
+
try {
|
|
1490
|
+
return createList(value2.items, value2.keyFn, value2.renderFn, value2.options);
|
|
1491
|
+
} finally {
|
|
1492
|
+
hydrating = prevH;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
function descriptorToElement(desc) {
|
|
1498
|
+
const prevHydrating = hydrating;
|
|
1499
|
+
hydrating = false;
|
|
1500
|
+
try {
|
|
1501
|
+
const children2 = desc.children.map((child) => {
|
|
1502
|
+
if (isDescriptor(child)) return descriptorToElement(child);
|
|
1503
|
+
if (isShowDescriptor(child)) return ensureNode(child);
|
|
1504
|
+
if (isListDescriptor(child)) return ensureNode(child);
|
|
1505
|
+
return child;
|
|
1506
|
+
});
|
|
1507
|
+
return h(desc.tag, desc.props, ...children2);
|
|
1508
|
+
} finally {
|
|
1509
|
+
hydrating = prevHydrating;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
function isIslandStart(data) {
|
|
1513
|
+
return data.length >= 4 && data.charCodeAt(0) === 102 && data.charCodeAt(1) === 58 && data.charCodeAt(2) === 105;
|
|
1514
|
+
}
|
|
1515
|
+
function isShowStart(data) {
|
|
1516
|
+
return data.length >= 4 && data.charCodeAt(0) === 102 && data.charCodeAt(1) === 58 && data.charCodeAt(2) === 115;
|
|
1517
|
+
}
|
|
1518
|
+
function isTextStart(data) {
|
|
1519
|
+
return data.length >= 4 && data.charCodeAt(0) === 102 && data.charCodeAt(1) === 58 && data.charCodeAt(2) === 116;
|
|
1520
|
+
}
|
|
1521
|
+
function isListStart(data) {
|
|
1522
|
+
return data.length >= 4 && data.charCodeAt(0) === 102 && data.charCodeAt(1) === 58 && data.charCodeAt(2) === 108;
|
|
1523
|
+
}
|
|
1524
|
+
function findClosingMarker(start) {
|
|
1525
|
+
const closing = "/" + start.data;
|
|
1526
|
+
let node = start.nextSibling;
|
|
1527
|
+
while (node) {
|
|
1528
|
+
if (node.nodeType === 8 && node.data === closing) {
|
|
1529
|
+
return node;
|
|
1530
|
+
}
|
|
1531
|
+
node = node.nextSibling;
|
|
1532
|
+
}
|
|
1533
|
+
return null;
|
|
1534
|
+
}
|
|
1535
|
+
function findTextBetween(start, end) {
|
|
1536
|
+
let node = start.nextSibling;
|
|
1537
|
+
while (node && node !== end) {
|
|
1538
|
+
if (node.nodeType === 3) return node;
|
|
1539
|
+
node = node.nextSibling;
|
|
1540
|
+
}
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
function nextElementBetweenMarkers(start, end) {
|
|
1544
|
+
let node = start.nextSibling;
|
|
1545
|
+
while (node && node !== end) {
|
|
1546
|
+
if (node.nodeType === 1) return node;
|
|
1547
|
+
node = node.nextSibling;
|
|
1548
|
+
}
|
|
1549
|
+
return void 0;
|
|
1550
|
+
}
|
|
1551
|
+
function extractContentBetweenMarkers(start, end) {
|
|
1552
|
+
const frag = document.createDocumentFragment();
|
|
1553
|
+
let node = start.nextSibling;
|
|
1554
|
+
while (node && node !== end) {
|
|
1555
|
+
const next = node.nextSibling;
|
|
1556
|
+
frag.appendChild(node);
|
|
1557
|
+
node = next;
|
|
1558
|
+
}
|
|
1559
|
+
return frag;
|
|
1560
|
+
}
|
|
1561
|
+
function setupShowEffect(desc, marker) {
|
|
1562
|
+
let currentCondition = !!desc.condition();
|
|
1563
|
+
let thenFragment = null;
|
|
1564
|
+
let elseFragment = null;
|
|
1565
|
+
const hasSSRContent = marker.start.nextSibling !== marker.end;
|
|
1566
|
+
if (!hasSSRContent && currentCondition) {
|
|
1567
|
+
if (__DEV__) console.warn("[forma] Hydration: show condition mismatch \u2014 SSR empty but client condition is true");
|
|
1568
|
+
const trueBranch = desc.whenTrue();
|
|
1569
|
+
if (trueBranch instanceof Node) {
|
|
1570
|
+
marker.start.parentNode.insertBefore(trueBranch, marker.end);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
internalEffect(() => {
|
|
1574
|
+
const next = !!desc.condition();
|
|
1575
|
+
if (next === currentCondition) return;
|
|
1576
|
+
currentCondition = next;
|
|
1577
|
+
const parent2 = marker.start.parentNode;
|
|
1578
|
+
if (!parent2) return;
|
|
1579
|
+
const current = extractContentBetweenMarkers(marker.start, marker.end);
|
|
1580
|
+
if (!next) {
|
|
1581
|
+
thenFragment = current;
|
|
1582
|
+
} else {
|
|
1583
|
+
elseFragment = current;
|
|
1584
|
+
}
|
|
1585
|
+
let branch = next ? thenFragment ?? desc.whenTrue() : desc.whenFalse ? elseFragment ?? desc.whenFalse() : null;
|
|
1586
|
+
if (next && thenFragment) thenFragment = null;
|
|
1587
|
+
if (!next && elseFragment) elseFragment = null;
|
|
1588
|
+
if (branch != null && !(branch instanceof Node)) {
|
|
1589
|
+
branch = ensureNode(branch);
|
|
1590
|
+
}
|
|
1591
|
+
if (branch instanceof Node) {
|
|
1592
|
+
parent2.insertBefore(branch, marker.end);
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
function adoptBranchContent(desc, regionStart, regionEnd) {
|
|
1597
|
+
if (isDescriptor(desc)) {
|
|
1598
|
+
const el = nextElementBetweenMarkers(regionStart, regionEnd);
|
|
1599
|
+
if (el) adoptNode(desc, el);
|
|
1600
|
+
} else if (isShowDescriptor(desc)) {
|
|
1601
|
+
let node = regionStart.nextSibling;
|
|
1602
|
+
while (node && node !== regionEnd) {
|
|
1603
|
+
if (node.nodeType === 8 && isShowStart(node.data)) {
|
|
1604
|
+
const innerStart = node;
|
|
1605
|
+
const innerEnd = findClosingMarker(innerStart);
|
|
1606
|
+
if (innerEnd) {
|
|
1607
|
+
if (desc.initialBranch) {
|
|
1608
|
+
adoptBranchContent(desc.initialBranch, innerStart, innerEnd);
|
|
1609
|
+
}
|
|
1610
|
+
setupShowEffect(desc, { start: innerStart, end: innerEnd, cachedContent: null });
|
|
1611
|
+
}
|
|
1612
|
+
break;
|
|
1613
|
+
}
|
|
1614
|
+
node = node.nextSibling;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function adoptNode(desc, ssrEl) {
|
|
1619
|
+
if (!ssrEl || ssrEl.tagName !== desc.tag.toUpperCase()) {
|
|
1620
|
+
if (__DEV__) console.warn(`Hydration mismatch: expected <${desc.tag}>, got <${ssrEl?.tagName?.toLowerCase() ?? "nothing"}>`);
|
|
1621
|
+
const fresh = descriptorToElement(desc);
|
|
1622
|
+
if (ssrEl) ssrEl.replaceWith(fresh);
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
applyDynamicProps(ssrEl, desc.props);
|
|
1626
|
+
let cursor = ssrEl.firstChild;
|
|
1627
|
+
for (const child of desc.children) {
|
|
1628
|
+
if (child === false || child == null) continue;
|
|
1629
|
+
if (isDescriptor(child)) {
|
|
1630
|
+
while (cursor && cursor.nodeType === 3 && !cursor.data.trim()) {
|
|
1631
|
+
cursor = cursor.nextSibling;
|
|
1632
|
+
}
|
|
1633
|
+
while (cursor && cursor.nodeType === 1 && cursor.hasAttribute("data-forma-island")) {
|
|
1634
|
+
cursor = cursor.nextSibling;
|
|
1635
|
+
}
|
|
1636
|
+
if (!cursor) {
|
|
1637
|
+
ssrEl.appendChild(descriptorToElement(child));
|
|
1638
|
+
continue;
|
|
1639
|
+
}
|
|
1640
|
+
if (cursor.nodeType === 1) {
|
|
1641
|
+
const el = cursor;
|
|
1642
|
+
cursor = cursor.nextSibling;
|
|
1643
|
+
adoptNode(child, el);
|
|
1644
|
+
} else if (cursor.nodeType === 8 && isIslandStart(cursor.data)) {
|
|
1645
|
+
const end = findClosingMarker(cursor);
|
|
1646
|
+
const fresh = descriptorToElement(child);
|
|
1647
|
+
if (end) {
|
|
1648
|
+
end.parentNode.insertBefore(fresh, end);
|
|
1649
|
+
cursor = end.nextSibling;
|
|
1650
|
+
} else {
|
|
1651
|
+
ssrEl.appendChild(fresh);
|
|
1652
|
+
cursor = null;
|
|
1653
|
+
}
|
|
1654
|
+
} else {
|
|
1655
|
+
ssrEl.appendChild(descriptorToElement(child));
|
|
1656
|
+
}
|
|
1657
|
+
} else if (isShowDescriptor(child)) {
|
|
1658
|
+
while (cursor && !(cursor.nodeType === 8 && isShowStart(cursor.data))) {
|
|
1659
|
+
cursor = cursor.nextSibling;
|
|
1660
|
+
}
|
|
1661
|
+
if (cursor) {
|
|
1662
|
+
const start = cursor;
|
|
1663
|
+
const end = findClosingMarker(start);
|
|
1664
|
+
if (end) {
|
|
1665
|
+
if (child.initialBranch) {
|
|
1666
|
+
adoptBranchContent(child.initialBranch, start, end);
|
|
1667
|
+
}
|
|
1668
|
+
setupShowEffect(child, { start, end, cachedContent: null });
|
|
1669
|
+
cursor = end.nextSibling;
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
} else if (isListDescriptor(child)) {
|
|
1673
|
+
while (cursor && !(cursor.nodeType === 8 && isListStart(cursor.data))) {
|
|
1674
|
+
cursor = cursor.nextSibling;
|
|
1675
|
+
}
|
|
1676
|
+
if (cursor) {
|
|
1677
|
+
const start = cursor;
|
|
1678
|
+
const end = findClosingMarker(start);
|
|
1679
|
+
if (end) {
|
|
1680
|
+
const ssrKeyMap = /* @__PURE__ */ new Map();
|
|
1681
|
+
const ssrElements = [];
|
|
1682
|
+
let node = start.nextSibling;
|
|
1683
|
+
while (node && node !== end) {
|
|
1684
|
+
if (node.nodeType === 1) {
|
|
1685
|
+
const el = node;
|
|
1686
|
+
ssrElements.push(el);
|
|
1687
|
+
const key = el.getAttribute("data-forma-key");
|
|
1688
|
+
if (key != null) {
|
|
1689
|
+
ssrKeyMap.set(key, el);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
node = node.nextSibling;
|
|
1693
|
+
}
|
|
1694
|
+
const currentItems = untrack(() => child.items());
|
|
1695
|
+
const listKeyFn = child.keyFn;
|
|
1696
|
+
const listRenderFn = child.renderFn;
|
|
1697
|
+
const useIndexFallback = ssrKeyMap.size === 0 && ssrElements.length > 0;
|
|
1698
|
+
const adoptedNodes = [];
|
|
1699
|
+
const adoptedItems = [];
|
|
1700
|
+
const usedIndices = /* @__PURE__ */ new Set();
|
|
1701
|
+
for (let i = 0; i < currentItems.length; i++) {
|
|
1702
|
+
const item = currentItems[i];
|
|
1703
|
+
const key = listKeyFn(item);
|
|
1704
|
+
let ssrNode;
|
|
1705
|
+
if (useIndexFallback) {
|
|
1706
|
+
if (i < ssrElements.length) {
|
|
1707
|
+
ssrNode = ssrElements[i];
|
|
1708
|
+
usedIndices.add(i);
|
|
1709
|
+
}
|
|
1710
|
+
} else {
|
|
1711
|
+
ssrNode = ssrKeyMap.get(String(key));
|
|
1712
|
+
if (ssrNode) ssrKeyMap.delete(String(key));
|
|
1713
|
+
}
|
|
1714
|
+
if (ssrNode) {
|
|
1715
|
+
adoptedNodes.push(ssrNode);
|
|
1716
|
+
adoptedItems.push(item);
|
|
1717
|
+
} else {
|
|
1718
|
+
if (__DEV__) console.warn(`[FormaJS] Hydration: list item key "${key}" not found in SSR \u2014 rendering fresh`);
|
|
1719
|
+
const prevHydrating = hydrating;
|
|
1720
|
+
hydrating = false;
|
|
1721
|
+
try {
|
|
1722
|
+
const [getIndex] = createSignal(i);
|
|
1723
|
+
const fresh = listRenderFn(item, getIndex);
|
|
1724
|
+
end.parentNode.insertBefore(fresh, end);
|
|
1725
|
+
adoptedNodes.push(fresh);
|
|
1726
|
+
adoptedItems.push(item);
|
|
1727
|
+
} finally {
|
|
1728
|
+
hydrating = prevHydrating;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
if (useIndexFallback) {
|
|
1733
|
+
for (let i = 0; i < ssrElements.length; i++) {
|
|
1734
|
+
if (!usedIndices.has(i) && ssrElements[i].parentNode) {
|
|
1735
|
+
ssrElements[i].parentNode.removeChild(ssrElements[i]);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
} else {
|
|
1739
|
+
for (const [unusedKey, unusedNode] of ssrKeyMap) {
|
|
1740
|
+
if (__DEV__) console.warn(`[FormaJS] Hydration: removing extra SSR list item with key "${unusedKey}"`);
|
|
1741
|
+
if (unusedNode.parentNode) {
|
|
1742
|
+
unusedNode.parentNode.removeChild(unusedNode);
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
const parent2 = start.parentNode;
|
|
1747
|
+
for (const adoptedNode of adoptedNodes) {
|
|
1748
|
+
parent2.insertBefore(adoptedNode, end);
|
|
1749
|
+
}
|
|
1750
|
+
let cache = /* @__PURE__ */ new Map();
|
|
1751
|
+
for (let i = 0; i < adoptedItems.length; i++) {
|
|
1752
|
+
const item = adoptedItems[i];
|
|
1753
|
+
const key = listKeyFn(item);
|
|
1754
|
+
const [getIndex, setIndex] = createSignal(i);
|
|
1755
|
+
cache.set(key, {
|
|
1756
|
+
element: adoptedNodes[i],
|
|
1757
|
+
item,
|
|
1758
|
+
getIndex,
|
|
1759
|
+
setIndex
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
let reconcileNodes = adoptedNodes.slice();
|
|
1763
|
+
let reconcileItems = adoptedItems.slice();
|
|
1764
|
+
internalEffect(() => {
|
|
1765
|
+
const newItems = child.items();
|
|
1766
|
+
const parent3 = start.parentNode;
|
|
1767
|
+
if (!parent3) return;
|
|
1768
|
+
const result = reconcileList(
|
|
1769
|
+
parent3,
|
|
1770
|
+
reconcileItems,
|
|
1771
|
+
newItems,
|
|
1772
|
+
reconcileNodes,
|
|
1773
|
+
listKeyFn,
|
|
1774
|
+
(item) => {
|
|
1775
|
+
const prevHydrating = hydrating;
|
|
1776
|
+
hydrating = false;
|
|
1777
|
+
try {
|
|
1778
|
+
const key = listKeyFn(item);
|
|
1779
|
+
const [getIndex, setIndex] = createSignal(0);
|
|
1780
|
+
const element = untrack(() => listRenderFn(item, getIndex));
|
|
1781
|
+
cache.set(key, { element, item, getIndex, setIndex });
|
|
1782
|
+
return element;
|
|
1783
|
+
} finally {
|
|
1784
|
+
hydrating = prevHydrating;
|
|
1785
|
+
}
|
|
1786
|
+
},
|
|
1787
|
+
(_node, item) => {
|
|
1788
|
+
const key = listKeyFn(item);
|
|
1789
|
+
const cached = cache.get(key);
|
|
1790
|
+
if (cached) cached.item = item;
|
|
1791
|
+
},
|
|
1792
|
+
end
|
|
1793
|
+
);
|
|
1794
|
+
const newCache = /* @__PURE__ */ new Map();
|
|
1795
|
+
for (let i = 0; i < newItems.length; i++) {
|
|
1796
|
+
const key = listKeyFn(newItems[i]);
|
|
1797
|
+
const cached = cache.get(key);
|
|
1798
|
+
if (cached) {
|
|
1799
|
+
cached.setIndex(i);
|
|
1800
|
+
newCache.set(key, cached);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
cache = newCache;
|
|
1804
|
+
reconcileNodes = result.nodes;
|
|
1805
|
+
reconcileItems = result.items;
|
|
1806
|
+
});
|
|
1807
|
+
cursor = end.nextSibling;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
} else if (typeof child === "function") {
|
|
1811
|
+
while (cursor && cursor.nodeType === 3 && !cursor.data.trim()) {
|
|
1812
|
+
cursor = cursor.nextSibling;
|
|
1813
|
+
}
|
|
1814
|
+
if (cursor && cursor.nodeType === 1) {
|
|
1815
|
+
const initial = child();
|
|
1816
|
+
if (isDescriptor(initial)) {
|
|
1817
|
+
const el = cursor;
|
|
1818
|
+
cursor = cursor.nextSibling;
|
|
1819
|
+
adoptNode(initial, el);
|
|
1820
|
+
continue;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
if (cursor && cursor.nodeType === 8) {
|
|
1824
|
+
const data = cursor.data;
|
|
1825
|
+
if (isTextStart(data)) {
|
|
1826
|
+
const endMarker = findClosingMarker(cursor);
|
|
1827
|
+
let textNode = cursor.nextSibling;
|
|
1828
|
+
if (!textNode || textNode.nodeType !== 3) {
|
|
1829
|
+
if (__DEV__) console.warn(`[FormaJS] Hydration: created text node for marker ${data} \u2014 SSR walker should emit content between markers`);
|
|
1830
|
+
const created = document.createTextNode("");
|
|
1831
|
+
cursor.parentNode.insertBefore(created, endMarker || cursor.nextSibling);
|
|
1832
|
+
textNode = created;
|
|
1833
|
+
}
|
|
1834
|
+
internalEffect(() => {
|
|
1835
|
+
textNode.data = String(child());
|
|
1836
|
+
});
|
|
1837
|
+
cursor = endMarker ? endMarker.nextSibling : textNode.nextSibling;
|
|
1838
|
+
} else if (isShowStart(data)) {
|
|
1839
|
+
const start = cursor;
|
|
1840
|
+
const end = findClosingMarker(start);
|
|
1841
|
+
if (end) {
|
|
1842
|
+
let textNode = findTextBetween(start, end);
|
|
1843
|
+
if (!textNode) {
|
|
1844
|
+
if (__DEV__) console.warn(`[FormaJS] Hydration: created text node for show marker ${start.data} \u2014 SSR walker should emit content between markers`);
|
|
1845
|
+
textNode = document.createTextNode("");
|
|
1846
|
+
start.parentNode.insertBefore(textNode, end);
|
|
1847
|
+
}
|
|
1848
|
+
internalEffect(() => {
|
|
1849
|
+
textNode.data = String(child());
|
|
1850
|
+
});
|
|
1851
|
+
cursor = end.nextSibling;
|
|
1852
|
+
} else {
|
|
1853
|
+
cursor = cursor.nextSibling;
|
|
1854
|
+
}
|
|
1855
|
+
} else {
|
|
1856
|
+
cursor = cursor.nextSibling;
|
|
1857
|
+
}
|
|
1858
|
+
} else if (cursor && cursor.nodeType === 3) {
|
|
1859
|
+
const textNode = cursor;
|
|
1860
|
+
cursor = cursor.nextSibling;
|
|
1861
|
+
internalEffect(() => {
|
|
1862
|
+
textNode.data = String(child());
|
|
1863
|
+
});
|
|
1864
|
+
} else {
|
|
1865
|
+
if (__DEV__) console.warn(`[FormaJS] Hydration: created text node in empty <${ssrEl.tagName.toLowerCase()}> \u2014 IR may not cover this component`);
|
|
1866
|
+
const textNode = document.createTextNode("");
|
|
1867
|
+
ssrEl.appendChild(textNode);
|
|
1868
|
+
internalEffect(() => {
|
|
1869
|
+
textNode.data = String(child());
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
} else if (typeof child === "string" || typeof child === "number") {
|
|
1873
|
+
if (cursor && cursor.nodeType === 3) {
|
|
1874
|
+
cursor = cursor.nextSibling;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
function hydrateIsland(component, target) {
|
|
1880
|
+
const hasSSRContent = target.childElementCount > 0 || target.childNodes.length > 0 && Array.from(target.childNodes).some((n) => n.nodeType === 1 || n.nodeType === 3 && n.data.trim());
|
|
1881
|
+
if (!hasSSRContent) {
|
|
1882
|
+
if (__DEV__) {
|
|
1883
|
+
const name = target.getAttribute("data-forma-component") || "unknown";
|
|
1884
|
+
console.warn(
|
|
1885
|
+
`[forma] Island "${name}" has no SSR content \u2014 falling back to CSR. This means the IR walker did not render content between ISLAND_START and ISLAND_END.`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
const result = component();
|
|
1889
|
+
if (result instanceof Element) {
|
|
1890
|
+
for (const attr of Array.from(target.attributes)) {
|
|
1891
|
+
if (attr.name.startsWith("data-forma-")) {
|
|
1892
|
+
result.setAttribute(attr.name, attr.value);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
target.replaceWith(result);
|
|
1896
|
+
return result;
|
|
1897
|
+
} else if (result instanceof Node) {
|
|
1898
|
+
target.appendChild(result);
|
|
1899
|
+
}
|
|
1900
|
+
return target;
|
|
1901
|
+
}
|
|
1902
|
+
setHydrating(true);
|
|
1903
|
+
let descriptor;
|
|
1904
|
+
try {
|
|
1905
|
+
descriptor = component();
|
|
1906
|
+
} finally {
|
|
1907
|
+
setHydrating(false);
|
|
1908
|
+
}
|
|
1909
|
+
if (!descriptor || !isDescriptor(descriptor)) {
|
|
1910
|
+
target.removeAttribute("data-forma-ssr");
|
|
1911
|
+
return target;
|
|
1912
|
+
}
|
|
1913
|
+
if (target.hasAttribute("data-forma-island")) {
|
|
1914
|
+
adoptNode(descriptor, target);
|
|
1915
|
+
} else {
|
|
1916
|
+
adoptNode(descriptor, target.children[0]);
|
|
1917
|
+
}
|
|
1918
|
+
target.removeAttribute("data-forma-ssr");
|
|
1919
|
+
return target;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
// src/dom/element.ts
|
|
1923
|
+
var Fragment = /* @__PURE__ */ Symbol.for("forma.fragment");
|
|
1924
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1925
|
+
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
1926
|
+
var SVG_TAGS = /* @__PURE__ */ new Set([
|
|
1927
|
+
"svg",
|
|
1928
|
+
"path",
|
|
1929
|
+
"circle",
|
|
1930
|
+
"rect",
|
|
1931
|
+
"line",
|
|
1932
|
+
"polyline",
|
|
1933
|
+
"polygon",
|
|
1934
|
+
"ellipse",
|
|
1935
|
+
"g",
|
|
1936
|
+
"text",
|
|
1937
|
+
"tspan",
|
|
1938
|
+
"textPath",
|
|
1939
|
+
"defs",
|
|
1940
|
+
"use",
|
|
1941
|
+
"symbol",
|
|
1942
|
+
"clipPath",
|
|
1943
|
+
"mask",
|
|
1944
|
+
"pattern",
|
|
1945
|
+
"marker",
|
|
1946
|
+
"linearGradient",
|
|
1947
|
+
"radialGradient",
|
|
1948
|
+
"stop",
|
|
1949
|
+
"filter",
|
|
1950
|
+
"feGaussianBlur",
|
|
1951
|
+
"feColorMatrix",
|
|
1952
|
+
"feOffset",
|
|
1953
|
+
"feBlend",
|
|
1954
|
+
"feMerge",
|
|
1955
|
+
"feMergeNode",
|
|
1956
|
+
"feComposite",
|
|
1957
|
+
"feFlood",
|
|
1958
|
+
"feMorphology",
|
|
1959
|
+
"feTurbulence",
|
|
1960
|
+
"feDisplacementMap",
|
|
1961
|
+
"feImage",
|
|
1962
|
+
"foreignObject",
|
|
1963
|
+
"animate",
|
|
1964
|
+
"animateTransform",
|
|
1965
|
+
"animateMotion",
|
|
1966
|
+
"set",
|
|
1967
|
+
"image",
|
|
1968
|
+
"switch",
|
|
1969
|
+
"desc",
|
|
1970
|
+
"title",
|
|
1971
|
+
"metadata"
|
|
1972
|
+
]);
|
|
1973
|
+
var BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
|
|
1974
|
+
"disabled",
|
|
1975
|
+
"checked",
|
|
1976
|
+
"readonly",
|
|
1977
|
+
"required",
|
|
1978
|
+
"autofocus",
|
|
1979
|
+
"autoplay",
|
|
1980
|
+
"controls",
|
|
1981
|
+
"default",
|
|
1982
|
+
"defer",
|
|
1983
|
+
"formnovalidate",
|
|
1984
|
+
"hidden",
|
|
1985
|
+
"ismap",
|
|
1986
|
+
"loop",
|
|
1987
|
+
"multiple",
|
|
1988
|
+
"muted",
|
|
1989
|
+
"nomodule",
|
|
1990
|
+
"novalidate",
|
|
1991
|
+
"open",
|
|
1992
|
+
"playsinline",
|
|
1993
|
+
"reversed",
|
|
1994
|
+
"selected",
|
|
1995
|
+
"async"
|
|
1996
|
+
]);
|
|
1997
|
+
var ELEMENT_PROTOS = null;
|
|
1998
|
+
function getProto(tag) {
|
|
1999
|
+
if (!ELEMENT_PROTOS) {
|
|
2000
|
+
ELEMENT_PROTOS = /* @__PURE__ */ Object.create(null);
|
|
2001
|
+
for (const t of [
|
|
2002
|
+
"div",
|
|
2003
|
+
"span",
|
|
2004
|
+
"p",
|
|
2005
|
+
"a",
|
|
2006
|
+
"li",
|
|
2007
|
+
"ul",
|
|
2008
|
+
"ol",
|
|
2009
|
+
"button",
|
|
2010
|
+
"input",
|
|
2011
|
+
"label",
|
|
2012
|
+
"h1",
|
|
2013
|
+
"h2",
|
|
2014
|
+
"h3",
|
|
2015
|
+
"h4",
|
|
2016
|
+
"h5",
|
|
2017
|
+
"h6",
|
|
2018
|
+
"section",
|
|
2019
|
+
"header",
|
|
2020
|
+
"footer",
|
|
2021
|
+
"main",
|
|
2022
|
+
"nav",
|
|
2023
|
+
"table",
|
|
2024
|
+
"tr",
|
|
2025
|
+
"td",
|
|
2026
|
+
"th",
|
|
2027
|
+
"tbody",
|
|
2028
|
+
"img",
|
|
2029
|
+
"form",
|
|
2030
|
+
"select",
|
|
2031
|
+
"option",
|
|
2032
|
+
"textarea",
|
|
2033
|
+
"i",
|
|
2034
|
+
"b",
|
|
2035
|
+
"strong",
|
|
2036
|
+
"em",
|
|
2037
|
+
"small",
|
|
2038
|
+
"article",
|
|
2039
|
+
"aside",
|
|
2040
|
+
"details",
|
|
2041
|
+
"summary"
|
|
2042
|
+
]) {
|
|
2043
|
+
ELEMENT_PROTOS[t] = document.createElement(t);
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
return ELEMENT_PROTOS[tag] ?? (ELEMENT_PROTOS[tag] = document.createElement(tag));
|
|
2047
|
+
}
|
|
2048
|
+
var EVENT_NAMES = /* @__PURE__ */ Object.create(null);
|
|
2049
|
+
function eventName(key) {
|
|
2050
|
+
return EVENT_NAMES[key] ?? (EVENT_NAMES[key] = key.slice(2).toLowerCase());
|
|
2051
|
+
}
|
|
2052
|
+
var ABORT_SYM3 = /* @__PURE__ */ Symbol.for("forma-abort");
|
|
2053
|
+
function getAbortController(el) {
|
|
2054
|
+
let controller = el[ABORT_SYM3];
|
|
2055
|
+
if (!controller) {
|
|
2056
|
+
controller = new AbortController();
|
|
2057
|
+
el[ABORT_SYM3] = controller;
|
|
2058
|
+
}
|
|
2059
|
+
return controller;
|
|
2060
|
+
}
|
|
2061
|
+
function cleanup(el) {
|
|
2062
|
+
const controller = el[ABORT_SYM3];
|
|
2063
|
+
if (controller) {
|
|
2064
|
+
controller.abort();
|
|
2065
|
+
delete el[ABORT_SYM3];
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
var CACHE_SYM2 = /* @__PURE__ */ Symbol.for("forma-attr-cache");
|
|
2069
|
+
var DYNAMIC_CHILD_SYM2 = /* @__PURE__ */ Symbol.for("forma-dynamic-child");
|
|
2070
|
+
function getCache(el) {
|
|
2071
|
+
return el[CACHE_SYM2] ?? (el[CACHE_SYM2] = /* @__PURE__ */ Object.create(null));
|
|
2072
|
+
}
|
|
2073
|
+
function handleClass(el, _key, value2) {
|
|
2074
|
+
if (typeof value2 === "function") {
|
|
2075
|
+
internalEffect(() => {
|
|
2076
|
+
const v = value2();
|
|
2077
|
+
const cache = getCache(el);
|
|
2078
|
+
if (cache["class"] === v) return;
|
|
2079
|
+
cache["class"] = v;
|
|
2080
|
+
if (el instanceof HTMLElement) {
|
|
2081
|
+
el.className = v;
|
|
2082
|
+
} else {
|
|
2083
|
+
el.setAttribute("class", v);
|
|
2084
|
+
}
|
|
2085
|
+
});
|
|
2086
|
+
} else {
|
|
2087
|
+
const cache = getCache(el);
|
|
2088
|
+
if (cache["class"] === value2) return;
|
|
2089
|
+
cache["class"] = value2;
|
|
2090
|
+
if (el instanceof HTMLElement) {
|
|
2091
|
+
el.className = value2;
|
|
2092
|
+
} else {
|
|
2093
|
+
el.setAttribute("class", value2);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
function handleStyle(el, _key, value2) {
|
|
2098
|
+
if (typeof value2 === "function") {
|
|
2099
|
+
let prevKeys = [];
|
|
2100
|
+
internalEffect(() => {
|
|
2101
|
+
const v = value2();
|
|
2102
|
+
if (typeof v === "string") {
|
|
2103
|
+
const cache = getCache(el);
|
|
2104
|
+
if (cache["style"] === v) return;
|
|
2105
|
+
cache["style"] = v;
|
|
2106
|
+
prevKeys = [];
|
|
2107
|
+
el.style.cssText = v;
|
|
2108
|
+
} else if (v && typeof v === "object") {
|
|
2109
|
+
const style = el.style;
|
|
2110
|
+
const nextKeys = Object.keys(v);
|
|
2111
|
+
for (const k of prevKeys) {
|
|
2112
|
+
if (!(k in v)) {
|
|
2113
|
+
style.removeProperty(k.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase()));
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
Object.assign(style, v);
|
|
2117
|
+
prevKeys = nextKeys;
|
|
2118
|
+
}
|
|
2119
|
+
});
|
|
2120
|
+
} else if (typeof value2 === "string") {
|
|
2121
|
+
const cache = getCache(el);
|
|
2122
|
+
if (cache["style"] === value2) return;
|
|
2123
|
+
cache["style"] = value2;
|
|
2124
|
+
el.style.cssText = value2;
|
|
2125
|
+
} else if (value2 && typeof value2 === "object") {
|
|
2126
|
+
Object.assign(el.style, value2);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
function handleEvent(el, key, value2) {
|
|
2130
|
+
const controller = getAbortController(el);
|
|
2131
|
+
el.addEventListener(
|
|
2132
|
+
eventName(key),
|
|
2133
|
+
value2,
|
|
2134
|
+
{ signal: controller.signal }
|
|
2135
|
+
);
|
|
2136
|
+
}
|
|
2137
|
+
function handleInnerHTML(el, _key, value2) {
|
|
2138
|
+
if (typeof value2 === "function") {
|
|
2139
|
+
internalEffect(() => {
|
|
2140
|
+
const resolved = value2();
|
|
2141
|
+
if (resolved == null) {
|
|
2142
|
+
el.innerHTML = "";
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
if (typeof resolved !== "object" || !("__html" in resolved)) {
|
|
2146
|
+
throw new TypeError(
|
|
2147
|
+
"dangerouslySetInnerHTML: expected { __html: string }, got " + typeof resolved
|
|
2148
|
+
);
|
|
2149
|
+
}
|
|
2150
|
+
const html = resolved.__html;
|
|
2151
|
+
if (typeof html !== "string") {
|
|
2152
|
+
throw new TypeError(
|
|
2153
|
+
"dangerouslySetInnerHTML: __html must be a string, got " + typeof html
|
|
2154
|
+
);
|
|
2155
|
+
}
|
|
2156
|
+
const cache = getCache(el);
|
|
2157
|
+
if (cache["innerHTML"] === html) return;
|
|
2158
|
+
cache["innerHTML"] = html;
|
|
2159
|
+
el.innerHTML = html;
|
|
2160
|
+
});
|
|
2161
|
+
} else {
|
|
2162
|
+
if (value2 == null) {
|
|
2163
|
+
el.innerHTML = "";
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
if (typeof value2 !== "object" || !("__html" in value2)) {
|
|
2167
|
+
throw new TypeError(
|
|
2168
|
+
"dangerouslySetInnerHTML: expected { __html: string }, got " + typeof value2
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
const html = value2.__html;
|
|
2172
|
+
if (typeof html !== "string") {
|
|
2173
|
+
throw new TypeError(
|
|
2174
|
+
"dangerouslySetInnerHTML: __html must be a string, got " + typeof html
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
el.innerHTML = html;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
function handleXLink(el, key, value2) {
|
|
2181
|
+
const localName = key.slice(6);
|
|
2182
|
+
if (typeof value2 === "function") {
|
|
2183
|
+
internalEffect(() => {
|
|
2184
|
+
const v = value2();
|
|
2185
|
+
if (v == null || v === false) {
|
|
2186
|
+
el.removeAttributeNS(XLINK_NS, localName);
|
|
2187
|
+
} else {
|
|
2188
|
+
el.setAttributeNS(XLINK_NS, key, String(v));
|
|
2189
|
+
}
|
|
2190
|
+
});
|
|
2191
|
+
} else {
|
|
2192
|
+
if (value2 == null || value2 === false) {
|
|
2193
|
+
el.removeAttributeNS(XLINK_NS, localName);
|
|
2194
|
+
} else {
|
|
2195
|
+
el.setAttributeNS(XLINK_NS, key, String(value2));
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
function handleBooleanAttr(el, key, value2) {
|
|
2200
|
+
if (typeof value2 === "function") {
|
|
2201
|
+
internalEffect(() => {
|
|
2202
|
+
const v = value2();
|
|
2203
|
+
const cache = getCache(el);
|
|
2204
|
+
if (cache[key] === v) return;
|
|
2205
|
+
cache[key] = v;
|
|
2206
|
+
if (v) {
|
|
2207
|
+
el.setAttribute(key, "");
|
|
2208
|
+
} else {
|
|
2209
|
+
el.removeAttribute(key);
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
} else {
|
|
2213
|
+
const cache = getCache(el);
|
|
2214
|
+
if (cache[key] === value2) return;
|
|
2215
|
+
cache[key] = value2;
|
|
2216
|
+
if (value2) {
|
|
2217
|
+
el.setAttribute(key, "");
|
|
2218
|
+
} else {
|
|
2219
|
+
el.removeAttribute(key);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
function handleGenericAttr(el, key, value2) {
|
|
2224
|
+
if (typeof value2 === "function") {
|
|
2225
|
+
internalEffect(() => {
|
|
2226
|
+
const v = value2();
|
|
2227
|
+
if (v == null || v === false) {
|
|
2228
|
+
const cache = getCache(el);
|
|
2229
|
+
if (cache[key] === null) return;
|
|
2230
|
+
cache[key] = null;
|
|
2231
|
+
el.removeAttribute(key);
|
|
2232
|
+
} else {
|
|
2233
|
+
const strVal = String(v);
|
|
2234
|
+
const cache = getCache(el);
|
|
2235
|
+
if (cache[key] === strVal) return;
|
|
2236
|
+
cache[key] = strVal;
|
|
2237
|
+
el.setAttribute(key, strVal);
|
|
2238
|
+
}
|
|
2239
|
+
});
|
|
2240
|
+
} else {
|
|
2241
|
+
if (value2 == null || value2 === false) {
|
|
2242
|
+
const cache = getCache(el);
|
|
2243
|
+
if (cache[key] === null) return;
|
|
2244
|
+
cache[key] = null;
|
|
2245
|
+
el.removeAttribute(key);
|
|
2246
|
+
} else {
|
|
2247
|
+
const strVal = String(value2);
|
|
2248
|
+
const cache = getCache(el);
|
|
2249
|
+
if (cache[key] === strVal) return;
|
|
2250
|
+
cache[key] = strVal;
|
|
2251
|
+
el.setAttribute(key, strVal);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
var PROP_HANDLERS = /* @__PURE__ */ new Map();
|
|
2256
|
+
PROP_HANDLERS.set("class", handleClass);
|
|
2257
|
+
PROP_HANDLERS.set("className", handleClass);
|
|
2258
|
+
PROP_HANDLERS.set("style", handleStyle);
|
|
2259
|
+
PROP_HANDLERS.set("ref", () => {
|
|
2260
|
+
});
|
|
2261
|
+
PROP_HANDLERS.set("dangerouslySetInnerHTML", handleInnerHTML);
|
|
2262
|
+
for (const attr of BOOLEAN_ATTRS) {
|
|
2263
|
+
PROP_HANDLERS.set(attr, handleBooleanAttr);
|
|
2264
|
+
}
|
|
2265
|
+
function applyProp(el, key, value2) {
|
|
2266
|
+
if (key === "class") {
|
|
2267
|
+
handleClass(el, key, value2);
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
if (key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.length > 2) {
|
|
2271
|
+
handleEvent(el, key, value2);
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
const handler = PROP_HANDLERS.get(key);
|
|
2275
|
+
if (handler) {
|
|
2276
|
+
handler(el, key, value2);
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
if (key.charCodeAt(0) === 120 && key.startsWith("xlink:")) {
|
|
2280
|
+
handleXLink(el, key, value2);
|
|
2281
|
+
return;
|
|
2282
|
+
}
|
|
2283
|
+
handleGenericAttr(el, key, value2);
|
|
2284
|
+
}
|
|
2285
|
+
function applyStaticProp(el, key, value2) {
|
|
2286
|
+
if (value2 == null || value2 === false) return;
|
|
2287
|
+
if (key === "class" || key === "className") {
|
|
2288
|
+
el.className = value2;
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
if (key === "style") {
|
|
2292
|
+
if (typeof value2 === "string") {
|
|
2293
|
+
el.style.cssText = value2;
|
|
2294
|
+
} else if (value2 && typeof value2 === "object") {
|
|
2295
|
+
Object.assign(el.style, value2);
|
|
2296
|
+
}
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
if (key === "dangerouslySetInnerHTML") {
|
|
2300
|
+
if (typeof value2 !== "object" || !("__html" in value2)) {
|
|
2301
|
+
throw new TypeError(
|
|
2302
|
+
"dangerouslySetInnerHTML: expected { __html: string }, got " + typeof value2
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2305
|
+
const html = value2.__html;
|
|
2306
|
+
if (typeof html !== "string") {
|
|
2307
|
+
throw new TypeError(
|
|
2308
|
+
"dangerouslySetInnerHTML: __html must be a string, got " + typeof html
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
el.innerHTML = html;
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
if (key.charCodeAt(0) === 120 && key.startsWith("xlink:")) {
|
|
2315
|
+
el.setAttributeNS(XLINK_NS, key, String(value2));
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
if (BOOLEAN_ATTRS.has(key)) {
|
|
2319
|
+
if (value2) el.setAttribute(key, "");
|
|
2320
|
+
return;
|
|
2321
|
+
}
|
|
2322
|
+
if (value2 === true) {
|
|
2323
|
+
el.setAttribute(key, "");
|
|
2324
|
+
} else {
|
|
2325
|
+
el.setAttribute(key, String(value2));
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
function appendChild(parent2, child) {
|
|
2329
|
+
if (child instanceof Node) {
|
|
2330
|
+
parent2.appendChild(child);
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
if (typeof child === "string") {
|
|
2334
|
+
parent2.appendChild(new Text(child));
|
|
2335
|
+
return;
|
|
2336
|
+
}
|
|
2337
|
+
if (child == null || child === false || child === true) {
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
if (typeof child === "number") {
|
|
2341
|
+
parent2.appendChild(new Text(String(child)));
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
if (typeof child === "function") {
|
|
2345
|
+
if (parent2 instanceof Element) {
|
|
2346
|
+
parent2[DYNAMIC_CHILD_SYM2] = true;
|
|
2347
|
+
}
|
|
2348
|
+
let currentNode = null;
|
|
2349
|
+
internalEffect(() => {
|
|
2350
|
+
const v = child();
|
|
2351
|
+
if (v instanceof Node) {
|
|
2352
|
+
if (currentNode) {
|
|
2353
|
+
parent2.replaceChild(v, currentNode);
|
|
2354
|
+
} else {
|
|
2355
|
+
parent2.appendChild(v);
|
|
2356
|
+
}
|
|
2357
|
+
currentNode = v;
|
|
2358
|
+
} else {
|
|
2359
|
+
const text = typeof v === "symbol" ? String(v) : String(v ?? "");
|
|
2360
|
+
if (!currentNode) {
|
|
2361
|
+
currentNode = new Text(text);
|
|
2362
|
+
parent2.appendChild(currentNode);
|
|
2363
|
+
} else if (currentNode.nodeType === 3) {
|
|
2364
|
+
currentNode.data = text;
|
|
2365
|
+
} else {
|
|
2366
|
+
const tn = new Text(text);
|
|
2367
|
+
parent2.replaceChild(tn, currentNode);
|
|
2368
|
+
currentNode = tn;
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
});
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
if (Array.isArray(child)) {
|
|
2375
|
+
for (const item of child) {
|
|
2376
|
+
appendChild(parent2, item);
|
|
2377
|
+
}
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
function h(tag, props, ...children2) {
|
|
2382
|
+
if (typeof tag === "function" && tag !== Fragment) {
|
|
2383
|
+
const mergedProps = { ...props ?? {}, children: children2 };
|
|
2384
|
+
return tag(mergedProps);
|
|
2385
|
+
}
|
|
2386
|
+
if (tag === Fragment) {
|
|
2387
|
+
const frag = document.createDocumentFragment();
|
|
2388
|
+
for (const child of children2) {
|
|
2389
|
+
appendChild(frag, child);
|
|
2390
|
+
}
|
|
2391
|
+
return frag;
|
|
2392
|
+
}
|
|
2393
|
+
const tagName = tag;
|
|
2394
|
+
if (hydrating) {
|
|
2395
|
+
return { type: "element", tag: tagName, props: props ?? null, children: children2 };
|
|
2396
|
+
}
|
|
2397
|
+
let el;
|
|
2398
|
+
if (ELEMENT_PROTOS && ELEMENT_PROTOS[tagName]) {
|
|
2399
|
+
el = ELEMENT_PROTOS[tagName].cloneNode(false);
|
|
2400
|
+
} else if (SVG_TAGS.has(tagName)) {
|
|
2401
|
+
el = document.createElementNS(SVG_NS, tagName);
|
|
2402
|
+
} else {
|
|
2403
|
+
el = getProto(tagName).cloneNode(false);
|
|
2404
|
+
}
|
|
2405
|
+
if (props) {
|
|
2406
|
+
let hasDynamic = false;
|
|
2407
|
+
for (const key in props) {
|
|
2408
|
+
if (key === "ref") continue;
|
|
2409
|
+
const value2 = props[key];
|
|
2410
|
+
if (key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.length > 2) {
|
|
2411
|
+
handleEvent(el, key, value2);
|
|
2412
|
+
continue;
|
|
2413
|
+
}
|
|
2414
|
+
if (typeof value2 === "function") {
|
|
2415
|
+
if (!hasDynamic) {
|
|
2416
|
+
el[CACHE_SYM2] = /* @__PURE__ */ Object.create(null);
|
|
2417
|
+
hasDynamic = true;
|
|
2418
|
+
}
|
|
2419
|
+
applyProp(el, key, value2);
|
|
2420
|
+
continue;
|
|
2421
|
+
}
|
|
2422
|
+
applyStaticProp(el, key, value2);
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
const childLen = children2.length;
|
|
2426
|
+
if (childLen === 1) {
|
|
2427
|
+
const only = children2[0];
|
|
2428
|
+
if (typeof only === "string") {
|
|
2429
|
+
el.textContent = only;
|
|
2430
|
+
} else if (typeof only === "number") {
|
|
2431
|
+
el.textContent = String(only);
|
|
2432
|
+
} else {
|
|
2433
|
+
appendChild(el, only);
|
|
2434
|
+
}
|
|
2435
|
+
} else if (childLen > 1) {
|
|
2436
|
+
for (const child of children2) {
|
|
2437
|
+
appendChild(el, child);
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
if (props && typeof props["ref"] === "function") {
|
|
2441
|
+
props["ref"](el);
|
|
2442
|
+
}
|
|
2443
|
+
return el;
|
|
2444
|
+
}
|
|
2445
|
+
function fragment(...children2) {
|
|
2446
|
+
const frag = document.createDocumentFragment();
|
|
2447
|
+
for (const child of children2) {
|
|
2448
|
+
appendChild(frag, child);
|
|
2449
|
+
}
|
|
2450
|
+
return frag;
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
// src/dom/text.ts
|
|
2454
|
+
function createText(value2) {
|
|
2455
|
+
if (typeof value2 === "function") {
|
|
2456
|
+
const node = new Text("");
|
|
2457
|
+
internalEffect(() => {
|
|
2458
|
+
node.data = value2();
|
|
2459
|
+
});
|
|
2460
|
+
return node;
|
|
2461
|
+
}
|
|
2462
|
+
return new Text(value2);
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
// src/dom/mount.ts
|
|
2466
|
+
function mount(component, container) {
|
|
2467
|
+
const target = typeof container === "string" ? document.querySelector(container) : container;
|
|
2468
|
+
if (!target) {
|
|
2469
|
+
throw new Error(`mount: container not found \u2014 "${container}"`);
|
|
2470
|
+
}
|
|
2471
|
+
let disposeRoot;
|
|
2472
|
+
if (target.hasAttribute("data-forma-ssr")) {
|
|
2473
|
+
createRoot((dispose) => {
|
|
2474
|
+
disposeRoot = dispose;
|
|
2475
|
+
hydrateIsland(component, target);
|
|
2476
|
+
});
|
|
2477
|
+
} else {
|
|
2478
|
+
const dom = createRoot((dispose) => {
|
|
2479
|
+
disposeRoot = dispose;
|
|
2480
|
+
return component();
|
|
2481
|
+
});
|
|
2482
|
+
target.innerHTML = "";
|
|
2483
|
+
target.appendChild(dom);
|
|
2484
|
+
}
|
|
2485
|
+
let unmounted = false;
|
|
2486
|
+
return () => {
|
|
2487
|
+
if (unmounted) return;
|
|
2488
|
+
unmounted = true;
|
|
2489
|
+
disposeRoot();
|
|
2490
|
+
target.innerHTML = "";
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// src/dom/switch.ts
|
|
2495
|
+
function createSwitch(value2, cases, fallback) {
|
|
2496
|
+
const startMarker = document.createComment("forma-switch");
|
|
2497
|
+
const endMarker = document.createComment("/forma-switch");
|
|
2498
|
+
const fragment2 = document.createDocumentFragment();
|
|
2499
|
+
fragment2.appendChild(startMarker);
|
|
2500
|
+
fragment2.appendChild(endMarker);
|
|
2501
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2502
|
+
let currentNode = null;
|
|
2503
|
+
let currentMatch = UNSET;
|
|
2504
|
+
const switchDispose = internalEffect(() => {
|
|
2505
|
+
const val = value2();
|
|
2506
|
+
if (val === currentMatch) return;
|
|
2507
|
+
const DEBUG = typeof globalThis.__FORMA_DEBUG__ !== "undefined";
|
|
2508
|
+
if (DEBUG) console.log("[forma:switch] transition", String(currentMatch), "\u2192", String(val));
|
|
2509
|
+
currentMatch = val;
|
|
2510
|
+
const parent2 = startMarker.parentNode;
|
|
2511
|
+
if (!parent2) {
|
|
2512
|
+
if (DEBUG) console.warn("[forma:switch] markers not in DOM yet, skipping");
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
if (currentNode) {
|
|
2516
|
+
if (currentNode.parentNode === parent2) {
|
|
2517
|
+
if (DEBUG) console.log("[forma:switch] removing single node");
|
|
2518
|
+
parent2.removeChild(currentNode);
|
|
2519
|
+
} else if (currentNode.nodeType === 11) {
|
|
2520
|
+
if (DEBUG) console.log("[forma:switch] scooping nodes back into fragment");
|
|
2521
|
+
let scooped = 0;
|
|
2522
|
+
while (startMarker.nextSibling && startMarker.nextSibling !== endMarker) {
|
|
2523
|
+
currentNode.appendChild(startMarker.nextSibling);
|
|
2524
|
+
scooped++;
|
|
2525
|
+
}
|
|
2526
|
+
if (DEBUG) console.log("[forma:switch] scooped", scooped, "nodes back into fragment");
|
|
2527
|
+
} else {
|
|
2528
|
+
if (DEBUG) console.log("[forma:switch] clearing detached node between markers");
|
|
2529
|
+
while (startMarker.nextSibling && startMarker.nextSibling !== endMarker) {
|
|
2530
|
+
parent2.removeChild(startMarker.nextSibling);
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
const matchedCase = cases.find((c) => c.match === val);
|
|
2535
|
+
if (matchedCase) {
|
|
2536
|
+
let entry = cache.get(val);
|
|
2537
|
+
if (!entry) {
|
|
2538
|
+
let branchDispose;
|
|
2539
|
+
const node = createRoot((dispose) => {
|
|
2540
|
+
branchDispose = dispose;
|
|
2541
|
+
return untrack(() => matchedCase.render());
|
|
2542
|
+
});
|
|
2543
|
+
entry = { node, dispose: branchDispose };
|
|
2544
|
+
cache.set(val, entry);
|
|
2545
|
+
if (DEBUG) console.log("[forma:switch] rendered new branch for", String(val), "\u2192", node.nodeName, "type", node.nodeType);
|
|
2546
|
+
} else {
|
|
2547
|
+
if (DEBUG) console.log("[forma:switch] reusing cached branch for", String(val), "\u2192", entry.node.nodeName, "type", entry.node.nodeType, "childNodes", entry.node.childNodes?.length);
|
|
2548
|
+
}
|
|
2549
|
+
currentNode = entry.node;
|
|
2550
|
+
} else {
|
|
2551
|
+
currentNode = fallback?.() ?? null;
|
|
2552
|
+
if (DEBUG) console.log("[forma:switch] no match, using fallback");
|
|
2553
|
+
}
|
|
2554
|
+
if (currentNode) {
|
|
2555
|
+
parent2.insertBefore(currentNode, endMarker);
|
|
2556
|
+
if (DEBUG) console.log("[forma:switch] inserted", currentNode.nodeName, "before end marker");
|
|
2557
|
+
}
|
|
2558
|
+
});
|
|
2559
|
+
fragment2.__switchDispose = () => {
|
|
2560
|
+
switchDispose();
|
|
2561
|
+
for (const entry of cache.values()) {
|
|
2562
|
+
entry.dispose();
|
|
2563
|
+
}
|
|
2564
|
+
cache.clear();
|
|
2565
|
+
};
|
|
2566
|
+
return fragment2;
|
|
2567
|
+
}
|
|
2568
|
+
var UNSET = /* @__PURE__ */ Symbol("unset");
|
|
2569
|
+
|
|
2570
|
+
// src/dom/portal.ts
|
|
2571
|
+
function createPortal(children2, target) {
|
|
2572
|
+
const placeholder = document.createComment("forma-portal");
|
|
2573
|
+
const resolvedTarget = typeof target === "string" ? document.querySelector(target) : target ?? document.body;
|
|
2574
|
+
if (!resolvedTarget) {
|
|
2575
|
+
throw new Error(`createPortal: target not found: ${target}`);
|
|
2576
|
+
}
|
|
2577
|
+
let mountedNode = null;
|
|
2578
|
+
const removeMountedNode = () => {
|
|
2579
|
+
if (mountedNode && mountedNode.parentNode === resolvedTarget) {
|
|
2580
|
+
resolvedTarget.removeChild(mountedNode);
|
|
2581
|
+
}
|
|
2582
|
+
mountedNode = null;
|
|
2583
|
+
};
|
|
2584
|
+
createEffect(() => {
|
|
2585
|
+
const node = children2();
|
|
2586
|
+
removeMountedNode();
|
|
2587
|
+
mountedNode = node;
|
|
2588
|
+
resolvedTarget.appendChild(node);
|
|
2589
|
+
return () => {
|
|
2590
|
+
removeMountedNode();
|
|
2591
|
+
};
|
|
2592
|
+
});
|
|
2593
|
+
return placeholder;
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
// src/dom/error-boundary.ts
|
|
2597
|
+
function createErrorBoundary(tryFn, catchFn) {
|
|
2598
|
+
const startMarker = document.createComment("forma-error-boundary");
|
|
2599
|
+
const endMarker = document.createComment("/forma-error-boundary");
|
|
2600
|
+
const fragment2 = document.createDocumentFragment();
|
|
2601
|
+
fragment2.appendChild(startMarker);
|
|
2602
|
+
fragment2.appendChild(endMarker);
|
|
2603
|
+
const [retryCount, setRetryCount] = createSignal(0);
|
|
2604
|
+
let currentNode = null;
|
|
2605
|
+
internalEffect(() => {
|
|
2606
|
+
retryCount();
|
|
2607
|
+
const parent2 = startMarker.parentNode;
|
|
2608
|
+
if (!parent2) return;
|
|
2609
|
+
if (currentNode && currentNode.parentNode === parent2) {
|
|
2610
|
+
parent2.removeChild(currentNode);
|
|
2611
|
+
}
|
|
2612
|
+
try {
|
|
2613
|
+
currentNode = tryFn();
|
|
2614
|
+
} catch (e) {
|
|
2615
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
2616
|
+
const retry = () => setRetryCount((c) => c + 1);
|
|
2617
|
+
currentNode = catchFn(error, retry);
|
|
2618
|
+
}
|
|
2619
|
+
if (currentNode) {
|
|
2620
|
+
parent2.insertBefore(currentNode, endMarker);
|
|
2621
|
+
}
|
|
2622
|
+
});
|
|
2623
|
+
return fragment2;
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
// src/dom/suspense.ts
|
|
2627
|
+
function createSuspense(fallback, children2) {
|
|
2628
|
+
const startMarker = document.createComment("forma-suspense");
|
|
2629
|
+
const endMarker = document.createComment("/forma-suspense");
|
|
2630
|
+
const fragment2 = document.createDocumentFragment();
|
|
2631
|
+
fragment2.appendChild(startMarker);
|
|
2632
|
+
fragment2.appendChild(endMarker);
|
|
2633
|
+
const [pending, setPending] = createSignal(0);
|
|
2634
|
+
let currentNode = null;
|
|
2635
|
+
let resolvedNode = null;
|
|
2636
|
+
let fallbackNode = null;
|
|
2637
|
+
const ctx = {
|
|
2638
|
+
increment() {
|
|
2639
|
+
setPending((p) => p + 1);
|
|
2640
|
+
},
|
|
2641
|
+
decrement() {
|
|
2642
|
+
setPending((p) => Math.max(0, p - 1));
|
|
2643
|
+
}
|
|
2644
|
+
};
|
|
2645
|
+
pushSuspenseContext(ctx);
|
|
2646
|
+
try {
|
|
2647
|
+
resolvedNode = children2();
|
|
2648
|
+
} finally {
|
|
2649
|
+
popSuspenseContext();
|
|
2650
|
+
}
|
|
2651
|
+
internalEffect(() => {
|
|
2652
|
+
const parent2 = startMarker.parentNode;
|
|
2653
|
+
if (!parent2) return;
|
|
2654
|
+
const isPending = pending() > 0;
|
|
2655
|
+
const newNode = isPending ? fallbackNode ??= fallback() : resolvedNode;
|
|
2656
|
+
if (newNode === currentNode) return;
|
|
2657
|
+
if (currentNode && currentNode.parentNode === parent2) {
|
|
2658
|
+
parent2.removeChild(currentNode);
|
|
2659
|
+
}
|
|
2660
|
+
if (newNode) {
|
|
2661
|
+
parent2.insertBefore(newNode, endMarker);
|
|
2662
|
+
}
|
|
2663
|
+
currentNode = newNode;
|
|
2664
|
+
});
|
|
2665
|
+
return fragment2;
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
// src/dom/activate.ts
|
|
2669
|
+
var FORBIDDEN_PROP_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
2670
|
+
function sanitizeProps(obj) {
|
|
2671
|
+
for (const key of FORBIDDEN_PROP_KEYS) {
|
|
2672
|
+
if (key in obj) delete obj[key];
|
|
2673
|
+
}
|
|
2674
|
+
return obj;
|
|
2675
|
+
}
|
|
2676
|
+
function loadIslandProps(root, id, sharedProps) {
|
|
2677
|
+
const inline = root.getAttribute("data-forma-props");
|
|
2678
|
+
if (inline) {
|
|
2679
|
+
return sanitizeProps(JSON.parse(inline));
|
|
2680
|
+
}
|
|
2681
|
+
if (sharedProps && String(id) in sharedProps) {
|
|
2682
|
+
return sanitizeProps(sharedProps[String(id)]);
|
|
2683
|
+
}
|
|
2684
|
+
return null;
|
|
2685
|
+
}
|
|
2686
|
+
function activateIslands(registry) {
|
|
2687
|
+
const scriptBlock = document.getElementById("__forma_islands");
|
|
2688
|
+
const sharedProps = scriptBlock ? JSON.parse(scriptBlock.textContent) : null;
|
|
2689
|
+
const islands = document.querySelectorAll("[data-forma-island]");
|
|
2690
|
+
for (const root of islands) {
|
|
2691
|
+
const id = parseInt(root.getAttribute("data-forma-island"), 10);
|
|
2692
|
+
const componentName = root.getAttribute("data-forma-component");
|
|
2693
|
+
const hydrateFn = registry[componentName];
|
|
2694
|
+
if (!hydrateFn) {
|
|
2695
|
+
if (__DEV__) console.warn(`[forma] No hydrate function for island "${componentName}" (id=${id})`);
|
|
2696
|
+
root.setAttribute("data-forma-status", "error");
|
|
2697
|
+
continue;
|
|
2698
|
+
}
|
|
2699
|
+
const trigger2 = root.getAttribute("data-forma-hydrate") || "load";
|
|
2700
|
+
if (trigger2 === "visible") {
|
|
2701
|
+
const observer = new IntersectionObserver(
|
|
2702
|
+
(entries) => {
|
|
2703
|
+
for (const entry of entries) {
|
|
2704
|
+
if (!entry.isIntersecting) continue;
|
|
2705
|
+
observer.disconnect();
|
|
2706
|
+
hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps);
|
|
2707
|
+
}
|
|
2708
|
+
},
|
|
2709
|
+
{ rootMargin: "200px" }
|
|
2710
|
+
);
|
|
2711
|
+
observer.observe(root);
|
|
2712
|
+
} else if (trigger2 === "idle") {
|
|
2713
|
+
const hydrate = () => hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps);
|
|
2714
|
+
if (typeof requestIdleCallback === "function") {
|
|
2715
|
+
requestIdleCallback(hydrate);
|
|
2716
|
+
} else {
|
|
2717
|
+
setTimeout(hydrate, 200);
|
|
2718
|
+
}
|
|
2719
|
+
} else if (trigger2 === "interaction") {
|
|
2720
|
+
const hydrate = () => {
|
|
2721
|
+
root.removeEventListener("pointerdown", hydrate, true);
|
|
2722
|
+
root.removeEventListener("focusin", hydrate, true);
|
|
2723
|
+
hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps);
|
|
2724
|
+
};
|
|
2725
|
+
root.addEventListener("pointerdown", hydrate, { capture: true, once: true });
|
|
2726
|
+
root.addEventListener("focusin", hydrate, { capture: true, once: true });
|
|
2727
|
+
} else {
|
|
2728
|
+
hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
function deactivateIsland(el) {
|
|
2733
|
+
const dispose = el.__formaDispose;
|
|
2734
|
+
if (typeof dispose === "function") {
|
|
2735
|
+
dispose();
|
|
2736
|
+
delete el.__formaDispose;
|
|
2737
|
+
el.setAttribute("data-forma-status", "disposed");
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
function deactivateAllIslands(root = document) {
|
|
2741
|
+
const islands = root.querySelectorAll('[data-forma-status="active"]');
|
|
2742
|
+
for (const island of islands) {
|
|
2743
|
+
deactivateIsland(island);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
function hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps) {
|
|
2747
|
+
try {
|
|
2748
|
+
const props = loadIslandProps(root, id, sharedProps);
|
|
2749
|
+
root.setAttribute("data-forma-status", "hydrating");
|
|
2750
|
+
let activeRoot = root;
|
|
2751
|
+
createRoot((dispose) => {
|
|
2752
|
+
activeRoot = hydrateIsland(() => hydrateFn(root, props), root);
|
|
2753
|
+
activeRoot.__formaDispose = dispose;
|
|
2754
|
+
});
|
|
2755
|
+
activeRoot.setAttribute("data-forma-status", "active");
|
|
2756
|
+
} catch (err) {
|
|
2757
|
+
if (__DEV__) console.error(`[forma] Island "${componentName}" (id=${id}) failed:`, err);
|
|
2758
|
+
root.setAttribute("data-forma-status", "error");
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
// src/component/define.ts
|
|
2763
|
+
var currentLifecycleContext = null;
|
|
2764
|
+
var lifecycleStack = [];
|
|
2765
|
+
function pushLifecycleContext(ctx) {
|
|
2766
|
+
lifecycleStack.push(currentLifecycleContext);
|
|
2767
|
+
currentLifecycleContext = ctx;
|
|
2768
|
+
}
|
|
2769
|
+
function popLifecycleContext() {
|
|
2770
|
+
currentLifecycleContext = lifecycleStack.pop() ?? null;
|
|
2771
|
+
}
|
|
2772
|
+
function onMount(fn) {
|
|
2773
|
+
if (currentLifecycleContext === null) {
|
|
2774
|
+
throw new Error("onMount() must be called inside a component setup function");
|
|
2775
|
+
}
|
|
2776
|
+
currentLifecycleContext.mountCallbacks.push(fn);
|
|
2777
|
+
}
|
|
2778
|
+
function onUnmount(fn) {
|
|
2779
|
+
if (currentLifecycleContext === null) {
|
|
2780
|
+
throw new Error("onUnmount() must be called inside a component setup function");
|
|
2781
|
+
}
|
|
2782
|
+
currentLifecycleContext.unmountCallbacks.push(fn);
|
|
2783
|
+
}
|
|
2784
|
+
var DISPOSE_KEY = /* @__PURE__ */ Symbol("forma:component:dispose");
|
|
2785
|
+
function defineComponent(setupOrDef) {
|
|
2786
|
+
const setup = typeof setupOrDef === "function" ? setupOrDef : setupOrDef.setup;
|
|
2787
|
+
const name = typeof setupOrDef === "function" ? void 0 : setupOrDef.name;
|
|
2788
|
+
return function componentFactory() {
|
|
2789
|
+
const ctx = {
|
|
2790
|
+
disposers: [],
|
|
2791
|
+
mountCallbacks: [],
|
|
2792
|
+
unmountCallbacks: []
|
|
2793
|
+
};
|
|
2794
|
+
pushLifecycleContext(ctx);
|
|
2795
|
+
let dom;
|
|
2796
|
+
try {
|
|
2797
|
+
dom = setup();
|
|
2798
|
+
} finally {
|
|
2799
|
+
popLifecycleContext();
|
|
2800
|
+
}
|
|
2801
|
+
const dispose = () => {
|
|
2802
|
+
for (const cb of ctx.unmountCallbacks) {
|
|
2803
|
+
try {
|
|
2804
|
+
cb();
|
|
2805
|
+
} catch (e) {
|
|
2806
|
+
reportError(e, "onUnmount");
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
for (const d of ctx.disposers) {
|
|
2810
|
+
try {
|
|
2811
|
+
d();
|
|
2812
|
+
} catch (e) {
|
|
2813
|
+
reportError(e, "component disposer");
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
ctx.disposers.length = 0;
|
|
2817
|
+
ctx.mountCallbacks.length = 0;
|
|
2818
|
+
ctx.unmountCallbacks.length = 0;
|
|
2819
|
+
};
|
|
2820
|
+
dom[DISPOSE_KEY] = dispose;
|
|
2821
|
+
for (const cb of ctx.mountCallbacks) {
|
|
2822
|
+
try {
|
|
2823
|
+
const cleanup2 = cb();
|
|
2824
|
+
if (typeof cleanup2 === "function") {
|
|
2825
|
+
ctx.unmountCallbacks.push(cleanup2);
|
|
2826
|
+
}
|
|
2827
|
+
} catch (e) {
|
|
2828
|
+
reportError(e, "onMount");
|
|
2829
|
+
}
|
|
2830
|
+
}
|
|
2831
|
+
return dom;
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
function disposeComponent(dom) {
|
|
2835
|
+
const disposable = dom;
|
|
2836
|
+
if (typeof disposable[DISPOSE_KEY] === "function") {
|
|
2837
|
+
disposable[DISPOSE_KEY]();
|
|
2838
|
+
delete disposable[DISPOSE_KEY];
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
function trackDisposer(dispose) {
|
|
2842
|
+
if (currentLifecycleContext !== null) {
|
|
2843
|
+
currentLifecycleContext.disposers.push(dispose);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
// src/component/context.ts
|
|
2848
|
+
var contextStacks = /* @__PURE__ */ new Map();
|
|
2849
|
+
function createContext(defaultValue) {
|
|
2850
|
+
return {
|
|
2851
|
+
id: /* @__PURE__ */ Symbol("forma:context"),
|
|
2852
|
+
defaultValue
|
|
2853
|
+
};
|
|
2854
|
+
}
|
|
2855
|
+
function provide(ctx, value2) {
|
|
2856
|
+
let stack = contextStacks.get(ctx.id);
|
|
2857
|
+
if (stack === void 0) {
|
|
2858
|
+
stack = [];
|
|
2859
|
+
contextStacks.set(ctx.id, stack);
|
|
2860
|
+
}
|
|
2861
|
+
stack.push(value2);
|
|
2862
|
+
}
|
|
2863
|
+
function inject(ctx) {
|
|
2864
|
+
const stack = contextStacks.get(ctx.id);
|
|
2865
|
+
if (stack === void 0 || stack.length === 0) {
|
|
2866
|
+
return ctx.defaultValue;
|
|
2867
|
+
}
|
|
2868
|
+
return stack[stack.length - 1];
|
|
2869
|
+
}
|
|
2870
|
+
function unprovide(ctx) {
|
|
2871
|
+
const stack = contextStacks.get(ctx.id);
|
|
2872
|
+
if (stack !== void 0 && stack.length > 0) {
|
|
2873
|
+
stack.pop();
|
|
2874
|
+
if (stack.length === 0) {
|
|
2875
|
+
contextStacks.delete(ctx.id);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
// src/state/store.ts
|
|
2881
|
+
var RAW = /* @__PURE__ */ Symbol("forma-raw");
|
|
2882
|
+
var PROXY = /* @__PURE__ */ Symbol("forma-proxy");
|
|
2883
|
+
var ARRAY_MUTATORS = /* @__PURE__ */ new Set([
|
|
2884
|
+
"push",
|
|
2885
|
+
"pop",
|
|
2886
|
+
"shift",
|
|
2887
|
+
"unshift",
|
|
2888
|
+
"splice",
|
|
2889
|
+
"sort",
|
|
2890
|
+
"reverse",
|
|
2891
|
+
"fill",
|
|
2892
|
+
"copyWithin"
|
|
2893
|
+
]);
|
|
2894
|
+
function shouldWrap(v) {
|
|
2895
|
+
if (v == null || typeof v !== "object") return false;
|
|
2896
|
+
if (v instanceof Date || v instanceof RegExp || v instanceof Map || v instanceof Set || v instanceof WeakMap || v instanceof WeakSet || v instanceof Error || v instanceof Promise) {
|
|
2897
|
+
return false;
|
|
2898
|
+
}
|
|
2899
|
+
if (v[PROXY]) return false;
|
|
2900
|
+
return true;
|
|
2901
|
+
}
|
|
2902
|
+
function deepClone(obj, seen) {
|
|
2903
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
2904
|
+
if (!seen) seen = /* @__PURE__ */ new WeakSet();
|
|
2905
|
+
if (seen.has(obj)) return obj;
|
|
2906
|
+
seen.add(obj);
|
|
2907
|
+
if (Array.isArray(obj)) return obj.map((item) => deepClone(item, seen));
|
|
2908
|
+
const out = {};
|
|
2909
|
+
for (const key of Object.keys(obj)) {
|
|
2910
|
+
out[key] = deepClone(obj[key], seen);
|
|
2911
|
+
}
|
|
2912
|
+
return out;
|
|
2913
|
+
}
|
|
2914
|
+
function createStore(initial) {
|
|
2915
|
+
const signals = /* @__PURE__ */ new Map();
|
|
2916
|
+
const children2 = /* @__PURE__ */ new Map();
|
|
2917
|
+
function registerChild(path) {
|
|
2918
|
+
const lastDot = path.lastIndexOf(".");
|
|
2919
|
+
if (lastDot === -1) return;
|
|
2920
|
+
const parentPath = path.substring(0, lastDot);
|
|
2921
|
+
let set = children2.get(parentPath);
|
|
2922
|
+
if (!set) {
|
|
2923
|
+
set = /* @__PURE__ */ new Set();
|
|
2924
|
+
children2.set(parentPath, set);
|
|
2925
|
+
}
|
|
2926
|
+
set.add(path);
|
|
2927
|
+
}
|
|
2928
|
+
function getSignal(path, initialValue) {
|
|
2929
|
+
let pair = signals.get(path);
|
|
2930
|
+
if (!pair) {
|
|
2931
|
+
pair = createSignal(initialValue);
|
|
2932
|
+
signals.set(path, pair);
|
|
2933
|
+
registerChild(path);
|
|
2934
|
+
}
|
|
2935
|
+
return pair;
|
|
2936
|
+
}
|
|
2937
|
+
const proxyCache = /* @__PURE__ */ new WeakMap();
|
|
2938
|
+
function invalidateChildren(parentPath) {
|
|
2939
|
+
const childSet = children2.get(parentPath);
|
|
2940
|
+
if (!childSet) return;
|
|
2941
|
+
for (const childPath of childSet) {
|
|
2942
|
+
invalidateChildren(childPath);
|
|
2943
|
+
signals.delete(childPath);
|
|
2944
|
+
children2.delete(childPath);
|
|
2945
|
+
}
|
|
2946
|
+
childSet.clear();
|
|
2947
|
+
}
|
|
2948
|
+
function wrap(raw, basePath) {
|
|
2949
|
+
if (!shouldWrap(raw)) return raw;
|
|
2950
|
+
const cached = proxyCache.get(raw);
|
|
2951
|
+
if (cached) return cached;
|
|
2952
|
+
const isArr = Array.isArray(raw);
|
|
2953
|
+
const basePrefix = basePath ? basePath + "." : "";
|
|
2954
|
+
let lastKey = "";
|
|
2955
|
+
let lastSignal;
|
|
2956
|
+
const proxy = new Proxy(raw, {
|
|
2957
|
+
// -------------------------------------------------------------------
|
|
2958
|
+
// GET
|
|
2959
|
+
// -------------------------------------------------------------------
|
|
2960
|
+
get(target, prop, receiver) {
|
|
2961
|
+
if (prop === RAW) return target;
|
|
2962
|
+
if (prop === PROXY) return true;
|
|
2963
|
+
if (typeof prop === "symbol") {
|
|
2964
|
+
return Reflect.get(target, prop, receiver);
|
|
2965
|
+
}
|
|
2966
|
+
const key = String(prop);
|
|
2967
|
+
const childPath = basePrefix + key;
|
|
2968
|
+
if (isArr && ARRAY_MUTATORS.has(key)) {
|
|
2969
|
+
return (...args) => {
|
|
2970
|
+
let result;
|
|
2971
|
+
batch(() => {
|
|
2972
|
+
const rawArgs = args.map(
|
|
2973
|
+
(a) => a != null && typeof a === "object" && a[RAW] ? a[RAW] : a
|
|
2974
|
+
);
|
|
2975
|
+
result = target[key].apply(target, rawArgs);
|
|
2976
|
+
invalidateChildren(basePath);
|
|
2977
|
+
const [, setLen] = getSignal(
|
|
2978
|
+
basePrefix + "length",
|
|
2979
|
+
target.length
|
|
2980
|
+
);
|
|
2981
|
+
setLen(target.length);
|
|
2982
|
+
});
|
|
2983
|
+
return result;
|
|
2984
|
+
};
|
|
2985
|
+
}
|
|
2986
|
+
if (isArr && key === "length") {
|
|
2987
|
+
const [getter] = getSignal(childPath, target.length);
|
|
2988
|
+
getter();
|
|
2989
|
+
return target.length;
|
|
2990
|
+
}
|
|
2991
|
+
const value2 = Reflect.get(target, prop);
|
|
2992
|
+
let pair;
|
|
2993
|
+
if (key === lastKey && lastSignal) {
|
|
2994
|
+
pair = lastSignal;
|
|
2995
|
+
} else {
|
|
2996
|
+
pair = getSignal(childPath, value2);
|
|
2997
|
+
lastKey = key;
|
|
2998
|
+
lastSignal = pair;
|
|
2999
|
+
}
|
|
3000
|
+
pair[0]();
|
|
3001
|
+
if (shouldWrap(value2)) {
|
|
3002
|
+
return wrap(value2, childPath);
|
|
3003
|
+
}
|
|
3004
|
+
return value2;
|
|
3005
|
+
},
|
|
3006
|
+
// -------------------------------------------------------------------
|
|
3007
|
+
// SET
|
|
3008
|
+
// -------------------------------------------------------------------
|
|
3009
|
+
set(target, prop, value2) {
|
|
3010
|
+
if (typeof prop === "symbol") {
|
|
3011
|
+
return Reflect.set(target, prop, value2);
|
|
3012
|
+
}
|
|
3013
|
+
const key = String(prop);
|
|
3014
|
+
const childPath = basePrefix + key;
|
|
3015
|
+
const rawValue = value2 != null && typeof value2 === "object" && value2[RAW] ? value2[RAW] : value2;
|
|
3016
|
+
Reflect.set(target, prop, rawValue);
|
|
3017
|
+
if (rawValue != null && typeof rawValue === "object") {
|
|
3018
|
+
invalidateChildren(childPath);
|
|
3019
|
+
}
|
|
3020
|
+
if (isArr && key !== "length") {
|
|
3021
|
+
const lengthPath = basePrefix + "length";
|
|
3022
|
+
const lenPair = signals.get(lengthPath);
|
|
3023
|
+
if (lenPair) {
|
|
3024
|
+
lenPair[1](target.length);
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
const [, setter2] = getSignal(childPath, rawValue);
|
|
3028
|
+
setter2(rawValue);
|
|
3029
|
+
return true;
|
|
3030
|
+
},
|
|
3031
|
+
// -------------------------------------------------------------------
|
|
3032
|
+
// HAS — track membership checks
|
|
3033
|
+
// -------------------------------------------------------------------
|
|
3034
|
+
has(target, prop) {
|
|
3035
|
+
if (typeof prop === "symbol") {
|
|
3036
|
+
return Reflect.has(target, prop);
|
|
3037
|
+
}
|
|
3038
|
+
const key = String(prop);
|
|
3039
|
+
const childPath = basePrefix + key;
|
|
3040
|
+
const [getter] = getSignal(childPath, Reflect.get(target, prop));
|
|
3041
|
+
getter();
|
|
3042
|
+
return Reflect.has(target, prop);
|
|
3043
|
+
},
|
|
3044
|
+
// -------------------------------------------------------------------
|
|
3045
|
+
// OWNKEYS — return keys from the raw target
|
|
3046
|
+
// -------------------------------------------------------------------
|
|
3047
|
+
ownKeys(target) {
|
|
3048
|
+
return Reflect.ownKeys(target);
|
|
3049
|
+
},
|
|
3050
|
+
// -------------------------------------------------------------------
|
|
3051
|
+
// GETOWNPROPERTYDESCRIPTOR — needed for Object.keys / spread / ...
|
|
3052
|
+
// -------------------------------------------------------------------
|
|
3053
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
3054
|
+
return Object.getOwnPropertyDescriptor(target, prop);
|
|
3055
|
+
},
|
|
3056
|
+
// -------------------------------------------------------------------
|
|
3057
|
+
// DELETEPROPERTY — clean up signals when a key is removed
|
|
3058
|
+
// -------------------------------------------------------------------
|
|
3059
|
+
deleteProperty(target, prop) {
|
|
3060
|
+
if (typeof prop === "symbol") {
|
|
3061
|
+
return Reflect.deleteProperty(target, prop);
|
|
3062
|
+
}
|
|
3063
|
+
const key = String(prop);
|
|
3064
|
+
const childPath = basePrefix + key;
|
|
3065
|
+
const result = Reflect.deleteProperty(target, prop);
|
|
3066
|
+
invalidateChildren(childPath);
|
|
3067
|
+
signals.delete(childPath);
|
|
3068
|
+
const parentPath = basePath;
|
|
3069
|
+
if (parentPath !== void 0) {
|
|
3070
|
+
const parentSet = children2.get(parentPath);
|
|
3071
|
+
if (parentSet) {
|
|
3072
|
+
parentSet.delete(childPath);
|
|
3073
|
+
if (parentSet.size === 0) children2.delete(parentPath);
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
children2.delete(childPath);
|
|
3077
|
+
return result;
|
|
3078
|
+
}
|
|
3079
|
+
});
|
|
3080
|
+
proxyCache.set(raw, proxy);
|
|
3081
|
+
return proxy;
|
|
3082
|
+
}
|
|
3083
|
+
const rootProxy = wrap(initial, "");
|
|
3084
|
+
function getCurrentSnapshot() {
|
|
3085
|
+
return untrack(() => deepClone(initial));
|
|
3086
|
+
}
|
|
3087
|
+
const setter = (partial) => {
|
|
3088
|
+
const updates = typeof partial === "function" ? partial(getCurrentSnapshot()) : partial;
|
|
3089
|
+
batch(() => {
|
|
3090
|
+
for (const key of Object.keys(updates)) {
|
|
3091
|
+
rootProxy[key] = updates[key];
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
3094
|
+
};
|
|
3095
|
+
return [rootProxy, setter];
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
// src/state/history.ts
|
|
3099
|
+
function createHistory(source, options) {
|
|
3100
|
+
const [sourceGet, sourceSet] = source;
|
|
3101
|
+
const maxLength = options?.maxLength ?? 100;
|
|
3102
|
+
let _stack = [sourceGet()];
|
|
3103
|
+
let _cursor = 0;
|
|
3104
|
+
const [stackSignal, setStackSignal] = createSignal([..._stack]);
|
|
3105
|
+
const [cursorSignal, setCursorSignal] = createSignal(_cursor);
|
|
3106
|
+
const [stackLenSignal, setStackLenSignal] = createSignal(_stack.length);
|
|
3107
|
+
function syncSignals() {
|
|
3108
|
+
batch(() => {
|
|
3109
|
+
setStackSignal([..._stack]);
|
|
3110
|
+
setCursorSignal(_cursor);
|
|
3111
|
+
setStackLenSignal(_stack.length);
|
|
3112
|
+
});
|
|
3113
|
+
}
|
|
3114
|
+
let ignoreNext = false;
|
|
3115
|
+
let isFirstRun = true;
|
|
3116
|
+
internalEffect(() => {
|
|
3117
|
+
const value2 = sourceGet();
|
|
3118
|
+
if (isFirstRun) {
|
|
3119
|
+
isFirstRun = false;
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
if (ignoreNext) {
|
|
3123
|
+
ignoreNext = false;
|
|
3124
|
+
return;
|
|
3125
|
+
}
|
|
3126
|
+
_stack = _stack.slice(0, _cursor + 1);
|
|
3127
|
+
_stack.push(value2);
|
|
3128
|
+
if (_stack.length > maxLength) {
|
|
3129
|
+
_stack.splice(0, _stack.length - maxLength);
|
|
3130
|
+
}
|
|
3131
|
+
_cursor = _stack.length - 1;
|
|
3132
|
+
syncSignals();
|
|
3133
|
+
});
|
|
3134
|
+
const canUndo = () => cursorSignal() > 0;
|
|
3135
|
+
const canRedo = () => cursorSignal() < stackLenSignal() - 1;
|
|
3136
|
+
const undo = () => {
|
|
3137
|
+
if (_cursor <= 0) return;
|
|
3138
|
+
_cursor--;
|
|
3139
|
+
ignoreNext = true;
|
|
3140
|
+
sourceSet(_stack[_cursor]);
|
|
3141
|
+
syncSignals();
|
|
3142
|
+
};
|
|
3143
|
+
const redo = () => {
|
|
3144
|
+
if (_cursor >= _stack.length - 1) return;
|
|
3145
|
+
_cursor++;
|
|
3146
|
+
ignoreNext = true;
|
|
3147
|
+
sourceSet(_stack[_cursor]);
|
|
3148
|
+
syncSignals();
|
|
3149
|
+
};
|
|
3150
|
+
const clear = () => {
|
|
3151
|
+
const currentValue = sourceGet();
|
|
3152
|
+
_stack = [currentValue];
|
|
3153
|
+
_cursor = 0;
|
|
3154
|
+
syncSignals();
|
|
3155
|
+
};
|
|
3156
|
+
return {
|
|
3157
|
+
undo,
|
|
3158
|
+
redo,
|
|
3159
|
+
canUndo,
|
|
3160
|
+
canRedo,
|
|
3161
|
+
history: () => stackSignal(),
|
|
3162
|
+
cursor: () => cursorSignal(),
|
|
3163
|
+
clear
|
|
3164
|
+
};
|
|
3165
|
+
}
|
|
3166
|
+
|
|
3167
|
+
// src/state/persist.ts
|
|
3168
|
+
function persist(source, key, options) {
|
|
3169
|
+
const [sourceGet, sourceSet] = source;
|
|
3170
|
+
const storage = options?.storage ?? globalThis.localStorage;
|
|
3171
|
+
const serialize = options?.serialize ?? JSON.stringify;
|
|
3172
|
+
const deserialize = options?.deserialize ?? JSON.parse;
|
|
3173
|
+
const validate = options?.validate;
|
|
3174
|
+
try {
|
|
3175
|
+
const stored = storage.getItem(key);
|
|
3176
|
+
if (stored !== null) {
|
|
3177
|
+
const value2 = deserialize(stored);
|
|
3178
|
+
if (!validate || validate(value2)) {
|
|
3179
|
+
sourceSet(value2);
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
} catch {
|
|
3183
|
+
}
|
|
3184
|
+
internalEffect(() => {
|
|
3185
|
+
const value2 = sourceGet();
|
|
3186
|
+
try {
|
|
3187
|
+
const serialized = serialize(value2);
|
|
3188
|
+
storage.setItem(key, serialized);
|
|
3189
|
+
} catch {
|
|
3190
|
+
}
|
|
3191
|
+
});
|
|
3192
|
+
}
|
|
3193
|
+
|
|
3194
|
+
// src/events/bus.ts
|
|
3195
|
+
function createBus() {
|
|
3196
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
3197
|
+
function getHandlers(event) {
|
|
3198
|
+
let set = listeners.get(event);
|
|
3199
|
+
if (!set) {
|
|
3200
|
+
set = /* @__PURE__ */ new Set();
|
|
3201
|
+
listeners.set(event, set);
|
|
3202
|
+
}
|
|
3203
|
+
return set;
|
|
3204
|
+
}
|
|
3205
|
+
function on2(event, handler) {
|
|
3206
|
+
const set = getHandlers(event);
|
|
3207
|
+
set.add(handler);
|
|
3208
|
+
return () => {
|
|
3209
|
+
set.delete(handler);
|
|
3210
|
+
};
|
|
3211
|
+
}
|
|
3212
|
+
function once(event, handler) {
|
|
3213
|
+
const wrapper = (payload) => {
|
|
3214
|
+
off(event, wrapper);
|
|
3215
|
+
handler(payload);
|
|
3216
|
+
};
|
|
3217
|
+
return on2(event, wrapper);
|
|
3218
|
+
}
|
|
3219
|
+
function emit(event, payload) {
|
|
3220
|
+
const set = listeners.get(event);
|
|
3221
|
+
if (set) {
|
|
3222
|
+
for (const handler of [...set]) {
|
|
3223
|
+
try {
|
|
3224
|
+
handler(payload);
|
|
3225
|
+
} catch (e) {
|
|
3226
|
+
console.error(`[forma] Bus handler error on "${String(event)}":`, e);
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
function off(event, handler) {
|
|
3232
|
+
const set = listeners.get(event);
|
|
3233
|
+
if (set) {
|
|
3234
|
+
set.delete(handler);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
function clear() {
|
|
3238
|
+
listeners.clear();
|
|
3239
|
+
}
|
|
3240
|
+
return { on: on2, once, emit, off, clear };
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
// src/events/delegate.ts
|
|
3244
|
+
function delegate(container, selector, event, handler, options) {
|
|
3245
|
+
const listener = (e) => {
|
|
3246
|
+
const target = e.target;
|
|
3247
|
+
if (!(target instanceof HTMLElement)) return;
|
|
3248
|
+
const root = container instanceof Document ? container.documentElement : container;
|
|
3249
|
+
const matched = target.closest(selector);
|
|
3250
|
+
if (matched instanceof HTMLElement && root.contains(matched)) {
|
|
3251
|
+
handler(e, matched);
|
|
3252
|
+
}
|
|
3253
|
+
};
|
|
3254
|
+
container.addEventListener(event, listener, options);
|
|
3255
|
+
return () => {
|
|
3256
|
+
container.removeEventListener(event, listener, options);
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
|
|
3260
|
+
// src/events/keyboard.ts
|
|
3261
|
+
function parseCombo(combo) {
|
|
3262
|
+
const parts = combo.toLowerCase().split("+").map((p) => p.trim());
|
|
3263
|
+
const modifiers = {
|
|
3264
|
+
ctrl: false,
|
|
3265
|
+
shift: false,
|
|
3266
|
+
alt: false,
|
|
3267
|
+
meta: false,
|
|
3268
|
+
key: ""
|
|
3269
|
+
};
|
|
3270
|
+
for (const part of parts) {
|
|
3271
|
+
switch (part) {
|
|
3272
|
+
case "ctrl":
|
|
3273
|
+
case "control":
|
|
3274
|
+
modifiers.ctrl = true;
|
|
3275
|
+
break;
|
|
3276
|
+
case "shift":
|
|
3277
|
+
modifiers.shift = true;
|
|
3278
|
+
break;
|
|
3279
|
+
case "alt":
|
|
3280
|
+
modifiers.alt = true;
|
|
3281
|
+
break;
|
|
3282
|
+
case "meta":
|
|
3283
|
+
case "cmd":
|
|
3284
|
+
case "command":
|
|
3285
|
+
modifiers.meta = true;
|
|
3286
|
+
break;
|
|
3287
|
+
default:
|
|
3288
|
+
modifiers.key = part;
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
return modifiers;
|
|
3292
|
+
}
|
|
3293
|
+
function matchesCombo(e, parsed) {
|
|
3294
|
+
if (e.ctrlKey !== parsed.ctrl) return false;
|
|
3295
|
+
if (e.shiftKey !== parsed.shift) return false;
|
|
3296
|
+
if (e.altKey !== parsed.alt) return false;
|
|
3297
|
+
if (e.metaKey !== parsed.meta) return false;
|
|
3298
|
+
return e.key.toLowerCase() === parsed.key;
|
|
3299
|
+
}
|
|
3300
|
+
function onKey(combo, handler, options) {
|
|
3301
|
+
const target = options?.target ?? document;
|
|
3302
|
+
const shouldPreventDefault = options?.preventDefault ?? true;
|
|
3303
|
+
const parsed = parseCombo(combo);
|
|
3304
|
+
const listener = (e) => {
|
|
3305
|
+
if (!(e instanceof KeyboardEvent)) return;
|
|
3306
|
+
if (matchesCombo(e, parsed)) {
|
|
3307
|
+
if (shouldPreventDefault) {
|
|
3308
|
+
e.preventDefault();
|
|
3309
|
+
}
|
|
3310
|
+
handler(e);
|
|
3311
|
+
}
|
|
3312
|
+
};
|
|
3313
|
+
target.addEventListener("keydown", listener);
|
|
3314
|
+
return () => {
|
|
3315
|
+
target.removeEventListener("keydown", listener);
|
|
3316
|
+
};
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3319
|
+
// src/dom-utils/query.ts
|
|
3320
|
+
function $(selector, parent2) {
|
|
3321
|
+
return (parent2 ?? document).querySelector(selector);
|
|
3322
|
+
}
|
|
3323
|
+
function $$(selector, parent2) {
|
|
3324
|
+
return Array.from((parent2 ?? document).querySelectorAll(selector));
|
|
3325
|
+
}
|
|
3326
|
+
|
|
3327
|
+
// src/dom-utils/mutate.ts
|
|
3328
|
+
function addClass(el, ...classes) {
|
|
3329
|
+
el.classList.add(...classes);
|
|
3330
|
+
}
|
|
3331
|
+
function removeClass(el, ...classes) {
|
|
3332
|
+
el.classList.remove(...classes);
|
|
3333
|
+
}
|
|
3334
|
+
function toggleClass(el, className, force) {
|
|
3335
|
+
return el.classList.toggle(className, force);
|
|
3336
|
+
}
|
|
3337
|
+
function setStyle(el, styles) {
|
|
3338
|
+
for (const [key, value2] of Object.entries(styles)) {
|
|
3339
|
+
if (value2 !== void 0) {
|
|
3340
|
+
el.style[key] = value2;
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
function setAttr(el, attrs) {
|
|
3345
|
+
for (const [name, value2] of Object.entries(attrs)) {
|
|
3346
|
+
if (value2 === false || value2 === null) {
|
|
3347
|
+
el.removeAttribute(name);
|
|
3348
|
+
} else if (value2 === true) {
|
|
3349
|
+
el.setAttribute(name, "");
|
|
3350
|
+
} else {
|
|
3351
|
+
el.setAttribute(name, value2);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
function setText(el, text) {
|
|
3356
|
+
el.textContent = text;
|
|
3357
|
+
}
|
|
3358
|
+
function setHTML(el, html) {
|
|
3359
|
+
el.innerHTML = html;
|
|
3360
|
+
}
|
|
3361
|
+
function setHTMLUnsafe(el, html) {
|
|
3362
|
+
el.innerHTML = html;
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
// src/dom-utils/traverse.ts
|
|
3366
|
+
function closest(el, selector) {
|
|
3367
|
+
return el.closest(selector);
|
|
3368
|
+
}
|
|
3369
|
+
function children(el, selector) {
|
|
3370
|
+
const all = Array.from(el.children);
|
|
3371
|
+
if (!selector) return all;
|
|
3372
|
+
return all.filter((child) => child.matches(selector));
|
|
3373
|
+
}
|
|
3374
|
+
function siblings(el, selector) {
|
|
3375
|
+
const parentEl = el.parentElement;
|
|
3376
|
+
if (!parentEl) return [];
|
|
3377
|
+
const all = Array.from(parentEl.children);
|
|
3378
|
+
const sibs = all.filter((child) => child !== el);
|
|
3379
|
+
if (!selector) return sibs;
|
|
3380
|
+
return sibs.filter((child) => child.matches(selector));
|
|
3381
|
+
}
|
|
3382
|
+
function parent(el) {
|
|
3383
|
+
return el.parentElement;
|
|
3384
|
+
}
|
|
3385
|
+
function nextSibling(el, selector) {
|
|
3386
|
+
let sib = el.nextElementSibling;
|
|
3387
|
+
while (sib) {
|
|
3388
|
+
if (sib instanceof HTMLElement) {
|
|
3389
|
+
if (!selector || sib.matches(selector)) {
|
|
3390
|
+
return sib;
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
sib = sib.nextElementSibling;
|
|
3394
|
+
}
|
|
3395
|
+
return null;
|
|
3396
|
+
}
|
|
3397
|
+
function prevSibling(el, selector) {
|
|
3398
|
+
let sib = el.previousElementSibling;
|
|
3399
|
+
while (sib) {
|
|
3400
|
+
if (sib instanceof HTMLElement) {
|
|
3401
|
+
if (!selector || sib.matches(selector)) {
|
|
3402
|
+
return sib;
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
sib = sib.previousElementSibling;
|
|
3406
|
+
}
|
|
3407
|
+
return null;
|
|
3408
|
+
}
|
|
3409
|
+
|
|
3410
|
+
// src/dom-utils/observe.ts
|
|
3411
|
+
function onResize(el, handler) {
|
|
3412
|
+
const observer = new ResizeObserver((entries) => {
|
|
3413
|
+
for (const entry of entries) {
|
|
3414
|
+
handler(entry);
|
|
3415
|
+
}
|
|
3416
|
+
});
|
|
3417
|
+
observer.observe(el);
|
|
3418
|
+
return () => {
|
|
3419
|
+
observer.disconnect();
|
|
3420
|
+
};
|
|
3421
|
+
}
|
|
3422
|
+
function onIntersect(el, handler, options) {
|
|
3423
|
+
const observer = new IntersectionObserver((entries) => {
|
|
3424
|
+
for (const entry of entries) {
|
|
3425
|
+
handler(entry);
|
|
3426
|
+
}
|
|
3427
|
+
}, options);
|
|
3428
|
+
observer.observe(el);
|
|
3429
|
+
return () => {
|
|
3430
|
+
observer.disconnect();
|
|
3431
|
+
};
|
|
3432
|
+
}
|
|
3433
|
+
function onMutation(el, handler, options) {
|
|
3434
|
+
const observer = new MutationObserver((mutations) => {
|
|
3435
|
+
handler(mutations);
|
|
3436
|
+
});
|
|
3437
|
+
observer.observe(el, options ?? { childList: true, subtree: true });
|
|
3438
|
+
return () => {
|
|
3439
|
+
observer.disconnect();
|
|
3440
|
+
};
|
|
3441
|
+
}
|
|
3442
|
+
return __toCommonJS(src_exports);
|
|
3443
|
+
})();
|
|
2
3444
|
//# sourceMappingURL=formajs.global.js.map
|