@vanijs/vani 0.5.0 → 0.5.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.
@@ -98,6 +98,17 @@ declare const radialGradient: (propsOrChild?: VChild | SvgProps<"radialGradient"
98
98
  declare const stop: (propsOrChild?: VChild | SvgProps<"stop">, ...children: VChild[]) => VNode;
99
99
  declare const use: (propsOrChild?: VChild | SvgProps<"use">, ...children: VChild[]) => VNode;
100
100
  //#endregion
101
+ //#region src/vani/signals.d.ts
102
+ type SignalGetter<T> = () => T;
103
+ type SignalSetter<T> = (value: T | ((prev: T) => T)) => void;
104
+ type Signal<T> = [SignalGetter<T>, SignalSetter<T>];
105
+ declare function signal<T>(value: T): Signal<T>;
106
+ declare function effect(fn: () => void | (() => void)): () => void;
107
+ declare function createEffect(fn: () => void | (() => void)): () => void;
108
+ declare function derive<T>(fn: () => T): SignalGetter<T>;
109
+ declare function text(value: SignalGetter<unknown> | (() => unknown) | unknown): TextNode;
110
+ declare function attr(el: Element, name: string, value: SignalGetter<AttrValue> | (() => AttrValue) | AttrValue): () => void;
111
+ //#endregion
101
112
  //#region src/vani/ssr.d.ts
102
113
  type Renderable = Component<any> | ComponentInstance<any>;
103
114
  declare function renderToString(components: Renderable | Renderable[]): Promise<string>;
@@ -110,5 +121,5 @@ type SvgRenderOptions = {
110
121
  };
111
122
  declare const renderSvgString: (svg: string, options?: SvgRenderOptions) => VNode;
112
123
  //#endregion
113
- export { AttrValue, ClassName, Component, ComponentInput, ComponentInstance, ComponentRef, DataAttribute, DomRef, ElementProps, Fragment, Handle, HtmlProps, HydrationError, RenderFn, RenderMode, Root, SSRNode, SvgProps, SvgRenderOptions, TextNode, UpdateOptions, VChild, VNode, a, abbr, article, aside, audio, batch, blockquote, br, button, caption, circle, cite, classNames, clipPath, code, col, colgroup, component, configureSignalDom, createRoot, datalist, dd, defs, details, dfn, div, dl, dt, el, ellipse, em, embed, fieldset, figcaption, figure, footer, form, fragment, g, getRenderMode, getSignalDomAdapter, h1, h2, h3, h4, h5, h6, header, hr, hydrateToDOM, iframe, img, input, isComponentInstance, isDevMode, kbd, label, legend, li, line, linearGradient, main, mark, mask, meter, mount, nav, noscript, ol, optgroup, option, output, p, path, pattern, picture, polygon, polyline, pre, progress, radialGradient, reactive, rect, renderKeyedChildren, renderSvgString, renderToDOM, renderToString, samp, script, section, select, setRenderMode, slot, small, source, span, startTransition, stop, strong, style, summary, svg, table, tbody, td, template, textarea, tfoot, th, thead, time, tr, ul, use, var_, video, withRenderMode };
124
+ export { AttrValue, ClassName, Component, ComponentInput, ComponentInstance, ComponentRef, DataAttribute, DomRef, ElementProps, Fragment, Handle, HtmlProps, HydrationError, RenderFn, RenderMode, Root, SSRNode, Signal, SignalGetter, SignalSetter, SvgProps, SvgRenderOptions, TextNode, UpdateOptions, VChild, VNode, a, abbr, article, aside, attr, audio, batch, blockquote, br, button, caption, circle, cite, classNames, clipPath, code, col, colgroup, component, configureSignalDom, createEffect, createRoot, datalist, dd, defs, derive, details, dfn, div, dl, dt, effect, el, ellipse, em, embed, fieldset, figcaption, figure, footer, form, fragment, g, getRenderMode, getSignalDomAdapter, h1, h2, h3, h4, h5, h6, header, hr, hydrateToDOM, iframe, img, input, isComponentInstance, isDevMode, kbd, label, legend, li, line, linearGradient, main, mark, mask, meter, mount, nav, noscript, ol, optgroup, option, output, p, path, pattern, picture, polygon, polyline, pre, progress, radialGradient, reactive, rect, renderKeyedChildren, renderSvgString, renderToDOM, renderToString, samp, script, section, select, setRenderMode, signal, slot, small, source, span, startTransition, stop, strong, style, summary, svg, table, tbody, td, template, text, textarea, tfoot, th, thead, time, tr, ul, use, var_, video, withRenderMode };
114
125
  //# sourceMappingURL=index.d.mts.map
@@ -1,2 +1,2 @@
1
- import{C as e,S as t,_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as ee,l as te,m as l,o as ne,p as u,s as re,t as ie,u as d,v as ae,w as oe,x as se,y as f}from"./jsx-runtime-BUSOLzm1.mjs";function p(e){return(t,...n)=>d(e,t,...n)}const m=p(`div`),h=p(`span`),g=p(`ul`),_=p(`li`),v=p(`ol`),y=p(`dl`),b=p(`dt`),x=p(`dd`),S=p(`main`),C=p(`header`),w=p(`footer`),T=p(`section`),E=p(`article`),D=p(`aside`),O=p(`nav`),k=p(`details`),A=p(`summary`),j=p(`a`),M=p(`button`),N=p(`input`),P=p(`output`),F=p(`textarea`),I=p(`select`),L=p(`option`),R=p(`optgroup`),z=p(`label`),B=p(`form`),V=p(`progress`),H=p(`meter`),U=p(`fieldset`),W=p(`legend`),G=p(`datalist`),K=p(`figure`),ce=p(`figcaption`),le=p(`img`),ue=p(`picture`),de=p(`source`),fe=p(`video`),pe=p(`audio`),me=p(`iframe`),he=p(`embed`),ge=p(`time`),_e=p(`mark`),ve=p(`p`),ye=p(`h1`),be=p(`h2`),xe=p(`h3`),Se=p(`h4`),Ce=p(`h5`),we=p(`h6`),Te=p(`code`),Ee=p(`pre`),De=p(`blockquote`),Oe=p(`var`),ke=p(`kbd`),Ae=p(`samp`),je=p(`cite`),Me=p(`dfn`),Ne=p(`abbr`),Pe=p(`small`),Fe=p(`strong`),Ie=p(`em`),Le=p(`br`),Re=p(`hr`),ze=p(`table`),Be=p(`caption`),Ve=p(`colgroup`),He=p(`col`),Ue=p(`tbody`),We=p(`thead`),Ge=p(`tfoot`),Ke=p(`tr`),qe=p(`td`),Je=p(`th`),Ye=p(`style`),Xe=p(`script`),Ze=p(`noscript`),Qe=p(`template`),$e=p(`slot`),et=p(`svg`),tt=p(`g`),nt=p(`path`),rt=p(`circle`),it=p(`rect`),at=p(`line`),ot=p(`polyline`),st=p(`polygon`),ct=p(`ellipse`),lt=p(`defs`),ut=p(`clipPath`),dt=p(`mask`),ft=p(`pattern`),pt=p(`linearGradient`),mt=p(`radialGradient`),ht=p(`stop`),gt=p(`use`);function _t(e){return Array.isArray(e)?e:[e]}const vt=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function yt(){return{update(){},updateSync(){},dispose(){},onCleanup(){},onBeforeMount(){},onMount(){}}}function bt(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function q(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}function xt(e){let t=[];for(let n of Object.keys(e)){let r=e[n];r==null||r===!1||n.startsWith(`on`)&&typeof r==`function`||(r===!0?t.push(n):t.push(`${n}="${q(String(r))}"`))}return t.length>0?` ${t.join(` `)}`:``}function J(e){if(e==null||e===!1)return{type:`fragment`,children:[]};if(typeof e==`string`||typeof e==`number`)return{type:`text`,text:String(e)};if(u(e))return{type:`component`,instance:e};if(typeof e==`object`&&`type`in e)return e;throw Error(`[vani] SSR received a DOM node. This is not supported.`)}async function St(e){let t=`<!--vani:start-->`,n=`<!--vani:end-->`;if(e.clientOnly){let r=e.props?.fallback;return r?`${t}${await Y(J(r()))}${n}`:`${t}${n}`}let r=e.component(e.props,yt());return`${t}${await Y(J((r instanceof Promise?await r:r)()))}${n}`}async function Y(e){switch(e.type){case`text`:return q(e.text);case`comment`:return`<!--${e.text}-->`;case`fragment`:return(await Promise.all(e.children.map(Y))).join(``);case`component`:return St(e.instance);case`element`:{let t=xt(e.props);if(vt.has(e.tag))return`<${e.tag}${t}>`;let n=(await Promise.all(e.children.map(Y))).join(``);return`<${e.tag}${t}>${n}</${e.tag}>`}}}async function X(e){return i(`ssr`,async()=>{if(t()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let n=_t(e).map(e=>({type:`component`,instance:bt(e)}));return(await Promise.all(n.map(Y))).join(``)})}const Z=new Map,Q=(e,t)=>{if(!t)return e;let n=`${e??``} ${t}`.trim();return n.length>0?n:void 0},Ct=(e,t)=>{if(!t)return;let n=t.size;if(n!=null&&(e.setAttribute(`width`,String(n)),e.setAttribute(`height`,String(n))),t.className){let n=Q(e.getAttribute(`class`)??void 0,t.className);n&&e.setAttribute(`class`,n)}if(t.attributes){for(let[n,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){e.setAttribute(n,``);continue}e.setAttribute(n,String(r))}}},wt=e=>{let t={},n=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g,r;for(;r=n.exec(e);){let e=r[1],n=r[2]??r[3]??r[4];t[e]=n===void 0?!0:n}return t},Tt=e=>{let t=e.replaceAll(/<!--[\s\S]*?-->/g,``).trim(),n=/<\/?[^>]+>/g,r=[],i=null,a=0,o,s=e=>{let t=r.at(-1);t&&(t.type===`element`||t.type===`fragment`)&&t.children.push(e)};for(;o=n.exec(t);){let e=t.slice(a,o.index);e.trim().length>0&&s({type:`text`,text:e});let c=o[0];if(c.startsWith(`</`))r.pop();else{let e=c.endsWith(`/>`),t=c.slice(1,e?-2:-1).trim(),n=t.search(/\s/),a={type:`element`,tag:n===-1?t:t.slice(0,n),props:wt(n===-1?``:t.slice(n+1)),children:[]};i==null?i=a:s(a),e||r.push(a)}a=n.lastIndex}return i??{type:`fragment`,children:[]}},$=e=>e.type===`text`?{type:`text`,text:e.text}:e.type===`comment`?{type:`comment`,text:e.text}:e.type===`fragment`?{type:`fragment`,children:e.children.map($)}:e.type===`component`?{type:`component`,instance:e.instance}:{type:`element`,tag:e.tag,props:{...e.props},children:e.children.map($)},Et=(e,t)=>{if(!t||e.type!==`element`||e.tag!==`svg`)return;let n=e.props;if(t.size!=null&&(n.width=String(t.size),n.height=String(t.size)),t.className){let e=Q(n.class,t.className);e&&(n.class=e)}if(t.attributes){for(let[e,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){n[e]=!0;continue}n[e]=String(r)}}},Dt=(e,n)=>{if(t()===`ssr`){let t=$(Tt(e));return Et(t,n),t}let r=Z.get(e);if(!r){let t=new DOMParser().parseFromString(e,`image/svg+xml`);if(t.documentElement.nodeName===`parsererror`?t.documentElement:t.querySelector(`parsererror`))throw Error(`[vani] invalid SVG string`);r=t.documentElement,Z.set(e,r)}let i=r.cloneNode(!0);return Ct(i,n),i};export{ie as Fragment,r as HydrationError,j as a,Ne as abbr,E as article,D as aside,pe as audio,ne as batch,De as blockquote,Le as br,M as button,Be as caption,rt as circle,je as cite,re as classNames,ut as clipPath,Te as code,He as col,Ve as colgroup,a as component,se as configureSignalDom,te as createRoot,G as datalist,x as dd,lt as defs,k as details,Me as dfn,m as div,y as dl,b as dt,d as el,ct as ellipse,Ie as em,he as embed,U as fieldset,ce as figcaption,K as figure,w as footer,B as form,o as fragment,tt as g,t as getRenderMode,e as getSignalDomAdapter,ye as h1,be as h2,xe as h3,Se as h4,Ce as h5,we as h6,C as header,Re as hr,s as hydrateToDOM,me as iframe,le as img,N as input,u as isComponentInstance,l as isDevMode,ke as kbd,z as label,W as legend,_ as li,at as line,pt as linearGradient,S as main,_e as mark,dt as mask,H as meter,ee as mount,O as nav,Ze as noscript,v as ol,R as optgroup,L as option,P as output,ve as p,nt as path,ft as pattern,ue as picture,st as polygon,ot as polyline,Ee as pre,V as progress,mt as radialGradient,c as reactive,it as rect,n as renderKeyedChildren,Dt as renderSvgString,ae as renderToDOM,X as renderToString,Ae as samp,Xe as script,T as section,I as select,oe as setRenderMode,$e as slot,Pe as small,de as source,h as span,f as startTransition,ht as stop,Fe as strong,Ye as style,A as summary,et as svg,ze as table,Ue as tbody,qe as td,Qe as template,F as textarea,Ge as tfoot,Je as th,We as thead,ge as time,Ke as tr,g as ul,gt as use,Oe as var_,fe as video,i as withRenderMode};
1
+ import{A as e,C as t,D as n,E as r,O as i,S as a,T as o,_ as s,a as c,b as l,c as ee,d as u,f as d,g as te,h as ne,k as re,l as ie,m as ae,o as oe,p as f,s as se,t as p,u as m,v as h,w as g,x as _,y as v}from"./jsx-runtime-Bbqe4zqZ.mjs";function y(e){return(t,...n)=>m(e,t,...n)}const b=y(`div`),x=y(`span`),S=y(`ul`),C=y(`li`),w=y(`ol`),T=y(`dl`),E=y(`dt`),D=y(`dd`),O=y(`main`),k=y(`header`),A=y(`footer`),j=y(`section`),M=y(`article`),N=y(`aside`),P=y(`nav`),F=y(`details`),I=y(`summary`),L=y(`a`),R=y(`button`),z=y(`input`),B=y(`output`),V=y(`textarea`),H=y(`select`),U=y(`option`),W=y(`optgroup`),G=y(`label`),K=y(`form`),ce=y(`progress`),le=y(`meter`),ue=y(`fieldset`),de=y(`legend`),fe=y(`datalist`),pe=y(`figure`),me=y(`figcaption`),he=y(`img`),ge=y(`picture`),_e=y(`source`),ve=y(`video`),ye=y(`audio`),be=y(`iframe`),xe=y(`embed`),Se=y(`time`),Ce=y(`mark`),we=y(`p`),Te=y(`h1`),Ee=y(`h2`),De=y(`h3`),Oe=y(`h4`),ke=y(`h5`),Ae=y(`h6`),je=y(`code`),Me=y(`pre`),Ne=y(`blockquote`),Pe=y(`var`),Fe=y(`kbd`),Ie=y(`samp`),Le=y(`cite`),Re=y(`dfn`),ze=y(`abbr`),Be=y(`small`),Ve=y(`strong`),He=y(`em`),Ue=y(`br`),We=y(`hr`),Ge=y(`table`),Ke=y(`caption`),qe=y(`colgroup`),Je=y(`col`),Ye=y(`tbody`),Xe=y(`thead`),Ze=y(`tfoot`),Qe=y(`tr`),$e=y(`td`),et=y(`th`),tt=y(`style`),nt=y(`script`),rt=y(`noscript`),it=y(`template`),at=y(`slot`),ot=y(`svg`),st=y(`g`),ct=y(`path`),lt=y(`circle`),ut=y(`rect`),dt=y(`line`),ft=y(`polyline`),pt=y(`polygon`),mt=y(`ellipse`),ht=y(`defs`),gt=y(`clipPath`),_t=y(`mask`),vt=y(`pattern`),yt=y(`linearGradient`),bt=y(`radialGradient`),xt=y(`stop`),St=y(`use`);function Ct(e){return Array.isArray(e)?e:[e]}const wt=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function Tt(){return{update(){},updateSync(){},dispose(){},onCleanup(){},onBeforeMount(){},onMount(){}}}function q(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function J(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}function Et(e){let t=[];for(let n of Object.keys(e)){let r=e[n];r==null||r===!1||n.startsWith(`on`)&&typeof r==`function`||(r===!0?t.push(n):t.push(`${n}="${J(String(r))}"`))}return t.length>0?` ${t.join(` `)}`:``}function Y(e){if(e==null||e===!1)return{type:`fragment`,children:[]};if(typeof e==`string`||typeof e==`number`)return{type:`text`,text:String(e)};if(f(e))return{type:`component`,instance:e};if(typeof e==`object`&&`type`in e)return e;throw Error(`[vani] SSR received a DOM node. This is not supported.`)}async function Dt(e){let t=`<!--vani:start-->`,n=`<!--vani:end-->`;if(e.clientOnly){let r=e.props?.fallback;return r?`${t}${await X(Y(r()))}${n}`:`${t}${n}`}let r=e.component(e.props,Tt());return`${t}${await X(Y((r instanceof Promise?await r:r)()))}${n}`}async function X(e){switch(e.type){case`text`:return J(e.text);case`comment`:return`<!--${e.text}-->`;case`fragment`:return(await Promise.all(e.children.map(X))).join(``);case`component`:return Dt(e.instance);case`element`:{let t=Et(e.props);if(wt.has(e.tag))return`<${e.tag}${t}>`;let n=(await Promise.all(e.children.map(X))).join(``);return`<${e.tag}${t}>${n}</${e.tag}>`}}}async function Ot(e){return l(`ssr`,async()=>{if(i()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let t=Ct(e).map(e=>({type:`component`,instance:q(e)}));return(await Promise.all(t.map(X))).join(``)})}const Z=new Map,Q=(e,t)=>{if(!t)return e;let n=`${e??``} ${t}`.trim();return n.length>0?n:void 0},kt=(e,t)=>{if(!t)return;let n=t.size;if(n!=null&&(e.setAttribute(`width`,String(n)),e.setAttribute(`height`,String(n))),t.className){let n=Q(e.getAttribute(`class`)??void 0,t.className);n&&e.setAttribute(`class`,n)}if(t.attributes){for(let[n,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){e.setAttribute(n,``);continue}e.setAttribute(n,String(r))}}},At=e=>{let t={},n=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g,r;for(;r=n.exec(e);){let e=r[1],n=r[2]??r[3]??r[4];t[e]=n===void 0?!0:n}return t},jt=e=>{let t=e.replaceAll(/<!--[\s\S]*?-->/g,``).trim(),n=/<\/?[^>]+>/g,r=[],i=null,a=0,o,s=e=>{let t=r.at(-1);t&&(t.type===`element`||t.type===`fragment`)&&t.children.push(e)};for(;o=n.exec(t);){let e=t.slice(a,o.index);e.trim().length>0&&s({type:`text`,text:e});let c=o[0];if(c.startsWith(`</`))r.pop();else{let e=c.endsWith(`/>`),t=c.slice(1,e?-2:-1).trim(),n=t.search(/\s/),a={type:`element`,tag:n===-1?t:t.slice(0,n),props:At(n===-1?``:t.slice(n+1)),children:[]};i==null?i=a:s(a),e||r.push(a)}a=n.lastIndex}return i??{type:`fragment`,children:[]}},$=e=>e.type===`text`?{type:`text`,text:e.text}:e.type===`comment`?{type:`comment`,text:e.text}:e.type===`fragment`?{type:`fragment`,children:e.children.map($)}:e.type===`component`?{type:`component`,instance:e.instance}:{type:`element`,tag:e.tag,props:{...e.props},children:e.children.map($)},Mt=(e,t)=>{if(!t||e.type!==`element`||e.tag!==`svg`)return;let n=e.props;if(t.size!=null&&(n.width=String(t.size),n.height=String(t.size)),t.className){let e=Q(n.class,t.className);e&&(n.class=e)}if(t.attributes){for(let[e,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){n[e]=!0;continue}n[e]=String(r)}}},Nt=(e,t)=>{if(i()===`ssr`){let n=$(jt(e));return Mt(n,t),n}let n=Z.get(e);if(!n){let t=new DOMParser().parseFromString(e,`image/svg+xml`);if(t.documentElement.nodeName===`parsererror`?t.documentElement:t.querySelector(`parsererror`))throw Error(`[vani] invalid SVG string`);n=t.documentElement,Z.set(e,n)}let r=n.cloneNode(!0);return kt(r,t),r};export{p as Fragment,c as HydrationError,L as a,ze as abbr,M as article,N as aside,_ as attr,ye as audio,oe as batch,Ne as blockquote,Ue as br,R as button,Ke as caption,lt as circle,Le as cite,se as classNames,gt as clipPath,je as code,Je as col,qe as colgroup,ee as component,n as configureSignalDom,a as createEffect,ie as createRoot,fe as datalist,D as dd,ht as defs,t as derive,F as details,Re as dfn,b as div,T as dl,E as dt,g as effect,m as el,mt as ellipse,He as em,xe as embed,ue as fieldset,me as figcaption,pe as figure,A as footer,K as form,u as fragment,st as g,i as getRenderMode,re as getSignalDomAdapter,Te as h1,Ee as h2,De as h3,Oe as h4,ke as h5,Ae as h6,k as header,We as hr,d as hydrateToDOM,be as iframe,he as img,z as input,f as isComponentInstance,ae as isDevMode,Fe as kbd,G as label,de as legend,C as li,dt as line,yt as linearGradient,O as main,Ce as mark,_t as mask,le as meter,ne as mount,P as nav,rt as noscript,w as ol,W as optgroup,U as option,B as output,we as p,ct as path,vt as pattern,ge as picture,pt as polygon,ft as polyline,Me as pre,ce as progress,bt as radialGradient,te as reactive,ut as rect,s as renderKeyedChildren,Nt as renderSvgString,h as renderToDOM,Ot as renderToString,Ie as samp,nt as script,j as section,H as select,e as setRenderMode,o as signal,at as slot,Be as small,_e as source,x as span,v as startTransition,xt as stop,Ve as strong,tt as style,I as summary,ot as svg,Ge as table,Ye as tbody,$e as td,it as template,r as text,V as textarea,Ze as tfoot,et as th,Xe as thead,Se as time,Qe as tr,S as ul,St as use,Pe as var_,ve as video,l as withRenderMode};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vani/html.ts","../../src/vani/ssr.ts","../../src/vani/svg.ts"],"sourcesContent":["// ─────────────────────────────────────────────\n// HTML element helpers\n// ─────────────────────────────────────────────\n\nimport { el, type ElementProps, type VChild } from './runtime'\n\ntype ElementTagName = keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap\n\nfunction createElementFn<E extends ElementTagName>(tag: E) {\n return (propsOrChild?: ElementProps<E> | VChild | null, ...children: VChild[]) =>\n el(tag, propsOrChild, ...children)\n}\n\n// Basic and semantic elements\nexport const div = createElementFn('div')\nexport const span = createElementFn('span')\nexport const ul = createElementFn('ul')\nexport const li = createElementFn('li')\nexport const ol = createElementFn('ol')\nexport const dl = createElementFn('dl')\nexport const dt = createElementFn('dt')\nexport const dd = createElementFn('dd')\nexport const main = createElementFn('main')\nexport const header = createElementFn('header')\nexport const footer = createElementFn('footer')\nexport const section = createElementFn('section')\nexport const article = createElementFn('article')\nexport const aside = createElementFn('aside')\nexport const nav = createElementFn('nav')\n\n// Interactive elements\nexport const details = createElementFn('details')\nexport const summary = createElementFn('summary')\nexport const a = createElementFn('a')\nexport const button = createElementFn('button')\nexport const input = createElementFn('input')\nexport const output = createElementFn('output')\nexport const textarea = createElementFn('textarea')\nexport const select = createElementFn('select')\nexport const option = createElementFn('option')\nexport const optgroup = createElementFn('optgroup')\nexport const label = createElementFn('label')\nexport const form = createElementFn('form')\nexport const progress = createElementFn('progress')\nexport const meter = createElementFn('meter')\nexport const fieldset = createElementFn('fieldset')\nexport const legend = createElementFn('legend')\nexport const datalist = createElementFn('datalist')\n\n// Media elements\nexport const figure = createElementFn('figure')\nexport const figcaption = createElementFn('figcaption')\nexport const img = createElementFn('img')\nexport const picture = createElementFn('picture')\nexport const source = createElementFn('source')\nexport const video = createElementFn('video')\nexport const audio = createElementFn('audio')\nexport const iframe = createElementFn('iframe')\nexport const embed = createElementFn('embed')\n\n// Prose elements\nexport const time = createElementFn('time')\nexport const mark = createElementFn('mark')\nexport const p = createElementFn('p')\nexport const h1 = createElementFn('h1')\nexport const h2 = createElementFn('h2')\nexport const h3 = createElementFn('h3')\nexport const h4 = createElementFn('h4')\nexport const h5 = createElementFn('h5')\nexport const h6 = createElementFn('h6')\nexport const code = createElementFn('code')\nexport const pre = createElementFn('pre')\nexport const blockquote = createElementFn('blockquote')\nexport const var_ = createElementFn('var')\nexport const kbd = createElementFn('kbd')\nexport const samp = createElementFn('samp')\nexport const cite = createElementFn('cite')\nexport const dfn = createElementFn('dfn')\nexport const abbr = createElementFn('abbr')\nexport const small = createElementFn('small')\nexport const strong = createElementFn('strong')\nexport const em = createElementFn('em')\nexport const br = createElementFn('br')\nexport const hr = createElementFn('hr')\n\n// Tables\nexport const table = createElementFn('table')\nexport const caption = createElementFn('caption')\nexport const colgroup = createElementFn('colgroup')\nexport const col = createElementFn('col')\nexport const tbody = createElementFn('tbody')\nexport const thead = createElementFn('thead')\nexport const tfoot = createElementFn('tfoot')\nexport const tr = createElementFn('tr')\nexport const td = createElementFn('td')\nexport const th = createElementFn('th')\n\n// Scripting elements\nexport const style = createElementFn('style')\nexport const script = createElementFn('script')\nexport const noscript = createElementFn('noscript')\nexport const template = createElementFn('template')\nexport const slot = createElementFn('slot')\n\n// SVG elements\nexport const svg = createElementFn('svg')\nexport const g = createElementFn('g')\nexport const path = createElementFn('path')\nexport const circle = createElementFn('circle')\nexport const rect = createElementFn('rect')\nexport const line = createElementFn('line')\nexport const polyline = createElementFn('polyline')\nexport const polygon = createElementFn('polygon')\nexport const ellipse = createElementFn('ellipse')\nexport const defs = createElementFn('defs')\nexport const clipPath = createElementFn('clipPath')\nexport const mask = createElementFn('mask')\nexport const pattern = createElementFn('pattern')\nexport const linearGradient = createElementFn('linearGradient')\nexport const radialGradient = createElementFn('radialGradient')\nexport const stop = createElementFn('stop')\nexport const use = createElementFn('use')\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport {\n isComponentInstance,\n withRenderMode,\n type Component,\n type ComponentInstance,\n type Handle,\n type RenderFn,\n type SSRNode,\n type VChild,\n} from './runtime'\n\ntype Renderable = Component<any> | ComponentInstance<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nconst voidElements = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nfunction createSsrHandle(): Handle {\n return {\n update() {},\n updateSync() {},\n dispose() {},\n onCleanup() {},\n onBeforeMount() {},\n onMount() {},\n }\n}\n\nfunction normalizeComponent(comp: Renderable): ComponentInstance<any> {\n if (typeof comp === 'function') {\n return {\n $$vani: 'component',\n component: comp,\n props: {},\n }\n }\n return comp\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;')\n}\n\nfunction serializeProps(props: Record<string, any>): string {\n const parts: string[] = []\n for (const key of Object.keys(props)) {\n const value = props[key]\n if (value == null || value === false) continue\n if (key.startsWith('on') && typeof value === 'function') continue\n\n if (value === true) {\n parts.push(key)\n } else {\n parts.push(`${key}=\"${escapeHtml(String(value))}\"`)\n }\n }\n\n return parts.length > 0 ? ` ${parts.join(' ')}` : ''\n}\n\nfunction toSsrNode(node: VChild): SSRNode {\n if (node == null || node === false) {\n return { type: 'fragment', children: [] }\n }\n\n if (typeof node === 'string' || typeof node === 'number') {\n return { type: 'text', text: String(node) }\n }\n\n if (isComponentInstance(node)) {\n return { type: 'component', instance: node }\n }\n\n if (typeof node === 'object' && 'type' in node) {\n return node as SSRNode\n }\n\n throw new Error('[vani] SSR received a DOM node. This is not supported.')\n}\n\nasync function renderComponent(instance: ComponentInstance<any>): Promise<string> {\n const start = '<!--vani:start-->'\n const end = '<!--vani:end-->'\n\n if (instance.clientOnly) {\n const fallback = (instance.props as any)?.fallback as RenderFn | undefined\n if (!fallback) {\n return `${start}${end}`\n }\n const fallbackNode = toSsrNode(fallback())\n return `${start}${await serializeNode(fallbackNode)}${end}`\n }\n\n const result = instance.component(instance.props, createSsrHandle())\n const renderFn = result instanceof Promise ? await result : result\n const node = toSsrNode(renderFn())\n return `${start}${await serializeNode(node)}${end}`\n}\n\nasync function serializeNode(node: SSRNode): Promise<string> {\n switch (node.type) {\n case 'text':\n return escapeHtml(node.text)\n case 'comment':\n return `<!--${node.text}-->`\n case 'fragment':\n return (await Promise.all(node.children.map(serializeNode))).join('')\n case 'component':\n return renderComponent(node.instance)\n case 'element': {\n const attrs = serializeProps(node.props)\n if (voidElements.has(node.tag)) {\n return `<${node.tag}${attrs}>`\n }\n const children = (await Promise.all(node.children.map(serializeNode))).join('')\n return `<${node.tag}${attrs}>${children}</${node.tag}>`\n }\n }\n}\n\nexport async function renderToString(components: Renderable | Renderable[]): Promise<string> {\n return withRenderMode('ssr', async () => {\n if (getRenderMode() !== 'ssr') {\n throw new Error('[vani] renderToString failed to set SSR render mode.')\n }\n\n const normalized = normalizeRenderables(components)\n const nodes: SSRNode[] = normalized.map((component) => ({\n type: 'component',\n instance: normalizeComponent(component),\n }))\n\n const rendered = await Promise.all(nodes.map(serializeNode))\n return rendered.join('')\n })\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport { type SSRNode, type SvgProps, type VNode } from './runtime'\n\nexport type SvgRenderOptions = {\n size?: number\n className?: string\n attributes?: SvgProps\n}\n\nconst svgStringCache = new Map<string, SVGSVGElement>()\n\nconst mergeClassValue = (base: string | undefined, extra: string | undefined) => {\n if (!extra) return base\n const merged = `${base ?? ''} ${extra}`.trim()\n return merged.length > 0 ? merged : undefined\n}\n\nconst applySvgOverridesToNode = (node: SVGSVGElement, options?: SvgRenderOptions) => {\n if (!options) return\n const size = options.size\n if (size != null) {\n node.setAttribute('width', String(size))\n node.setAttribute('height', String(size))\n }\n if (options.className) {\n const merged = mergeClassValue(node.getAttribute('class') ?? undefined, options.className)\n if (merged) {\n node.setAttribute('class', merged)\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n node.setAttribute(key, '')\n continue\n }\n node.setAttribute(key, String(value))\n }\n }\n}\n\nconst parseSvgAttributes = (input: string) => {\n const attrs: Record<string, string | boolean> = {}\n const attrRegex = /([^\\s=]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'>]+)))?/g\n let match: RegExpExecArray | null\n while ((match = attrRegex.exec(input))) {\n const key = match[1]\n const value = match[2] ?? match[3] ?? match[4]\n attrs[key] = value === undefined ? true : value\n }\n return attrs\n}\n\nconst parseSvgToSsrNode = (svg: string): SSRNode => {\n const cleaned = svg.replaceAll(/<!--[\\s\\S]*?-->/g, '').trim()\n const tagRegex = /<\\/?[^>]+>/g\n const stack: Array<SSRNode> = []\n let root: SSRNode | null = null\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n const appendChild = (child: SSRNode) => {\n const parent = stack.at(-1)\n if (parent && (parent.type === 'element' || parent.type === 'fragment')) {\n parent.children.push(child)\n }\n }\n\n while ((match = tagRegex.exec(cleaned))) {\n const text = cleaned.slice(lastIndex, match.index)\n if (text.trim().length > 0) {\n appendChild({ type: 'text', text })\n }\n\n const token = match[0]\n if (token.startsWith('</')) {\n stack.pop()\n } else {\n const selfClosing = token.endsWith('/>')\n const inside = token.slice(1, selfClosing ? -2 : -1).trim()\n const spaceIndex = inside.search(/\\s/)\n const tag = spaceIndex === -1 ? inside : inside.slice(0, spaceIndex)\n const attrString = spaceIndex === -1 ? '' : inside.slice(spaceIndex + 1)\n const props = parseSvgAttributes(attrString)\n const node: SSRNode = { type: 'element', tag, props, children: [] }\n\n if (root == null) {\n root = node\n } else {\n appendChild(node)\n }\n\n if (!selfClosing) {\n stack.push(node)\n }\n }\n\n lastIndex = tagRegex.lastIndex\n }\n\n return root ?? { type: 'fragment', children: [] }\n}\n\nconst cloneSsrNode = (node: SSRNode): SSRNode => {\n if (node.type === 'text') {\n return { type: 'text', text: node.text }\n }\n if (node.type === 'comment') {\n return { type: 'comment', text: node.text }\n }\n if (node.type === 'fragment') {\n return { type: 'fragment', children: node.children.map(cloneSsrNode) }\n }\n if (node.type === 'component') {\n return { type: 'component', instance: node.instance }\n }\n return {\n type: 'element',\n tag: node.tag,\n props: { ...node.props },\n children: node.children.map(cloneSsrNode),\n }\n}\n\nconst applySvgOverridesToSsr = (node: SSRNode, options?: SvgRenderOptions) => {\n if (!options || node.type !== 'element' || node.tag !== 'svg') return\n const props = node.props as Record<string, any>\n if (options.size != null) {\n props.width = String(options.size)\n props.height = String(options.size)\n }\n if (options.className) {\n const merged = mergeClassValue(props.class as string | undefined, options.className)\n if (merged) {\n props.class = merged\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n props[key] = true\n continue\n }\n props[key] = String(value)\n }\n }\n}\n\nexport const renderSvgString = (svg: string, options?: SvgRenderOptions): VNode => {\n if (getRenderMode() === 'ssr') {\n const parsed = cloneSsrNode(parseSvgToSsrNode(svg))\n applySvgOverridesToSsr(parsed, options)\n return parsed\n }\n\n let base = svgStringCache.get(svg)\n if (!base) {\n const doc = new DOMParser().parseFromString(svg, 'image/svg+xml')\n const parserError =\n doc.documentElement.nodeName === 'parsererror'\n ? doc.documentElement\n : doc.querySelector('parsererror')\n if (parserError) {\n throw new Error('[vani] invalid SVG string')\n }\n base = doc.documentElement as unknown as SVGSVGElement\n svgStringCache.set(svg, base)\n }\n const node = base.cloneNode(true) as SVGSVGElement\n applySvgOverridesToNode(node, options)\n return node\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vani/html.ts","../../src/vani/ssr.ts","../../src/vani/svg.ts"],"sourcesContent":["// ─────────────────────────────────────────────\n// HTML element helpers\n// ─────────────────────────────────────────────\n\nimport { el, type ElementProps, type VChild } from './runtime'\n\n// Re-export Fragment from jsx-runtime for convenience\nexport { Fragment } from './jsx-runtime'\n\ntype ElementTagName = keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap\n\nfunction createElementFn<E extends ElementTagName>(tag: E) {\n return (propsOrChild?: ElementProps<E> | VChild | null, ...children: VChild[]) =>\n el(tag, propsOrChild, ...children)\n}\n\n// Basic and semantic elements\nexport const div = createElementFn('div')\nexport const span = createElementFn('span')\nexport const ul = createElementFn('ul')\nexport const li = createElementFn('li')\nexport const ol = createElementFn('ol')\nexport const dl = createElementFn('dl')\nexport const dt = createElementFn('dt')\nexport const dd = createElementFn('dd')\nexport const main = createElementFn('main')\nexport const header = createElementFn('header')\nexport const footer = createElementFn('footer')\nexport const section = createElementFn('section')\nexport const article = createElementFn('article')\nexport const aside = createElementFn('aside')\nexport const nav = createElementFn('nav')\n\n// Interactive elements\nexport const details = createElementFn('details')\nexport const summary = createElementFn('summary')\nexport const a = createElementFn('a')\nexport const button = createElementFn('button')\nexport const input = createElementFn('input')\nexport const output = createElementFn('output')\nexport const textarea = createElementFn('textarea')\nexport const select = createElementFn('select')\nexport const option = createElementFn('option')\nexport const optgroup = createElementFn('optgroup')\nexport const label = createElementFn('label')\nexport const form = createElementFn('form')\nexport const progress = createElementFn('progress')\nexport const meter = createElementFn('meter')\nexport const fieldset = createElementFn('fieldset')\nexport const legend = createElementFn('legend')\nexport const datalist = createElementFn('datalist')\n\n// Media elements\nexport const figure = createElementFn('figure')\nexport const figcaption = createElementFn('figcaption')\nexport const img = createElementFn('img')\nexport const picture = createElementFn('picture')\nexport const source = createElementFn('source')\nexport const video = createElementFn('video')\nexport const audio = createElementFn('audio')\nexport const iframe = createElementFn('iframe')\nexport const embed = createElementFn('embed')\n\n// Prose elements\nexport const time = createElementFn('time')\nexport const mark = createElementFn('mark')\nexport const p = createElementFn('p')\nexport const h1 = createElementFn('h1')\nexport const h2 = createElementFn('h2')\nexport const h3 = createElementFn('h3')\nexport const h4 = createElementFn('h4')\nexport const h5 = createElementFn('h5')\nexport const h6 = createElementFn('h6')\nexport const code = createElementFn('code')\nexport const pre = createElementFn('pre')\nexport const blockquote = createElementFn('blockquote')\nexport const var_ = createElementFn('var')\nexport const kbd = createElementFn('kbd')\nexport const samp = createElementFn('samp')\nexport const cite = createElementFn('cite')\nexport const dfn = createElementFn('dfn')\nexport const abbr = createElementFn('abbr')\nexport const small = createElementFn('small')\nexport const strong = createElementFn('strong')\nexport const em = createElementFn('em')\nexport const br = createElementFn('br')\nexport const hr = createElementFn('hr')\n\n// Tables\nexport const table = createElementFn('table')\nexport const caption = createElementFn('caption')\nexport const colgroup = createElementFn('colgroup')\nexport const col = createElementFn('col')\nexport const tbody = createElementFn('tbody')\nexport const thead = createElementFn('thead')\nexport const tfoot = createElementFn('tfoot')\nexport const tr = createElementFn('tr')\nexport const td = createElementFn('td')\nexport const th = createElementFn('th')\n\n// Scripting elements\nexport const style = createElementFn('style')\nexport const script = createElementFn('script')\nexport const noscript = createElementFn('noscript')\nexport const template = createElementFn('template')\nexport const slot = createElementFn('slot')\n\n// SVG elements\nexport const svg = createElementFn('svg')\nexport const g = createElementFn('g')\nexport const path = createElementFn('path')\nexport const circle = createElementFn('circle')\nexport const rect = createElementFn('rect')\nexport const line = createElementFn('line')\nexport const polyline = createElementFn('polyline')\nexport const polygon = createElementFn('polygon')\nexport const ellipse = createElementFn('ellipse')\nexport const defs = createElementFn('defs')\nexport const clipPath = createElementFn('clipPath')\nexport const mask = createElementFn('mask')\nexport const pattern = createElementFn('pattern')\nexport const linearGradient = createElementFn('linearGradient')\nexport const radialGradient = createElementFn('radialGradient')\nexport const stop = createElementFn('stop')\nexport const use = createElementFn('use')\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport {\n isComponentInstance,\n withRenderMode,\n type Component,\n type ComponentInstance,\n type Handle,\n type RenderFn,\n type SSRNode,\n type VChild,\n} from './runtime'\n\ntype Renderable = Component<any> | ComponentInstance<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nconst voidElements = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nfunction createSsrHandle(): Handle {\n return {\n update() {},\n updateSync() {},\n dispose() {},\n onCleanup() {},\n onBeforeMount() {},\n onMount() {},\n }\n}\n\nfunction normalizeComponent(comp: Renderable): ComponentInstance<any> {\n if (typeof comp === 'function') {\n return {\n $$vani: 'component',\n component: comp,\n props: {},\n }\n }\n return comp\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;')\n}\n\nfunction serializeProps(props: Record<string, any>): string {\n const parts: string[] = []\n for (const key of Object.keys(props)) {\n const value = props[key]\n if (value == null || value === false) continue\n if (key.startsWith('on') && typeof value === 'function') continue\n\n if (value === true) {\n parts.push(key)\n } else {\n parts.push(`${key}=\"${escapeHtml(String(value))}\"`)\n }\n }\n\n return parts.length > 0 ? ` ${parts.join(' ')}` : ''\n}\n\nfunction toSsrNode(node: VChild): SSRNode {\n if (node == null || node === false) {\n return { type: 'fragment', children: [] }\n }\n\n if (typeof node === 'string' || typeof node === 'number') {\n return { type: 'text', text: String(node) }\n }\n\n if (isComponentInstance(node)) {\n return { type: 'component', instance: node }\n }\n\n if (typeof node === 'object' && 'type' in node) {\n return node as SSRNode\n }\n\n throw new Error('[vani] SSR received a DOM node. This is not supported.')\n}\n\nasync function renderComponent(instance: ComponentInstance<any>): Promise<string> {\n const start = '<!--vani:start-->'\n const end = '<!--vani:end-->'\n\n if (instance.clientOnly) {\n const fallback = (instance.props as any)?.fallback as RenderFn | undefined\n if (!fallback) {\n return `${start}${end}`\n }\n const fallbackNode = toSsrNode(fallback())\n return `${start}${await serializeNode(fallbackNode)}${end}`\n }\n\n const result = instance.component(instance.props, createSsrHandle())\n const renderFn = result instanceof Promise ? await result : result\n const node = toSsrNode(renderFn())\n return `${start}${await serializeNode(node)}${end}`\n}\n\nasync function serializeNode(node: SSRNode): Promise<string> {\n switch (node.type) {\n case 'text':\n return escapeHtml(node.text)\n case 'comment':\n return `<!--${node.text}-->`\n case 'fragment':\n return (await Promise.all(node.children.map(serializeNode))).join('')\n case 'component':\n return renderComponent(node.instance)\n case 'element': {\n const attrs = serializeProps(node.props)\n if (voidElements.has(node.tag)) {\n return `<${node.tag}${attrs}>`\n }\n const children = (await Promise.all(node.children.map(serializeNode))).join('')\n return `<${node.tag}${attrs}>${children}</${node.tag}>`\n }\n }\n}\n\nexport async function renderToString(components: Renderable | Renderable[]): Promise<string> {\n return withRenderMode('ssr', async () => {\n if (getRenderMode() !== 'ssr') {\n throw new Error('[vani] renderToString failed to set SSR render mode.')\n }\n\n const normalized = normalizeRenderables(components)\n const nodes: SSRNode[] = normalized.map((component) => ({\n type: 'component',\n instance: normalizeComponent(component),\n }))\n\n const rendered = await Promise.all(nodes.map(serializeNode))\n return rendered.join('')\n })\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport { type SSRNode, type SvgProps, type VNode } from './runtime'\n\nexport type SvgRenderOptions = {\n size?: number\n className?: string\n attributes?: SvgProps\n}\n\nconst svgStringCache = new Map<string, SVGSVGElement>()\n\nconst mergeClassValue = (base: string | undefined, extra: string | undefined) => {\n if (!extra) return base\n const merged = `${base ?? ''} ${extra}`.trim()\n return merged.length > 0 ? merged : undefined\n}\n\nconst applySvgOverridesToNode = (node: SVGSVGElement, options?: SvgRenderOptions) => {\n if (!options) return\n const size = options.size\n if (size != null) {\n node.setAttribute('width', String(size))\n node.setAttribute('height', String(size))\n }\n if (options.className) {\n const merged = mergeClassValue(node.getAttribute('class') ?? undefined, options.className)\n if (merged) {\n node.setAttribute('class', merged)\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n node.setAttribute(key, '')\n continue\n }\n node.setAttribute(key, String(value))\n }\n }\n}\n\nconst parseSvgAttributes = (input: string) => {\n const attrs: Record<string, string | boolean> = {}\n const attrRegex = /([^\\s=]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'>]+)))?/g\n let match: RegExpExecArray | null\n while ((match = attrRegex.exec(input))) {\n const key = match[1]\n const value = match[2] ?? match[3] ?? match[4]\n attrs[key] = value === undefined ? true : value\n }\n return attrs\n}\n\nconst parseSvgToSsrNode = (svg: string): SSRNode => {\n const cleaned = svg.replaceAll(/<!--[\\s\\S]*?-->/g, '').trim()\n const tagRegex = /<\\/?[^>]+>/g\n const stack: Array<SSRNode> = []\n let root: SSRNode | null = null\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n const appendChild = (child: SSRNode) => {\n const parent = stack.at(-1)\n if (parent && (parent.type === 'element' || parent.type === 'fragment')) {\n parent.children.push(child)\n }\n }\n\n while ((match = tagRegex.exec(cleaned))) {\n const text = cleaned.slice(lastIndex, match.index)\n if (text.trim().length > 0) {\n appendChild({ type: 'text', text })\n }\n\n const token = match[0]\n if (token.startsWith('</')) {\n stack.pop()\n } else {\n const selfClosing = token.endsWith('/>')\n const inside = token.slice(1, selfClosing ? -2 : -1).trim()\n const spaceIndex = inside.search(/\\s/)\n const tag = spaceIndex === -1 ? inside : inside.slice(0, spaceIndex)\n const attrString = spaceIndex === -1 ? '' : inside.slice(spaceIndex + 1)\n const props = parseSvgAttributes(attrString)\n const node: SSRNode = { type: 'element', tag, props, children: [] }\n\n if (root == null) {\n root = node\n } else {\n appendChild(node)\n }\n\n if (!selfClosing) {\n stack.push(node)\n }\n }\n\n lastIndex = tagRegex.lastIndex\n }\n\n return root ?? { type: 'fragment', children: [] }\n}\n\nconst cloneSsrNode = (node: SSRNode): SSRNode => {\n if (node.type === 'text') {\n return { type: 'text', text: node.text }\n }\n if (node.type === 'comment') {\n return { type: 'comment', text: node.text }\n }\n if (node.type === 'fragment') {\n return { type: 'fragment', children: node.children.map(cloneSsrNode) }\n }\n if (node.type === 'component') {\n return { type: 'component', instance: node.instance }\n }\n return {\n type: 'element',\n tag: node.tag,\n props: { ...node.props },\n children: node.children.map(cloneSsrNode),\n }\n}\n\nconst applySvgOverridesToSsr = (node: SSRNode, options?: SvgRenderOptions) => {\n if (!options || node.type !== 'element' || node.tag !== 'svg') return\n const props = node.props as Record<string, any>\n if (options.size != null) {\n props.width = String(options.size)\n props.height = String(options.size)\n }\n if (options.className) {\n const merged = mergeClassValue(props.class as string | undefined, options.className)\n if (merged) {\n props.class = merged\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n props[key] = true\n continue\n }\n props[key] = String(value)\n }\n }\n}\n\nexport const renderSvgString = (svg: string, options?: SvgRenderOptions): VNode => {\n if (getRenderMode() === 'ssr') {\n const parsed = cloneSsrNode(parseSvgToSsrNode(svg))\n applySvgOverridesToSsr(parsed, options)\n return parsed\n }\n\n let base = svgStringCache.get(svg)\n if (!base) {\n const doc = new DOMParser().parseFromString(svg, 'image/svg+xml')\n const parserError =\n doc.documentElement.nodeName === 'parsererror'\n ? doc.documentElement\n : doc.querySelector('parsererror')\n if (parserError) {\n throw new Error('[vani] invalid SVG string')\n }\n base = doc.documentElement as unknown as SVGSVGElement\n svgStringCache.set(svg, base)\n }\n const node = base.cloneNode(true) as SVGSVGElement\n applySvgOverridesToNode(node, options)\n return node\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- import{i as e,n as t,r as n,t as r}from"./jsx-runtime-BUSOLzm1.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};
1
+ import{i as e,n as t,r as n,t as r}from"./jsx-runtime-Bbqe4zqZ.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};
@@ -0,0 +1,2 @@
1
+ const e={renderMode:`dom`,domAdapter:null};function t(){return e.renderMode}function n(t){e.renderMode=t}function r(t){e.domAdapter=t}function i(){return e.domAdapter}let a=null;const o=new Set;let s=!1;function c(e){!a||a.disposed||a.deps.has(e)||(a.deps.add(e),e.observers.add(a))}function l(e){for(let t of e.deps)t.observers.delete(e);e.deps.clear(),e.cleanup&&=(e.cleanup(),void 0)}function u(e){if(e.disposed)return;l(e);let t=a;a=e;let n=e.fn();a=t,typeof n==`function`&&(e.cleanup=n)}function d(e){e.disposed||(o.add(e),!s&&(s=!0,queueMicrotask(()=>{s=!1;let e=Array.from(o);o.clear();for(let t of e)u(t)})))}function f(e){let t={value:e,observers:new Set};return[()=>(c(t),t.value),e=>{let n=typeof e==`function`?e(t.value):e;if(!Object.is(n,t.value)){t.value=n;for(let e of t.observers)d(e)}}]}function p(e){return t()===`ssr`?(e(),()=>{}):m(e)}function m(e){let t={fn:e,deps:new Set,disposed:!1};return u(t),()=>{t.disposed||(t.disposed=!0,l(t))}}function ee(e){let[t,n]=f(e());return m(()=>{n(e())}),t}function te(e){let t=()=>typeof e==`function`?e():e,n=String(t()??``),r=i();if(!r)return typeof document<`u`?document.createTextNode(n):{type:`text`,text:n};let a=r.createTextNode(n);if(r.getRenderMode()===`ssr`)return a;if(typeof e==`function`){let e=a,n=m(()=>{e.textContent=String(t()??``)});i()?.addNodeCleanup(e,n)}return a}function ne(e,t,n){let r=i();if(!r||r.getRenderMode()===`ssr`||t.startsWith(`on`))return()=>{};let a=e instanceof SVGElement,o=t===`className`?`class`:r.normalizeAttrKey(t,a),s=t=>{if(o===`class`){let n=r.classNames(t);if(!n){e.removeAttribute(`class`);return}e.setAttribute(`class`,n);return}if(t===!0){e.setAttribute(o,``);return}if(t===!1||t==null){e.removeAttribute(o);return}e.setAttribute(o,String(t))};if(typeof n==`function`){let t=m(()=>{s(n())});return r.addNodeCleanup(e,t),t}return s(n),()=>{}}var h=class extends Error{constructor(e){super(e),this.name=`HydrationError`}};function g(e){let t=e;return t.__vaniKeyed||=new Map,t.__vaniKeyed}function _(e){let t=t=>{let n,r,i=!1,a=t;if(t&&typeof t==`object`){let e=t;if(n=e.key,r=e.ref,i=e.clientOnly,`key`in e||`ref`in e){let{key:t,ref:n,clientOnly:r,...i}=e;a=i}}return{$$vani:`component`,component:e,props:a,key:n,ref:r,clientOnly:i}};return t.$$vaniWrapped=!0,t}function re(e){return _((t,n)=>{let r=e(t,n);return r instanceof Promise?r.then(e=>ie(e,n)):ie(r,n)})}function ie(e,t){let n,r=!0;return t.onBeforeMount(()=>(n=m(()=>{if(e(),r){r=!1;return}t.update()}),n)),e}function ae(e,r){let i=t();n(e);let a=r();return a&&typeof a.finally==`function`?a.finally(()=>{n(i)}):(n(i),a)}function v(e){if(typeof e!=`object`||!e||!(`type`in e))return!1;let t=e;switch(t.type){case`element`:return typeof t.tag==`string`&&typeof t.props==`object`&&Array.isArray(t.children);case`text`:case`comment`:return typeof t.text==`string`;case`fragment`:return Array.isArray(t.children);case`component`:return typeof t.instance==`object`&&t.instance!=null;default:return!1}}function y(e){return v(e)&&e.type===`element`}function oe(e){return v(e)&&e.type===`fragment`}const se=new Set([`svg`,`g`,`path`,`circle`,`rect`,`line`,`polyline`,`polygon`,`ellipse`,`defs`,`clipPath`,`mask`,`pattern`,`linearGradient`,`radialGradient`,`stop`,`use`]);function ce(e){return t()===`dom`?se.has(e)?document.createElementNS(`http://www.w3.org/2000/svg`,e):document.createElement(e):{type:`element`,tag:e,props:{},children:[]}}function b(e){return t()===`dom`?document.createTextNode(e):{type:`text`,text:e}}function x(e,n){if(t()===`dom`){e.appendChild(n);return}(y(e)||oe(e))&&e.children.push(n)}function le(e,t){let n=e;if(!n.__vaniCleanup){n.__vaniCleanup=[t];return}n.__vaniCleanup.push(t)}function ue(e){let t=e,n=t.__vaniCleanup;if(Array.isArray(n)){t.__vaniCleanup=null;for(let e of n)e()}}function S(e,t){let n=e.nextSibling;for(;n&&n!==t;){let e=n.nextSibling;if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`){let t=n.__vaniHandle;if(t){let r=t.__vaniEnd?.nextSibling??e;t.dispose(),n=r;continue}}ue(n);let t=n;t.__vaniDomRef&&(t.__vaniDomRef.current=null),n.remove(),n=e}}function C(e,t){let n=[],r=e.nextSibling;for(;r&&r!==t;)n.push(r),r=r.nextSibling;return n}function de(e){if(e==null||e===!1)return document.createComment(`vani:empty`);if(T(e)){let t=document.createDocumentFragment(),n=w(e.component,E(e),t);return e.ref&&(e.ref.current=n),t}if(typeof e==`string`||typeof e==`number`)return document.createTextNode(String(e));if(e instanceof Node)return e;throw Error(`[vani] render returned an unsupported node type in DOM mode`)}function w(e,t,n,r){let i=[],a=[],o=!1,s=!1,c,l,u=null,d=t?.clientOnly===!0;if(q){let e=Y;Y+=1,c=ke(n,e),l=Ae(c,e)}else c=document.createComment(`vani:start`),l=document.createComment(`vani:end`),n.appendChild(c),n.appendChild(l);let f,p={update(e){if(o)return;let t=p.__vaniUpdateOptions,n=e?.onlyAttributes?{onlyAttributes:!0}:{onlyAttributes:!1};(!t||!t.onlyAttributes||!n.onlyAttributes)&&(p.__vaniUpdateOptions=n),z?W.has(p)||(G.add(p),V>0?U=!0:K()):(G.delete(p),W.add(p),V>0?H=!0:De())},updateSync(e){if(o||!c.parentNode)return;let t=e??p.__vaniUpdateOptions;if(p.__vaniUpdateOptions=void 0,t?.onlyAttributes&&u){let e=F;F=!0;let t;try{t=f()}finally{F=e}if(t instanceof Node){let e=O(t);if(e&&e.tagName===u.tagName){_e(u,e);return}}}S(c,l);let n=de(f()),r=O(n);if(l.before(n),u=r,!s&&(s=!0,a.length>0)){let e=c.parentNode,t=null,n=()=>t||(t=C(c,l),t),r=a.splice(0,a.length);for(let t of r){let r=t(n,e);typeof r==`function`&&i.push(r)}}},onCleanup(e){i.push(e)},dispose(){if(!o){o=!0,c.__vaniHandle=null,p.__vaniStart=null,p.__vaniEnd=null,W.delete(p),G.delete(p);for(let e of i)e();i.length=0,S(c,l),c.remove(),l.remove(),f=(()=>document.createComment(`disposed`))}},onBeforeMount(e){let t=e();typeof t==`function`&&i.push(t)},onMount(e){if(!o){if(s){queueMicrotask(()=>{if(o)return;let t=c.parentNode,n=null,r=e(()=>n||(n=C(c,l),n),t);typeof r==`function`&&i.push(r)});return}a.push(e)}}};if(p.__vaniStart=c,p.__vaniEnd=l,c.__vaniHandle=p,q&&!d){let n=!1;return f=()=>{if(!n){n=!0;let r=e(t,p);f=r instanceof Promise?()=>document.createComment(`async`):r}return f()},p}let m=e(t,p);return m instanceof Promise?(f=t?.fallback||(()=>document.createComment(`vani:async`)),(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),m.then(e=>{o||(f=e,p.update())}).catch(e=>{o||(console.error(`[vani] async component failed:`,e),queueMicrotask(()=>{throw e}))}),p):(f=m,(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),p)}function fe(e){return Array.isArray(e)?e:[e]}function pe(e,t){if(!t)throw Error(`[vani] root element not found`);globalThis.Vani$$=!0;let n=[],r=fe(e);for(let e of r){if(typeof e==`function`){if(e.$$vaniWrapped){let r=e(),i=w(r.component,E(r),t);n.push(i);continue}let r=w(e,{},t);n.push(r);continue}let r=w(e.component,E(e),t);n.push(r)}return n}function me(e){if(!e)throw Error(`[vani] container element not found`);globalThis.Vani$$=!0;let t=[],n=!1;return{render(r){if(n)throw Error(`[vani] Cannot render to an unmounted root. Create a new root instead.`);for(let e of t)e.dispose();t=[],e.innerHTML=``;let i=fe(r);for(let n of i){if(typeof n==`function`){if(n.$$vaniWrapped){let r=n(),i=w(r.component,E(r),e);t.push(i);continue}let r=w(n,{},e);t.push(r);continue}let r=w(n.component,E(n),e);t.push(r)}},unmount(){if(!n){n=!0;for(let e of t)e.dispose();t=[],e.innerHTML=``}}}}function T(e){let t=typeof Node<`u`&&e instanceof Node;if(typeof e!=`object`||t)return!1;let n=e;return n.$$vani===`component`&&typeof n.component==`function`}function he(e){let t=typeof Node<`u`&&e instanceof Node;return typeof e==`object`&&!!e&&!t&&!T(e)&&!v(e)}function E(e){return e.clientOnly?{...e.props??{},clientOnly:!0}:e.props}function ge(e){let t=e.__vaniStart,n=e.__vaniEnd;return!t||!n?null:{start:t,end:n}}function D(e,t,n,r=null){let i=document.createDocumentFragment(),a=t;for(;a;){let e=a.nextSibling;if(i.appendChild(a),a===n)break;a=e}e.insertBefore(i,r)}function O(e){if(e.nodeType===Node.ELEMENT_NODE)return e;if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE){let t=e.firstChild;if(t&&t.nodeType===Node.ELEMENT_NODE&&t.nextSibling===null)return t}return null}function _e(e,t){let n=new Set(t.getAttributeNames());for(let t of e.getAttributeNames())n.has(t)||e.removeAttribute(t);for(let r of n){let n=t.getAttribute(r);e.getAttribute(r)!==n&&(n===null?e.removeAttribute(r):e.setAttribute(r,n))}}function k(e,t){if(e.props===t)return!1;if(!e.props||typeof e.props!=`object`||!t||typeof t!=`object`)return e.props=t,!0;let n=!1,r=e.props,i=t;for(let e in r)e in i||(delete r[e],n=!0);for(let e in i)r[e]!==i[e]&&(r[e]=i[e],n=!0);return n}function A(e,t,n=null){let r=document.createDocumentFragment(),i=w(t.component,E(t),r,{initialRender:`sync`});t.ref&&(t.ref.current=i);let a=ge(i)??void 0,o={component:t.component,handle:i,fragment:r,ref:t.ref,props:t.props,start:a?.start,end:a?.end};return e.insertBefore(r,n),o}function j(e){let t=[];for(let n of e)Array.isArray(n)?t.push(...j(n)):t.push(n);return t}function M(e,n){let r=j(n);if(t()===`ssr`){for(let t of r)if(!(t==null||t===!1||t===void 0)){if(T(t)){x(e,{type:`component`,instance:t});continue}if(typeof t==`string`||typeof t==`number`){x(e,b(String(t)));continue}if(!Array.isArray(t)&&v(t)){x(e,t);continue}}return}let i=e;for(let e of r)if(!(e==null||e===!1||e===void 0)){if(T(e)){if(e.key!=null){let t=g(i),n=i.__vaniUsedKeys??=new Set,r=t.get(e.key);r&&r.component!==e.component&&(r.handle.dispose(),r.ref&&(r.ref.current=null),t.delete(e.key),r=void 0),r?(r.ref!==e.ref&&(r.ref&&(r.ref.current=null),r.ref=e.ref),r.ref&&(r.ref.current=r.handle),k(r,e.props)&&r.handle.update(),r.start&&r.end&&D(i,r.start,r.end)):(r=A(i,e,null),t.set(e.key,r)),n.add(e.key);continue}let t=document.createDocumentFragment(),n=w(e.component,E(e),t);e.ref&&(e.ref.current=n),i.appendChild(t);continue}if(typeof e==`string`||typeof e==`number`){i.appendChild(document.createTextNode(String(e)));continue}Array.isArray(e)||i.appendChild(e)}let a=i.__vaniKeyed,o=i.__vaniUsedKeys;if(a&&o){for(let[e,t]of a)o.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),a.delete(e));o.clear()}}function ve(e,n){if(t()===`ssr`)throw Error(`[vani] renderKeyedChildren is not supported in SSR mode`);let r=e,i=g(r),a=r.__vaniUsedKeys??=new Set,o=r.firstChild;for(let e of n){if(!T(e)||e.key==null)continue;let t=i.get(e.key);t&&t.component!==e.component&&(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e.key),t=void 0);let n=t==null;if(n)t=A(r,e,o),i.set(e.key,t);else{let n=t;n.ref!==e.ref&&(n.ref&&(n.ref.current=null),n.ref=e.ref),n.ref&&(n.ref.current=n.handle),k(n,e.props)&&n.handle.update(),t=n}let s=t;s.start&&s.end&&(!n&&o&&s.start!==o&&D(r,s.start,s.end,o),o=s.end.nextSibling),a.add(e.key)}for(let[e,t]of i)a.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e));a.clear()}function ye(e){return typeof SVGElement<`u`&&e instanceof SVGElement}function N(e,t){return e.startsWith(`aria`)?`aria-`+e.replace(`aria-`,``).replace(`aria`,``).toLowerCase():e.startsWith(`data`)?`data-`+e.replace(`data-`,``).replace(`data`,``):e.toLowerCase()===`htmlfor`?`for`:t?e:e.toLowerCase()}r({getRenderMode:t,createTextNode:e=>b(e),addNodeCleanup:le,classNames:P,normalizeAttrKey:N});function be(e,t){if(`class`in t&&`className`in t)throw Error(`[vani] Cannot use both "class" and "className" on the same element. Use one or the other.`);let n=y(e)?se.has(e.tag):ye(e);for(let r in t){let i=t[r];if(![`key`,`ref`].includes(r)){if(r===`className`||r===`class`){let t=P(i);y(e)?e.props.class=t:n?e.setAttribute(`class`,t):e.className=t;continue}if(r.startsWith(`on`)&&typeof i==`function`)y(e)||(e[r.toLowerCase()]=i);else if(r===`value`||r===`checked`||r===`selected`)y(e)?e.props[r]=String(i):e[r]=i;else if(i===!0)y(e)?e.props[r]=!0:e.setAttribute(r,``);else if(i===!1||i==null)continue;else{let t=N(r,n);y(e)?e.props[t]=String(i):e.setAttribute(t,String(i))}}}}function P(...e){return e.map(e=>{if(!(e==null||e===``))return typeof e==`string`?e.trim():Array.isArray(e)?P(...e):Object.entries(e).filter(([e,t])=>t).map(([e])=>e.trim()).join(` `).trim()}).filter(Boolean).join(` `)}let F=!1;const xe={select:[`value`]};function Se(e,t){let n=xe[e];if(!n)return{cleanProps:t,deferred:{}};let r={},i=!1;for(let e of n)e in t&&t[e]!==void 0&&(r[e]=t[e],i=!0);if(!i)return{cleanProps:t,deferred:{}};let a={...t};for(let e of n)delete a[e];return{cleanProps:a,deferred:r}}function Ce(e,t){if(!y(e))for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r)}function I(e,t,...n){let r=ce(e);if(he(t)){t.ref&&(!y(r)&&!F?(t.ref.current=r,r.__vaniDomRef=t.ref):t.ref.current=null);let{cleanProps:i,deferred:a}=Se(e,t);return be(r,i),F||M(r,n),Ce(r,a),r}return M(r,[t,...n]),r}const L=(...e)=>{if(t()===`ssr`){let t={type:`fragment`,children:[]};return M(t,e),t}let n=document.createDocumentFragment();return M(n,e),n};function we(e,n){if(t()===`ssr`)return{type:`component`,instance:{$$vani:`component`,component:e,props:n}};let r=document.createDocumentFragment();return w(e,n,r),r}let R=!1,z=!1,B=!1,V=0,H=!1,U=!1;const W=new Set,G=new Set;function Te(e){let t=z;z=!0;try{e()}finally{z=t,V>0?U=!0:K()}}function Ee(e){V+=1;try{e()}finally{--V,V===0&&(H&&(H=!1,De()),U&&(U=!1,K()))}}function K(){B||(B=!0,setTimeout(()=>{B=!1,Oe()},0))}function De(){R||(R=!0,queueMicrotask(()=>{R=!1;for(let e of W)e.updateSync(e.__vaniUpdateOptions);W.clear()}))}function Oe(){for(let e of G)e.updateSync(e.__vaniUpdateOptions);G.clear(),G.size>0&&K()}let q=!1,J=null,Y=0;function X(e){Z()&&console.warn(`[vani] hydration warning: ${e}`)}function ke(e,t){let n=J;(!n||!e.contains(n))&&(n=e.firstChild);let r=!1;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`)return r&&X(`Found <!--vani:end--> before <!--vani:start--> for component #${t}. This usually means the server HTML anchor order is incorrect.`),n;n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:end`&&(r=!0),n=n.nextSibling}throw X(`Expected <!--vani:start--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new h(`[vani] hydration failed: start anchor not found`)}function Ae(e,t){let n=e.nextSibling,r=0;for(;n;){if(n.nodeType===Node.COMMENT_NODE){if(n.nodeValue===`vani:start`)r+=1;else if(n.nodeValue===`vani:end`){if(r===0)return J=n.nextSibling,n;--r}}n=n.nextSibling}throw X(`Expected <!--vani:end--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new h(`[vani] hydration failed: end anchor not found`)}function je(e,t){let n=[];q=!0,J=t.firstChild,Y=0;try{n=pe(e,t)}catch(e){if(e instanceof h)console.error(`[vani] hydration failed:`,e);else throw e}finally{if(Z()&&J){let e=J,t=!1;for(;e;){if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;if(n===`vani:start`||n===`vani:end`){t=!0;break}}e=e.nextSibling}t&&X(`Unused SSR anchors detected after hydration. Some server-rendered DOM was not claimed by the client runtime.`)}q=!1,J=null,Y=0}return n}function Z(){return`__vaniDevMode`in globalThis?globalThis.__vaniDevMode===!0:import.meta.env?import.meta.env.DEV:typeof process<`u`&&process.env!==void 0?process.env.NODE_ENV===`development`:!1}const Q=Symbol.for(`vani.fragment`);function Me(e){return e==null||e===!1?[]:Array.isArray(e)?e:[e]}function Ne(e,t){if(!e||typeof e!=`object`)return{props:null,children:[],key:t,ref:void 0,hasChildrenProp:!1};let n=Object.prototype.hasOwnProperty.call(e,`children`),r=n?Me(e.children):[],i=t??e.key,a=e.ref,{key:o,ref:s,children:c,...l}=e;return{props:Object.keys(l).length>0?l:null,children:r,key:i,ref:a,hasChildrenProp:n}}function $(e,t,n){let{props:r,children:i,key:a,ref:o,hasChildrenProp:s}=Ne(t,n);if(e===Q)return L(...i);if(typeof e==`string`){let t=o==null?r:{...r??{},ref:o};return t?I(e,t,...i):I(e,null,...i)}if(typeof e==`function`){let t={...r??{}};return(i.length>0||s)&&(t.children=i.length<=1?i[0]:i),a!=null&&(t.key=a),o&&(t.ref=o),e.$$vaniWrapped?e(t):_(e)(t)}throw Error(`[vani] jsx runtime received an unsupported element type.`)}const Pe=$;function Fe(e,t,n,r,i,a){return $(e,t,n)}export{n as A,ee as C,r as D,te as E,t as O,m as S,f as T,ve as _,h as a,ae as b,_ as c,L as d,je as f,re as g,we as h,Pe as i,i as k,me as l,Z as m,$ as n,Ee as o,T as p,Fe as r,P as s,Q as t,I as u,pe as v,p as w,ne as x,Te as y};
2
+ //# sourceMappingURL=jsx-runtime-Bbqe4zqZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-runtime-BUSOLzm1.mjs","names":[],"sources":["../../src/vani/common.ts","../../src/vani/signals.ts","../../src/vani/runtime.ts","../../src/vani/jsx-runtime.ts"],"sourcesContent":["export type ClassName =\n | string\n | undefined\n | null\n | {\n [key: string]: boolean | undefined | null\n }\n | ClassName[]\n\nexport type RenderMode = 'dom' | 'ssr'\n\nexport type AttrValue = ClassName | string | number | boolean | null | undefined\nexport type TextNode = Node | { type: 'text'; text: string }\n\ntype StaticSettings = {\n renderMode: RenderMode\n domAdapter: SignalDomAdapter | null\n}\ntype SignalDomAdapter = {\n getRenderMode: () => 'dom' | 'ssr'\n createTextNode: (text: string) => TextNode\n addNodeCleanup: (node: Node, cleanup: () => void) => void\n classNames: (...classes: ClassName[]) => string\n normalizeAttrKey: (key: string, isSvg: boolean) => string\n}\n\nconst staticSettings: StaticSettings = {\n renderMode: 'dom',\n domAdapter: null,\n}\n\nexport function getRenderMode(): RenderMode {\n return staticSettings.renderMode\n}\n\nexport function setRenderMode(mode: RenderMode): void {\n staticSettings.renderMode = mode\n}\n\nexport function configureSignalDom(adapter: SignalDomAdapter): void {\n staticSettings.domAdapter = adapter\n}\n\nexport function getSignalDomAdapter(): SignalDomAdapter | null {\n return staticSettings.domAdapter\n}\n","import {\n getRenderMode,\n getSignalDomAdapter,\n type AttrValue,\n type ClassName,\n type TextNode,\n} from './common'\n\nexport type SignalGetter<T> = () => T\nexport type SignalSetter<T> = (value: T | ((prev: T) => T)) => void\nexport type Signal<T> = [SignalGetter<T>, SignalSetter<T>]\n\ntype SignalRecord<T> = {\n value: T\n observers: Set<SignalObserver>\n}\n\ntype SignalObserver = {\n fn: () => void | (() => void)\n deps: Set<SignalRecord<any>>\n cleanup?: () => void\n disposed: boolean\n}\n\nlet currentObserver: SignalObserver | null = null\nconst observerQueue = new Set<SignalObserver>()\nlet observerFlushScheduled = false\n\nfunction trackSignal(record: SignalRecord<any>) {\n if (!currentObserver || currentObserver.disposed) return\n if (!currentObserver.deps.has(record)) {\n currentObserver.deps.add(record)\n record.observers.add(currentObserver)\n }\n}\n\nfunction cleanupObserver(observer: SignalObserver) {\n for (const record of observer.deps) {\n record.observers.delete(observer)\n }\n observer.deps.clear()\n if (observer.cleanup) {\n observer.cleanup()\n observer.cleanup = undefined\n }\n}\n\nfunction runObserver(observer: SignalObserver) {\n if (observer.disposed) return\n cleanupObserver(observer)\n const prev = currentObserver\n currentObserver = observer\n const cleanup = observer.fn()\n currentObserver = prev\n if (typeof cleanup === 'function') {\n observer.cleanup = cleanup\n }\n}\n\nfunction scheduleObserver(observer: SignalObserver) {\n if (observer.disposed) return\n observerQueue.add(observer)\n if (observerFlushScheduled) return\n observerFlushScheduled = true\n queueMicrotask(() => {\n observerFlushScheduled = false\n const queued = Array.from(observerQueue)\n observerQueue.clear()\n for (const next of queued) {\n runObserver(next)\n }\n })\n}\n\nexport function signal<T>(value: T): Signal<T> {\n const record: SignalRecord<T> = {\n value,\n observers: new Set(),\n }\n\n const getter: SignalGetter<T> = () => {\n trackSignal(record)\n return record.value\n }\n\n const setter: SignalSetter<T> = (next) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(record.value) : next\n if (Object.is(resolved, record.value)) return\n record.value = resolved\n for (const observer of record.observers) {\n scheduleObserver(observer)\n }\n }\n\n return [getter, setter]\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n if (getRenderMode() === 'ssr') {\n fn()\n return () => {}\n }\n return createEffect(fn)\n}\n\nexport function createEffect(fn: () => void | (() => void)): () => void {\n const observer: SignalObserver = {\n fn,\n deps: new Set(),\n disposed: false,\n }\n\n runObserver(observer)\n\n return () => {\n if (observer.disposed) return\n observer.disposed = true\n cleanupObserver(observer)\n }\n}\n\nexport function derive<T>(fn: () => T): SignalGetter<T> {\n const [get, set] = signal(fn())\n createEffect(() => {\n set(fn())\n })\n return get\n}\n\nexport function text(value: SignalGetter<unknown> | (() => unknown) | unknown): TextNode {\n const resolve = () => (typeof value === 'function' ? (value as () => unknown)() : value)\n const textValue = String(resolve() ?? '')\n const adapter = getSignalDomAdapter()\n if (!adapter) {\n if (typeof document !== 'undefined') {\n return document.createTextNode(textValue)\n }\n return { type: 'text', text: textValue }\n }\n\n const node = adapter.createTextNode(textValue)\n if (adapter.getRenderMode() === 'ssr') {\n return node\n }\n\n if (typeof value === 'function') {\n const textNode = node as Text\n const dispose = createEffect(() => {\n textNode.textContent = String(resolve() ?? '')\n })\n getSignalDomAdapter()?.addNodeCleanup(textNode, dispose)\n }\n\n return node as TextNode\n}\n\nexport function attr(\n el: Element,\n name: string,\n value: SignalGetter<AttrValue> | (() => AttrValue) | AttrValue,\n) {\n const adapter = getSignalDomAdapter()\n if (!adapter) return () => {}\n if (adapter.getRenderMode() === 'ssr') return () => {}\n if (name.startsWith('on')) return () => {}\n\n const isSvg = el instanceof SVGElement\n const key = name === 'className' ? 'class' : adapter.normalizeAttrKey(name, isSvg)\n\n const apply = (nextValue: AttrValue) => {\n if (key === 'class') {\n const classValue = adapter.classNames(nextValue as ClassName)\n if (!classValue) {\n el.removeAttribute('class')\n return\n }\n el.setAttribute('class', classValue)\n return\n }\n\n if (nextValue === true) {\n el.setAttribute(key, '')\n return\n }\n\n if (nextValue === false || nextValue == null) {\n el.removeAttribute(key)\n return\n }\n\n el.setAttribute(key, String(nextValue))\n }\n\n if (typeof value === 'function') {\n const disposer = createEffect(() => {\n apply((value as () => AttrValue)())\n })\n adapter.addNodeCleanup(el, disposer)\n return disposer\n }\n\n apply(value as AttrValue)\n return () => {}\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/prefer-dom-node-append */\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable unicorn/no-negated-condition */\n\nimport {\n configureSignalDom,\n getRenderMode,\n setRenderMode,\n type ClassName,\n type RenderMode,\n type TextNode,\n} from './common'\nimport { createEffect } from './signals'\n\n// ─────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────\n\nexport type SSRNode =\n | {\n type: 'element'\n tag: string\n props: Record<string, any>\n children: SSRNode[]\n }\n | { type: 'text'; text: string }\n | { type: 'comment'; text: string }\n | { type: 'fragment'; children: SSRNode[] }\n | { type: 'component'; instance: ComponentInstance<any> }\n\nexport type VNode = Node | SSRNode\n\nexport class HydrationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'HydrationError'\n }\n}\n\nexport interface Handle {\n /**\n * Schedules a render for the component.\n * This triggers a re-render on the next microtask.\n */\n update(options?: UpdateOptions): void\n /**\n * Flushes the component render.\n * This triggers a re-render immediately.\n */\n updateSync(options?: UpdateOptions): void\n /**\n * Disposes the component: removes the component from the DOM and runs all cleanup functions.\n */\n dispose(): void\n /**\n * Adds a cleanup function that is called when the component is disposed.\n */\n onCleanup(fn: () => void): void\n /**\n * This is purely syntatic sugar, as it is basically the same as running the function\n * on the setup phase and calling onCleanup to add a cleanup function.\n *\n * Using onBeforeMount is necessary in SSR mode, for side effects to not run on the server\n * (e.g. timers, subscriptions, DOM usage, etc.)\n *\n * Runs a side effect function during component setup, before the first render.\n * The returning function may be a cleanup function that is called when the component is disposed.\n *\n */\n onBeforeMount(fn: () => void | (() => void)): void\n /**\n * Runs after the first render, once the component's nodes are in the DOM.\n * The first argument is a lazy getter for the mounted nodes, so it only traverses\n * the DOM if called. The second argument is the parent mount point.\n * The returning function may be a cleanup function that is called when the component is disposed.\n */\n onMount(fn: (getNodes: () => Node[], parent: Node | null) => void | (() => void)): void\n}\n\nexport type RenderFn = () => VChild\n\nexport type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>\n\n// Component instance descriptor (returned by component())\nexport type ComponentInstance<Props = any> = {\n $$vani: 'component'\n component: Component<Props>\n props: Props\n /**\n * A key is used to identify the component when it is re-rendered.\n * If a key is provided, the component will be re-rendered only if the key changes.\n */\n key?: string | number\n /**\n * A ref is used to get a reference to the component instance.\n * The ref is set to the component instance when the component is mounted.\n * The ref is set to null when the component is disposed.\n */\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport type ComponentInput<Props> = Props & {\n key?: string | number\n ref?: ComponentRef\n}\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n fallback?: RenderFn\n clientOnly?: boolean\n}\n\nexport type VChild =\n | VNode\n | ComponentInstance<any>\n | string\n | number\n | null\n | undefined\n | false\n | VChild[]\n\nexport type DataAttribute = `data-${string}` | `data${Capitalize<string>}`\n\ntype HtmlTagName = keyof HTMLElementTagNameMap\ntype SvgTagName = keyof SVGElementTagNameMap\ntype ElementTagName = HtmlTagName | SvgTagName\n\ntype ElementByTag<T extends ElementTagName> = T extends HtmlTagName\n ? HTMLElementTagNameMap[T]\n : T extends SvgTagName\n ? SVGElementTagNameMap[T]\n : Element\n\nexport type SvgProps<T extends SvgTagName = SvgTagName> = BaseProps<T> & {\n [key: string]: unknown\n}\n\ntype BaseProps<T extends ElementTagName> = (\n | {\n class?: ClassName\n className?: never\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n | {\n class?: never\n className?: ClassName\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n) & {\n [key: DataAttribute]: string | number | boolean | undefined | null\n}\n\nexport type HtmlProps<T extends HtmlTagName = HtmlTagName> = BaseProps<T> &\n Partial<Omit<ElementByTag<T>, 'children' | 'className' | 'style'>>\n\nexport type ElementProps<T extends ElementTagName> = T extends SvgTagName\n ? SvgProps<T>\n : HtmlProps<Extract<T, HtmlTagName>>\n\ntype KeyedRecord = {\n handle: Handle\n fragment: DocumentFragment\n ref?: ComponentRef\n component: Component<any>\n props: unknown\n start?: Comment\n end?: Comment\n}\n\nexport type ComponentRef = {\n current: Handle | null\n}\n\nexport type DomRef<T extends Element = Element> = {\n current: T | null\n}\n\nexport type UpdateOptions = {\n onlyAttributes?: boolean\n}\n\n// ─────────────────────────────────────────────\n// component() helper\n// ─────────────────────────────────────────────\n\nfunction getKeyedMap(parent: Node): Map<string | number, KeyedRecord> {\n const anyParent = parent as any\n if (!anyParent.__vaniKeyed) {\n anyParent.__vaniKeyed = new Map()\n }\n return anyParent.__vaniKeyed\n}\n\nexport function component(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function component<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function component<Props>(fn: Component<Props>) {\n const wrapper = (input?: ComponentInput<Props>): ComponentInstance<Props> => {\n let key: string | number | undefined\n let ref: ComponentRef | undefined\n let clientOnly = false\n let props = input as Props\n\n if (input && typeof input === 'object') {\n const anyInput = input as any\n key = anyInput.key\n ref = anyInput.ref\n clientOnly = anyInput.clientOnly\n if ('key' in anyInput || 'ref' in anyInput) {\n const { key: _, ref: __, clientOnly: ___, ...rest } = anyInput\n props = rest\n }\n }\n\n return {\n $$vani: 'component',\n component: fn,\n props,\n key,\n ref,\n clientOnly,\n }\n }\n\n // Mark as wrapped component for JSX runtime detection\n ;(wrapper as any).$$vaniWrapped = true\n\n return wrapper\n}\n\n/**\n * Creates a reactive component that auto-tracks signal reads and re-renders when signals change.\n *\n * This is the only \"magic\" in Vani - signals read during render are automatically tracked,\n * and when any tracked signal changes, the component re-renders.\n *\n * @example\n * ```tsx\n * const [count, setCount] = signal(0)\n *\n * const Counter = reactive((props, handle) => {\n * return () => <div>Count: {count()}</div>\n * })\n * ```\n */\nexport function reactive(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function reactive<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function reactive<Props>(fn: Component<Props>) {\n const reactiveComponent: Component<Props> = (props, handle) => {\n const render = fn(props, handle)\n\n // Handle async components\n if (render instanceof Promise) {\n return render.then((renderFn) => {\n return wrapRenderWithEffect(renderFn, handle)\n })\n }\n\n return wrapRenderWithEffect(render, handle)\n }\n\n return component(reactiveComponent)\n}\n\nfunction wrapRenderWithEffect(render: RenderFn, handle: Handle): RenderFn {\n let disposeEffect: (() => void) | undefined\n let isFirstRun = true\n\n handle.onBeforeMount(() => {\n disposeEffect = createEffect(() => {\n // Run render to track signal dependencies\n render()\n\n if (isFirstRun) {\n isFirstRun = false\n return\n }\n\n // On subsequent runs, trigger component update\n handle.update()\n })\n\n return disposeEffect\n })\n\n return render\n}\n\n// ─────────────────────────────────────────────\n// Render mode (DOM vs SSR)\n// ─────────────────────────────────────────────\n\nexport function withRenderMode<T>(mode: RenderMode, fn: () => T): T {\n const prev = getRenderMode()\n setRenderMode(mode)\n const result = fn()\n if (result && typeof (result as unknown as Promise<unknown>).finally === 'function') {\n return (result as unknown as Promise<unknown>).finally(() => {\n setRenderMode(prev)\n }) as T\n }\n setRenderMode(prev)\n return result\n}\n\nfunction isSsrNode(node: VNode): node is SSRNode {\n if (typeof node !== 'object' || node === null || !('type' in node)) {\n return false\n }\n\n const anyNode = node as SSRNode\n switch (anyNode.type) {\n case 'element':\n return (\n typeof anyNode.tag === 'string' &&\n typeof anyNode.props === 'object' &&\n Array.isArray(anyNode.children)\n )\n case 'text':\n case 'comment':\n return typeof anyNode.text === 'string'\n case 'fragment':\n return Array.isArray(anyNode.children)\n case 'component':\n return typeof anyNode.instance === 'object' && anyNode.instance != null\n default:\n return false\n }\n}\n\nfunction isSsrElement(node: VNode): node is Extract<SSRNode, { type: 'element' }> {\n return isSsrNode(node) && node.type === 'element'\n}\n\nfunction isSsrFragment(node: VNode): node is Extract<SSRNode, { type: 'fragment' }> {\n return isSsrNode(node) && node.type === 'fragment'\n}\n\nconst svgTags = new Set<string>([\n 'svg',\n 'g',\n 'path',\n 'circle',\n 'rect',\n 'line',\n 'polyline',\n 'polygon',\n 'ellipse',\n 'defs',\n 'clipPath',\n 'mask',\n 'pattern',\n 'linearGradient',\n 'radialGradient',\n 'stop',\n 'use',\n])\n\nfunction createElementNode(tag: string): VNode {\n if (getRenderMode() === 'dom') {\n if (svgTags.has(tag)) {\n return document.createElementNS('http://www.w3.org/2000/svg', tag)\n }\n return document.createElement(tag)\n }\n return { type: 'element', tag, props: {}, children: [] }\n}\n\nfunction createTextNode(text: string): VNode {\n if (getRenderMode() === 'dom') {\n return document.createTextNode(text)\n }\n return { type: 'text', text }\n}\n\nfunction appendChildNode(parent: VNode, child: VNode) {\n if (getRenderMode() === 'dom') {\n ;(parent as Node).appendChild(child as Node)\n return\n }\n\n if (isSsrElement(parent) || isSsrFragment(parent)) {\n parent.children.push(child as SSRNode)\n }\n}\n\nfunction addNodeCleanup(node: Node, cleanup: () => void) {\n const anyNode = node as any\n if (!anyNode.__vaniCleanup) {\n anyNode.__vaniCleanup = [cleanup]\n return\n }\n anyNode.__vaniCleanup.push(cleanup)\n}\n\nfunction runNodeCleanup(node: Node) {\n const anyNode = node as any\n const cleanups = anyNode.__vaniCleanup\n if (!Array.isArray(cleanups)) return\n anyNode.__vaniCleanup = null\n for (const cleanup of cleanups) {\n cleanup()\n }\n}\n\n// ─────────────────────────────────────────────\n// Internal helpers\n// ─────────────────────────────────────────────\n\nfunction clearBetween(start: Comment, end: Comment) {\n let node = start.nextSibling\n while (node && node !== end) {\n const next = node.nextSibling\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n const handle = (node as any).__vaniHandle as Handle | undefined\n if (handle) {\n const endAnchor = (handle as any).__vaniEnd as Comment | undefined\n const afterDisposed = endAnchor?.nextSibling ?? next\n handle.dispose()\n node = afterDisposed\n continue\n }\n }\n runNodeCleanup(node)\n const anyNode = node as any\n if (anyNode.__vaniDomRef) {\n anyNode.__vaniDomRef.current = null\n }\n node.remove()\n node = next\n }\n}\n\nfunction getNodesBetween(start: Comment, end: Comment): Node[] {\n const nodes: Node[] = []\n let node = start.nextSibling\n while (node && node !== end) {\n nodes.push(node)\n node = node.nextSibling\n }\n return nodes\n}\n\n// ─────────────────────────────────────────────\n// Core mounting logic\n// ─────────────────────────────────────────────\n\nfunction normalizeDomChild(child: VChild): Node {\n if (child == null || child === false) {\n return document.createComment('vani:empty')\n }\n\n if (isComponentInstance(child)) {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n return fragment\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n return document.createTextNode(String(child))\n }\n\n if (child instanceof Node) {\n return child\n }\n\n throw new Error('[vani] render returned an unsupported node type in DOM mode')\n}\n\ntype MountOptions = {\n initialRender?: 'scheduled' | 'sync'\n}\n\nfunction mountComponent<Props>(\n component: Component<Props>,\n props: Props,\n parent: Node,\n options?: MountOptions,\n): Handle {\n const cleanups: Array<() => void> = []\n const mountCallbacks: Array<\n (getNodes: () => Node[], parent: Node | null) => void | (() => void)\n > = []\n let disposed = false\n let hasMounted = false\n let start: Comment\n let end: Comment\n let currentRootElement: Element | null = null\n\n // ─────────────────────────────────────────────\n // Anchor handling (hydration-aware)\n // ─────────────────────────────────────────────\n\n const clientOnly = (props as any)?.clientOnly === true\n\n if (isHydrating) {\n const componentIndex = hydrationComponentIndex\n hydrationComponentIndex += 1\n start = findNextStartAnchor(parent, componentIndex)\n end = findMatchingEndAnchor(start, componentIndex)\n } else {\n start = document.createComment('vani:start')\n end = document.createComment('vani:end')\n parent.appendChild(start)\n parent.appendChild(end)\n }\n\n let render!: RenderFn\n\n // ─────────────────────────────────────────────\n // Handle\n // ─────────────────────────────────────────────\n\n const handle: Handle = {\n update(options) {\n if (disposed) return\n\n const existingOptions = (handle as any).__vaniUpdateOptions as UpdateOptions | undefined\n const nextOptions = options?.onlyAttributes\n ? { onlyAttributes: true }\n : { onlyAttributes: false }\n if (!existingOptions || !existingOptions.onlyAttributes || !nextOptions.onlyAttributes) {\n ;(handle as any).__vaniUpdateOptions = nextOptions\n }\n\n if (inTransition) {\n if (!urgentQueue.has(handle)) {\n transitionQueue.add(handle)\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n } else {\n transitionQueue.delete(handle)\n urgentQueue.add(handle)\n if (batchDepth > 0) {\n pendingUrgentFlush = true\n } else {\n scheduleUrgentFlush()\n }\n }\n },\n\n updateSync(options) {\n if (disposed) return\n if (!start.parentNode) return\n\n const resolvedOptions =\n options ?? ((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n ;(handle as any).__vaniUpdateOptions = undefined\n\n if (resolvedOptions?.onlyAttributes && currentRootElement) {\n const prevAttrMode = attributesOnlyMode\n attributesOnlyMode = true\n let nextChild: VChild\n try {\n nextChild = render()\n } finally {\n attributesOnlyMode = prevAttrMode\n }\n\n if (nextChild instanceof Node) {\n const nextElement = getSingleElementFromNode(nextChild)\n if (nextElement && nextElement.tagName === currentRootElement.tagName) {\n patchElementAttributes(currentRootElement, nextElement)\n return\n }\n }\n }\n\n clearBetween(start, end)\n const node = normalizeDomChild(render())\n const nextElement = getSingleElementFromNode(node)\n end.before(node)\n currentRootElement = nextElement\n\n if (!hasMounted) {\n hasMounted = true\n if (mountCallbacks.length > 0) {\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const callbacks = mountCallbacks.splice(0, mountCallbacks.length)\n for (const callback of callbacks) {\n const cleanup = callback(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n }\n }\n }\n },\n\n onCleanup(fn) {\n cleanups.push(fn)\n },\n\n dispose() {\n if (disposed) return\n disposed = true\n ;(start as any).__vaniHandle = null\n ;(handle as any).__vaniStart = null\n ;(handle as any).__vaniEnd = null\n\n urgentQueue.delete(handle)\n transitionQueue.delete(handle)\n\n for (const fn of cleanups) fn()\n cleanups.length = 0\n\n clearBetween(start, end)\n start.remove()\n end.remove()\n\n // prevent accidental reuse\n render = (() => document.createComment('disposed')) as any\n },\n\n onBeforeMount(fn) {\n const cleanup = fn()\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n },\n\n onMount(fn) {\n if (disposed) return\n if (hasMounted) {\n queueMicrotask(() => {\n if (disposed) return\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const cleanup = fn(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n })\n return\n }\n mountCallbacks.push(fn)\n },\n }\n\n ;(handle as any).__vaniStart = start\n ;(handle as any).__vaniEnd = end\n ;(start as any).__vaniHandle = handle\n\n // ─────────────────────────────────────────────\n // Setup phase\n // ─────────────────────────────────────────────\n\n if (isHydrating && !clientOnly) {\n let initialized = false\n\n render = () => {\n if (!initialized) {\n initialized = true\n const result = component(props, handle)\n render = result instanceof Promise ? () => document.createComment('async') : result\n }\n return render()\n }\n\n return handle\n }\n\n const result = component(props, handle)\n\n // ─────────────────────────────────────────────\n // Async component\n // ─────────────────────────────────────────────\n\n if (result instanceof Promise) {\n const fallback = (props as any)?.fallback\n render = fallback ? fallback : () => document.createComment('vani:async')\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n result\n .then((realRender) => {\n if (disposed) return\n render = realRender\n handle.update()\n })\n .catch((error) => {\n if (disposed) return\n console.error('[vani] async component failed:', error)\n queueMicrotask(() => {\n throw error\n })\n })\n\n return handle\n }\n\n // ─────────────────────────────────────────────\n // Sync component\n // ─────────────────────────────────────────────\n\n render = result\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n return handle\n}\n\n// ─────────────────────────────────────────────\n// Public render API\n// ─────────────────────────────────────────────\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = ((\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>) & { $$vaniWrapped?: true }\n\ntype Renderable = Component<any> | ComponentInstance<any> | WrappedComponent<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nexport function renderToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n if (!root) {\n throw new Error('[vani] root element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n const handles: Handle[] = []\n const normalized = normalizeRenderables(components)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n // Check if it's a wrapped component (created with component())\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), root)\n handles.push(handle)\n continue\n }\n // raw component (no props)\n const handle = mountComponent(Comp as Component<any>, {} as any, root)\n handles.push(handle)\n continue\n }\n\n // ComponentInstance descriptor\n const handle = mountComponent(Comp.component, getMountProps(Comp), root)\n handles.push(handle)\n }\n\n return handles\n}\n\n// ─────────────────────────────────────────────\n// createRoot helper\n// ─────────────────────────────────────────────\n\nexport type Root = {\n /**\n * Renders a component into the root container.\n * Clears any existing content before rendering.\n * Can be called multiple times to replace the rendered content.\n */\n render(component: Renderable): void\n /**\n * Unmounts the rendered content and cleans up all resources.\n * After calling unmount(), the root cannot be used again.\n */\n unmount(): void\n}\n\n/**\n * Creates a root for rendering Vani components.\n *\n * Similar to React's createRoot API, this provides a clean way to manage\n * component lifecycle with automatic container clearing and proper cleanup.\n *\n * @example\n * ```ts\n * const root = createRoot(document.getElementById('app')!)\n * root.render(App())\n *\n * // Later, to unmount:\n * root.unmount()\n * ```\n */\nexport function createRoot(container: HTMLElement): Root {\n if (!container) {\n throw new Error('[vani] container element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n let handles: Handle[] = []\n let unmounted = false\n\n const root: Root = {\n render(component: Renderable) {\n if (unmounted) {\n throw new Error('[vani] Cannot render to an unmounted root. Create a new root instead.')\n }\n\n // Dispose existing handles\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n\n // Clear container content\n container.innerHTML = ''\n\n // Mount the new component\n const normalized = normalizeRenderables(component)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), container)\n handles.push(handle)\n continue\n }\n const handle = mountComponent(Comp as Component<any>, {} as any, container)\n handles.push(handle)\n continue\n }\n\n const handle = mountComponent(Comp.component, getMountProps(Comp), container)\n handles.push(handle)\n }\n },\n\n unmount() {\n if (unmounted) return\n\n unmounted = true\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n container.innerHTML = ''\n },\n }\n\n return root\n}\n\n// ─────────────────────────────────────────────\n// DOM helpers\n// ─────────────────────────────────────────────\n\nexport function isComponentInstance(child: VChild): child is ComponentInstance<any> {\n const isDomNode = typeof Node !== 'undefined' && child instanceof Node\n if (typeof child !== 'object' || isDomNode) return false\n const instance = child as ComponentInstance<any>\n return instance.$$vani === 'component' && typeof instance.component === 'function'\n}\n\nfunction isHtmlProps(props: any): props is ElementProps<any> {\n const isDomNode = typeof Node !== 'undefined' && props instanceof Node\n return (\n props !== null &&\n typeof props === 'object' &&\n !isDomNode &&\n !isComponentInstance(props as VChild) &&\n !isSsrNode(props as VNode)\n )\n}\n\nfunction getMountProps<Props>(instance: ComponentInstance<Props>): Props {\n if (!instance.clientOnly) return instance.props\n const base = (instance.props ?? {}) as Record<string, any>\n return { ...base, clientOnly: true } as Props\n}\n\nfunction getHandleAnchors(handle: Handle): { start: Comment; end: Comment } | null {\n const start = (handle as any).__vaniStart as Comment | null | undefined\n const end = (handle as any).__vaniEnd as Comment | null | undefined\n if (!start || !end) return null\n return { start, end }\n}\n\nfunction moveAnchoredRange(\n parent: Node,\n start: Comment,\n end: Comment,\n before: ChildNode | null = null,\n) {\n const fragment = document.createDocumentFragment()\n let node: ChildNode | null = start\n while (node) {\n const nextNode: ChildNode | null = node.nextSibling\n fragment.appendChild(node)\n if (node === end) break\n node = nextNode\n }\n parent.insertBefore(fragment, before)\n}\n\nfunction getSingleElementFromNode(node: Node): Element | null {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return node as Element\n }\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const fragment = node as DocumentFragment\n const first = fragment.firstChild\n if (first && first.nodeType === Node.ELEMENT_NODE && first.nextSibling === null) {\n return first as Element\n }\n }\n return null\n}\n\nfunction patchElementAttributes(target: Element, source: Element) {\n const nextNames = new Set(source.getAttributeNames())\n for (const name of target.getAttributeNames()) {\n if (!nextNames.has(name)) {\n target.removeAttribute(name)\n }\n }\n for (const name of nextNames) {\n const value = source.getAttribute(name)\n if (target.getAttribute(name) !== value) {\n if (value === null) {\n target.removeAttribute(name)\n } else {\n target.setAttribute(name, value)\n }\n }\n }\n}\n\nfunction updateRecordProps(record: KeyedRecord, nextProps: unknown): boolean {\n if (record.props === nextProps) return false\n if (\n !record.props ||\n typeof record.props !== 'object' ||\n !nextProps ||\n typeof nextProps !== 'object'\n ) {\n record.props = nextProps\n return true\n }\n\n let changed = false\n const prev = record.props as Record<string, any>\n const next = nextProps as Record<string, any>\n\n for (const key in prev) {\n if (!(key in next)) {\n delete prev[key]\n changed = true\n }\n }\n\n for (const key in next) {\n if (prev[key] !== next[key]) {\n prev[key] = next[key]\n changed = true\n }\n }\n\n return changed\n}\n\nfunction mountKeyedRecord(\n domParent: Node,\n instance: ComponentInstance<any>,\n before: ChildNode | null = null,\n): KeyedRecord {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(instance.component, getMountProps(instance), fragment, {\n initialRender: 'sync',\n })\n if (instance.ref) {\n instance.ref.current = handle\n }\n const anchors = getHandleAnchors(handle) ?? undefined\n const record: KeyedRecord = {\n component: instance.component,\n handle,\n fragment,\n ref: instance.ref,\n props: instance.props,\n start: anchors?.start,\n end: anchors?.end,\n }\n domParent.insertBefore(fragment, before)\n return record\n}\n\n// Flatten nested arrays recursively\nfunction flattenChildren(children: VChild[]): VChild[] {\n const result: VChild[] = []\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child as VChild[]))\n } else {\n result.push(child)\n }\n }\n return result\n}\n\nfunction appendChildren(parent: VNode, children: VChild[]) {\n // Auto-flatten arrays so users don't need fragment() for mapped children\n const flatChildren = flattenChildren(children)\n\n if (getRenderMode() === 'ssr') {\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n appendChildNode(parent, { type: 'component', instance: child })\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n appendChildNode(parent, createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n if (isSsrNode(child)) {\n appendChildNode(parent, child)\n continue\n }\n }\n\n return\n }\n\n const domParent = parent as Node\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n // keyed component\n // Only components support keys, and that is the correct design:\n // - DOM elements don’t need identity, components do.\n // - React uses virtual DOM and diffing, but Vani uses the real DOM and is simpler and faster.\n // - forcing identity only where it matters keeps Vani simple, fast, and predictable\n if (child.key != null) {\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n if (!record) {\n record = mountKeyedRecord(domParent, child, null)\n keyedMap.set(child.key, record)\n } else {\n if (record.ref !== child.ref) {\n if (record.ref) record.ref.current = null\n record.ref = child.ref\n }\n if (record.ref) record.ref.current = record.handle\n if (updateRecordProps(record, child.props)) {\n record.handle.update()\n }\n if (record.start && record.end) {\n moveAnchoredRange(domParent, record.start, record.end)\n }\n }\n\n usedKeys.add(child.key)\n continue\n }\n\n // non-keyed component\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n domParent.appendChild(fragment)\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n domParent.appendChild(document.createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n domParent.appendChild(child as Node)\n }\n\n const keyedMap = (domParent as any).__vaniKeyed as Map<string | number, KeyedRecord> | undefined\n const usedKeys = (domParent as any).__vaniUsedKeys as Set<string | number> | undefined\n\n if (keyedMap && usedKeys) {\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n }\n}\n\nexport function renderKeyedChildren(parent: Node, children: Array<ComponentInstance<any>>): void {\n if (getRenderMode() === 'ssr') {\n throw new Error('[vani] renderKeyedChildren is not supported in SSR mode')\n }\n\n const domParent = parent as Node\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n let cursor: ChildNode | null = domParent.firstChild\n\n for (const child of children) {\n if (!isComponentInstance(child) || child.key == null) {\n continue\n }\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n const isNewRecord = record == null\n if (isNewRecord) {\n record = mountKeyedRecord(domParent, child, cursor)\n keyedMap.set(child.key, record)\n } else {\n const existingRecord = record as KeyedRecord\n if (existingRecord.ref !== child.ref) {\n if (existingRecord.ref) existingRecord.ref.current = null\n existingRecord.ref = child.ref\n }\n if (existingRecord.ref) existingRecord.ref.current = existingRecord.handle\n if (updateRecordProps(existingRecord, child.props)) {\n existingRecord.handle.update()\n }\n record = existingRecord\n }\n\n const activeRecord = record as KeyedRecord\n if (activeRecord.start && activeRecord.end) {\n if (!isNewRecord && cursor && activeRecord.start !== cursor) {\n moveAnchoredRange(domParent, activeRecord.start, activeRecord.end, cursor)\n }\n cursor = activeRecord.end.nextSibling\n }\n\n usedKeys.add(child.key)\n }\n\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n}\n\nfunction isSvgElement(el: VNode): el is SVGElement {\n return typeof SVGElement !== 'undefined' && el instanceof SVGElement\n}\n\nfunction normalizeAttrKey(key: string, isSvg: boolean) {\n if (key.startsWith('aria')) {\n return 'aria-' + key.replace('aria-', '').replace('aria', '').toLowerCase()\n }\n if (key.startsWith('data')) {\n return 'data-' + key.replace('data-', '').replace('data', '')\n }\n if (key.toLowerCase() === 'htmlfor') {\n return 'for'\n }\n if (isSvg) return key\n return key.toLowerCase()\n}\n\nconfigureSignalDom({\n getRenderMode,\n createTextNode: (text: string) => createTextNode(text) as TextNode,\n addNodeCleanup,\n classNames,\n normalizeAttrKey,\n})\n\nfunction setProps(el: VNode, props: Record<string, any>) {\n // Check for class/className conflict\n if ('class' in props && 'className' in props) {\n throw new Error(\n '[vani] Cannot use both \"class\" and \"className\" on the same element. Use one or the other.',\n )\n }\n\n const isSvg = isSsrElement(el) ? svgTags.has(el.tag) : isSvgElement(el)\n for (const key in props) {\n const value = props[key]\n\n if (['key', 'ref'].includes(key)) {\n continue\n }\n\n // Handle both class and className (class is alias for className)\n if (key === 'className' || key === 'class') {\n const classValue = classNames(value)\n if (isSsrElement(el)) {\n el.props.class = classValue\n } else if (isSvg) {\n ;(el as SVGElement).setAttribute('class', classValue)\n } else {\n ;(el as HTMLElement).className = classValue\n }\n continue\n }\n\n if (key.startsWith('on') && typeof value === 'function') {\n if (!isSsrElement(el)) {\n ;(el as any)[key.toLowerCase()] = value\n }\n } else if (key === 'value' || key === 'checked' || key === 'selected') {\n // These properties must be set as DOM properties, not attributes\n if (!isSsrElement(el)) {\n ;(el as any)[key] = value\n } else {\n el.props[key] = String(value)\n }\n } else if (value === true) {\n if (isSsrElement(el)) {\n el.props[key] = true\n } else {\n ;(el as HTMLElement).setAttribute(key, '')\n }\n } else if (value === false || value == null) {\n continue\n } else {\n const normalizedKey = normalizeAttrKey(key, isSvg)\n if (isSsrElement(el)) {\n el.props[normalizedKey] = String(value)\n } else {\n ;(el as HTMLElement).setAttribute(normalizedKey, String(value))\n }\n }\n }\n}\n\nexport function classNames(...classes: ClassName[]): string {\n return classes\n .map((cls) => {\n if (cls === null || cls === undefined || cls === '') {\n return\n }\n if (typeof cls === 'string') {\n return cls.trim()\n }\n if (Array.isArray(cls)) {\n return classNames(...cls)\n }\n return Object.entries(cls)\n .filter(([_, value]) => value)\n .map(([key]) => key.trim())\n .join(' ')\n .trim()\n })\n .filter(Boolean)\n .join(' ')\n}\n\n// ─────────────────────────────────────────────\n// Element helpers\n// ─────────────────────────────────────────────\n\nlet attributesOnlyMode = false\n\n// Properties that must be set AFTER children are appended (e.g., select value needs options first)\nconst DEFERRED_PROPS: Record<string, string[]> = {\n select: ['value'],\n // Add other elements here if needed in the future\n}\n\ntype DeferredPropValues = Record<string, unknown>\n\nfunction extractDeferredProps(\n tag: string,\n props: Record<string, any>,\n): { cleanProps: Record<string, any>; deferred: DeferredPropValues } {\n const deferredKeys = DEFERRED_PROPS[tag]\n if (!deferredKeys) {\n return { cleanProps: props, deferred: {} }\n }\n\n const deferred: DeferredPropValues = {}\n let hasDeferred = false\n\n for (const key of deferredKeys) {\n if (key in props && props[key] !== undefined) {\n deferred[key] = props[key]\n hasDeferred = true\n }\n }\n\n if (!hasDeferred) {\n return { cleanProps: props, deferred: {} }\n }\n\n const cleanProps = { ...props }\n for (const key of deferredKeys) {\n delete cleanProps[key]\n }\n\n return { cleanProps, deferred }\n}\n\nfunction applyDeferredProps(node: VNode, deferred: DeferredPropValues): void {\n if (isSsrElement(node)) return\n\n for (const [key, value] of Object.entries(deferred)) {\n if (value !== undefined) {\n ;(node as any)[key] = value\n }\n }\n}\n\nexport function el<E extends ElementTagName>(\n tag: E,\n props?: ElementProps<E> | VChild | null,\n ...children: VChild[]\n): VNode {\n const node = createElementNode(tag)\n if (isHtmlProps(props)) {\n if (props.ref) {\n if (!isSsrElement(node) && !attributesOnlyMode) {\n props.ref.current = node as ElementByTag<E>\n ;(node as any).__vaniDomRef = props.ref\n } else {\n props.ref.current = null\n }\n }\n\n const { cleanProps, deferred } = extractDeferredProps(tag, props)\n setProps(node, cleanProps)\n\n if (!attributesOnlyMode) {\n appendChildren(node, children)\n }\n\n applyDeferredProps(node, deferred)\n return node\n }\n\n appendChildren(node, [props, ...children])\n return node\n}\n\nexport const fragment = (...children: VChild[]) => {\n if (getRenderMode() === 'ssr') {\n const node: SSRNode = { type: 'fragment', children: [] }\n appendChildren(node, children)\n return node\n }\n\n const node = document.createDocumentFragment()\n appendChildren(node, children)\n return node\n}\n\n// ─────────────────────────────────────────────\n// Low-level mount helper for unwrapped component functions\n// ─────────────────────────────────────────────\nexport function mount<Props>(component: Component<Props>, props: Props): VNode {\n if (getRenderMode() === 'ssr') {\n return {\n type: 'component',\n instance: {\n $$vani: 'component',\n component,\n props,\n },\n }\n }\n\n const fragment = document.createDocumentFragment()\n mountComponent(component, props, fragment)\n return fragment\n}\n\n// ─────────────────────────────────────────────\n// Transitions and Render batching\n// ─────────────────────────────────────────────\nlet flushScheduled = false\nlet inTransition = false\nlet transitionFlushScheduled = false\nlet batchDepth = 0\nlet pendingUrgentFlush = false\nlet pendingTransitionFlush = false\n\nconst urgentQueue = new Set<Handle>()\nconst transitionQueue = new Set<Handle>()\n\n/**\n * Marks all updates triggered inside the callback as a \"transition\".\n *\n * A transition represents non-urgent UI work that can be deferred\n * to keep the application responsive.\n *\n * Updates scheduled inside `startTransition`:\n * - do NOT block user interactions\n * - are batched separately from urgent updates\n * - may be flushed later (e.g. after the current event or during idle time)\n *\n * Transitions are NOT animations.\n * They do not control how updates look, only *when* they are applied.\n *\n * Typical use cases:\n * - Filtering or sorting large lists\n * - Rendering expensive subtrees\n * - Applying async results that are not immediately visible\n *\n * Example:\n * ```ts\n * button({\n * onclick: () => {\n * // urgent update\n * setOpen(true)\n * handle.update()\n *\n * // non-urgent update\n * startTransition(() => {\n * setItems(filter(items))\n * handle.update()\n * })\n * },\n * })\n * ```\n *\n * If multiple transitions are triggered, they are automatically batched.\n * Transition updates never interrupt urgent updates.\n */\nexport function startTransition(fn: () => void): void {\n const prev = inTransition\n inTransition = true\n\n try {\n fn()\n } finally {\n inTransition = prev\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n}\n\nexport function batch(fn: () => void): void {\n batchDepth += 1\n try {\n fn()\n } finally {\n batchDepth -= 1\n if (batchDepth === 0) {\n if (pendingUrgentFlush) {\n pendingUrgentFlush = false\n scheduleUrgentFlush()\n }\n if (pendingTransitionFlush) {\n pendingTransitionFlush = false\n scheduleTransitionFlush()\n }\n }\n }\n}\n\nfunction scheduleTransitionFlush() {\n if (transitionFlushScheduled) return\n transitionFlushScheduled = true\n\n // defer more than urgent work\n setTimeout(() => {\n transitionFlushScheduled = false\n flushTransitionQueue()\n }, 0)\n}\n\nfunction scheduleUrgentFlush() {\n if (flushScheduled) return\n flushScheduled = true\n\n queueMicrotask(() => {\n flushScheduled = false\n for (const handle of urgentQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n urgentQueue.clear()\n })\n}\n\nfunction flushTransitionQueue() {\n for (const handle of transitionQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n transitionQueue.clear()\n\n // if something queued during flush, schedule again\n if (transitionQueue.size > 0) {\n scheduleTransitionFlush()\n }\n}\n\n// ─────────────────────────────────────────────\n// Hydration and SSR\n// ─────────────────────────────────────────────\nlet isHydrating = false\nlet hydrationCursor: ChildNode | null = null\nlet hydrationComponentIndex = 0\n\nfunction warnHydration(message: string) {\n if (!isDevMode()) return\n console.warn(`[vani] hydration warning: ${message}`)\n}\n\nfunction findNextStartAnchor(parent: Node, componentIndex: number): Comment {\n let node = hydrationCursor\n if (!node || !parent.contains(node)) {\n node = parent.firstChild\n }\n let sawEndBeforeStart = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n if (sawEndBeforeStart) {\n warnHydration(\n `Found <!--vani:end--> before <!--vani:start--> for component #${componentIndex}. ` +\n `This usually means the server HTML anchor order is incorrect.`,\n )\n }\n return node as Comment\n }\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:end') {\n sawEndBeforeStart = true\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:start--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: start anchor not found')\n}\n\nfunction findMatchingEndAnchor(start: Comment, componentIndex: number): Comment {\n let node = start.nextSibling\n let depth = 0\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n if (node.nodeValue === 'vani:start') {\n depth += 1\n } else if (node.nodeValue === 'vani:end') {\n if (depth === 0) {\n hydrationCursor = node.nextSibling\n return node as Comment\n }\n depth -= 1\n }\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:end--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: end anchor not found')\n}\n\nexport function hydrateToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n let handles: Handle[] = []\n isHydrating = true\n hydrationCursor = root.firstChild\n hydrationComponentIndex = 0\n try {\n handles = renderToDOM(components, root)\n } catch (error) {\n if (error instanceof HydrationError) {\n console.error('[vani] hydration failed:', error)\n } else {\n throw error\n }\n } finally {\n if (isDevMode() && hydrationCursor) {\n let node: ChildNode | null = hydrationCursor\n let foundExtraAnchors = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n const value = node.nodeValue\n if (value === 'vani:start' || value === 'vani:end') {\n foundExtraAnchors = true\n break\n }\n }\n node = node.nextSibling\n }\n\n if (foundExtraAnchors) {\n warnHydration(\n 'Unused SSR anchors detected after hydration. ' +\n 'Some server-rendered DOM was not claimed by the client runtime.',\n )\n }\n }\n isHydrating = false\n hydrationCursor = null\n hydrationComponentIndex = 0\n }\n return handles\n}\n\nexport function isDevMode() {\n if ('__vaniDevMode' in globalThis) {\n return (globalThis as any).__vaniDevMode === true\n }\n\n // @ts-ignore\n if (import.meta.env) {\n // @ts-ignore\n return import.meta.env.DEV\n }\n\n // @ts-ignore\n if (typeof process !== 'undefined' && process.env !== undefined) {\n // @ts-ignore\n return process.env.NODE_ENV === 'development'\n }\n\n return false\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-namespace */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n/* eslint-disable unicorn/no-useless-fallback-in-spread */\n\nimport {\n component,\n el,\n fragment,\n type Component,\n type ComponentInstance,\n type ComponentRef,\n type DomRef,\n type ElementProps,\n type VChild,\n type VNode,\n} from './runtime'\nimport type { ClassName } from './common'\n\ntype ElementTagName = Extract<keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap, string>\ntype IntrinsicElementProps<Tag extends ElementTagName> = ElementProps<Tag> & {\n children?: VChild | VChild[]\n key?: string | number\n class?: ClassName // Alias for className, for HTML compatibility\n}\ntype Key = string | number | null | undefined\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = (\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport const Fragment = Symbol.for('vani.fragment')\n\ntype SplitPropsResult = {\n props: Record<string, any> | null\n children: VChild[]\n key: Key\n ref: DomRef<Element> | ComponentRef | undefined\n hasChildrenProp: boolean\n}\n\nfunction toChildArray(children: VChild | VChild[] | undefined): VChild[] {\n if (children == null || children === false) return []\n return Array.isArray(children) ? children : [children]\n}\n\nfunction splitProps(input: Record<string, any> | null | undefined, key?: Key): SplitPropsResult {\n if (!input || typeof input !== 'object') {\n return {\n props: null,\n children: [],\n key,\n ref: undefined,\n hasChildrenProp: false,\n }\n }\n\n const hasChildrenProp = Object.prototype.hasOwnProperty.call(input, 'children')\n const children = hasChildrenProp ? toChildArray(input.children) : []\n const resolvedKey = key ?? input.key\n const ref = input.ref as DomRef<Element> | ComponentRef | undefined\n const { key: _key, ref: _ref, children: _children, ...rest } = input\n const props = Object.keys(rest).length > 0 ? rest : null\n\n return { props, children, key: resolvedKey, ref, hasChildrenProp }\n}\n\ntype JsxElementType = string | Component<any> | WrappedComponent<any> | typeof Fragment\n\nexport function jsx(type: JsxElementType, props: Record<string, any> | null, key?: Key) {\n const {\n props: cleanProps,\n children,\n key: resolvedKey,\n ref,\n hasChildrenProp,\n } = splitProps(props, key)\n\n if (type === Fragment) {\n return fragment(...children)\n }\n\n if (typeof type === 'string') {\n const elementProps =\n ref == null ? cleanProps : ({ ...(cleanProps ?? {}), ref } as Record<string, any>)\n if (elementProps) {\n return el(type as ElementTagName, elementProps, ...children)\n }\n return el(type as ElementTagName, null, ...children)\n }\n\n if (typeof type === 'function') {\n const componentProps = { ...(cleanProps ?? {}) } as Record<string, any>\n if (children.length > 0 || hasChildrenProp) {\n componentProps.children = children.length <= 1 ? children[0] : children\n }\n if (resolvedKey != null) {\n componentProps.key = resolvedKey\n }\n if (ref) {\n componentProps.ref = ref\n }\n // Check if it's already a wrapped component (has $$vaniWrapped marker)\n if ((type as any).$$vaniWrapped) {\n return (type as WrappedComponent)(componentProps)\n }\n // Otherwise wrap it as a raw Component\n return component(type as Component<any>)(componentProps)\n }\n\n throw new Error('[vani] jsx runtime received an unsupported element type.')\n}\n\nexport const jsxs = jsx\n\nexport function jsxDEV(\n type: JsxElementType,\n props: Record<string, any> | null,\n key?: Key,\n _isStaticChildren?: boolean,\n _source?: unknown,\n _self?: unknown,\n) {\n return jsx(type, props, key)\n}\n\nexport namespace JSX {\n export type Element = VNode | ComponentInstance<any>\n export type ElementType = JsxElementType\n export interface ElementChildrenAttribute {\n children: {}\n }\n export interface IntrinsicAttributes {\n key?: string | number\n ref?: DomRef<globalThis.Element> | ComponentRef\n }\n export type IntrinsicElements = { [K in ElementTagName]: IntrinsicElementProps<K> }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"jsx-runtime-Bbqe4zqZ.mjs","names":[],"sources":["../../src/vani/common.ts","../../src/vani/signals.ts","../../src/vani/runtime.ts","../../src/vani/jsx-runtime.ts"],"sourcesContent":["export type ClassName =\n | string\n | undefined\n | null\n | {\n [key: string]: boolean | undefined | null\n }\n | ClassName[]\n\nexport type RenderMode = 'dom' | 'ssr'\n\nexport type AttrValue = ClassName | string | number | boolean | null | undefined\nexport type TextNode = Node | { type: 'text'; text: string }\n\ntype StaticSettings = {\n renderMode: RenderMode\n domAdapter: SignalDomAdapter | null\n}\ntype SignalDomAdapter = {\n getRenderMode: () => 'dom' | 'ssr'\n createTextNode: (text: string) => TextNode\n addNodeCleanup: (node: Node, cleanup: () => void) => void\n classNames: (...classes: ClassName[]) => string\n normalizeAttrKey: (key: string, isSvg: boolean) => string\n}\n\nconst staticSettings: StaticSettings = {\n renderMode: 'dom',\n domAdapter: null,\n}\n\nexport function getRenderMode(): RenderMode {\n return staticSettings.renderMode\n}\n\nexport function setRenderMode(mode: RenderMode): void {\n staticSettings.renderMode = mode\n}\n\nexport function configureSignalDom(adapter: SignalDomAdapter): void {\n staticSettings.domAdapter = adapter\n}\n\nexport function getSignalDomAdapter(): SignalDomAdapter | null {\n return staticSettings.domAdapter\n}\n","import {\n getRenderMode,\n getSignalDomAdapter,\n type AttrValue,\n type ClassName,\n type TextNode,\n} from './common'\n\nexport type SignalGetter<T> = () => T\nexport type SignalSetter<T> = (value: T | ((prev: T) => T)) => void\nexport type Signal<T> = [SignalGetter<T>, SignalSetter<T>]\n\ntype SignalRecord<T> = {\n value: T\n observers: Set<SignalObserver>\n}\n\ntype SignalObserver = {\n fn: () => void | (() => void)\n deps: Set<SignalRecord<any>>\n cleanup?: () => void\n disposed: boolean\n}\n\nlet currentObserver: SignalObserver | null = null\nconst observerQueue = new Set<SignalObserver>()\nlet observerFlushScheduled = false\n\nfunction trackSignal(record: SignalRecord<any>) {\n if (!currentObserver || currentObserver.disposed) return\n if (!currentObserver.deps.has(record)) {\n currentObserver.deps.add(record)\n record.observers.add(currentObserver)\n }\n}\n\nfunction cleanupObserver(observer: SignalObserver) {\n for (const record of observer.deps) {\n record.observers.delete(observer)\n }\n observer.deps.clear()\n if (observer.cleanup) {\n observer.cleanup()\n observer.cleanup = undefined\n }\n}\n\nfunction runObserver(observer: SignalObserver) {\n if (observer.disposed) return\n cleanupObserver(observer)\n const prev = currentObserver\n currentObserver = observer\n const cleanup = observer.fn()\n currentObserver = prev\n if (typeof cleanup === 'function') {\n observer.cleanup = cleanup\n }\n}\n\nfunction scheduleObserver(observer: SignalObserver) {\n if (observer.disposed) return\n observerQueue.add(observer)\n if (observerFlushScheduled) return\n observerFlushScheduled = true\n queueMicrotask(() => {\n observerFlushScheduled = false\n const queued = Array.from(observerQueue)\n observerQueue.clear()\n for (const next of queued) {\n runObserver(next)\n }\n })\n}\n\nexport function signal<T>(value: T): Signal<T> {\n const record: SignalRecord<T> = {\n value,\n observers: new Set(),\n }\n\n const getter: SignalGetter<T> = () => {\n trackSignal(record)\n return record.value\n }\n\n const setter: SignalSetter<T> = (next) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(record.value) : next\n if (Object.is(resolved, record.value)) return\n record.value = resolved\n for (const observer of record.observers) {\n scheduleObserver(observer)\n }\n }\n\n return [getter, setter]\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n if (getRenderMode() === 'ssr') {\n fn()\n return () => {}\n }\n return createEffect(fn)\n}\n\nexport function createEffect(fn: () => void | (() => void)): () => void {\n const observer: SignalObserver = {\n fn,\n deps: new Set(),\n disposed: false,\n }\n\n runObserver(observer)\n\n return () => {\n if (observer.disposed) return\n observer.disposed = true\n cleanupObserver(observer)\n }\n}\n\nexport function derive<T>(fn: () => T): SignalGetter<T> {\n const [get, set] = signal(fn())\n createEffect(() => {\n set(fn())\n })\n return get\n}\n\nexport function text(value: SignalGetter<unknown> | (() => unknown) | unknown): TextNode {\n const resolve = () => (typeof value === 'function' ? (value as () => unknown)() : value)\n const textValue = String(resolve() ?? '')\n const adapter = getSignalDomAdapter()\n if (!adapter) {\n if (typeof document !== 'undefined') {\n return document.createTextNode(textValue)\n }\n return { type: 'text', text: textValue }\n }\n\n const node = adapter.createTextNode(textValue)\n if (adapter.getRenderMode() === 'ssr') {\n return node\n }\n\n if (typeof value === 'function') {\n const textNode = node as Text\n const dispose = createEffect(() => {\n textNode.textContent = String(resolve() ?? '')\n })\n getSignalDomAdapter()?.addNodeCleanup(textNode, dispose)\n }\n\n return node as TextNode\n}\n\nexport function attr(\n el: Element,\n name: string,\n value: SignalGetter<AttrValue> | (() => AttrValue) | AttrValue,\n) {\n const adapter = getSignalDomAdapter()\n if (!adapter) return () => {}\n if (adapter.getRenderMode() === 'ssr') return () => {}\n if (name.startsWith('on')) return () => {}\n\n const isSvg = el instanceof SVGElement\n const key = name === 'className' ? 'class' : adapter.normalizeAttrKey(name, isSvg)\n\n const apply = (nextValue: AttrValue) => {\n if (key === 'class') {\n const classValue = adapter.classNames(nextValue as ClassName)\n if (!classValue) {\n el.removeAttribute('class')\n return\n }\n el.setAttribute('class', classValue)\n return\n }\n\n if (nextValue === true) {\n el.setAttribute(key, '')\n return\n }\n\n if (nextValue === false || nextValue == null) {\n el.removeAttribute(key)\n return\n }\n\n el.setAttribute(key, String(nextValue))\n }\n\n if (typeof value === 'function') {\n const disposer = createEffect(() => {\n apply((value as () => AttrValue)())\n })\n adapter.addNodeCleanup(el, disposer)\n return disposer\n }\n\n apply(value as AttrValue)\n return () => {}\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/prefer-dom-node-append */\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable unicorn/no-negated-condition */\n\nimport {\n configureSignalDom,\n getRenderMode,\n setRenderMode,\n type ClassName,\n type RenderMode,\n type TextNode,\n} from './common'\nimport { createEffect } from './signals'\n\n// ─────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────\n\nexport type SSRNode =\n | {\n type: 'element'\n tag: string\n props: Record<string, any>\n children: SSRNode[]\n }\n | { type: 'text'; text: string }\n | { type: 'comment'; text: string }\n | { type: 'fragment'; children: SSRNode[] }\n | { type: 'component'; instance: ComponentInstance<any> }\n\nexport type VNode = Node | SSRNode\n\nexport class HydrationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'HydrationError'\n }\n}\n\nexport interface Handle {\n /**\n * Schedules a render for the component.\n * This triggers a re-render on the next microtask.\n */\n update(options?: UpdateOptions): void\n /**\n * Flushes the component render.\n * This triggers a re-render immediately.\n */\n updateSync(options?: UpdateOptions): void\n /**\n * Disposes the component: removes the component from the DOM and runs all cleanup functions.\n */\n dispose(): void\n /**\n * Adds a cleanup function that is called when the component is disposed.\n */\n onCleanup(fn: () => void): void\n /**\n * This is purely syntatic sugar, as it is basically the same as running the function\n * on the setup phase and calling onCleanup to add a cleanup function.\n *\n * Using onBeforeMount is necessary in SSR mode, for side effects to not run on the server\n * (e.g. timers, subscriptions, DOM usage, etc.)\n *\n * Runs a side effect function during component setup, before the first render.\n * The returning function may be a cleanup function that is called when the component is disposed.\n *\n */\n onBeforeMount(fn: () => void | (() => void)): void\n /**\n * Runs after the first render, once the component's nodes are in the DOM.\n * The first argument is a lazy getter for the mounted nodes, so it only traverses\n * the DOM if called. The second argument is the parent mount point.\n * The returning function may be a cleanup function that is called when the component is disposed.\n */\n onMount(fn: (getNodes: () => Node[], parent: Node | null) => void | (() => void)): void\n}\n\nexport type RenderFn = () => VChild\n\nexport type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>\n\n// Component instance descriptor (returned by component())\nexport type ComponentInstance<Props = any> = {\n $$vani: 'component'\n component: Component<Props>\n props: Props\n /**\n * A key is used to identify the component when it is re-rendered.\n * If a key is provided, the component will be re-rendered only if the key changes.\n */\n key?: string | number\n /**\n * A ref is used to get a reference to the component instance.\n * The ref is set to the component instance when the component is mounted.\n * The ref is set to null when the component is disposed.\n */\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport type ComponentInput<Props> = Props & {\n key?: string | number\n ref?: ComponentRef\n}\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n fallback?: RenderFn\n clientOnly?: boolean\n}\n\nexport type VChild =\n | VNode\n | ComponentInstance<any>\n | string\n | number\n | null\n | undefined\n | false\n | VChild[]\n\nexport type DataAttribute = `data-${string}` | `data${Capitalize<string>}`\n\ntype HtmlTagName = keyof HTMLElementTagNameMap\ntype SvgTagName = keyof SVGElementTagNameMap\ntype ElementTagName = HtmlTagName | SvgTagName\n\ntype ElementByTag<T extends ElementTagName> = T extends HtmlTagName\n ? HTMLElementTagNameMap[T]\n : T extends SvgTagName\n ? SVGElementTagNameMap[T]\n : Element\n\nexport type SvgProps<T extends SvgTagName = SvgTagName> = BaseProps<T> & {\n [key: string]: unknown\n}\n\ntype BaseProps<T extends ElementTagName> = (\n | {\n class?: ClassName\n className?: never\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n | {\n class?: never\n className?: ClassName\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n) & {\n [key: DataAttribute]: string | number | boolean | undefined | null\n}\n\nexport type HtmlProps<T extends HtmlTagName = HtmlTagName> = BaseProps<T> &\n Partial<Omit<ElementByTag<T>, 'children' | 'className' | 'style'>>\n\nexport type ElementProps<T extends ElementTagName> = T extends SvgTagName\n ? SvgProps<T>\n : HtmlProps<Extract<T, HtmlTagName>>\n\ntype KeyedRecord = {\n handle: Handle\n fragment: DocumentFragment\n ref?: ComponentRef\n component: Component<any>\n props: unknown\n start?: Comment\n end?: Comment\n}\n\nexport type ComponentRef = {\n current: Handle | null\n}\n\nexport type DomRef<T extends Element = Element> = {\n current: T | null\n}\n\nexport type UpdateOptions = {\n onlyAttributes?: boolean\n}\n\n// ─────────────────────────────────────────────\n// component() helper\n// ─────────────────────────────────────────────\n\nfunction getKeyedMap(parent: Node): Map<string | number, KeyedRecord> {\n const anyParent = parent as any\n if (!anyParent.__vaniKeyed) {\n anyParent.__vaniKeyed = new Map()\n }\n return anyParent.__vaniKeyed\n}\n\nexport function component(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function component<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function component<Props>(fn: Component<Props>) {\n const wrapper = (input?: ComponentInput<Props>): ComponentInstance<Props> => {\n let key: string | number | undefined\n let ref: ComponentRef | undefined\n let clientOnly = false\n let props = input as Props\n\n if (input && typeof input === 'object') {\n const anyInput = input as any\n key = anyInput.key\n ref = anyInput.ref\n clientOnly = anyInput.clientOnly\n if ('key' in anyInput || 'ref' in anyInput) {\n const { key: _, ref: __, clientOnly: ___, ...rest } = anyInput\n props = rest\n }\n }\n\n return {\n $$vani: 'component',\n component: fn,\n props,\n key,\n ref,\n clientOnly,\n }\n }\n\n // Mark as wrapped component for JSX runtime detection\n ;(wrapper as any).$$vaniWrapped = true\n\n return wrapper\n}\n\n/**\n * Creates a reactive component that auto-tracks signal reads and re-renders when signals change.\n *\n * This is the only \"magic\" in Vani - signals read during render are automatically tracked,\n * and when any tracked signal changes, the component re-renders.\n *\n * @example\n * ```tsx\n * const [count, setCount] = signal(0)\n *\n * const Counter = reactive((props, handle) => {\n * return () => <div>Count: {count()}</div>\n * })\n * ```\n */\nexport function reactive(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function reactive<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function reactive<Props>(fn: Component<Props>) {\n const reactiveComponent: Component<Props> = (props, handle) => {\n const render = fn(props, handle)\n\n // Handle async components\n if (render instanceof Promise) {\n return render.then((renderFn) => {\n return wrapRenderWithEffect(renderFn, handle)\n })\n }\n\n return wrapRenderWithEffect(render, handle)\n }\n\n return component(reactiveComponent)\n}\n\nfunction wrapRenderWithEffect(render: RenderFn, handle: Handle): RenderFn {\n let disposeEffect: (() => void) | undefined\n let isFirstRun = true\n\n handle.onBeforeMount(() => {\n disposeEffect = createEffect(() => {\n // Run render to track signal dependencies\n render()\n\n if (isFirstRun) {\n isFirstRun = false\n return\n }\n\n // On subsequent runs, trigger component update\n handle.update()\n })\n\n return disposeEffect\n })\n\n return render\n}\n\n// ─────────────────────────────────────────────\n// Render mode (DOM vs SSR)\n// ─────────────────────────────────────────────\n\nexport function withRenderMode<T>(mode: RenderMode, fn: () => T): T {\n const prev = getRenderMode()\n setRenderMode(mode)\n const result = fn()\n if (result && typeof (result as unknown as Promise<unknown>).finally === 'function') {\n return (result as unknown as Promise<unknown>).finally(() => {\n setRenderMode(prev)\n }) as T\n }\n setRenderMode(prev)\n return result\n}\n\nfunction isSsrNode(node: VNode): node is SSRNode {\n if (typeof node !== 'object' || node === null || !('type' in node)) {\n return false\n }\n\n const anyNode = node as SSRNode\n switch (anyNode.type) {\n case 'element':\n return (\n typeof anyNode.tag === 'string' &&\n typeof anyNode.props === 'object' &&\n Array.isArray(anyNode.children)\n )\n case 'text':\n case 'comment':\n return typeof anyNode.text === 'string'\n case 'fragment':\n return Array.isArray(anyNode.children)\n case 'component':\n return typeof anyNode.instance === 'object' && anyNode.instance != null\n default:\n return false\n }\n}\n\nfunction isSsrElement(node: VNode): node is Extract<SSRNode, { type: 'element' }> {\n return isSsrNode(node) && node.type === 'element'\n}\n\nfunction isSsrFragment(node: VNode): node is Extract<SSRNode, { type: 'fragment' }> {\n return isSsrNode(node) && node.type === 'fragment'\n}\n\nconst svgTags = new Set<string>([\n 'svg',\n 'g',\n 'path',\n 'circle',\n 'rect',\n 'line',\n 'polyline',\n 'polygon',\n 'ellipse',\n 'defs',\n 'clipPath',\n 'mask',\n 'pattern',\n 'linearGradient',\n 'radialGradient',\n 'stop',\n 'use',\n])\n\nfunction createElementNode(tag: string): VNode {\n if (getRenderMode() === 'dom') {\n if (svgTags.has(tag)) {\n return document.createElementNS('http://www.w3.org/2000/svg', tag)\n }\n return document.createElement(tag)\n }\n return { type: 'element', tag, props: {}, children: [] }\n}\n\nfunction createTextNode(text: string): VNode {\n if (getRenderMode() === 'dom') {\n return document.createTextNode(text)\n }\n return { type: 'text', text }\n}\n\nfunction appendChildNode(parent: VNode, child: VNode) {\n if (getRenderMode() === 'dom') {\n ;(parent as Node).appendChild(child as Node)\n return\n }\n\n if (isSsrElement(parent) || isSsrFragment(parent)) {\n parent.children.push(child as SSRNode)\n }\n}\n\nfunction addNodeCleanup(node: Node, cleanup: () => void) {\n const anyNode = node as any\n if (!anyNode.__vaniCleanup) {\n anyNode.__vaniCleanup = [cleanup]\n return\n }\n anyNode.__vaniCleanup.push(cleanup)\n}\n\nfunction runNodeCleanup(node: Node) {\n const anyNode = node as any\n const cleanups = anyNode.__vaniCleanup\n if (!Array.isArray(cleanups)) return\n anyNode.__vaniCleanup = null\n for (const cleanup of cleanups) {\n cleanup()\n }\n}\n\n// ─────────────────────────────────────────────\n// Internal helpers\n// ─────────────────────────────────────────────\n\nfunction clearBetween(start: Comment, end: Comment) {\n let node = start.nextSibling\n while (node && node !== end) {\n const next = node.nextSibling\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n const handle = (node as any).__vaniHandle as Handle | undefined\n if (handle) {\n const endAnchor = (handle as any).__vaniEnd as Comment | undefined\n const afterDisposed = endAnchor?.nextSibling ?? next\n handle.dispose()\n node = afterDisposed\n continue\n }\n }\n runNodeCleanup(node)\n const anyNode = node as any\n if (anyNode.__vaniDomRef) {\n anyNode.__vaniDomRef.current = null\n }\n node.remove()\n node = next\n }\n}\n\nfunction getNodesBetween(start: Comment, end: Comment): Node[] {\n const nodes: Node[] = []\n let node = start.nextSibling\n while (node && node !== end) {\n nodes.push(node)\n node = node.nextSibling\n }\n return nodes\n}\n\n// ─────────────────────────────────────────────\n// Core mounting logic\n// ─────────────────────────────────────────────\n\nfunction normalizeDomChild(child: VChild): Node {\n if (child == null || child === false) {\n return document.createComment('vani:empty')\n }\n\n if (isComponentInstance(child)) {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n return fragment\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n return document.createTextNode(String(child))\n }\n\n if (child instanceof Node) {\n return child\n }\n\n throw new Error('[vani] render returned an unsupported node type in DOM mode')\n}\n\ntype MountOptions = {\n initialRender?: 'scheduled' | 'sync'\n}\n\nfunction mountComponent<Props>(\n component: Component<Props>,\n props: Props,\n parent: Node,\n options?: MountOptions,\n): Handle {\n const cleanups: Array<() => void> = []\n const mountCallbacks: Array<\n (getNodes: () => Node[], parent: Node | null) => void | (() => void)\n > = []\n let disposed = false\n let hasMounted = false\n let start: Comment\n let end: Comment\n let currentRootElement: Element | null = null\n\n // ─────────────────────────────────────────────\n // Anchor handling (hydration-aware)\n // ─────────────────────────────────────────────\n\n const clientOnly = (props as any)?.clientOnly === true\n\n if (isHydrating) {\n const componentIndex = hydrationComponentIndex\n hydrationComponentIndex += 1\n start = findNextStartAnchor(parent, componentIndex)\n end = findMatchingEndAnchor(start, componentIndex)\n } else {\n start = document.createComment('vani:start')\n end = document.createComment('vani:end')\n parent.appendChild(start)\n parent.appendChild(end)\n }\n\n let render!: RenderFn\n\n // ─────────────────────────────────────────────\n // Handle\n // ─────────────────────────────────────────────\n\n const handle: Handle = {\n update(options) {\n if (disposed) return\n\n const existingOptions = (handle as any).__vaniUpdateOptions as UpdateOptions | undefined\n const nextOptions = options?.onlyAttributes\n ? { onlyAttributes: true }\n : { onlyAttributes: false }\n if (!existingOptions || !existingOptions.onlyAttributes || !nextOptions.onlyAttributes) {\n ;(handle as any).__vaniUpdateOptions = nextOptions\n }\n\n if (inTransition) {\n if (!urgentQueue.has(handle)) {\n transitionQueue.add(handle)\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n } else {\n transitionQueue.delete(handle)\n urgentQueue.add(handle)\n if (batchDepth > 0) {\n pendingUrgentFlush = true\n } else {\n scheduleUrgentFlush()\n }\n }\n },\n\n updateSync(options) {\n if (disposed) return\n if (!start.parentNode) return\n\n const resolvedOptions =\n options ?? ((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n ;(handle as any).__vaniUpdateOptions = undefined\n\n if (resolvedOptions?.onlyAttributes && currentRootElement) {\n const prevAttrMode = attributesOnlyMode\n attributesOnlyMode = true\n let nextChild: VChild\n try {\n nextChild = render()\n } finally {\n attributesOnlyMode = prevAttrMode\n }\n\n if (nextChild instanceof Node) {\n const nextElement = getSingleElementFromNode(nextChild)\n if (nextElement && nextElement.tagName === currentRootElement.tagName) {\n patchElementAttributes(currentRootElement, nextElement)\n return\n }\n }\n }\n\n clearBetween(start, end)\n const node = normalizeDomChild(render())\n const nextElement = getSingleElementFromNode(node)\n end.before(node)\n currentRootElement = nextElement\n\n if (!hasMounted) {\n hasMounted = true\n if (mountCallbacks.length > 0) {\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const callbacks = mountCallbacks.splice(0, mountCallbacks.length)\n for (const callback of callbacks) {\n const cleanup = callback(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n }\n }\n }\n },\n\n onCleanup(fn) {\n cleanups.push(fn)\n },\n\n dispose() {\n if (disposed) return\n disposed = true\n ;(start as any).__vaniHandle = null\n ;(handle as any).__vaniStart = null\n ;(handle as any).__vaniEnd = null\n\n urgentQueue.delete(handle)\n transitionQueue.delete(handle)\n\n for (const fn of cleanups) fn()\n cleanups.length = 0\n\n clearBetween(start, end)\n start.remove()\n end.remove()\n\n // prevent accidental reuse\n render = (() => document.createComment('disposed')) as any\n },\n\n onBeforeMount(fn) {\n const cleanup = fn()\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n },\n\n onMount(fn) {\n if (disposed) return\n if (hasMounted) {\n queueMicrotask(() => {\n if (disposed) return\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const cleanup = fn(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n })\n return\n }\n mountCallbacks.push(fn)\n },\n }\n\n ;(handle as any).__vaniStart = start\n ;(handle as any).__vaniEnd = end\n ;(start as any).__vaniHandle = handle\n\n // ─────────────────────────────────────────────\n // Setup phase\n // ─────────────────────────────────────────────\n\n if (isHydrating && !clientOnly) {\n let initialized = false\n\n render = () => {\n if (!initialized) {\n initialized = true\n const result = component(props, handle)\n render = result instanceof Promise ? () => document.createComment('async') : result\n }\n return render()\n }\n\n return handle\n }\n\n const result = component(props, handle)\n\n // ─────────────────────────────────────────────\n // Async component\n // ─────────────────────────────────────────────\n\n if (result instanceof Promise) {\n const fallback = (props as any)?.fallback\n render = fallback ? fallback : () => document.createComment('vani:async')\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n result\n .then((realRender) => {\n if (disposed) return\n render = realRender\n handle.update()\n })\n .catch((error) => {\n if (disposed) return\n console.error('[vani] async component failed:', error)\n queueMicrotask(() => {\n throw error\n })\n })\n\n return handle\n }\n\n // ─────────────────────────────────────────────\n // Sync component\n // ─────────────────────────────────────────────\n\n render = result\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n return handle\n}\n\n// ─────────────────────────────────────────────\n// Public render API\n// ─────────────────────────────────────────────\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = ((\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>) & { $$vaniWrapped?: true }\n\ntype Renderable = Component<any> | ComponentInstance<any> | WrappedComponent<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nexport function renderToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n if (!root) {\n throw new Error('[vani] root element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n const handles: Handle[] = []\n const normalized = normalizeRenderables(components)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n // Check if it's a wrapped component (created with component())\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), root)\n handles.push(handle)\n continue\n }\n // raw component (no props)\n const handle = mountComponent(Comp as Component<any>, {} as any, root)\n handles.push(handle)\n continue\n }\n\n // ComponentInstance descriptor\n const handle = mountComponent(Comp.component, getMountProps(Comp), root)\n handles.push(handle)\n }\n\n return handles\n}\n\n// ─────────────────────────────────────────────\n// createRoot helper\n// ─────────────────────────────────────────────\n\nexport type Root = {\n /**\n * Renders a component into the root container.\n * Clears any existing content before rendering.\n * Can be called multiple times to replace the rendered content.\n */\n render(component: Renderable): void\n /**\n * Unmounts the rendered content and cleans up all resources.\n * After calling unmount(), the root cannot be used again.\n */\n unmount(): void\n}\n\n/**\n * Creates a root for rendering Vani components.\n *\n * Similar to React's createRoot API, this provides a clean way to manage\n * component lifecycle with automatic container clearing and proper cleanup.\n *\n * @example\n * ```ts\n * const root = createRoot(document.getElementById('app')!)\n * root.render(App())\n *\n * // Later, to unmount:\n * root.unmount()\n * ```\n */\nexport function createRoot(container: HTMLElement): Root {\n if (!container) {\n throw new Error('[vani] container element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n let handles: Handle[] = []\n let unmounted = false\n\n const root: Root = {\n render(component: Renderable) {\n if (unmounted) {\n throw new Error('[vani] Cannot render to an unmounted root. Create a new root instead.')\n }\n\n // Dispose existing handles\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n\n // Clear container content\n container.innerHTML = ''\n\n // Mount the new component\n const normalized = normalizeRenderables(component)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), container)\n handles.push(handle)\n continue\n }\n const handle = mountComponent(Comp as Component<any>, {} as any, container)\n handles.push(handle)\n continue\n }\n\n const handle = mountComponent(Comp.component, getMountProps(Comp), container)\n handles.push(handle)\n }\n },\n\n unmount() {\n if (unmounted) return\n\n unmounted = true\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n container.innerHTML = ''\n },\n }\n\n return root\n}\n\n// ─────────────────────────────────────────────\n// DOM helpers\n// ─────────────────────────────────────────────\n\nexport function isComponentInstance(child: VChild): child is ComponentInstance<any> {\n const isDomNode = typeof Node !== 'undefined' && child instanceof Node\n if (typeof child !== 'object' || isDomNode) return false\n const instance = child as ComponentInstance<any>\n return instance.$$vani === 'component' && typeof instance.component === 'function'\n}\n\nfunction isHtmlProps(props: any): props is ElementProps<any> {\n const isDomNode = typeof Node !== 'undefined' && props instanceof Node\n return (\n props !== null &&\n typeof props === 'object' &&\n !isDomNode &&\n !isComponentInstance(props as VChild) &&\n !isSsrNode(props as VNode)\n )\n}\n\nfunction getMountProps<Props>(instance: ComponentInstance<Props>): Props {\n if (!instance.clientOnly) return instance.props\n const base = (instance.props ?? {}) as Record<string, any>\n return { ...base, clientOnly: true } as Props\n}\n\nfunction getHandleAnchors(handle: Handle): { start: Comment; end: Comment } | null {\n const start = (handle as any).__vaniStart as Comment | null | undefined\n const end = (handle as any).__vaniEnd as Comment | null | undefined\n if (!start || !end) return null\n return { start, end }\n}\n\nfunction moveAnchoredRange(\n parent: Node,\n start: Comment,\n end: Comment,\n before: ChildNode | null = null,\n) {\n const fragment = document.createDocumentFragment()\n let node: ChildNode | null = start\n while (node) {\n const nextNode: ChildNode | null = node.nextSibling\n fragment.appendChild(node)\n if (node === end) break\n node = nextNode\n }\n parent.insertBefore(fragment, before)\n}\n\nfunction getSingleElementFromNode(node: Node): Element | null {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return node as Element\n }\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const fragment = node as DocumentFragment\n const first = fragment.firstChild\n if (first && first.nodeType === Node.ELEMENT_NODE && first.nextSibling === null) {\n return first as Element\n }\n }\n return null\n}\n\nfunction patchElementAttributes(target: Element, source: Element) {\n const nextNames = new Set(source.getAttributeNames())\n for (const name of target.getAttributeNames()) {\n if (!nextNames.has(name)) {\n target.removeAttribute(name)\n }\n }\n for (const name of nextNames) {\n const value = source.getAttribute(name)\n if (target.getAttribute(name) !== value) {\n if (value === null) {\n target.removeAttribute(name)\n } else {\n target.setAttribute(name, value)\n }\n }\n }\n}\n\nfunction updateRecordProps(record: KeyedRecord, nextProps: unknown): boolean {\n if (record.props === nextProps) return false\n if (\n !record.props ||\n typeof record.props !== 'object' ||\n !nextProps ||\n typeof nextProps !== 'object'\n ) {\n record.props = nextProps\n return true\n }\n\n let changed = false\n const prev = record.props as Record<string, any>\n const next = nextProps as Record<string, any>\n\n for (const key in prev) {\n if (!(key in next)) {\n delete prev[key]\n changed = true\n }\n }\n\n for (const key in next) {\n if (prev[key] !== next[key]) {\n prev[key] = next[key]\n changed = true\n }\n }\n\n return changed\n}\n\nfunction mountKeyedRecord(\n domParent: Node,\n instance: ComponentInstance<any>,\n before: ChildNode | null = null,\n): KeyedRecord {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(instance.component, getMountProps(instance), fragment, {\n initialRender: 'sync',\n })\n if (instance.ref) {\n instance.ref.current = handle\n }\n const anchors = getHandleAnchors(handle) ?? undefined\n const record: KeyedRecord = {\n component: instance.component,\n handle,\n fragment,\n ref: instance.ref,\n props: instance.props,\n start: anchors?.start,\n end: anchors?.end,\n }\n domParent.insertBefore(fragment, before)\n return record\n}\n\n// Flatten nested arrays recursively\nfunction flattenChildren(children: VChild[]): VChild[] {\n const result: VChild[] = []\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child as VChild[]))\n } else {\n result.push(child)\n }\n }\n return result\n}\n\nfunction appendChildren(parent: VNode, children: VChild[]) {\n // Auto-flatten arrays so users don't need fragment() for mapped children\n const flatChildren = flattenChildren(children)\n\n if (getRenderMode() === 'ssr') {\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n appendChildNode(parent, { type: 'component', instance: child })\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n appendChildNode(parent, createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n if (isSsrNode(child)) {\n appendChildNode(parent, child)\n continue\n }\n }\n\n return\n }\n\n const domParent = parent as Node\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n // keyed component\n // Only components support keys, and that is the correct design:\n // - DOM elements don’t need identity, components do.\n // - React uses virtual DOM and diffing, but Vani uses the real DOM and is simpler and faster.\n // - forcing identity only where it matters keeps Vani simple, fast, and predictable\n if (child.key != null) {\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n if (!record) {\n record = mountKeyedRecord(domParent, child, null)\n keyedMap.set(child.key, record)\n } else {\n if (record.ref !== child.ref) {\n if (record.ref) record.ref.current = null\n record.ref = child.ref\n }\n if (record.ref) record.ref.current = record.handle\n if (updateRecordProps(record, child.props)) {\n record.handle.update()\n }\n if (record.start && record.end) {\n moveAnchoredRange(domParent, record.start, record.end)\n }\n }\n\n usedKeys.add(child.key)\n continue\n }\n\n // non-keyed component\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n domParent.appendChild(fragment)\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n domParent.appendChild(document.createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n domParent.appendChild(child as Node)\n }\n\n const keyedMap = (domParent as any).__vaniKeyed as Map<string | number, KeyedRecord> | undefined\n const usedKeys = (domParent as any).__vaniUsedKeys as Set<string | number> | undefined\n\n if (keyedMap && usedKeys) {\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n }\n}\n\nexport function renderKeyedChildren(parent: Node, children: Array<ComponentInstance<any>>): void {\n if (getRenderMode() === 'ssr') {\n throw new Error('[vani] renderKeyedChildren is not supported in SSR mode')\n }\n\n const domParent = parent as Node\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n let cursor: ChildNode | null = domParent.firstChild\n\n for (const child of children) {\n if (!isComponentInstance(child) || child.key == null) {\n continue\n }\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n const isNewRecord = record == null\n if (isNewRecord) {\n record = mountKeyedRecord(domParent, child, cursor)\n keyedMap.set(child.key, record)\n } else {\n const existingRecord = record as KeyedRecord\n if (existingRecord.ref !== child.ref) {\n if (existingRecord.ref) existingRecord.ref.current = null\n existingRecord.ref = child.ref\n }\n if (existingRecord.ref) existingRecord.ref.current = existingRecord.handle\n if (updateRecordProps(existingRecord, child.props)) {\n existingRecord.handle.update()\n }\n record = existingRecord\n }\n\n const activeRecord = record as KeyedRecord\n if (activeRecord.start && activeRecord.end) {\n if (!isNewRecord && cursor && activeRecord.start !== cursor) {\n moveAnchoredRange(domParent, activeRecord.start, activeRecord.end, cursor)\n }\n cursor = activeRecord.end.nextSibling\n }\n\n usedKeys.add(child.key)\n }\n\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n}\n\nfunction isSvgElement(el: VNode): el is SVGElement {\n return typeof SVGElement !== 'undefined' && el instanceof SVGElement\n}\n\nfunction normalizeAttrKey(key: string, isSvg: boolean) {\n if (key.startsWith('aria')) {\n return 'aria-' + key.replace('aria-', '').replace('aria', '').toLowerCase()\n }\n if (key.startsWith('data')) {\n return 'data-' + key.replace('data-', '').replace('data', '')\n }\n if (key.toLowerCase() === 'htmlfor') {\n return 'for'\n }\n if (isSvg) return key\n return key.toLowerCase()\n}\n\nconfigureSignalDom({\n getRenderMode,\n createTextNode: (text: string) => createTextNode(text) as TextNode,\n addNodeCleanup,\n classNames,\n normalizeAttrKey,\n})\n\nfunction setProps(el: VNode, props: Record<string, any>) {\n // Check for class/className conflict\n if ('class' in props && 'className' in props) {\n throw new Error(\n '[vani] Cannot use both \"class\" and \"className\" on the same element. Use one or the other.',\n )\n }\n\n const isSvg = isSsrElement(el) ? svgTags.has(el.tag) : isSvgElement(el)\n for (const key in props) {\n const value = props[key]\n\n if (['key', 'ref'].includes(key)) {\n continue\n }\n\n // Handle both class and className (class is alias for className)\n if (key === 'className' || key === 'class') {\n const classValue = classNames(value)\n if (isSsrElement(el)) {\n el.props.class = classValue\n } else if (isSvg) {\n ;(el as SVGElement).setAttribute('class', classValue)\n } else {\n ;(el as HTMLElement).className = classValue\n }\n continue\n }\n\n if (key.startsWith('on') && typeof value === 'function') {\n if (!isSsrElement(el)) {\n ;(el as any)[key.toLowerCase()] = value\n }\n } else if (key === 'value' || key === 'checked' || key === 'selected') {\n // These properties must be set as DOM properties, not attributes\n if (!isSsrElement(el)) {\n ;(el as any)[key] = value\n } else {\n el.props[key] = String(value)\n }\n } else if (value === true) {\n if (isSsrElement(el)) {\n el.props[key] = true\n } else {\n ;(el as HTMLElement).setAttribute(key, '')\n }\n } else if (value === false || value == null) {\n continue\n } else {\n const normalizedKey = normalizeAttrKey(key, isSvg)\n if (isSsrElement(el)) {\n el.props[normalizedKey] = String(value)\n } else {\n ;(el as HTMLElement).setAttribute(normalizedKey, String(value))\n }\n }\n }\n}\n\nexport function classNames(...classes: ClassName[]): string {\n return classes\n .map((cls) => {\n if (cls === null || cls === undefined || cls === '') {\n return\n }\n if (typeof cls === 'string') {\n return cls.trim()\n }\n if (Array.isArray(cls)) {\n return classNames(...cls)\n }\n return Object.entries(cls)\n .filter(([_, value]) => value)\n .map(([key]) => key.trim())\n .join(' ')\n .trim()\n })\n .filter(Boolean)\n .join(' ')\n}\n\n// ─────────────────────────────────────────────\n// Element helpers\n// ─────────────────────────────────────────────\n\nlet attributesOnlyMode = false\n\n// Properties that must be set AFTER children are appended (e.g., select value needs options first)\nconst DEFERRED_PROPS: Record<string, string[]> = {\n select: ['value'],\n // Add other elements here if needed in the future\n}\n\ntype DeferredPropValues = Record<string, unknown>\n\nfunction extractDeferredProps(\n tag: string,\n props: Record<string, any>,\n): { cleanProps: Record<string, any>; deferred: DeferredPropValues } {\n const deferredKeys = DEFERRED_PROPS[tag]\n if (!deferredKeys) {\n return { cleanProps: props, deferred: {} }\n }\n\n const deferred: DeferredPropValues = {}\n let hasDeferred = false\n\n for (const key of deferredKeys) {\n if (key in props && props[key] !== undefined) {\n deferred[key] = props[key]\n hasDeferred = true\n }\n }\n\n if (!hasDeferred) {\n return { cleanProps: props, deferred: {} }\n }\n\n const cleanProps = { ...props }\n for (const key of deferredKeys) {\n delete cleanProps[key]\n }\n\n return { cleanProps, deferred }\n}\n\nfunction applyDeferredProps(node: VNode, deferred: DeferredPropValues): void {\n if (isSsrElement(node)) return\n\n for (const [key, value] of Object.entries(deferred)) {\n if (value !== undefined) {\n ;(node as any)[key] = value\n }\n }\n}\n\nexport function el<E extends ElementTagName>(\n tag: E,\n props?: ElementProps<E> | VChild | null,\n ...children: VChild[]\n): VNode {\n const node = createElementNode(tag)\n if (isHtmlProps(props)) {\n if (props.ref) {\n if (!isSsrElement(node) && !attributesOnlyMode) {\n props.ref.current = node as ElementByTag<E>\n ;(node as any).__vaniDomRef = props.ref\n } else {\n props.ref.current = null\n }\n }\n\n const { cleanProps, deferred } = extractDeferredProps(tag, props)\n setProps(node, cleanProps)\n\n if (!attributesOnlyMode) {\n appendChildren(node, children)\n }\n\n applyDeferredProps(node, deferred)\n return node\n }\n\n appendChildren(node, [props, ...children])\n return node\n}\n\nexport const fragment = (...children: VChild[]) => {\n if (getRenderMode() === 'ssr') {\n const node: SSRNode = { type: 'fragment', children: [] }\n appendChildren(node, children)\n return node\n }\n\n const node = document.createDocumentFragment()\n appendChildren(node, children)\n return node\n}\n\n// ─────────────────────────────────────────────\n// Low-level mount helper for unwrapped component functions\n// ─────────────────────────────────────────────\nexport function mount<Props>(component: Component<Props>, props: Props): VNode {\n if (getRenderMode() === 'ssr') {\n return {\n type: 'component',\n instance: {\n $$vani: 'component',\n component,\n props,\n },\n }\n }\n\n const fragment = document.createDocumentFragment()\n mountComponent(component, props, fragment)\n return fragment\n}\n\n// ─────────────────────────────────────────────\n// Transitions and Render batching\n// ─────────────────────────────────────────────\nlet flushScheduled = false\nlet inTransition = false\nlet transitionFlushScheduled = false\nlet batchDepth = 0\nlet pendingUrgentFlush = false\nlet pendingTransitionFlush = false\n\nconst urgentQueue = new Set<Handle>()\nconst transitionQueue = new Set<Handle>()\n\n/**\n * Marks all updates triggered inside the callback as a \"transition\".\n *\n * A transition represents non-urgent UI work that can be deferred\n * to keep the application responsive.\n *\n * Updates scheduled inside `startTransition`:\n * - do NOT block user interactions\n * - are batched separately from urgent updates\n * - may be flushed later (e.g. after the current event or during idle time)\n *\n * Transitions are NOT animations.\n * They do not control how updates look, only *when* they are applied.\n *\n * Typical use cases:\n * - Filtering or sorting large lists\n * - Rendering expensive subtrees\n * - Applying async results that are not immediately visible\n *\n * Example:\n * ```ts\n * button({\n * onclick: () => {\n * // urgent update\n * setOpen(true)\n * handle.update()\n *\n * // non-urgent update\n * startTransition(() => {\n * setItems(filter(items))\n * handle.update()\n * })\n * },\n * })\n * ```\n *\n * If multiple transitions are triggered, they are automatically batched.\n * Transition updates never interrupt urgent updates.\n */\nexport function startTransition(fn: () => void): void {\n const prev = inTransition\n inTransition = true\n\n try {\n fn()\n } finally {\n inTransition = prev\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n}\n\nexport function batch(fn: () => void): void {\n batchDepth += 1\n try {\n fn()\n } finally {\n batchDepth -= 1\n if (batchDepth === 0) {\n if (pendingUrgentFlush) {\n pendingUrgentFlush = false\n scheduleUrgentFlush()\n }\n if (pendingTransitionFlush) {\n pendingTransitionFlush = false\n scheduleTransitionFlush()\n }\n }\n }\n}\n\nfunction scheduleTransitionFlush() {\n if (transitionFlushScheduled) return\n transitionFlushScheduled = true\n\n // defer more than urgent work\n setTimeout(() => {\n transitionFlushScheduled = false\n flushTransitionQueue()\n }, 0)\n}\n\nfunction scheduleUrgentFlush() {\n if (flushScheduled) return\n flushScheduled = true\n\n queueMicrotask(() => {\n flushScheduled = false\n for (const handle of urgentQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n urgentQueue.clear()\n })\n}\n\nfunction flushTransitionQueue() {\n for (const handle of transitionQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n transitionQueue.clear()\n\n // if something queued during flush, schedule again\n if (transitionQueue.size > 0) {\n scheduleTransitionFlush()\n }\n}\n\n// ─────────────────────────────────────────────\n// Hydration and SSR\n// ─────────────────────────────────────────────\nlet isHydrating = false\nlet hydrationCursor: ChildNode | null = null\nlet hydrationComponentIndex = 0\n\nfunction warnHydration(message: string) {\n if (!isDevMode()) return\n console.warn(`[vani] hydration warning: ${message}`)\n}\n\nfunction findNextStartAnchor(parent: Node, componentIndex: number): Comment {\n let node = hydrationCursor\n if (!node || !parent.contains(node)) {\n node = parent.firstChild\n }\n let sawEndBeforeStart = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n if (sawEndBeforeStart) {\n warnHydration(\n `Found <!--vani:end--> before <!--vani:start--> for component #${componentIndex}. ` +\n `This usually means the server HTML anchor order is incorrect.`,\n )\n }\n return node as Comment\n }\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:end') {\n sawEndBeforeStart = true\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:start--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: start anchor not found')\n}\n\nfunction findMatchingEndAnchor(start: Comment, componentIndex: number): Comment {\n let node = start.nextSibling\n let depth = 0\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n if (node.nodeValue === 'vani:start') {\n depth += 1\n } else if (node.nodeValue === 'vani:end') {\n if (depth === 0) {\n hydrationCursor = node.nextSibling\n return node as Comment\n }\n depth -= 1\n }\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:end--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: end anchor not found')\n}\n\nexport function hydrateToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n let handles: Handle[] = []\n isHydrating = true\n hydrationCursor = root.firstChild\n hydrationComponentIndex = 0\n try {\n handles = renderToDOM(components, root)\n } catch (error) {\n if (error instanceof HydrationError) {\n console.error('[vani] hydration failed:', error)\n } else {\n throw error\n }\n } finally {\n if (isDevMode() && hydrationCursor) {\n let node: ChildNode | null = hydrationCursor\n let foundExtraAnchors = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n const value = node.nodeValue\n if (value === 'vani:start' || value === 'vani:end') {\n foundExtraAnchors = true\n break\n }\n }\n node = node.nextSibling\n }\n\n if (foundExtraAnchors) {\n warnHydration(\n 'Unused SSR anchors detected after hydration. ' +\n 'Some server-rendered DOM was not claimed by the client runtime.',\n )\n }\n }\n isHydrating = false\n hydrationCursor = null\n hydrationComponentIndex = 0\n }\n return handles\n}\n\nexport function isDevMode() {\n if ('__vaniDevMode' in globalThis) {\n return (globalThis as any).__vaniDevMode === true\n }\n\n // @ts-ignore\n if (import.meta.env) {\n // @ts-ignore\n return import.meta.env.DEV\n }\n\n // @ts-ignore\n if (typeof process !== 'undefined' && process.env !== undefined) {\n // @ts-ignore\n return process.env.NODE_ENV === 'development'\n }\n\n return false\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-namespace */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n/* eslint-disable unicorn/no-useless-fallback-in-spread */\n\nimport {\n component,\n el,\n fragment,\n type Component,\n type ComponentInstance,\n type ComponentRef,\n type DomRef,\n type ElementProps,\n type VChild,\n type VNode,\n} from './runtime'\nimport type { ClassName } from './common'\n\ntype ElementTagName = Extract<keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap, string>\ntype IntrinsicElementProps<Tag extends ElementTagName> = ElementProps<Tag> & {\n children?: VChild | VChild[]\n key?: string | number\n class?: ClassName // Alias for className, for HTML compatibility\n}\ntype Key = string | number | null | undefined\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = (\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport const Fragment = Symbol.for('vani.fragment')\n\ntype SplitPropsResult = {\n props: Record<string, any> | null\n children: VChild[]\n key: Key\n ref: DomRef<Element> | ComponentRef | undefined\n hasChildrenProp: boolean\n}\n\nfunction toChildArray(children: VChild | VChild[] | undefined): VChild[] {\n if (children == null || children === false) return []\n return Array.isArray(children) ? children : [children]\n}\n\nfunction splitProps(input: Record<string, any> | null | undefined, key?: Key): SplitPropsResult {\n if (!input || typeof input !== 'object') {\n return {\n props: null,\n children: [],\n key,\n ref: undefined,\n hasChildrenProp: false,\n }\n }\n\n const hasChildrenProp = Object.prototype.hasOwnProperty.call(input, 'children')\n const children = hasChildrenProp ? toChildArray(input.children) : []\n const resolvedKey = key ?? input.key\n const ref = input.ref as DomRef<Element> | ComponentRef | undefined\n const { key: _key, ref: _ref, children: _children, ...rest } = input\n const props = Object.keys(rest).length > 0 ? rest : null\n\n return { props, children, key: resolvedKey, ref, hasChildrenProp }\n}\n\ntype JsxElementType = string | Component<any> | WrappedComponent<any> | typeof Fragment\n\nexport function jsx(type: JsxElementType, props: Record<string, any> | null, key?: Key) {\n const {\n props: cleanProps,\n children,\n key: resolvedKey,\n ref,\n hasChildrenProp,\n } = splitProps(props, key)\n\n if (type === Fragment) {\n return fragment(...children)\n }\n\n if (typeof type === 'string') {\n const elementProps =\n ref == null ? cleanProps : ({ ...(cleanProps ?? {}), ref } as Record<string, any>)\n if (elementProps) {\n return el(type as ElementTagName, elementProps, ...children)\n }\n return el(type as ElementTagName, null, ...children)\n }\n\n if (typeof type === 'function') {\n const componentProps = { ...(cleanProps ?? {}) } as Record<string, any>\n if (children.length > 0 || hasChildrenProp) {\n componentProps.children = children.length <= 1 ? children[0] : children\n }\n if (resolvedKey != null) {\n componentProps.key = resolvedKey\n }\n if (ref) {\n componentProps.ref = ref\n }\n // Check if it's already a wrapped component (has $$vaniWrapped marker)\n if ((type as any).$$vaniWrapped) {\n return (type as WrappedComponent)(componentProps)\n }\n // Otherwise wrap it as a raw Component\n return component(type as Component<any>)(componentProps)\n }\n\n throw new Error('[vani] jsx runtime received an unsupported element type.')\n}\n\nexport const jsxs = jsx\n\nexport function jsxDEV(\n type: JsxElementType,\n props: Record<string, any> | null,\n key?: Key,\n _isStaticChildren?: boolean,\n _source?: unknown,\n _self?: unknown,\n) {\n return jsx(type, props, key)\n}\n\nexport namespace JSX {\n export type Element = VNode | ComponentInstance<any>\n export type ElementType = JsxElementType\n export interface ElementChildrenAttribute {\n children: {}\n }\n export interface IntrinsicAttributes {\n key?: string | number\n ref?: DomRef<globalThis.Element> | ComponentRef\n }\n export type IntrinsicElements = { [K in ElementTagName]: IntrinsicElementProps<K> }\n}\n"],"mappings":"AA0BA,MAAM,EAAiC,CACrC,WAAY,MACZ,WAAY,KACb,CAED,SAAgB,GAA4B,CAC1C,OAAO,EAAe,WAGxB,SAAgB,EAAc,EAAwB,CACpD,EAAe,WAAa,EAG9B,SAAgB,EAAmB,EAAiC,CAClE,EAAe,WAAa,EAG9B,SAAgB,GAA+C,CAC7D,OAAO,EAAe,WCpBxB,IAAI,EAAyC,KAC7C,MAAM,EAAgB,IAAI,IAC1B,IAAI,EAAyB,GAE7B,SAAS,EAAY,EAA2B,CAC1C,CAAC,GAAmB,EAAgB,UACnC,EAAgB,KAAK,IAAI,EAAO,GACnC,EAAgB,KAAK,IAAI,EAAO,CAChC,EAAO,UAAU,IAAI,EAAgB,EAIzC,SAAS,EAAgB,EAA0B,CACjD,IAAK,IAAM,KAAU,EAAS,KAC5B,EAAO,UAAU,OAAO,EAAS,CAEnC,EAAS,KAAK,OAAO,CACrB,AAEE,EAAS,WADT,EAAS,SAAS,CACC,IAAA,IAIvB,SAAS,EAAY,EAA0B,CAC7C,GAAI,EAAS,SAAU,OACvB,EAAgB,EAAS,CACzB,IAAM,EAAO,EACb,EAAkB,EAClB,IAAM,EAAU,EAAS,IAAI,CAC7B,EAAkB,EACd,OAAO,GAAY,aACrB,EAAS,QAAU,GAIvB,SAAS,EAAiB,EAA0B,CAC9C,EAAS,WACb,EAAc,IAAI,EAAS,CACvB,KACJ,EAAyB,GACzB,mBAAqB,CACnB,EAAyB,GACzB,IAAM,EAAS,MAAM,KAAK,EAAc,CACxC,EAAc,OAAO,CACrB,IAAK,IAAM,KAAQ,EACjB,EAAY,EAAK,EAEnB,GAGJ,SAAgB,EAAU,EAAqB,CAC7C,IAAM,EAA0B,CAC9B,QACA,UAAW,IAAI,IAChB,CAgBD,MAAO,MAbL,EAAY,EAAO,CACZ,EAAO,OAGiB,GAAS,CACxC,IAAM,EAAW,OAAO,GAAS,WAAc,EAAwB,EAAO,MAAM,CAAG,EACnF,WAAO,GAAG,EAAU,EAAO,MAAM,CACrC,GAAO,MAAQ,EACf,IAAK,IAAM,KAAY,EAAO,UAC5B,EAAiB,EAAS,GAIP,CAGzB,SAAgB,EAAO,EAA2C,CAKhE,OAJI,GAAe,GAAK,OACtB,GAAI,KACS,IAER,EAAa,EAAG,CAGzB,SAAgB,EAAa,EAA2C,CACtE,IAAM,EAA2B,CAC/B,KACA,KAAM,IAAI,IACV,SAAU,GACX,CAID,OAFA,EAAY,EAAS,KAER,CACP,EAAS,WACb,EAAS,SAAW,GACpB,EAAgB,EAAS,GAI7B,SAAgB,GAAU,EAA8B,CACtD,GAAM,CAAC,EAAK,GAAO,EAAO,GAAI,CAAC,CAI/B,OAHA,MAAmB,CACjB,EAAI,GAAI,CAAC,EACT,CACK,EAGT,SAAgB,GAAK,EAAoE,CACvF,IAAM,MAAiB,OAAO,GAAU,WAAc,GAAyB,CAAG,EAC5E,EAAY,OAAO,GAAS,EAAI,GAAG,CACnC,EAAU,GAAqB,CACrC,GAAI,CAAC,EAIH,OAHI,OAAO,SAAa,IACf,SAAS,eAAe,EAAU,CAEpC,CAAE,KAAM,OAAQ,KAAM,EAAW,CAG1C,IAAM,EAAO,EAAQ,eAAe,EAAU,CAC9C,GAAI,EAAQ,eAAe,GAAK,MAC9B,OAAO,EAGT,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,EAAW,EACX,EAAU,MAAmB,CACjC,EAAS,YAAc,OAAO,GAAS,EAAI,GAAG,EAC9C,CACF,GAAqB,EAAE,eAAe,EAAU,EAAQ,CAG1D,OAAO,EAGT,SAAgB,GACd,EACA,EACA,EACA,CACA,IAAM,EAAU,GAAqB,CAGrC,GAFI,CAAC,GACD,EAAQ,eAAe,GAAK,OAC5B,EAAK,WAAW,KAAK,CAAE,UAAa,GAExC,IAAM,EAAQ,aAAc,WACtB,EAAM,IAAS,YAAc,QAAU,EAAQ,iBAAiB,EAAM,EAAM,CAE5E,EAAS,GAAyB,CACtC,GAAI,IAAQ,QAAS,CACnB,IAAM,EAAa,EAAQ,WAAW,EAAuB,CAC7D,GAAI,CAAC,EAAY,CACf,EAAG,gBAAgB,QAAQ,CAC3B,OAEF,EAAG,aAAa,QAAS,EAAW,CACpC,OAGF,GAAI,IAAc,GAAM,CACtB,EAAG,aAAa,EAAK,GAAG,CACxB,OAGF,GAAI,IAAc,IAAS,GAAa,KAAM,CAC5C,EAAG,gBAAgB,EAAI,CACvB,OAGF,EAAG,aAAa,EAAK,OAAO,EAAU,CAAC,EAGzC,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,EAAW,MAAmB,CAClC,EAAO,GAA2B,CAAC,EACnC,CAEF,OADA,EAAQ,eAAe,EAAI,EAAS,CAC7B,EAIT,OADA,EAAM,EAAmB,KACZ,GCxKf,IAAa,EAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,CAC3B,MAAM,EAAQ,CACd,KAAK,KAAO,mBA2JhB,SAAS,EAAY,EAAiD,CACpE,IAAM,EAAY,EAIlB,MAHA,CACE,EAAU,cAAc,IAAI,IAEvB,EAAU,YASnB,SAAgB,EAAiB,EAAsB,CACrD,IAAM,EAAW,GAA4D,CAC3E,IAAI,EACA,EACA,EAAa,GACb,EAAQ,EAEZ,GAAI,GAAS,OAAO,GAAU,SAAU,CACtC,IAAM,EAAW,EAIjB,GAHA,EAAM,EAAS,IACf,EAAM,EAAS,IACf,EAAa,EAAS,WAClB,QAAS,GAAY,QAAS,EAAU,CAC1C,GAAM,CAAE,IAAK,EAAG,IAAK,EAAI,WAAY,EAAK,GAAG,GAAS,EACtD,EAAQ,GAIZ,MAAO,CACL,OAAQ,YACR,UAAW,EACX,QACA,MACA,MACA,aACD,EAMH,MAFE,GAAgB,cAAgB,GAE3B,EAwBT,SAAgB,GAAgB,EAAsB,CAcpD,OAAO,GAbsC,EAAO,IAAW,CAC7D,IAAM,EAAS,EAAG,EAAO,EAAO,CAShC,OANI,aAAkB,QACb,EAAO,KAAM,GACX,GAAqB,EAAU,EAAO,CAC7C,CAGG,GAAqB,EAAQ,EAAO,EAGV,CAGrC,SAAS,GAAqB,EAAkB,EAA0B,CACxE,IAAI,EACA,EAAa,GAmBjB,OAjBA,EAAO,mBACL,EAAgB,MAAmB,CAIjC,GAFA,GAAQ,CAEJ,EAAY,CACd,EAAa,GACb,OAIF,EAAO,QAAQ,EACf,CAEK,GACP,CAEK,EAOT,SAAgB,GAAkB,EAAkB,EAAgB,CAClE,IAAM,EAAO,GAAe,CAC5B,EAAc,EAAK,CACnB,IAAM,EAAS,GAAI,CAOnB,OANI,GAAU,OAAQ,EAAuC,SAAY,WAC/D,EAAuC,YAAc,CAC3D,EAAc,EAAK,EACnB,EAEJ,EAAc,EAAK,CACZ,GAGT,SAAS,EAAU,EAA8B,CAC/C,GAAI,OAAO,GAAS,WAAY,GAAiB,EAAE,SAAU,GAC3D,MAAO,GAGT,IAAM,EAAU,EAChB,OAAQ,EAAQ,KAAhB,CACE,IAAK,UACH,OACE,OAAO,EAAQ,KAAQ,UACvB,OAAO,EAAQ,OAAU,UACzB,MAAM,QAAQ,EAAQ,SAAS,CAEnC,IAAK,OACL,IAAK,UACH,OAAO,OAAO,EAAQ,MAAS,SACjC,IAAK,WACH,OAAO,MAAM,QAAQ,EAAQ,SAAS,CACxC,IAAK,YACH,OAAO,OAAO,EAAQ,UAAa,UAAY,EAAQ,UAAY,KACrE,QACE,MAAO,IAIb,SAAS,EAAa,EAA4D,CAChF,OAAO,EAAU,EAAK,EAAI,EAAK,OAAS,UAG1C,SAAS,GAAc,EAA6D,CAClF,OAAO,EAAU,EAAK,EAAI,EAAK,OAAS,WAG1C,MAAM,GAAU,IAAI,IAAY,CAC9B,MACA,IACA,OACA,SACA,OACA,OACA,WACA,UACA,UACA,OACA,WACA,OACA,UACA,iBACA,iBACA,OACA,MACD,CAAC,CAEF,SAAS,GAAkB,EAAoB,CAO7C,OANI,GAAe,GAAK,MAClB,GAAQ,IAAI,EAAI,CACX,SAAS,gBAAgB,6BAA8B,EAAI,CAE7D,SAAS,cAAc,EAAI,CAE7B,CAAE,KAAM,UAAW,MAAK,MAAO,EAAE,CAAE,SAAU,EAAE,CAAE,CAG1D,SAAS,EAAe,EAAqB,CAI3C,OAHI,GAAe,GAAK,MACf,SAAS,eAAe,EAAK,CAE/B,CAAE,KAAM,OAAQ,OAAM,CAG/B,SAAS,EAAgB,EAAe,EAAc,CACpD,GAAI,GAAe,GAAK,MAAO,CAC3B,EAAgB,YAAY,EAAc,CAC5C,QAGE,EAAa,EAAO,EAAI,GAAc,EAAO,GAC/C,EAAO,SAAS,KAAK,EAAiB,CAI1C,SAAS,GAAe,EAAY,EAAqB,CACvD,IAAM,EAAU,EAChB,GAAI,CAAC,EAAQ,cAAe,CAC1B,EAAQ,cAAgB,CAAC,EAAQ,CACjC,OAEF,EAAQ,cAAc,KAAK,EAAQ,CAGrC,SAAS,GAAe,EAAY,CAClC,IAAM,EAAU,EACV,EAAW,EAAQ,cACpB,SAAM,QAAQ,EAAS,CAC5B,GAAQ,cAAgB,KACxB,IAAK,IAAM,KAAW,EACpB,GAAS,EAQb,SAAS,EAAa,EAAgB,EAAc,CAClD,IAAI,EAAO,EAAM,YACjB,KAAO,GAAQ,IAAS,GAAK,CAC3B,IAAM,EAAO,EAAK,YAClB,GAAI,EAAK,WAAa,KAAK,cAAgB,EAAK,YAAc,aAAc,CAC1E,IAAM,EAAU,EAAa,aAC7B,GAAI,EAAQ,CAEV,IAAM,EADa,EAAe,WACD,aAAe,EAChD,EAAO,SAAS,CAChB,EAAO,EACP,UAGJ,GAAe,EAAK,CACpB,IAAM,EAAU,EACZ,EAAQ,eACV,EAAQ,aAAa,QAAU,MAEjC,EAAK,QAAQ,CACb,EAAO,GAIX,SAAS,EAAgB,EAAgB,EAAsB,CAC7D,IAAM,EAAgB,EAAE,CACpB,EAAO,EAAM,YACjB,KAAO,GAAQ,IAAS,GACtB,EAAM,KAAK,EAAK,CAChB,EAAO,EAAK,YAEd,OAAO,EAOT,SAAS,GAAkB,EAAqB,CAC9C,GAAI,GAAS,MAAQ,IAAU,GAC7B,OAAO,SAAS,cAAc,aAAa,CAG7C,GAAI,EAAoB,EAAM,CAAE,CAC9B,IAAM,EAAW,SAAS,wBAAwB,CAC5C,EAAS,EAAe,EAAM,UAAW,EAAc,EAAM,CAAE,EAAS,CAI9E,OAHI,EAAM,MACR,EAAM,IAAI,QAAU,GAEf,EAGT,GAAI,OAAO,GAAU,UAAY,OAAO,GAAU,SAChD,OAAO,SAAS,eAAe,OAAO,EAAM,CAAC,CAG/C,GAAI,aAAiB,KACnB,OAAO,EAGT,MAAU,MAAM,8DAA8D,CAOhF,SAAS,EACP,EACA,EACA,EACA,EACQ,CACR,IAAM,EAA8B,EAAE,CAChC,EAEF,EAAE,CACF,EAAW,GACX,EAAa,GACb,EACA,EACA,EAAqC,KAMnC,EAAc,GAAe,aAAe,GAElD,GAAI,EAAa,CACf,IAAM,EAAiB,EACvB,GAA2B,EAC3B,EAAQ,GAAoB,EAAQ,EAAe,CACnD,EAAM,GAAsB,EAAO,EAAe,MAElD,EAAQ,SAAS,cAAc,aAAa,CAC5C,EAAM,SAAS,cAAc,WAAW,CACxC,EAAO,YAAY,EAAM,CACzB,EAAO,YAAY,EAAI,CAGzB,IAAI,EAME,EAAiB,CACrB,OAAO,EAAS,CACd,GAAI,EAAU,OAEd,IAAM,EAAmB,EAAe,oBAClC,EAAc,GAAS,eACzB,CAAE,eAAgB,GAAM,CACxB,CAAE,eAAgB,GAAO,EACzB,CAAC,GAAmB,CAAC,EAAgB,gBAAkB,CAAC,EAAY,kBACpE,EAAe,oBAAsB,GAGrC,EACG,EAAY,IAAI,EAAO,GAC1B,EAAgB,IAAI,EAAO,CACvB,EAAa,EACf,EAAyB,GAEzB,GAAyB,GAI7B,EAAgB,OAAO,EAAO,CAC9B,EAAY,IAAI,EAAO,CACnB,EAAa,EACf,EAAqB,GAErB,IAAqB,GAK3B,WAAW,EAAS,CAElB,GADI,GACA,CAAC,EAAM,WAAY,OAEvB,IAAM,EACJ,GAAa,EAAe,oBAG9B,GAFE,EAAe,oBAAsB,IAAA,GAEnC,GAAiB,gBAAkB,EAAoB,CACzD,IAAM,EAAe,EACrB,EAAqB,GACrB,IAAI,EACJ,GAAI,CACF,EAAY,GAAQ,QACZ,CACR,EAAqB,EAGvB,GAAI,aAAqB,KAAM,CAC7B,IAAM,EAAc,EAAyB,EAAU,CACvD,GAAI,GAAe,EAAY,UAAY,EAAmB,QAAS,CACrE,GAAuB,EAAoB,EAAY,CACvD,SAKN,EAAa,EAAO,EAAI,CACxB,IAAM,EAAO,GAAkB,GAAQ,CAAC,CAClC,EAAc,EAAyB,EAAK,CAIlD,GAHA,EAAI,OAAO,EAAK,CAChB,EAAqB,EAEjB,CAAC,IACH,EAAa,GACT,EAAe,OAAS,GAAG,CAC7B,IAAM,EAAa,EAAM,WACrB,EAA6B,KAC3B,MACA,IACJ,EAAc,EAAgB,EAAO,EAAI,CAClC,GAEH,EAAY,EAAe,OAAO,EAAG,EAAe,OAAO,CACjE,IAAK,IAAM,KAAY,EAAW,CAChC,IAAM,EAAU,EAAS,EAAU,EAAW,CAC1C,OAAO,GAAY,YACrB,EAAS,KAAK,EAAQ,IAOhC,UAAU,EAAI,CACZ,EAAS,KAAK,EAAG,EAGnB,SAAU,CACJ,MAOJ,CANA,EAAW,GACT,EAAc,aAAe,KAC7B,EAAe,YAAc,KAC7B,EAAe,UAAY,KAE7B,EAAY,OAAO,EAAO,CAC1B,EAAgB,OAAO,EAAO,CAE9B,IAAK,IAAM,KAAM,EAAU,GAAI,CAC/B,EAAS,OAAS,EAElB,EAAa,EAAO,EAAI,CACxB,EAAM,QAAQ,CACd,EAAI,QAAQ,CAGZ,OAAgB,SAAS,cAAc,WAAW,IAGpD,cAAc,EAAI,CAChB,IAAM,EAAU,GAAI,CAChB,OAAO,GAAY,YACrB,EAAS,KAAK,EAAQ,EAI1B,QAAQ,EAAI,CACN,MACJ,IAAI,EAAY,CACd,mBAAqB,CACnB,GAAI,EAAU,OACd,IAAM,EAAa,EAAM,WACrB,EAA6B,KAM3B,EAAU,MAJV,IACJ,EAAc,EAAgB,EAAO,EAAI,CAClC,GAEoB,EAAW,CACpC,OAAO,GAAY,YACrB,EAAS,KAAK,EAAQ,EAExB,CACF,OAEF,EAAe,KAAK,EAAG,GAE1B,CAUD,GARE,EAAe,YAAc,EAC7B,EAAe,UAAY,EAC3B,EAAc,aAAe,EAM3B,GAAe,CAAC,EAAY,CAC9B,IAAI,EAAc,GAWlB,MATA,OAAe,CACb,GAAI,CAAC,EAAa,CAChB,EAAc,GACd,IAAM,EAAS,EAAU,EAAO,EAAO,CACvC,EAAS,aAAkB,YAAgB,SAAS,cAAc,QAAQ,CAAG,EAE/E,OAAO,GAAQ,EAGV,EAGT,IAAM,EAAS,EAAU,EAAO,EAAO,CAmDvC,OA7CI,aAAkB,SAEpB,EADkB,GAAe,eACI,SAAS,cAAc,aAAa,GAGrE,CAAC,GAAe,KACd,GAAS,gBAAkB,OAC7B,EAAO,YAAY,CAEnB,EAAO,QAAQ,EAInB,EACG,KAAM,GAAe,CAChB,IACJ,EAAS,EACT,EAAO,QAAQ,GACf,CACD,MAAO,GAAU,CACZ,IACJ,QAAQ,MAAM,iCAAkC,EAAM,CACtD,mBAAqB,CACnB,MAAM,GACN,GACF,CAEG,IAOT,EAAS,GAGL,CAAC,GAAe,KACd,GAAS,gBAAkB,OAC7B,EAAO,YAAY,CAEnB,EAAO,QAAQ,EAIZ,GAcT,SAAS,GAAqB,EAAgD,CAC5E,OAAO,MAAM,QAAQ,EAAM,CAAG,EAAQ,CAAC,EAAM,CAG/C,SAAgB,GAAY,EAAuC,EAA6B,CAC9F,GAAI,CAAC,EACH,MAAU,MAAM,gCAAgC,CAIhD,WAAmB,OAAS,GAE9B,IAAM,EAAoB,EAAE,CACtB,EAAa,GAAqB,EAAW,CACnD,IAAK,IAAM,KAAQ,EAAY,CAC7B,GAAI,OAAO,GAAS,WAAY,CAE9B,GAAK,EAAa,cAAe,CAC/B,IAAM,EAAY,GAA2B,CACvC,EAAS,EAAe,EAAS,UAAW,EAAc,EAAS,CAAE,EAAK,CAChF,EAAQ,KAAK,EAAO,CACpB,SAGF,IAAM,EAAS,EAAe,EAAwB,EAAE,CAAS,EAAK,CACtE,EAAQ,KAAK,EAAO,CACpB,SAIF,IAAM,EAAS,EAAe,EAAK,UAAW,EAAc,EAAK,CAAE,EAAK,CACxE,EAAQ,KAAK,EAAO,CAGtB,OAAO,EAoCT,SAAgB,GAAW,EAA8B,CACvD,GAAI,CAAC,EACH,MAAU,MAAM,qCAAqC,CAIrD,WAAmB,OAAS,GAE9B,IAAI,EAAoB,EAAE,CACtB,EAAY,GAiDhB,MA/CmB,CACjB,OAAO,EAAuB,CAC5B,GAAI,EACF,MAAU,MAAM,wEAAwE,CAI1F,IAAK,IAAM,KAAU,EACnB,EAAO,SAAS,CAElB,EAAU,EAAE,CAGZ,EAAU,UAAY,GAGtB,IAAM,EAAa,GAAqB,EAAU,CAClD,IAAK,IAAM,KAAQ,EAAY,CAC7B,GAAI,OAAO,GAAS,WAAY,CAC9B,GAAK,EAAa,cAAe,CAC/B,IAAM,EAAY,GAA2B,CACvC,EAAS,EAAe,EAAS,UAAW,EAAc,EAAS,CAAE,EAAU,CACrF,EAAQ,KAAK,EAAO,CACpB,SAEF,IAAM,EAAS,EAAe,EAAwB,EAAE,CAAS,EAAU,CAC3E,EAAQ,KAAK,EAAO,CACpB,SAGF,IAAM,EAAS,EAAe,EAAK,UAAW,EAAc,EAAK,CAAE,EAAU,CAC7E,EAAQ,KAAK,EAAO,GAIxB,SAAU,CACJ,MAEJ,GAAY,GACZ,IAAK,IAAM,KAAU,EACnB,EAAO,SAAS,CAElB,EAAU,EAAE,CACZ,EAAU,UAAY,KAEzB,CASH,SAAgB,EAAoB,EAAgD,CAClF,IAAM,EAAY,OAAO,KAAS,KAAe,aAAiB,KAClE,GAAI,OAAO,GAAU,UAAY,EAAW,MAAO,GACnD,IAAM,EAAW,EACjB,OAAO,EAAS,SAAW,aAAe,OAAO,EAAS,WAAc,WAG1E,SAAS,GAAY,EAAwC,CAC3D,IAAM,EAAY,OAAO,KAAS,KAAe,aAAiB,KAClE,OAEE,OAAO,GAAU,YADjB,GAEA,CAAC,GACD,CAAC,EAAoB,EAAgB,EACrC,CAAC,EAAU,EAAe,CAI9B,SAAS,EAAqB,EAA2C,CAGvE,OAFK,EAAS,WAEP,CAAE,GADK,EAAS,OAAS,EAAE,CAChB,WAAY,GAAM,CAFH,EAAS,MAK5C,SAAS,GAAiB,EAAyD,CACjF,IAAM,EAAS,EAAe,YACxB,EAAO,EAAe,UAE5B,MADI,CAAC,GAAS,CAAC,EAAY,KACpB,CAAE,QAAO,MAAK,CAGvB,SAAS,EACP,EACA,EACA,EACA,EAA2B,KAC3B,CACA,IAAM,EAAW,SAAS,wBAAwB,CAC9C,EAAyB,EAC7B,KAAO,GAAM,CACX,IAAM,EAA6B,EAAK,YAExC,GADA,EAAS,YAAY,EAAK,CACtB,IAAS,EAAK,MAClB,EAAO,EAET,EAAO,aAAa,EAAU,EAAO,CAGvC,SAAS,EAAyB,EAA4B,CAC5D,GAAI,EAAK,WAAa,KAAK,aACzB,OAAO,EAET,GAAI,EAAK,WAAa,KAAK,uBAAwB,CAEjD,IAAM,EADW,EACM,WACvB,GAAI,GAAS,EAAM,WAAa,KAAK,cAAgB,EAAM,cAAgB,KACzE,OAAO,EAGX,OAAO,KAGT,SAAS,GAAuB,EAAiB,EAAiB,CAChE,IAAM,EAAY,IAAI,IAAI,EAAO,mBAAmB,CAAC,CACrD,IAAK,IAAM,KAAQ,EAAO,mBAAmB,CACtC,EAAU,IAAI,EAAK,EACtB,EAAO,gBAAgB,EAAK,CAGhC,IAAK,IAAM,KAAQ,EAAW,CAC5B,IAAM,EAAQ,EAAO,aAAa,EAAK,CACnC,EAAO,aAAa,EAAK,GAAK,IAC5B,IAAU,KACZ,EAAO,gBAAgB,EAAK,CAE5B,EAAO,aAAa,EAAM,EAAM,GAMxC,SAAS,EAAkB,EAAqB,EAA6B,CAC3E,GAAI,EAAO,QAAU,EAAW,MAAO,GACvC,GACE,CAAC,EAAO,OACR,OAAO,EAAO,OAAU,UACxB,CAAC,GACD,OAAO,GAAc,SAGrB,MADA,GAAO,MAAQ,EACR,GAGT,IAAI,EAAU,GACR,EAAO,EAAO,MACd,EAAO,EAEb,IAAK,IAAM,KAAO,EACV,KAAO,IACX,OAAO,EAAK,GACZ,EAAU,IAId,IAAK,IAAM,KAAO,EACZ,EAAK,KAAS,EAAK,KACrB,EAAK,GAAO,EAAK,GACjB,EAAU,IAId,OAAO,EAGT,SAAS,EACP,EACA,EACA,EAA2B,KACd,CACb,IAAM,EAAW,SAAS,wBAAwB,CAC5C,EAAS,EAAe,EAAS,UAAW,EAAc,EAAS,CAAE,EAAU,CACnF,cAAe,OAChB,CAAC,CACE,EAAS,MACX,EAAS,IAAI,QAAU,GAEzB,IAAM,EAAU,GAAiB,EAAO,EAAI,IAAA,GACtC,EAAsB,CAC1B,UAAW,EAAS,UACpB,SACA,WACA,IAAK,EAAS,IACd,MAAO,EAAS,MAChB,MAAO,GAAS,MAChB,IAAK,GAAS,IACf,CAED,OADA,EAAU,aAAa,EAAU,EAAO,CACjC,EAIT,SAAS,EAAgB,EAA8B,CACrD,IAAM,EAAmB,EAAE,CAC3B,IAAK,IAAM,KAAS,EACd,MAAM,QAAQ,EAAM,CACtB,EAAO,KAAK,GAAG,EAAgB,EAAkB,CAAC,CAElD,EAAO,KAAK,EAAM,CAGtB,OAAO,EAGT,SAAS,EAAe,EAAe,EAAoB,CAEzD,IAAM,EAAe,EAAgB,EAAS,CAE9C,GAAI,GAAe,GAAK,MAAO,CAC7B,IAAK,IAAM,KAAS,EACd,QAAS,MAAQ,IAAU,IAAS,IAAU,IAAA,IAElD,IAAI,EAAoB,EAAM,CAAE,CAC9B,EAAgB,EAAQ,CAAE,KAAM,YAAa,SAAU,EAAO,CAAC,CAC/D,SAGF,GAAI,OAAO,GAAU,UAAY,OAAO,GAAU,SAAU,CAC1D,EAAgB,EAAQ,EAAe,OAAO,EAAM,CAAC,CAAC,CACtD,SAIE,UAAM,QAAQ,EAAM,EAEpB,EAAU,EAAM,CAAE,CACpB,EAAgB,EAAQ,EAAM,CAC9B,UAIJ,OAGF,IAAM,EAAY,EAClB,IAAK,IAAM,KAAS,EACd,QAAS,MAAQ,IAAU,IAAS,IAAU,IAAA,IAElD,IAAI,EAAoB,EAAM,CAAE,CAM9B,GAAI,EAAM,KAAO,KAAM,CACrB,IAAM,EAAW,EAAY,EAAU,CACjC,EAAY,EAAmB,iBAAmB,IAAI,IAExD,EAAS,EAAS,IAAI,EAAM,IAAI,CAEhC,GAAU,EAAO,YAAc,EAAM,YACvC,EAAO,OAAO,SAAS,CACnB,EAAO,MACT,EAAO,IAAI,QAAU,MAEvB,EAAS,OAAO,EAAM,IAAI,CAC1B,EAAS,IAAA,IAGN,GAIC,EAAO,MAAQ,EAAM,MACnB,EAAO,MAAK,EAAO,IAAI,QAAU,MACrC,EAAO,IAAM,EAAM,KAEjB,EAAO,MAAK,EAAO,IAAI,QAAU,EAAO,QACxC,EAAkB,EAAQ,EAAM,MAAM,EACxC,EAAO,OAAO,QAAQ,CAEpB,EAAO,OAAS,EAAO,KACzB,EAAkB,EAAW,EAAO,MAAO,EAAO,IAAI,GAZxD,EAAS,EAAiB,EAAW,EAAO,KAAK,CACjD,EAAS,IAAI,EAAM,IAAK,EAAO,EAejC,EAAS,IAAI,EAAM,IAAI,CACvB,SAIF,IAAM,EAAW,SAAS,wBAAwB,CAC5C,EAAS,EAAe,EAAM,UAAW,EAAc,EAAM,CAAE,EAAS,CAC1E,EAAM,MACR,EAAM,IAAI,QAAU,GAEtB,EAAU,YAAY,EAAS,CAC/B,SAGF,GAAI,OAAO,GAAU,UAAY,OAAO,GAAU,SAAU,CAC1D,EAAU,YAAY,SAAS,eAAe,OAAO,EAAM,CAAC,CAAC,CAC7D,SAIE,MAAM,QAAQ,EAAM,EAExB,EAAU,YAAY,EAAc,CAGtC,IAAM,EAAY,EAAkB,YAC9B,EAAY,EAAkB,eAEpC,GAAI,GAAY,EAAU,CACxB,IAAK,GAAM,CAAC,EAAK,KAAW,EACrB,EAAS,IAAI,EAAI,GACpB,EAAO,OAAO,SAAS,CACnB,EAAO,MACT,EAAO,IAAI,QAAU,MAEvB,EAAS,OAAO,EAAI,EAGxB,EAAS,OAAO,EAIpB,SAAgB,GAAoB,EAAc,EAA+C,CAC/F,GAAI,GAAe,GAAK,MACtB,MAAU,MAAM,0DAA0D,CAG5E,IAAM,EAAY,EACZ,EAAW,EAAY,EAAU,CACjC,EAAY,EAAmB,iBAAmB,IAAI,IACxD,EAA2B,EAAU,WAEzC,IAAK,IAAM,KAAS,EAAU,CAC5B,GAAI,CAAC,EAAoB,EAAM,EAAI,EAAM,KAAO,KAC9C,SAGF,IAAI,EAAS,EAAS,IAAI,EAAM,IAAI,CAEhC,GAAU,EAAO,YAAc,EAAM,YACvC,EAAO,OAAO,SAAS,CACnB,EAAO,MACT,EAAO,IAAI,QAAU,MAEvB,EAAS,OAAO,EAAM,IAAI,CAC1B,EAAS,IAAA,IAGX,IAAM,EAAc,GAAU,KAC9B,GAAI,EACF,EAAS,EAAiB,EAAW,EAAO,EAAO,CACnD,EAAS,IAAI,EAAM,IAAK,EAAO,KAC1B,CACL,IAAM,EAAiB,EACnB,EAAe,MAAQ,EAAM,MAC3B,EAAe,MAAK,EAAe,IAAI,QAAU,MACrD,EAAe,IAAM,EAAM,KAEzB,EAAe,MAAK,EAAe,IAAI,QAAU,EAAe,QAChE,EAAkB,EAAgB,EAAM,MAAM,EAChD,EAAe,OAAO,QAAQ,CAEhC,EAAS,EAGX,IAAM,EAAe,EACjB,EAAa,OAAS,EAAa,MACjC,CAAC,GAAe,GAAU,EAAa,QAAU,GACnD,EAAkB,EAAW,EAAa,MAAO,EAAa,IAAK,EAAO,CAE5E,EAAS,EAAa,IAAI,aAG5B,EAAS,IAAI,EAAM,IAAI,CAGzB,IAAK,GAAM,CAAC,EAAK,KAAW,EACrB,EAAS,IAAI,EAAI,GACpB,EAAO,OAAO,SAAS,CACnB,EAAO,MACT,EAAO,IAAI,QAAU,MAEvB,EAAS,OAAO,EAAI,EAGxB,EAAS,OAAO,CAGlB,SAAS,GAAa,EAA6B,CACjD,OAAO,OAAO,WAAe,KAAe,aAAc,WAG5D,SAAS,EAAiB,EAAa,EAAgB,CAWrD,OAVI,EAAI,WAAW,OAAO,CACjB,QAAU,EAAI,QAAQ,QAAS,GAAG,CAAC,QAAQ,OAAQ,GAAG,CAAC,aAAa,CAEzE,EAAI,WAAW,OAAO,CACjB,QAAU,EAAI,QAAQ,QAAS,GAAG,CAAC,QAAQ,OAAQ,GAAG,CAE3D,EAAI,aAAa,GAAK,UACjB,MAEL,EAAc,EACX,EAAI,aAAa,CAG1B,EAAmB,CACjB,gBACA,eAAiB,GAAiB,EAAe,EAAK,CACtD,kBACA,aACA,mBACD,CAAC,CAEF,SAAS,GAAS,EAAW,EAA4B,CAEvD,GAAI,UAAW,GAAS,cAAe,EACrC,MAAU,MACR,4FACD,CAGH,IAAM,EAAQ,EAAa,EAAG,CAAG,GAAQ,IAAI,EAAG,IAAI,CAAG,GAAa,EAAG,CACvE,IAAK,IAAM,KAAO,EAAO,CACvB,IAAM,EAAQ,EAAM,GAEhB,KAAC,MAAO,MAAM,CAAC,SAAS,EAAI,CAKhC,IAAI,IAAQ,aAAe,IAAQ,QAAS,CAC1C,IAAM,EAAa,EAAW,EAAM,CAChC,EAAa,EAAG,CAClB,EAAG,MAAM,MAAQ,EACR,EACP,EAAkB,aAAa,QAAS,EAAW,CAEnD,EAAmB,UAAY,EAEnC,SAGF,GAAI,EAAI,WAAW,KAAK,EAAI,OAAO,GAAU,WACtC,EAAa,EAAG,GACjB,EAAW,EAAI,aAAa,EAAI,WAE3B,IAAQ,SAAW,IAAQ,WAAa,IAAQ,WAEpD,EAAa,EAAG,CAGnB,EAAG,MAAM,GAAO,OAAO,EAAM,CAF3B,EAAW,GAAO,UAIb,IAAU,GACf,EAAa,EAAG,CAClB,EAAG,MAAM,GAAO,GAEd,EAAmB,aAAa,EAAK,GAAG,SAEnC,IAAU,IAAS,GAAS,KACrC,aACK,CACL,IAAM,EAAgB,EAAiB,EAAK,EAAM,CAC9C,EAAa,EAAG,CAClB,EAAG,MAAM,GAAiB,OAAO,EAAM,CAErC,EAAmB,aAAa,EAAe,OAAO,EAAM,CAAC,IAMvE,SAAgB,EAAW,GAAG,EAA8B,CAC1D,OAAO,EACJ,IAAK,GAAQ,CACR,QAAQ,MAA6B,IAAQ,IASjD,OANI,OAAO,GAAQ,SACV,EAAI,MAAM,CAEf,MAAM,QAAQ,EAAI,CACb,EAAW,GAAG,EAAI,CAEpB,OAAO,QAAQ,EAAI,CACvB,QAAQ,CAAC,EAAG,KAAW,EAAM,CAC7B,KAAK,CAAC,KAAS,EAAI,MAAM,CAAC,CAC1B,KAAK,IAAI,CACT,MAAM,EACT,CACD,OAAO,QAAQ,CACf,KAAK,IAAI,CAOd,IAAI,EAAqB,GAGzB,MAAM,GAA2C,CAC/C,OAAQ,CAAC,QAAQ,CAElB,CAID,SAAS,GACP,EACA,EACmE,CACnE,IAAM,EAAe,GAAe,GACpC,GAAI,CAAC,EACH,MAAO,CAAE,WAAY,EAAO,SAAU,EAAE,CAAE,CAG5C,IAAM,EAA+B,EAAE,CACnC,EAAc,GAElB,IAAK,IAAM,KAAO,EACZ,KAAO,GAAS,EAAM,KAAS,IAAA,KACjC,EAAS,GAAO,EAAM,GACtB,EAAc,IAIlB,GAAI,CAAC,EACH,MAAO,CAAE,WAAY,EAAO,SAAU,EAAE,CAAE,CAG5C,IAAM,EAAa,CAAE,GAAG,EAAO,CAC/B,IAAK,IAAM,KAAO,EAChB,OAAO,EAAW,GAGpB,MAAO,CAAE,aAAY,WAAU,CAGjC,SAAS,GAAmB,EAAa,EAAoC,CACvE,MAAa,EAAK,CAEtB,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAS,CAC7C,IAAU,IAAA,KACV,EAAa,GAAO,GAK5B,SAAgB,EACd,EACA,EACA,GAAG,EACI,CACP,IAAM,EAAO,GAAkB,EAAI,CACnC,GAAI,GAAY,EAAM,CAAE,CAClB,EAAM,MACJ,CAAC,EAAa,EAAK,EAAI,CAAC,GAC1B,EAAM,IAAI,QAAU,EAClB,EAAa,aAAe,EAAM,KAEpC,EAAM,IAAI,QAAU,MAIxB,GAAM,CAAE,aAAY,YAAa,GAAqB,EAAK,EAAM,CAQjE,OAPA,GAAS,EAAM,EAAW,CAErB,GACH,EAAe,EAAM,EAAS,CAGhC,GAAmB,EAAM,EAAS,CAC3B,EAIT,OADA,EAAe,EAAM,CAAC,EAAO,GAAG,EAAS,CAAC,CACnC,EAGT,MAAa,GAAY,GAAG,IAAuB,CACjD,GAAI,GAAe,GAAK,MAAO,CAC7B,IAAM,EAAgB,CAAE,KAAM,WAAY,SAAU,EAAE,CAAE,CAExD,OADA,EAAe,EAAM,EAAS,CACvB,EAGT,IAAM,EAAO,SAAS,wBAAwB,CAE9C,OADA,EAAe,EAAM,EAAS,CACvB,GAMT,SAAgB,GAAa,EAA6B,EAAqB,CAC7E,GAAI,GAAe,GAAK,MACtB,MAAO,CACL,KAAM,YACN,SAAU,CACR,OAAQ,YACR,YACA,QACD,CACF,CAGH,IAAM,EAAW,SAAS,wBAAwB,CAElD,OADA,EAAe,EAAW,EAAO,EAAS,CACnC,EAMT,IAAI,EAAiB,GACjB,EAAe,GACf,EAA2B,GAC3B,EAAa,EACb,EAAqB,GACrB,EAAyB,GAE7B,MAAM,EAAc,IAAI,IAClB,EAAkB,IAAI,IAyC5B,SAAgB,GAAgB,EAAsB,CACpD,IAAM,EAAO,EACb,EAAe,GAEf,GAAI,CACF,GAAI,QACI,CACR,EAAe,EACX,EAAa,EACf,EAAyB,GAEzB,GAAyB,EAK/B,SAAgB,GAAM,EAAsB,CAC1C,GAAc,EACd,GAAI,CACF,GAAI,QACI,CACR,IACI,IAAe,IACb,IACF,EAAqB,GACrB,IAAqB,EAEnB,IACF,EAAyB,GACzB,GAAyB,IAMjC,SAAS,GAA0B,CAC7B,IACJ,EAA2B,GAG3B,eAAiB,CACf,EAA2B,GAC3B,IAAsB,EACrB,EAAE,EAGP,SAAS,IAAsB,CACzB,IACJ,EAAiB,GAEjB,mBAAqB,CACnB,EAAiB,GACjB,IAAK,IAAM,KAAU,EACnB,EAAO,WAAY,EAAe,oBAAiD,CAErF,EAAY,OAAO,EACnB,EAGJ,SAAS,IAAuB,CAC9B,IAAK,IAAM,KAAU,EACnB,EAAO,WAAY,EAAe,oBAAiD,CAErF,EAAgB,OAAO,CAGnB,EAAgB,KAAO,GACzB,GAAyB,CAO7B,IAAI,EAAc,GACd,EAAoC,KACpC,EAA0B,EAE9B,SAAS,EAAc,EAAiB,CACjC,GAAW,EAChB,QAAQ,KAAK,6BAA6B,IAAU,CAGtD,SAAS,GAAoB,EAAc,EAAiC,CAC1E,IAAI,EAAO,GACP,CAAC,GAAQ,CAAC,EAAO,SAAS,EAAK,IACjC,EAAO,EAAO,YAEhB,IAAI,EAAoB,GACxB,KAAO,GAAM,CACX,GAAI,EAAK,WAAa,KAAK,cAAgB,EAAK,YAAc,aAO5D,OANI,GACF,EACE,iEAAiE,EAAe,iEAEjF,CAEI,EAEL,EAAK,WAAa,KAAK,cAAgB,EAAK,YAAc,aAC5D,EAAoB,IAEtB,EAAO,EAAK,YAMd,MAJA,EACE,6CAA6C,EAAe,oGAE7D,CACK,IAAI,EAAe,kDAAkD,CAG7E,SAAS,GAAsB,EAAgB,EAAiC,CAC9E,IAAI,EAAO,EAAM,YACb,EAAQ,EACZ,KAAO,GAAM,CACX,GAAI,EAAK,WAAa,KAAK,iBACrB,EAAK,YAAc,aACrB,GAAS,UACA,EAAK,YAAc,WAAY,CACxC,GAAI,IAAU,EAEZ,MADA,GAAkB,EAAK,YAChB,EAET,KAGJ,EAAO,EAAK,YAMd,MAJA,EACE,2CAA2C,EAAe,oGAE3D,CACK,IAAI,EAAe,gDAAgD,CAG3E,SAAgB,GAAa,EAAuC,EAA6B,CAC/F,IAAI,EAAoB,EAAE,CAC1B,EAAc,GACd,EAAkB,EAAK,WACvB,EAA0B,EAC1B,GAAI,CACF,EAAU,GAAY,EAAY,EAAK,OAChC,EAAO,CACd,GAAI,aAAiB,EACnB,QAAQ,MAAM,2BAA4B,EAAM,MAEhD,MAAM,SAEA,CACR,GAAI,GAAW,EAAI,EAAiB,CAClC,IAAI,EAAyB,EACzB,EAAoB,GACxB,KAAO,GAAM,CACX,GAAI,EAAK,WAAa,KAAK,aAAc,CACvC,IAAM,EAAQ,EAAK,UACnB,GAAI,IAAU,cAAgB,IAAU,WAAY,CAClD,EAAoB,GACpB,OAGJ,EAAO,EAAK,YAGV,GACF,EACE,+GAED,CAGL,EAAc,GACd,EAAkB,KAClB,EAA0B,EAE5B,OAAO,EAGT,SAAgB,GAAY,CAiB1B,MAhBI,kBAAmB,WACb,WAAmB,gBAAkB,GAI3C,OAAO,KAAK,IAEP,OAAO,KAAK,IAAI,IAIrB,OAAO,QAAY,KAAe,QAAQ,MAAQ,IAAA,GAE7C,QAAQ,IAAI,WAAa,cAG3B,GC3nDT,MAAa,EAAW,OAAO,IAAI,gBAAgB,CAUnD,SAAS,GAAa,EAAmD,CAEvE,OADI,GAAY,MAAQ,IAAa,GAAc,EAAE,CAC9C,MAAM,QAAQ,EAAS,CAAG,EAAW,CAAC,EAAS,CAGxD,SAAS,GAAW,EAA+C,EAA6B,CAC9F,GAAI,CAAC,GAAS,OAAO,GAAU,SAC7B,MAAO,CACL,MAAO,KACP,SAAU,EAAE,CACZ,MACA,IAAK,IAAA,GACL,gBAAiB,GAClB,CAGH,IAAM,EAAkB,OAAO,UAAU,eAAe,KAAK,EAAO,WAAW,CACzE,EAAW,EAAkB,GAAa,EAAM,SAAS,CAAG,EAAE,CAC9D,EAAc,GAAO,EAAM,IAC3B,EAAM,EAAM,IACZ,CAAE,IAAK,EAAM,IAAK,EAAM,SAAU,EAAW,GAAG,GAAS,EAG/D,MAAO,CAAE,MAFK,OAAO,KAAK,EAAK,CAAC,OAAS,EAAI,EAAO,KAEpC,WAAU,IAAK,EAAa,MAAK,kBAAiB,CAKpE,SAAgB,EAAI,EAAsB,EAAmC,EAAW,CACtF,GAAM,CACJ,MAAO,EACP,WACA,IAAK,EACL,MACA,mBACE,GAAW,EAAO,EAAI,CAE1B,GAAI,IAAS,EACX,OAAO,EAAS,GAAG,EAAS,CAG9B,GAAI,OAAO,GAAS,SAAU,CAC5B,IAAM,EACJ,GAAO,KAAO,EAAc,CAAE,GAAI,GAAc,EAAE,CAAG,MAAK,CAI5D,OAHI,EACK,EAAG,EAAwB,EAAc,GAAG,EAAS,CAEvD,EAAG,EAAwB,KAAM,GAAG,EAAS,CAGtD,GAAI,OAAO,GAAS,WAAY,CAC9B,IAAM,EAAiB,CAAE,GAAI,GAAc,EAAE,CAAG,CAehD,OAdI,EAAS,OAAS,GAAK,KACzB,EAAe,SAAW,EAAS,QAAU,EAAI,EAAS,GAAK,GAE7D,GAAe,OACjB,EAAe,IAAM,GAEnB,IACF,EAAe,IAAM,GAGlB,EAAa,cACR,EAA0B,EAAe,CAG5C,EAAU,EAAuB,CAAC,EAAe,CAG1D,MAAU,MAAM,2DAA2D,CAG7E,MAAa,GAAO,EAEpB,SAAgB,GACd,EACA,EACA,EACA,EACA,EACA,EACA,CACA,OAAO,EAAI,EAAM,EAAO,EAAI"}
@@ -1 +1 @@
1
- import{i as e,n as t,r as n,t as r}from"./jsx-runtime-BUSOLzm1.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};
1
+ import{i as e,n as t,r as n,t as r}from"./jsx-runtime-Bbqe4zqZ.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanijs/vani",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Web-standards-first UI runtime with explicit updates, fine-grained DOM ownership, and zero dependencies. JS-first, transpiler-free, with an optional JSX adapter. Built for SPA, SSR, and SSG.",
5
5
  "keywords": [
6
6
  "ui",
@@ -40,6 +40,42 @@
40
40
  "default": "./dist/lib/index.mjs"
41
41
  }
42
42
  },
43
+ "./common": {
44
+ "import": {
45
+ "types": "./dist/lib/common.d.mts",
46
+ "default": "./dist/lib/common.mjs"
47
+ }
48
+ },
49
+ "./html": {
50
+ "import": {
51
+ "types": "./dist/lib/html.d.mts",
52
+ "default": "./dist/lib/html.mjs"
53
+ }
54
+ },
55
+ "./runtime": {
56
+ "import": {
57
+ "types": "./dist/lib/runtime.d.mts",
58
+ "default": "./dist/lib/runtime.mjs"
59
+ }
60
+ },
61
+ "./signals": {
62
+ "import": {
63
+ "types": "./dist/lib/signals.d.mts",
64
+ "default": "./dist/lib/signals.mjs"
65
+ }
66
+ },
67
+ "./ssr": {
68
+ "import": {
69
+ "types": "./dist/lib/ssr.d.mts",
70
+ "default": "./dist/lib/ssr.mjs"
71
+ }
72
+ },
73
+ "./svg": {
74
+ "import": {
75
+ "types": "./dist/lib/svg.d.mts",
76
+ "default": "./dist/lib/svg.mjs"
77
+ }
78
+ },
43
79
  "./jsx-runtime": {
44
80
  "import": {
45
81
  "types": "./dist/lib/jsx-runtime.d.mts",
@@ -1,2 +0,0 @@
1
- const e={renderMode:`dom`,domAdapter:null};function t(){return e.renderMode}function n(t){e.renderMode=t}function r(t){e.domAdapter=t}function i(){return e.domAdapter}let a=null;function o(e){for(let t of e.deps)t.observers.delete(e);e.deps.clear(),e.cleanup&&=(e.cleanup(),void 0)}function s(e){if(e.disposed)return;o(e);let t=a;a=e;let n=e.fn();a=t,typeof n==`function`&&(e.cleanup=n)}function c(e){let t={fn:e,deps:new Set,disposed:!1};return s(t),()=>{t.disposed||(t.disposed=!0,o(t))}}var l=class extends Error{constructor(e){super(e),this.name=`HydrationError`}};function u(e){let t=e;return t.__vaniKeyed||=new Map,t.__vaniKeyed}function d(e){let t=t=>{let n,r,i=!1,a=t;if(t&&typeof t==`object`){let e=t;if(n=e.key,r=e.ref,i=e.clientOnly,`key`in e||`ref`in e){let{key:t,ref:n,clientOnly:r,...i}=e;a=i}}return{$$vani:`component`,component:e,props:a,key:n,ref:r,clientOnly:i}};return t.$$vaniWrapped=!0,t}function f(e){return d((t,n)=>{let r=e(t,n);return r instanceof Promise?r.then(e=>p(e,n)):p(r,n)})}function p(e,t){let n,r=!0;return t.onBeforeMount(()=>(n=c(()=>{if(e(),r){r=!1;return}t.update()}),n)),e}function m(e,r){let i=t();n(e);let a=r();return a&&typeof a.finally==`function`?a.finally(()=>{n(i)}):(n(i),a)}function h(e){if(typeof e!=`object`||!e||!(`type`in e))return!1;let t=e;switch(t.type){case`element`:return typeof t.tag==`string`&&typeof t.props==`object`&&Array.isArray(t.children);case`text`:case`comment`:return typeof t.text==`string`;case`fragment`:return Array.isArray(t.children);case`component`:return typeof t.instance==`object`&&t.instance!=null;default:return!1}}function g(e){return h(e)&&e.type===`element`}function ee(e){return h(e)&&e.type===`fragment`}const _=new Set([`svg`,`g`,`path`,`circle`,`rect`,`line`,`polyline`,`polygon`,`ellipse`,`defs`,`clipPath`,`mask`,`pattern`,`linearGradient`,`radialGradient`,`stop`,`use`]);function te(e){return t()===`dom`?_.has(e)?document.createElementNS(`http://www.w3.org/2000/svg`,e):document.createElement(e):{type:`element`,tag:e,props:{},children:[]}}function v(e){return t()===`dom`?document.createTextNode(e):{type:`text`,text:e}}function y(e,n){if(t()===`dom`){e.appendChild(n);return}(g(e)||ee(e))&&e.children.push(n)}function ne(e,t){let n=e;if(!n.__vaniCleanup){n.__vaniCleanup=[t];return}n.__vaniCleanup.push(t)}function re(e){let t=e,n=t.__vaniCleanup;if(Array.isArray(n)){t.__vaniCleanup=null;for(let e of n)e()}}function b(e,t){let n=e.nextSibling;for(;n&&n!==t;){let e=n.nextSibling;if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`){let t=n.__vaniHandle;if(t){let r=t.__vaniEnd?.nextSibling??e;t.dispose(),n=r;continue}}re(n);let t=n;t.__vaniDomRef&&(t.__vaniDomRef.current=null),n.remove(),n=e}}function x(e,t){let n=[],r=e.nextSibling;for(;r&&r!==t;)n.push(r),r=r.nextSibling;return n}function ie(e){if(e==null||e===!1)return document.createComment(`vani:empty`);if(T(e)){let t=document.createDocumentFragment(),n=S(e.component,E(e),t);return e.ref&&(e.ref.current=n),t}if(typeof e==`string`||typeof e==`number`)return document.createTextNode(String(e));if(e instanceof Node)return e;throw Error(`[vani] render returned an unsupported node type in DOM mode`)}function S(e,t,n,r){let i=[],a=[],o=!1,s=!1,c,l,u=null,d=t?.clientOnly===!0;if(q){let e=Y;Y+=1,c=be(n,e),l=xe(c,e)}else c=document.createComment(`vani:start`),l=document.createComment(`vani:end`),n.appendChild(c),n.appendChild(l);let f,p={update(e){if(o)return;let t=p.__vaniUpdateOptions,n=e?.onlyAttributes?{onlyAttributes:!0}:{onlyAttributes:!1};(!t||!t.onlyAttributes||!n.onlyAttributes)&&(p.__vaniUpdateOptions=n),R?U.has(p)||(W.add(p),B>0?H=!0:G()):(W.delete(p),U.add(p),B>0?V=!0:K())},updateSync(e){if(o||!c.parentNode)return;let t=e??p.__vaniUpdateOptions;if(p.__vaniUpdateOptions=void 0,t?.onlyAttributes&&u){let e=P;P=!0;let t;try{t=f()}finally{P=e}if(t instanceof Node){let e=D(t);if(e&&e.tagName===u.tagName){le(u,e);return}}}b(c,l);let n=ie(f()),r=D(n);if(l.before(n),u=r,!s&&(s=!0,a.length>0)){let e=c.parentNode,t=null,n=()=>t||(t=x(c,l),t),r=a.splice(0,a.length);for(let t of r){let r=t(n,e);typeof r==`function`&&i.push(r)}}},onCleanup(e){i.push(e)},dispose(){if(!o){o=!0,c.__vaniHandle=null,p.__vaniStart=null,p.__vaniEnd=null,U.delete(p),W.delete(p);for(let e of i)e();i.length=0,b(c,l),c.remove(),l.remove(),f=(()=>document.createComment(`disposed`))}},onBeforeMount(e){let t=e();typeof t==`function`&&i.push(t)},onMount(e){if(!o){if(s){queueMicrotask(()=>{if(o)return;let t=c.parentNode,n=null,r=e(()=>n||(n=x(c,l),n),t);typeof r==`function`&&i.push(r)});return}a.push(e)}}};if(p.__vaniStart=c,p.__vaniEnd=l,c.__vaniHandle=p,q&&!d){let n=!1;return f=()=>{if(!n){n=!0;let r=e(t,p);f=r instanceof Promise?()=>document.createComment(`async`):r}return f()},p}let m=e(t,p);return m instanceof Promise?(f=t?.fallback||(()=>document.createComment(`vani:async`)),(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),m.then(e=>{o||(f=e,p.update())}).catch(e=>{o||(console.error(`[vani] async component failed:`,e),queueMicrotask(()=>{throw e}))}),p):(f=m,(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),p)}function C(e){return Array.isArray(e)?e:[e]}function w(e,t){if(!t)throw Error(`[vani] root element not found`);globalThis.Vani$$=!0;let n=[],r=C(e);for(let e of r){if(typeof e==`function`){if(e.$$vaniWrapped){let r=e(),i=S(r.component,E(r),t);n.push(i);continue}let r=S(e,{},t);n.push(r);continue}let r=S(e.component,E(e),t);n.push(r)}return n}function ae(e){if(!e)throw Error(`[vani] container element not found`);globalThis.Vani$$=!0;let t=[],n=!1;return{render(r){if(n)throw Error(`[vani] Cannot render to an unmounted root. Create a new root instead.`);for(let e of t)e.dispose();t=[],e.innerHTML=``;let i=C(r);for(let n of i){if(typeof n==`function`){if(n.$$vaniWrapped){let r=n(),i=S(r.component,E(r),e);t.push(i);continue}let r=S(n,{},e);t.push(r);continue}let r=S(n.component,E(n),e);t.push(r)}},unmount(){if(!n){n=!0;for(let e of t)e.dispose();t=[],e.innerHTML=``}}}}function T(e){let t=typeof Node<`u`&&e instanceof Node;if(typeof e!=`object`||t)return!1;let n=e;return n.$$vani===`component`&&typeof n.component==`function`}function oe(e){let t=typeof Node<`u`&&e instanceof Node;return typeof e==`object`&&!!e&&!t&&!T(e)&&!h(e)}function E(e){return e.clientOnly?{...e.props??{},clientOnly:!0}:e.props}function se(e){let t=e.__vaniStart,n=e.__vaniEnd;return!t||!n?null:{start:t,end:n}}function ce(e,t,n,r=null){let i=document.createDocumentFragment(),a=t;for(;a;){let e=a.nextSibling;if(i.appendChild(a),a===n)break;a=e}e.insertBefore(i,r)}function D(e){if(e.nodeType===Node.ELEMENT_NODE)return e;if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE){let t=e.firstChild;if(t&&t.nodeType===Node.ELEMENT_NODE&&t.nextSibling===null)return t}return null}function le(e,t){let n=new Set(t.getAttributeNames());for(let t of e.getAttributeNames())n.has(t)||e.removeAttribute(t);for(let r of n){let n=t.getAttribute(r);e.getAttribute(r)!==n&&(n===null?e.removeAttribute(r):e.setAttribute(r,n))}}function O(e,t){if(e.props===t)return!1;if(!e.props||typeof e.props!=`object`||!t||typeof t!=`object`)return e.props=t,!0;let n=!1,r=e.props,i=t;for(let e in r)e in i||(delete r[e],n=!0);for(let e in i)r[e]!==i[e]&&(r[e]=i[e],n=!0);return n}function k(e,t,n=null){let r=document.createDocumentFragment(),i=S(t.component,E(t),r,{initialRender:`sync`});t.ref&&(t.ref.current=i);let a=se(i)??void 0,o={component:t.component,handle:i,fragment:r,ref:t.ref,props:t.props,start:a?.start,end:a?.end};return e.insertBefore(r,n),o}function A(e){let t=[];for(let n of e)Array.isArray(n)?t.push(...A(n)):t.push(n);return t}function j(e,n){let r=A(n);if(t()===`ssr`){for(let t of r)if(!(t==null||t===!1||t===void 0)){if(T(t)){y(e,{type:`component`,instance:t});continue}if(typeof t==`string`||typeof t==`number`){y(e,v(String(t)));continue}if(!Array.isArray(t)&&h(t)){y(e,t);continue}}return}let i=e;for(let e of r)if(!(e==null||e===!1||e===void 0)){if(T(e)){if(e.key!=null){let t=u(i),n=i.__vaniUsedKeys??=new Set,r=t.get(e.key);r&&r.component!==e.component&&(r.handle.dispose(),r.ref&&(r.ref.current=null),t.delete(e.key),r=void 0),r?(r.ref!==e.ref&&(r.ref&&(r.ref.current=null),r.ref=e.ref),r.ref&&(r.ref.current=r.handle),O(r,e.props)&&r.handle.update(),r.start&&r.end&&ce(i,r.start,r.end)):(r=k(i,e,null),t.set(e.key,r)),n.add(e.key);continue}let t=document.createDocumentFragment(),n=S(e.component,E(e),t);e.ref&&(e.ref.current=n),i.appendChild(t);continue}if(typeof e==`string`||typeof e==`number`){i.appendChild(document.createTextNode(String(e)));continue}Array.isArray(e)||i.appendChild(e)}let a=i.__vaniKeyed,o=i.__vaniUsedKeys;if(a&&o){for(let[e,t]of a)o.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),a.delete(e));o.clear()}}function ue(e,n){if(t()===`ssr`)throw Error(`[vani] renderKeyedChildren is not supported in SSR mode`);let r=e,i=u(r),a=r.__vaniUsedKeys??=new Set,o=r.firstChild;for(let e of n){if(!T(e)||e.key==null)continue;let t=i.get(e.key);t&&t.component!==e.component&&(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e.key),t=void 0);let n=t==null;if(n)t=k(r,e,o),i.set(e.key,t);else{let n=t;n.ref!==e.ref&&(n.ref&&(n.ref.current=null),n.ref=e.ref),n.ref&&(n.ref.current=n.handle),O(n,e.props)&&n.handle.update(),t=n}let s=t;s.start&&s.end&&(!n&&o&&s.start!==o&&ce(r,s.start,s.end,o),o=s.end.nextSibling),a.add(e.key)}for(let[e,t]of i)a.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e));a.clear()}function de(e){return typeof SVGElement<`u`&&e instanceof SVGElement}function M(e,t){return e.startsWith(`aria`)?`aria-`+e.replace(`aria-`,``).replace(`aria`,``).toLowerCase():e.startsWith(`data`)?`data-`+e.replace(`data-`,``).replace(`data`,``):e.toLowerCase()===`htmlfor`?`for`:t?e:e.toLowerCase()}r({getRenderMode:t,createTextNode:e=>v(e),addNodeCleanup:ne,classNames:N,normalizeAttrKey:M});function fe(e,t){if(`class`in t&&`className`in t)throw Error(`[vani] Cannot use both "class" and "className" on the same element. Use one or the other.`);let n=g(e)?_.has(e.tag):de(e);for(let r in t){let i=t[r];if(![`key`,`ref`].includes(r)){if(r===`className`||r===`class`){let t=N(i);g(e)?e.props.class=t:n?e.setAttribute(`class`,t):e.className=t;continue}if(r.startsWith(`on`)&&typeof i==`function`)g(e)||(e[r.toLowerCase()]=i);else if(r===`value`||r===`checked`||r===`selected`)g(e)?e.props[r]=String(i):e[r]=i;else if(i===!0)g(e)?e.props[r]=!0:e.setAttribute(r,``);else if(i===!1||i==null)continue;else{let t=M(r,n);g(e)?e.props[t]=String(i):e.setAttribute(t,String(i))}}}}function N(...e){return e.map(e=>{if(!(e==null||e===``))return typeof e==`string`?e.trim():Array.isArray(e)?N(...e):Object.entries(e).filter(([e,t])=>t).map(([e])=>e.trim()).join(` `).trim()}).filter(Boolean).join(` `)}let P=!1;const pe={select:[`value`]};function me(e,t){let n=pe[e];if(!n)return{cleanProps:t,deferred:{}};let r={},i=!1;for(let e of n)e in t&&t[e]!==void 0&&(r[e]=t[e],i=!0);if(!i)return{cleanProps:t,deferred:{}};let a={...t};for(let e of n)delete a[e];return{cleanProps:a,deferred:r}}function he(e,t){if(!g(e))for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r)}function F(e,t,...n){let r=te(e);if(oe(t)){t.ref&&(!g(r)&&!P?(t.ref.current=r,r.__vaniDomRef=t.ref):t.ref.current=null);let{cleanProps:i,deferred:a}=me(e,t);return fe(r,i),P||j(r,n),he(r,a),r}return j(r,[t,...n]),r}const I=(...e)=>{if(t()===`ssr`){let t={type:`fragment`,children:[]};return j(t,e),t}let n=document.createDocumentFragment();return j(n,e),n};function ge(e,n){if(t()===`ssr`)return{type:`component`,instance:{$$vani:`component`,component:e,props:n}};let r=document.createDocumentFragment();return S(e,n,r),r}let L=!1,R=!1,z=!1,B=0,V=!1,H=!1;const U=new Set,W=new Set;function _e(e){let t=R;R=!0;try{e()}finally{R=t,B>0?H=!0:G()}}function ve(e){B+=1;try{e()}finally{--B,B===0&&(V&&(V=!1,K()),H&&(H=!1,G()))}}function G(){z||(z=!0,setTimeout(()=>{z=!1,ye()},0))}function K(){L||(L=!0,queueMicrotask(()=>{L=!1;for(let e of U)e.updateSync(e.__vaniUpdateOptions);U.clear()}))}function ye(){for(let e of W)e.updateSync(e.__vaniUpdateOptions);W.clear(),W.size>0&&G()}let q=!1,J=null,Y=0;function X(e){Z()&&console.warn(`[vani] hydration warning: ${e}`)}function be(e,t){let n=J;(!n||!e.contains(n))&&(n=e.firstChild);let r=!1;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`)return r&&X(`Found <!--vani:end--> before <!--vani:start--> for component #${t}. This usually means the server HTML anchor order is incorrect.`),n;n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:end`&&(r=!0),n=n.nextSibling}throw X(`Expected <!--vani:start--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new l(`[vani] hydration failed: start anchor not found`)}function xe(e,t){let n=e.nextSibling,r=0;for(;n;){if(n.nodeType===Node.COMMENT_NODE){if(n.nodeValue===`vani:start`)r+=1;else if(n.nodeValue===`vani:end`){if(r===0)return J=n.nextSibling,n;--r}}n=n.nextSibling}throw X(`Expected <!--vani:end--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new l(`[vani] hydration failed: end anchor not found`)}function Se(e,t){let n=[];q=!0,J=t.firstChild,Y=0;try{n=w(e,t)}catch(e){if(e instanceof l)console.error(`[vani] hydration failed:`,e);else throw e}finally{if(Z()&&J){let e=J,t=!1;for(;e;){if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;if(n===`vani:start`||n===`vani:end`){t=!0;break}}e=e.nextSibling}t&&X(`Unused SSR anchors detected after hydration. Some server-rendered DOM was not claimed by the client runtime.`)}q=!1,J=null,Y=0}return n}function Z(){return`__vaniDevMode`in globalThis?globalThis.__vaniDevMode===!0:import.meta.env?import.meta.env.DEV:typeof process<`u`&&process.env!==void 0?process.env.NODE_ENV===`development`:!1}const Q=Symbol.for(`vani.fragment`);function Ce(e){return e==null||e===!1?[]:Array.isArray(e)?e:[e]}function we(e,t){if(!e||typeof e!=`object`)return{props:null,children:[],key:t,ref:void 0,hasChildrenProp:!1};let n=Object.prototype.hasOwnProperty.call(e,`children`),r=n?Ce(e.children):[],i=t??e.key,a=e.ref,{key:o,ref:s,children:c,...l}=e;return{props:Object.keys(l).length>0?l:null,children:r,key:i,ref:a,hasChildrenProp:n}}function $(e,t,n){let{props:r,children:i,key:a,ref:o,hasChildrenProp:s}=we(t,n);if(e===Q)return I(...i);if(typeof e==`string`){let t=o==null?r:{...r??{},ref:o};return t?F(e,t,...i):F(e,null,...i)}if(typeof e==`function`){let t={...r??{}};return(i.length>0||s)&&(t.children=i.length<=1?i[0]:i),a!=null&&(t.key=a),o&&(t.ref=o),e.$$vaniWrapped?e(t):d(e)(t)}throw Error(`[vani] jsx runtime received an unsupported element type.`)}const Te=$;function Ee(e,t,n,r,i,a){return $(e,t,n)}export{i as C,t as S,ue as _,l as a,m as b,d as c,I as d,Se as f,f as g,ge as h,Te as i,ae as l,Z as m,$ as n,ve as o,T as p,Ee as r,N as s,Q as t,F as u,w as v,n as w,r as x,_e as y};
2
- //# sourceMappingURL=jsx-runtime-BUSOLzm1.mjs.map