@ryupold/vode 1.8.3 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vode.min.mjs CHANGED
@@ -1 +1 @@
1
- var P={currentViewTransition:void 0,requestAnimationFrame:window.requestAnimationFrame?window.requestAnimationFrame.bind(window):(e=>e()),startViewTransition:document.startViewTransition?document.startViewTransition.bind(document):null};function q(e,n,...s){if(!e)throw new Error("first argument to vode() must be a tag name or a vode");return Array.isArray(e)?e:n?[e,n,...s]:[e,...s]}function w(e,n,s,...a){if(!e?.parentElement)throw new Error("first argument to app() must be a valid HTMLElement inside the <html></html> document");if(!n||typeof n!="object")throw new Error("second argument to app() must be a state object");if(typeof s!="function")throw new Error("third argument to app() must be a function that returns a vode");let t={};t.syncRenderer=P.requestAnimationFrame,t.asyncRenderer=P.startViewTransition,t.qSync=null,t.qAsync=null,t.stats={lastSyncRenderTime:0,lastAsyncRenderTime:0,syncRenderCount:0,asyncRenderCount:0,liveEffectCount:0,patchCount:0,syncRenderPatchCount:0,asyncRenderPatchCount:0};let o=n;"patch"in n&&typeof n.patch=="function"&&Array.isArray(n.patch.initialPatches)&&(a=[...n.patch.initialPatches,...a]),Object.defineProperty(n,"patch",{enumerable:!1,configurable:!0,writable:!1,value:async(l,y)=>{if(!(!l||typeof l!="function"&&typeof l!="object"))if(t.stats.patchCount++,l?.next){let S=l;t.stats.liveEffectCount++;try{let u=await S.next();for(;u.done===!1;){t.stats.liveEffectCount++;try{o.patch(u.value,y),u=await S.next()}finally{t.stats.liveEffectCount--}}o.patch(u.value,y)}finally{t.stats.liveEffectCount--}}else if(l.then){t.stats.liveEffectCount++;try{let S=await l;o.patch(S,y)}finally{t.stats.liveEffectCount--}}else if(Array.isArray(l))if(l.length>0)for(let S of l)o.patch(S,!document.hidden&&!!t.asyncRenderer);else{t.qSync=E(t.qSync||{},t.qAsync,!1),t.qAsync=null;try{P.currentViewTransition?.skipTransition()}catch{}t.stats.syncRenderPatchCount++,t.renderSync()}else typeof l=="function"?o.patch(l(t.state),y):y?(t.stats.asyncRenderPatchCount++,t.qAsync=E(t.qAsync||{},l,!1),await t.renderAsync()):(t.stats.syncRenderPatchCount++,t.qSync=E(t.qSync||{},l,!1),t.renderSync())}});function r(l){let y=Date.now(),S=s(t.state);t.vode=C(t.state,e.parentElement,0,0,t.vode,S),e.tagName.toUpperCase()!==S[0].toUpperCase()&&(e=t.vode.node,e._vode=t),l||(t.stats.lastSyncRenderTime=Date.now()-y,t.stats.syncRenderCount++,t.isRendering=!1,t.qSync&&t.renderSync())}let p=r.bind(null,!1),i=r.bind(null,!0);Object.defineProperty(t,"renderSync",{enumerable:!1,configurable:!0,writable:!1,value:()=>{t.isRendering||!t.qSync||(t.isRendering=!0,t.state=E(t.state,t.qSync,!0),t.qSync=null,t.syncRenderer(p))}}),Object.defineProperty(t,"renderAsync",{enumerable:!1,configurable:!0,writable:!1,value:async()=>{if(t.isAnimating||!t.qAsync||(await P.currentViewTransition?.updateCallbackDone,t.isAnimating||!t.qAsync||document.hidden))return;t.isAnimating=!0;let l=Date.now();try{t.state=E(t.state,t.qAsync,!0),t.qAsync=null,P.currentViewTransition=t.asyncRenderer(i),await P.currentViewTransition?.updateCallbackDone}finally{t.stats.lastAsyncRenderTime=Date.now()-l,t.stats.asyncRenderCount++,t.isAnimating=!1}t.qAsync&&t.renderAsync()}}),t.state=o;let c=e;c._vode=t;let d=Array.from(e.parentElement.children).indexOf(e);t.vode=C(n,e.parentElement,d,d,D(e,!0),s(n));for(let l of a)o.patch(l);return l=>o.patch(l)}function F(e){if(e?._vode){let s=function(t){if(!t?.node)return;let o=A(t);if(o){for(let r in o)r[0]==="o"&&r[1]==="n"&&(t.node[r]=null);t.node.catch=null}if(t.node._vode)F(t.node);else{let r=N(t);if(r)for(let p of r)s(p)}};var n=s;let a=e._vode;delete e._vode,Object.defineProperty(a.state,"patch",{value:void 0}),Object.defineProperty(a,"renderSync",{value:()=>{}}),Object.defineProperty(a,"renderAsync",{value:()=>{}}),s(a.vode)}else for(let s of e.children)F(s)}function D(e,n){if(e?.nodeType===Node.TEXT_NODE)return e.nodeValue?.trim()!==""?n?e:e.nodeValue:void 0;if(e.nodeType===Node.COMMENT_NODE)return;if(e.nodeType===Node.ELEMENT_NODE){let a=[e.tagName.toLowerCase()];if(n&&(a.node=e),e?.hasAttributes()){let t={},o=e.attributes;for(let r of o)t[r.name]=r.value;a.push(t)}if(e.hasChildNodes()){let t=[];for(let o of e.childNodes){let r=o&&D(o,n);r?a.push(r):o&&n&&t.push(o)}for(let o of t)o.remove()}return a}else return}function X(e,n){if(!e||!Array.isArray(e))throw new Error("first argument to memo() must be an array of values to compare");if(typeof n!="function")throw new Error("second argument to memo() must be a function that returns a vode or props object");return n.__memo=e,n}function Y(e){if(!e||typeof e!="object")throw new Error("createState() must be called with a state object");return"patch"in e||Object.defineProperty(e,"patch",{enumerable:!1,configurable:!0,writable:!1,value:n=>{let s=e;Array.isArray(s.patch.initialPatches)||(s.patch.initialPatches=[]),s.patch.initialPatches.push(n)}}),e}function W(e){return e}function $(e){return e?Array.isArray(e)?e[0]:typeof e=="string"||e.nodeType===Node.TEXT_NODE?"#text":void 0:void 0}function A(e){if(Array.isArray(e)&&e.length>1&&e[1]&&!Array.isArray(e[1])&&typeof e[1]=="object"&&e[1].nodeType!==Node.TEXT_NODE)return e[1]}function N(e){let n=v(e);return n>0?e.slice(n):null}function J(e){let n=v(e);return n<0?0:e.length-n}function Q(e,n){let s=v(e);if(s>0)return e[n+s]}function v(e){return A(e)?e.length>2?2:-1:Array.isArray(e)&&e.length>1?1:-1}function E(e,n,s){if(!n)return e;for(let a in n){let t=n[a];if(t&&typeof t=="object"){let o=e[a];o?Array.isArray(t)?e[a]=[...t]:t instanceof Date&&o!==t?e[a]=new Date(t):Array.isArray(o)?e[a]=E({},t,s):typeof o=="object"?E(e[a],t,s):e[a]=E({},t,s):Array.isArray(t)?e[a]=[...t]:t instanceof Date?e[a]=new Date(t):e[a]=E({},t,s)}else t===void 0&&s?delete e[a]:e[a]=t}return e}function C(e,n,s,a,t,o,r){try{o=R(e,o,t);let p=!o||typeof o=="number"||typeof o=="boolean";if(o===t||!t&&p)return t;let i=t?.nodeType===Node.TEXT_NODE,c=i?t:t?.node;if(p){c?.onUnmount&&e.patch(c.onUnmount(c)),c?.remove();return}let d=!p&&_(o),l=!p&&K(o),y=!!o&&typeof o!="string"&&!!(o?.node||o?.nodeType===Node.TEXT_NODE);if(!d&&!l&&!y&&!t)throw new Error("Invalid vode: "+typeof o+" "+JSON.stringify(o));if(y&&d?o=o.wholeText:y&&l&&(o=[...o]),i&&d)return c.nodeValue!==o&&(c.nodeValue=o),t;if(d&&(!c||!i)){let S=document.createTextNode(o);if(c)c.onUnmount&&e.patch(c.onUnmount(c)),c.replaceWith(S);else{let u=!1;for(let f=a;f<n.childNodes.length;f++){let x=n.childNodes[f];if(x){x.before(S,x),u=!0;break}}u||n.appendChild(S)}return S}if(l&&(!c||i||t[0]!==o[0])){let S=o;1 in S&&(S[1]=R(e,S[1],void 0));let u=A(o);u?.xmlns!==void 0&&(r=u.xmlns);let f=r?document.createElementNS(r,o[0]):document.createElement(o[0]);if(o.node=f,O(e,f,void 0,u,r??null),u&&"catch"in u&&(o.node.catch=null,o.node.removeAttribute("catch")),c)c.onUnmount&&e.patch(c.onUnmount(c)),c.replaceWith(f);else{let h=!1;for(let g=a;g<n.childNodes.length;g++){let T=n.childNodes[g];if(T){T.before(f,T),h=!0;break}}h||n.appendChild(f)}let x=N(o);if(x){let h=u?2:1,g=0;for(let T=0;T<x.length;T++){let m=x[T],b=C(e,f,T,g,void 0,m,r??null);o[T+h]=b,b&&g++}}return f.onMount&&e.patch(f.onMount(f)),o}if(!i&&l&&t[0]===o[0]){o.node=c;let S=o,u=t,f=A(o),x=A(t);if(f?.xmlns!==void 0&&(r=f.xmlns),S[1]?.__memo){let T=S[1];S[1]=R(e,S[1],u[1]),T!==S[1]&&O(e,c,x,f,r)}else O(e,c,x,f,r);f?.catch&&x?.catch!==f.catch&&(o.node.catch=null,o.node.removeAttribute("catch"));let h=N(o),g=N(t);if(h){let T=f?2:1,m=0;for(let b=0;b<h.length;b++){let k=h[b],B=g&&g[b],I=C(e,c,b,m,B,k,r);o[b+T]=I,I&&m++}}if(g){let T=h?h.length:0;for(let m=g.length-1;m>=T;m--)C(e,c,m,m,g[m],void 0,r)}return o}}catch(p){let i=A(o)?.catch;if(i){let c=typeof i=="function"?i(e,p):i;return C(e,n,s,a,D(o?.node||t?.node,!0),c,r)}else throw p}}function K(e){return Array.isArray(e)&&e.length>0&&typeof e[0]=="string"}function _(e){return typeof e=="string"||e?.nodeType===Node.TEXT_NODE}function R(e,n,s){if(typeof n!="function")return n;let a=n?.__memo,t=s?.__memo;if(Array.isArray(a)&&Array.isArray(t)&&a.length===t.length){let r=!0;for(let p=0;p<a.length;p++)if(a[p]!==t[p]){r=!1;break}if(r)return s}let o=V(n,e);return typeof o=="object"&&(o.__memo=n?.__memo),o}function V(e,n){return typeof e=="function"?V(e(n),n):e}function O(e,n,s,a,t){if(!a&&!s)return;let o=t!==void 0;if(s)for(let r in s){let p=s[r],i=a?.[r];p!==i&&(a?a[r]=M(e,n,r,p,i,o):M(e,n,r,p,void 0,o))}if(a&&s){for(let r in a)if(!(r in s)){let p=a[r];a[r]=M(e,n,r,void 0,p,o)}}else if(a)for(let r in a){let p=a[r];a[r]=M(e,n,r,void 0,p,o)}}function M(e,n,s,a,t,o){if(s==="style")if(!t)n.style.cssText="";else if(typeof t=="string")a!==t&&(n.style.cssText=t);else if(a&&typeof a=="object"){for(let r in a)t[r]||(n.style[r]=null);for(let r in t){let p=a[r],i=t[r];p!==i&&(n.style[r]=i)}}else for(let r in t)n.style[r]=t[r];else if(s==="class")t?n.setAttribute("class",j(t)):n.removeAttribute("class");else if(s[0]==="o"&&s[1]==="n")if(t){let r=null;if(typeof t=="function"){let p=t;r=i=>e.patch(p(e,i))}else typeof t=="object"&&(r=()=>e.patch(t));n[s]=r}else n[s]=null;else o||(n[s]=t),t==null||t===!1?n.removeAttribute(s):n.setAttribute(s,t);return t}function j(e){return typeof e=="string"?e:Array.isArray(e)?e.map(j).join(" "):typeof e=="object"?Object.keys(e).filter(n=>e[n]).join(" "):""}var Z="a",tt="abbr",et="address",nt="area",ot="article",at="aside",st="audio",rt="b",ct="base",it="bdi",lt="bdo",pt="blockquote",St="body",ft="br",dt="button",ut="canvas",Tt="caption",yt="cite",gt="code",xt="col",ht="colgroup",mt="data",bt="datalist",Et="dd",Pt="del",At="details",Ct="dfn",Mt="dialog",Nt="div",Rt="dl",Ot="dt",Dt="em",vt="embed",Lt="fieldset",It="figcaption",Ft="figure",Vt="footer",jt="form",Ht="h1",Ut="h2",Gt="h3",kt="h4",Bt="h5",Kt="h6",_t="head",qt="header",wt="hgroup",Xt="hr",Yt="html",Wt="i",$t="iframe",Jt="img",Qt="input",zt="ins",Zt="kbd",te="label",ee="legend",ne="li",oe="link",ae="main",se="map",re="mark",ce="menu",ie="meta",le="meter",pe="nav",Se="noscript",fe="object",de="ol",ue="optgroup",Te="option",ye="output",ge="p",xe="picture",he="pre",me="progress",be="q",Ee="rp",Pe="rt",Ae="ruby",Ce="s",Me="samp",Ne="script",Re="search",Oe="section",De="select",ve="slot",Le="small",Ie="source",Fe="span",Ve="strong",je="style",He="sub",Ue="summary",Ge="sup",ke="table",Be="tbody",Ke="td",_e="template",qe="textarea",we="tfoot",Xe="th",Ye="thead",We="time",$e="title",Je="tr",Qe="track",ze="u",Ze="ul",tn="var",en="video",nn="wbr",on="animate",an="animateMotion",sn="animateTransform",rn="circle",cn="clipPath",ln="defs",pn="desc",Sn="ellipse",fn="feBlend",dn="feColorMatrix",un="feComponentTransfer",Tn="feComposite",yn="feConvolveMatrix",gn="feDiffuseLighting",xn="feDisplacementMap",hn="feDistantLight",mn="feDropShadow",bn="feFlood",En="feFuncA",Pn="feFuncB",An="feFuncG",Cn="feFuncR",Mn="feGaussianBlur",Nn="feImage",Rn="feMerge",On="feMergeNode",Dn="feMorphology",vn="feOffset",Ln="fePointLight",In="feSpecularLighting",Fn="feSpotLight",Vn="feTile",jn="feTurbulence",Hn="filter",Un="foreignObject",Gn="g",kn="image",Bn="line",Kn="linearGradient",_n="marker",qn="mask",wn="metadata",Xn="mpath",Yn="path",Wn="pattern",$n="polygon",Jn="polyline",Qn="radialGradient",zn="rect",Zn="set",to="stop",eo="svg",no="switch",oo="symbol",ao="text",so="textPath",ro="tspan",co="use",io="view",lo="annotation",po="annotation-xml",So="maction",fo="math",uo="merror",To="mfrac",yo="mi",go="mmultiscripts",xo="mn",ho="mo",mo="mover",bo="mpadded",Eo="mphantom",Po="mprescripts",Ao="mroot",Co="mrow",Mo="ms",No="mspace",Ro="msqrt",Oo="mstyle",Do="msub",vo="msubsup",Lo="msup",Io="mtable",Fo="mtd",Vo="mtext",jo="mtr",Ho="munder",Uo="munderover",Go="semantics";function H(...e){if(!e||e.length===0)return null;if(e.length===1)return e[0];let n=e[0];for(let s=1;s<e.length;s++){let a=n,t=e[s];if(!a)n=t;else if(t)if(typeof a=="string"&&typeof t=="string"){let o=a.split(" "),r=t.split(" "),p=new Set([...o,...r]);n=Array.from(p).join(" ").trim()}else if(typeof a=="string"&&Array.isArray(t)){let o=new Set([...t,...a.split(" ")]);n=Array.from(o).join(" ").trim()}else if(Array.isArray(a)&&typeof t=="string"){let o=new Set([...a,...t.split(" ")]);n=Array.from(o).join(" ").trim()}else if(Array.isArray(a)&&Array.isArray(t)){let o=new Set([...a,...t]);n=Array.from(o).join(" ").trim()}else if(typeof a=="string"&&typeof t=="object")n={[a]:!0,...t};else if(typeof a=="object"&&typeof t=="string")n={...a,[t]:!0};else if(typeof a=="object"&&typeof t=="object")n={...a,...t};else if(typeof a=="object"&&Array.isArray(t)){let o={...a};for(let r of t)o[r]=!0;n=o}else if(Array.isArray(a)&&typeof t=="object"){let o={};for(let r of a)o[r]=!0;for(let r of Object.keys(t))o[r]=t[r];n=o}else throw new Error(`cannot merge classes of ${a} (${typeof a}) and ${t} (${typeof t})`);else continue}return n}var U=document.createElement("div");function G(...e){try{let n=U.style;for(let s of e)if(typeof s=="object"&&s!==null)for(let a in s)n[a]=s[a];else typeof s=="string"&&(n.cssText+=";"+s);return n.cssText}finally{U.style.cssText=""}}function wo(...e){if(e.length===0)return;if(e.length===1)return e[0]||void 0;let n;for(let s of e)if(!(typeof s!="object"||s===null)){n||(n={});for(let a in s)a==="style"?n.style=G(n.style,s.style):a==="class"?n.class=H(n.class,s.class):n[a]=s[a]}return n}function Yo(e){return new L(e,[])}var L=class e{constructor(n,s){this.state=n;this.keys=s;function a(i,c){if(s.length>1){let d=0,l=c[s[d]];for((typeof l!="object"||l===null)&&(c[s[d]]=l={}),d=1;d<s.length-1;d++){let y=l;l=l[s[d]],(typeof l!="object"||l===null)&&(y[s[d]]=l={})}l[s[d]]=i}else s.length===1?typeof c[s[0]]=="object"&&typeof i=="object"?Object.assign(c[s[0]],i):c[s[0]]=i:Object.assign(c,i)}function t(i){let c={};return a(i,c),c}function o(){if(s.length===0)return n;let i=n?n[s[0]]:void 0;for(let c=1;c<s.length&&i;c++)i=i[s[c]];return i}function r(i){a(i,n)}function p(i){if(Array.isArray(i)){let c=[];for(let d of i)c.push(t(d));n.patch(c)}else n.patch(t(i))}return new Proxy(this,{get:(i,c,d)=>{if(c==="state")return n;if(c==="get")return o;if(c==="put")return r;if(c==="patch")return p;let l=[...i.keys,String(c)];return new e(i.state,l)}})}state;keys;get(){}put(n){}patch(n){}};export{Z as A,tt as ABBR,et as ADDRESS,on as ANIMATE,an as ANIMATEMOTION,sn as ANIMATETRANSFORM,lo as ANNOTATION,po as ANNOTATION_XML,nt as AREA,ot as ARTICLE,at as ASIDE,st as AUDIO,rt as B,ct as BASE,it as BDI,lt as BDO,pt as BLOCKQUOTE,St as BODY,ft as BR,dt as BUTTON,ut as CANVAS,Tt as CAPTION,rn as CIRCLE,yt as CITE,cn as CLIPPATH,gt as CODE,xt as COL,ht as COLGROUP,mt as DATA,bt as DATALIST,Et as DD,ln as DEFS,Pt as DEL,pn as DESC,At as DETAILS,Ct as DFN,Mt as DIALOG,Nt as DIV,Rt as DL,Ot as DT,Sn as ELLIPSE,Dt as EM,vt as EMBED,fn as FEBLEND,dn as FECOLORMATRIX,un as FECOMPONENTTRANSFER,Tn as FECOMPOSITE,yn as FECONVOLVEMATRIX,gn as FEDIFFUSELIGHTING,xn as FEDISPLACEMENTMAP,hn as FEDISTANTLIGHT,mn as FEDROPSHADOW,bn as FEFLOOD,En as FEFUNCA,Pn as FEFUNCB,An as FEFUNCG,Cn as FEFUNCR,Mn as FEGAUSSIANBLUR,Nn as FEIMAGE,Rn as FEMERGE,On as FEMERGENODE,Dn as FEMORPHOLOGY,vn as FEOFFSET,Ln as FEPOINTLIGHT,In as FESPECULARLIGHTING,Fn as FESPOTLIGHT,Vn as FETILE,jn as FETURBULENCE,Lt as FIELDSET,It as FIGCAPTION,Ft as FIGURE,Hn as FILTER,Vt as FOOTER,Un as FOREIGNOBJECT,jt as FORM,Gn as G,Ht as H1,Ut as H2,Gt as H3,kt as H4,Bt as H5,Kt as H6,_t as HEAD,qt as HEADER,wt as HGROUP,Xt as HR,Yt as HTML,Wt as I,$t as IFRAME,kn as IMAGE,Jt as IMG,Qt as INPUT,zt as INS,Zt as KBD,te as LABEL,ee as LEGEND,ne as LI,Bn as LINE,Kn as LINEARGRADIENT,oe as LINK,So as MACTION,ae as MAIN,se as MAP,re as MARK,_n as MARKER,qn as MASK,fo as MATH,ce as MENU,uo as MERROR,ie as META,wn as METADATA,le as METER,To as MFRAC,yo as MI,go as MMULTISCRIPTS,xo as MN,ho as MO,mo as MOVER,bo as MPADDED,Xn as MPATH,Eo as MPHANTOM,Po as MPRESCRIPTS,Ao as MROOT,Co as MROW,Mo as MS,No as MSPACE,Ro as MSQRT,Oo as MSTYLE,Do as MSUB,vo as MSUBSUP,Lo as MSUP,Io as MTABLE,Fo as MTD,Vo as MTEXT,jo as MTR,Ho as MUNDER,Uo as MUNDEROVER,pe as NAV,Se as NOSCRIPT,fe as OBJECT,de as OL,ue as OPTGROUP,Te as OPTION,ye as OUTPUT,ge as P,Yn as PATH,Wn as PATTERN,xe as PICTURE,$n as POLYGON,Jn as POLYLINE,he as PRE,me as PROGRESS,be as Q,Qn as RADIALGRADIENT,zn as RECT,Ee as RP,Pe as RT,Ae as RUBY,Ce as S,Me as SAMP,Ne as SCRIPT,Re as SEARCH,Oe as SECTION,De as SELECT,Go as SEMANTICS,Zn as SET,ve as SLOT,Le as SMALL,Ie as SOURCE,Fe as SPAN,to as STOP,Ve as STRONG,je as STYLE,He as SUB,Ue as SUMMARY,Ge as SUP,eo as SVG,no as SWITCH,oo as SYMBOL,ke as TABLE,Be as TBODY,Ke as TD,_e as TEMPLATE,ao as TEXT,qe as TEXTAREA,so as TEXTPATH,we as TFOOT,Xe as TH,Ye as THEAD,We as TIME,$e as TITLE,Je as TR,Qe as TRACK,ro as TSPAN,ze as U,Ze as UL,co as USE,tn as VAR,en as VIDEO,io as VIEW,nn as WBR,w as app,Q as child,J as childCount,N as children,v as childrenStart,Yo as context,W as createPatch,Y as createState,F as defuse,P as globals,D as hydrate,X as memo,H as mergeClass,wo as mergeProps,G as mergeStyle,A as props,$ as tag,q as vode};
1
+ var P={currentViewTransition:void 0,requestAnimationFrame:typeof window<"u"&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame.bind(window):(e=>e()),startViewTransition:typeof document<"u"&&typeof document.startViewTransition=="function"?document.startViewTransition.bind(document):null};function q(e,n,...s){if(!e)throw new Error("first argument to vode() must be a tag name or a vode");return Array.isArray(e)?e:typeof n=="object"?[e,n,...s]:[e,...s]}function w(e,n,s,...a){if(!e?.parentElement)throw new Error("first argument to app() must be a valid HTMLElement inside the <html></html> document");if(!n||typeof n!="object")throw new Error("second argument to app() must be a state object");if(typeof s!="function")throw new Error("third argument to app() must be a function that returns a vode");let t={};t.syncRenderer=P.requestAnimationFrame,t.asyncRenderer=P.startViewTransition,t.qSync=null,t.qAsync=null,t.stats={lastSyncRenderTime:0,lastAsyncRenderTime:0,syncRenderCount:0,asyncRenderCount:0,liveEffectCount:0,patchCount:0,syncRenderPatchCount:0,asyncRenderPatchCount:0};let o=n;"patch"in n&&typeof n.patch=="function"&&Array.isArray(n.patch.initialPatches)&&(a=[...n.patch.initialPatches,...a]),Object.defineProperty(n,"patch",{enumerable:!1,configurable:!0,writable:!1,value:async(l,y)=>{if(!(!l||typeof l!="function"&&typeof l!="object"))if(t.stats.patchCount++,l?.next){let f=l;t.stats.liveEffectCount++;try{let u=await f.next();for(;u.done===!1;){t.stats.liveEffectCount++;try{o.patch(u.value,y),u=await f.next()}finally{t.stats.liveEffectCount--}}o.patch(u.value,y)}finally{t.stats.liveEffectCount--}}else if(l.then){t.stats.liveEffectCount++;try{let f=await l;o.patch(f,y)}finally{t.stats.liveEffectCount--}}else if(Array.isArray(l))if(l.length>0)for(let f of l)o.patch(f,!document.hidden&&!!t.asyncRenderer);else{t.qSync=E(t.qSync||{},t.qAsync,!1),t.qAsync=null;try{P.currentViewTransition?.skipTransition()}catch{}t.stats.syncRenderPatchCount++,t.renderSync()}else typeof l=="function"?o.patch(l(t.state),y):y?(t.stats.asyncRenderPatchCount++,t.qAsync=E(t.qAsync||{},l,!1),await t.renderAsync()):(t.stats.syncRenderPatchCount++,t.qSync=E(t.qSync||{},l,!1),t.renderSync())}});function r(l){let y=Date.now(),f=s(t.state);t.vode=C(t.state,e.parentElement,0,0,t.vode,f),e.tagName.toUpperCase()!==f[0].toUpperCase()&&(e=t.vode.node,e._vode=t),l||(t.stats.lastSyncRenderTime=Date.now()-y,t.stats.syncRenderCount++,t.isRendering=!1,t.qSync&&t.renderSync())}let p=r.bind(null,!1),i=r.bind(null,!0);Object.defineProperty(t,"renderSync",{enumerable:!1,configurable:!0,writable:!1,value:()=>{t.isRendering||!t.qSync||(t.isRendering=!0,t.state=E(t.state,t.qSync,!0),t.qSync=null,t.syncRenderer(p))}}),Object.defineProperty(t,"renderAsync",{enumerable:!1,configurable:!0,writable:!1,value:async()=>{if(t.isAnimating||!t.qAsync||(await P.currentViewTransition?.updateCallbackDone,t.isAnimating||!t.qAsync||document.hidden))return;t.isAnimating=!0;let l=Date.now();try{t.state=E(t.state,t.qAsync,!0),t.qAsync=null,P.currentViewTransition=t.asyncRenderer(i),await P.currentViewTransition?.updateCallbackDone}finally{t.stats.lastAsyncRenderTime=Date.now()-l,t.stats.asyncRenderCount++,t.isAnimating=!1}t.qAsync&&t.renderAsync()}}),t.state=o;let c=e;c._vode=t;let S=Array.from(e.parentElement.children).indexOf(e);t.vode=C(n,e.parentElement,S,S,v(e,!0),s(n));for(let l of a)o.patch(l);return l=>o.patch(l)}function V(e){if(e?._vode){let s=function(t){if(!t?.node)return;let o=A(t);if(o){for(let r in o)r[0]==="o"&&r[1]==="n"&&(t.node[r]=null);t.node.catch=null}if(t.node._vode)V(t.node);else{let r=N(t);if(r)for(let p of r)s(p)}};var n=s;let a=e._vode;delete e._vode,Object.defineProperty(a.state,"patch",{value:void 0}),Object.defineProperty(a,"renderSync",{value:()=>{}}),Object.defineProperty(a,"renderAsync",{value:()=>{}}),s(a.vode)}else for(let s of e.children)V(s)}function v(e,n){if(e?.nodeType===Node.TEXT_NODE)return e.nodeValue?.trim()!==""?n?e:e.nodeValue:void 0;if(e.nodeType===Node.ELEMENT_NODE){let a=[e.tagName.toLowerCase()];if(n&&(a.node=e),e?.hasAttributes()){let t={},o=e.attributes;for(let r of o)t[r.name]=r.value;a.push(t)}if(e.hasChildNodes()){let t=[];for(let o of e.childNodes){let r=o&&v(o,n);r?a.push(r):o&&n&&t.push(o)}for(let o of t)o.remove()}return a}else return}function X(e,n){if(!e||!Array.isArray(e))throw new Error("first argument to memo() must be an array of values to compare");if(typeof n!="function")throw new Error("second argument to memo() must be a function that returns a vode or props object");return n.__memo=e,n}function Y(e){if(!e||typeof e!="object")throw new Error("createState() must be called with a state object");return"patch"in e||Object.defineProperty(e,"patch",{enumerable:!1,configurable:!0,writable:!1,value:n=>{let s=e;Array.isArray(s.patch.initialPatches)||(s.patch.initialPatches=[]),s.patch.initialPatches.push(n)}}),e}function W(e){return e}function $(e){return e?Array.isArray(e)?e[0]:typeof e=="string"||e.nodeType===Node.TEXT_NODE?"#text":void 0:void 0}function A(e){if(Array.isArray(e)&&e.length>1&&e[1]&&!Array.isArray(e[1])&&typeof e[1]=="object"&&e[1].nodeType!==Node.TEXT_NODE)return e[1]}function N(e){let n=L(e);return n>0?e.slice(n):null}function J(e){let n=L(e);return n<0?0:e.length-n}function Q(e,n){let s=L(e);if(s>0)return e[n+s]}function L(e){return A(e)?e.length>2?2:-1:Array.isArray(e)&&e.length>1?1:-1}function E(e,n,s){if(!n)return e;for(let a in n){let t=n[a];if(t&&typeof t=="object"){let o=e[a];o?Array.isArray(t)?e[a]=[...t]:t instanceof Date&&o!==t?e[a]=new Date(t):Array.isArray(o)?e[a]=E({},t,s):typeof o=="object"?E(e[a],t,s):e[a]=E({},t,s):Array.isArray(t)?e[a]=[...t]:t instanceof Date?e[a]=new Date(t):e[a]=E({},t,s)}else t===void 0&&s?delete e[a]:e[a]=t}return e}function C(e,n,s,a,t,o,r){try{o=O(e,o,t);let p=!o||typeof o=="number"||typeof o=="boolean";if(o===t||!t&&p)return t;let i=t?.nodeType===Node.TEXT_NODE,c=i?t:t?.node;if(p){c?.onUnmount&&e.patch(c.onUnmount(c)),c?.remove();return}let S=!p&&K(o),l=!p&&B(o),y=!!o&&typeof o!="string"&&!!(o?.node||o?.nodeType===Node.TEXT_NODE);if(!S&&!l&&!y&&!t)throw new Error("Invalid vode: "+typeof o+" "+JSON.stringify(o));if(y&&S?o=o.wholeText:y&&l&&(o=[...o]),i&&S)return c.nodeValue!==o&&(c.nodeValue=o),t;if(S&&(!c||!i)){let f=document.createTextNode(o);if(c)c.onUnmount&&e.patch(c.onUnmount(c)),c.replaceWith(f);else{let u=!1;for(let d=a;d<n.childNodes.length;d++){let x=n.childNodes[d];if(x){x.before(f,x),u=!0;break}}u||n.appendChild(f)}return f}if(l&&(!c||i||t[0]!==o[0])){let f=o;1 in f&&(f[1]=O(e,f[1],void 0));let u=A(o);u?.xmlns!==void 0&&(r=u.xmlns);let d=r?document.createElementNS(r,o[0]):document.createElement(o[0]);if(o.node=d,D(e,d,void 0,u,r??null),u&&"catch"in u&&(o.node.catch=null,o.node.removeAttribute("catch")),c)c.onUnmount&&e.patch(c.onUnmount(c)),c.replaceWith(d);else{let h=!1;for(let g=a;g<n.childNodes.length;g++){let T=n.childNodes[g];if(T){T.before(d,T),h=!0;break}}h||n.appendChild(d)}let x=N(o);if(x){let h=u?2:1,g=0;for(let T=0;T<x.length;T++){let m=x[T],b=C(e,d,T,g,void 0,m,r??null);o[T+h]=b,b&&g++}}return d.onMount&&e.patch(d.onMount(d)),o}if(!i&&l&&t[0]===o[0]){o.node=c;let f=o,u=t,d=A(o),x=A(t);if(d?.xmlns!==void 0&&(r=d.xmlns),f[1]?.__memo){let T=f[1];f[1]=O(e,f[1],u[1]),T!==f[1]&&D(e,c,x,d,r)}else D(e,c,x,d,r);d?.catch&&x?.catch!==d.catch&&(o.node.catch=null,o.node.removeAttribute("catch"));let h=N(o),g=N(t);if(h){let T=d?2:1,m=0;for(let b=0;b<h.length;b++){let k=h[b],_=g&&g[b],F=C(e,c,b,m,_,k,r);o[b+T]=F,F&&m++}}if(g){let T=h?h.length:0;for(let m=g.length-1;m>=T;m--)C(e,c,m,m,g[m],void 0,r)}return o}}catch(p){let i=A(o)?.catch;if(i){let c=typeof i=="function"?i(e,p):i;return C(e,n,s,a,v(o?.node||t?.node,!0),c,r)}else throw p}}function B(e){return Array.isArray(e)&&e.length>0&&typeof e[0]=="string"}function K(e){return typeof e=="string"||e?.nodeType===Node.TEXT_NODE}function O(e,n,s){if(typeof n!="function")return n;let a=n?.__memo,t=s?.__memo;if(Array.isArray(a)&&Array.isArray(t)&&a.length===t.length){let p=!0;for(let i=0;i<a.length;i++)if(a[i]!==t[i]){p=!1;break}if(p)return s}let o=n(e);if(typeof o=="function"&&o?.__memo){let p=o.__memo;if(Array.isArray(p)&&Array.isArray(t)&&p.length===t.length){let c=!0;for(let S=0;S<p.length;S++)if(p[S]!==t[S]){c=!1;break}if(c)return s}let i=o(e);return typeof i=="object"&&(i.__memo=p),i}let r=typeof o=="function"?j(o,e):o;return typeof r=="object"&&(r.__memo=o?.__memo||n?.__memo),r}function j(e,n){return typeof e=="function"?j(e(n),n):e}function D(e,n,s,a,t){if(!a&&!s)return;let o=t!==void 0;if(s)for(let r in s){let p=s[r],i=a?.[r];p!==i&&(a?a[r]=M(e,n,r,p,i,o):M(e,n,r,p,void 0,o))}if(a&&s){for(let r in a)if(!(r in s)){let p=a[r];a[r]=M(e,n,r,void 0,p,o)}}else if(a)for(let r in a){let p=a[r];a[r]=M(e,n,r,void 0,p,o)}}function M(e,n,s,a,t,o){if(s==="style")if(!t)n.style.cssText="";else if(typeof t=="string")a!==t&&(n.style.cssText=t);else if(a&&typeof a=="object"){for(let r in a)t[r]||(n.style[r]=null);for(let r in t){let p=a[r],i=t[r];p!==i&&(n.style[r]=i)}}else for(let r in t)n.style[r]=t[r];else if(s==="class")t?n.setAttribute("class",H(t)):n.removeAttribute("class");else if(s[0]==="o"&&s[1]==="n")if(t){let r=null;if(typeof t=="function"){let p=t;r=i=>e.patch(p(e,i))}else typeof t=="object"&&(r=()=>e.patch(t));n[s]=r}else n[s]=null;else o||(n[s]=t),t==null||t===!1?n.removeAttribute(s):n.setAttribute(s,t);return t}function H(e){return typeof e=="string"?e:Array.isArray(e)?e.map(H).join(" "):typeof e=="object"?Object.keys(e).filter(n=>e[n]).join(" "):""}var Z="a",tt="abbr",et="address",nt="area",ot="article",at="aside",st="audio",rt="b",ct="base",it="bdi",lt="bdo",pt="blockquote",ft="body",St="br",dt="button",ut="canvas",Tt="caption",yt="cite",gt="code",xt="col",ht="colgroup",mt="data",bt="datalist",Et="dd",Pt="del",At="details",Ct="dfn",Mt="dialog",Nt="div",Rt="dl",Ot="dt",Dt="em",vt="embed",Lt="fieldset",It="figcaption",Ft="figure",Vt="footer",jt="form",Ht="h1",Ut="h2",Gt="h3",kt="h4",_t="h5",Bt="h6",Kt="head",qt="header",wt="hgroup",Xt="hr",Yt="html",Wt="i",$t="iframe",Jt="img",Qt="input",zt="ins",Zt="kbd",te="label",ee="legend",ne="li",oe="link",ae="main",se="map",re="mark",ce="menu",ie="meta",le="meter",pe="nav",fe="noscript",Se="object",de="ol",ue="optgroup",Te="option",ye="output",ge="p",xe="picture",he="pre",me="progress",be="q",Ee="rp",Pe="rt",Ae="ruby",Ce="s",Me="samp",Ne="script",Re="search",Oe="section",De="select",ve="slot",Le="small",Ie="source",Fe="span",Ve="strong",je="style",He="sub",Ue="summary",Ge="sup",ke="table",_e="tbody",Be="td",Ke="template",qe="textarea",we="tfoot",Xe="th",Ye="thead",We="time",$e="title",Je="tr",Qe="track",ze="u",Ze="ul",tn="var",en="video",nn="wbr",on="animate",an="animateMotion",sn="animateTransform",rn="circle",cn="clipPath",ln="defs",pn="desc",fn="ellipse",Sn="feBlend",dn="feColorMatrix",un="feComponentTransfer",Tn="feComposite",yn="feConvolveMatrix",gn="feDiffuseLighting",xn="feDisplacementMap",hn="feDistantLight",mn="feDropShadow",bn="feFlood",En="feFuncA",Pn="feFuncB",An="feFuncG",Cn="feFuncR",Mn="feGaussianBlur",Nn="feImage",Rn="feMerge",On="feMergeNode",Dn="feMorphology",vn="feOffset",Ln="fePointLight",In="feSpecularLighting",Fn="feSpotLight",Vn="feTile",jn="feTurbulence",Hn="filter",Un="foreignObject",Gn="g",kn="image",_n="line",Bn="linearGradient",Kn="marker",qn="mask",wn="metadata",Xn="mpath",Yn="path",Wn="pattern",$n="polygon",Jn="polyline",Qn="radialGradient",zn="rect",Zn="set",to="stop",eo="svg",no="switch",oo="symbol",ao="text",so="textPath",ro="tspan",co="use",io="view",lo="annotation",po="annotation-xml",fo="maction",So="math",uo="merror",To="mfrac",yo="mi",go="mmultiscripts",xo="mn",ho="mo",mo="mover",bo="mpadded",Eo="mphantom",Po="mprescripts",Ao="mroot",Co="mrow",Mo="ms",No="mspace",Ro="msqrt",Oo="mstyle",Do="msub",vo="msubsup",Lo="msup",Io="mtable",Fo="mtd",Vo="mtext",jo="mtr",Ho="munder",Uo="munderover",Go="semantics";function U(...e){if(!e||e.length===0)return null;if(e.length===1)return e[0];let n=e[0];for(let s=1;s<e.length;s++){let a=n,t=e[s];if(!a)n=t;else if(t)if(typeof a=="string"&&typeof t=="string"){let o=a.split(" "),r=t.split(" "),p=new Set([...o,...r]);n=Array.from(p).join(" ").trim()}else if(typeof a=="string"&&Array.isArray(t)){let o=new Set([...t,...a.split(" ")]);n=Array.from(o).join(" ").trim()}else if(Array.isArray(a)&&typeof t=="string"){let o=new Set([...a,...t.split(" ")]);n=Array.from(o).join(" ").trim()}else if(Array.isArray(a)&&Array.isArray(t)){let o=new Set([...a,...t]);n=Array.from(o).join(" ").trim()}else if(typeof a=="string"&&typeof t=="object")n={[a]:!0,...t};else if(typeof a=="object"&&typeof t=="string")n={...a,[t]:!0};else if(typeof a=="object"&&typeof t=="object")n={...a,...t};else if(typeof a=="object"&&Array.isArray(t)){let o={...a};for(let r of t)o[r]=!0;n=o}else if(Array.isArray(a)&&typeof t=="object"){let o={};for(let r of a)o[r]=!0;for(let r of Object.keys(t))o[r]=t[r];n=o}else throw new Error(`cannot merge classes of ${a} (${typeof a}) and ${t} (${typeof t})`);else continue}return n}var R;function G(...e){R||(R=document.createElement("div"));try{let n=R.style;for(let s of e)if(typeof s=="object"&&s!==null)for(let a in s)n[a]=s[a];else typeof s=="string"&&(n.cssText+=";"+s);return n.cssText}finally{R.style.cssText=""}}function wo(...e){if(e.length===0)return;if(e.length===1)return e[0]||void 0;let n;for(let s of e)if(!(typeof s!="object"||s===null)){n||(n={});for(let a in s)a==="style"?n.style=G(n.style,s.style):a==="class"?n.class=U(n.class,s.class):n[a]=s[a]}return n}function Yo(e){return new I(e,[])}var I=class e{constructor(n,s){this.state=n;this.keys=s;function a(i,c){if(s.length>1){let S=0,l=c[s[S]];for((typeof l!="object"||l===null)&&(c[s[S]]=l={}),S=1;S<s.length-1;S++){let y=l;l=l[s[S]],(typeof l!="object"||l===null)&&(y[s[S]]=l={})}l[s[S]]=i}else s.length===1?typeof c[s[0]]=="object"&&typeof i=="object"?Object.assign(c[s[0]],i):c[s[0]]=i:Object.assign(c,i)}function t(i){let c={};return a(i,c),c}function o(){if(s.length===0)return n;let i=n?n[s[0]]:void 0;for(let c=1;c<s.length&&i;c++)i=i[s[c]];return i}function r(i){a(i,n)}function p(i,c){c?n.patch([t(i)]):n.patch(t(i))}return new Proxy(this,{get:(i,c,S)=>{if(c==="state")return n;if(c==="get")return o;if(c==="put")return r;if(c==="patch")return p;let l=[...i.keys,String(c)];return new e(i.state,l)}})}state;keys;get(){}put(n){}patch(n){}};export{Z as A,tt as ABBR,et as ADDRESS,on as ANIMATE,an as ANIMATEMOTION,sn as ANIMATETRANSFORM,lo as ANNOTATION,po as ANNOTATION_XML,nt as AREA,ot as ARTICLE,at as ASIDE,st as AUDIO,rt as B,ct as BASE,it as BDI,lt as BDO,pt as BLOCKQUOTE,ft as BODY,St as BR,dt as BUTTON,ut as CANVAS,Tt as CAPTION,rn as CIRCLE,yt as CITE,cn as CLIPPATH,gt as CODE,xt as COL,ht as COLGROUP,mt as DATA,bt as DATALIST,Et as DD,ln as DEFS,Pt as DEL,pn as DESC,At as DETAILS,Ct as DFN,Mt as DIALOG,Nt as DIV,Rt as DL,Ot as DT,fn as ELLIPSE,Dt as EM,vt as EMBED,Sn as FEBLEND,dn as FECOLORMATRIX,un as FECOMPONENTTRANSFER,Tn as FECOMPOSITE,yn as FECONVOLVEMATRIX,gn as FEDIFFUSELIGHTING,xn as FEDISPLACEMENTMAP,hn as FEDISTANTLIGHT,mn as FEDROPSHADOW,bn as FEFLOOD,En as FEFUNCA,Pn as FEFUNCB,An as FEFUNCG,Cn as FEFUNCR,Mn as FEGAUSSIANBLUR,Nn as FEIMAGE,Rn as FEMERGE,On as FEMERGENODE,Dn as FEMORPHOLOGY,vn as FEOFFSET,Ln as FEPOINTLIGHT,In as FESPECULARLIGHTING,Fn as FESPOTLIGHT,Vn as FETILE,jn as FETURBULENCE,Lt as FIELDSET,It as FIGCAPTION,Ft as FIGURE,Hn as FILTER,Vt as FOOTER,Un as FOREIGNOBJECT,jt as FORM,Gn as G,Ht as H1,Ut as H2,Gt as H3,kt as H4,_t as H5,Bt as H6,Kt as HEAD,qt as HEADER,wt as HGROUP,Xt as HR,Yt as HTML,Wt as I,$t as IFRAME,kn as IMAGE,Jt as IMG,Qt as INPUT,zt as INS,Zt as KBD,te as LABEL,ee as LEGEND,ne as LI,_n as LINE,Bn as LINEARGRADIENT,oe as LINK,fo as MACTION,ae as MAIN,se as MAP,re as MARK,Kn as MARKER,qn as MASK,So as MATH,ce as MENU,uo as MERROR,ie as META,wn as METADATA,le as METER,To as MFRAC,yo as MI,go as MMULTISCRIPTS,xo as MN,ho as MO,mo as MOVER,bo as MPADDED,Xn as MPATH,Eo as MPHANTOM,Po as MPRESCRIPTS,Ao as MROOT,Co as MROW,Mo as MS,No as MSPACE,Ro as MSQRT,Oo as MSTYLE,Do as MSUB,vo as MSUBSUP,Lo as MSUP,Io as MTABLE,Fo as MTD,Vo as MTEXT,jo as MTR,Ho as MUNDER,Uo as MUNDEROVER,pe as NAV,fe as NOSCRIPT,Se as OBJECT,de as OL,ue as OPTGROUP,Te as OPTION,ye as OUTPUT,ge as P,Yn as PATH,Wn as PATTERN,xe as PICTURE,$n as POLYGON,Jn as POLYLINE,he as PRE,me as PROGRESS,be as Q,Qn as RADIALGRADIENT,zn as RECT,Ee as RP,Pe as RT,Ae as RUBY,Ce as S,Me as SAMP,Ne as SCRIPT,Re as SEARCH,Oe as SECTION,De as SELECT,Go as SEMANTICS,Zn as SET,ve as SLOT,Le as SMALL,Ie as SOURCE,Fe as SPAN,to as STOP,Ve as STRONG,je as STYLE,He as SUB,Ue as SUMMARY,Ge as SUP,eo as SVG,no as SWITCH,oo as SYMBOL,ke as TABLE,_e as TBODY,Be as TD,Ke as TEMPLATE,ao as TEXT,qe as TEXTAREA,so as TEXTPATH,we as TFOOT,Xe as TH,Ye as THEAD,We as TIME,$e as TITLE,Je as TR,Qe as TRACK,ro as TSPAN,ze as U,Ze as UL,co as USE,tn as VAR,en as VIDEO,io as VIEW,nn as WBR,w as app,Q as child,J as childCount,N as children,L as childrenStart,Yo as context,W as createPatch,Y as createState,V as defuse,P as globals,v as hydrate,X as memo,U as mergeClass,wo as mergeProps,G as mergeStyle,A as props,$ as tag,q as vode};
package/dist/vode.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  // src/vode.ts
2
2
  var globals = {
3
3
  currentViewTransition: void 0,
4
- requestAnimationFrame: !!window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : ((cb) => cb()),
5
- startViewTransition: !!document.startViewTransition ? document.startViewTransition.bind(document) : null
4
+ requestAnimationFrame: typeof window !== "undefined" && typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame.bind(window) : ((cb) => cb()),
5
+ startViewTransition: typeof document !== "undefined" && typeof document.startViewTransition === "function" ? document.startViewTransition.bind(document) : null
6
6
  };
7
7
  function vode(tag2, props2, ...children2) {
8
8
  if (!tag2) throw new Error("first argument to vode() must be a tag name or a vode");
9
9
  if (Array.isArray(tag2)) return tag2;
10
- else if (props2) return [tag2, props2, ...children2];
10
+ else if (typeof props2 === "object") return [tag2, props2, ...children2];
11
11
  else return [tag2, ...children2];
12
12
  }
13
13
  function app(container, state, dom, ...initialPatches) {
@@ -200,8 +200,6 @@ function hydrate(element, prepareForRender) {
200
200
  if (element.nodeValue?.trim() !== "")
201
201
  return prepareForRender ? element : element.nodeValue;
202
202
  return void 0;
203
- } else if (element.nodeType === Node.COMMENT_NODE) {
204
- return void 0;
205
203
  } else if (element.nodeType === Node.ELEMENT_NODE) {
206
204
  const tag2 = element.tagName.toLowerCase();
207
205
  const root = [tag2];
@@ -496,9 +494,28 @@ function remember(state, present, past) {
496
494
  }
497
495
  if (same) return past;
498
496
  }
499
- const newRender = unwrap(present, state);
497
+ const result = present(state);
498
+ if (typeof result === "function" && result?.__memo) {
499
+ const resultMemo = result.__memo;
500
+ if (Array.isArray(resultMemo) && Array.isArray(pastMemo) && resultMemo.length === pastMemo.length) {
501
+ let same = true;
502
+ for (let i = 0; i < resultMemo.length; i++) {
503
+ if (resultMemo[i] !== pastMemo[i]) {
504
+ same = false;
505
+ break;
506
+ }
507
+ }
508
+ if (same) return past;
509
+ }
510
+ const innerRender = result(state);
511
+ if (typeof innerRender === "object") {
512
+ innerRender.__memo = resultMemo;
513
+ }
514
+ return innerRender;
515
+ }
516
+ const newRender = typeof result === "function" ? unwrap(result, state) : result;
500
517
  if (typeof newRender === "object") {
501
- newRender.__memo = present?.__memo;
518
+ newRender.__memo = result?.__memo || present?.__memo;
502
519
  }
503
520
  return newRender;
504
521
  }
@@ -857,8 +874,11 @@ function mergeClass(...classes) {
857
874
  }
858
875
 
859
876
  // src/merge-style.ts
860
- var tempDivForStyling = document.createElement("div");
877
+ var tempDivForStyling;
861
878
  function mergeStyle(...props2) {
879
+ if (!tempDivForStyling) {
880
+ tempDivForStyling = document.createElement("div");
881
+ }
862
882
  try {
863
883
  const merged = tempDivForStyling.style;
864
884
  for (const style of props2) {
@@ -946,13 +966,9 @@ var ProxyStateContextImpl = class _ProxyStateContextImpl {
946
966
  function put(value) {
947
967
  putDeep(value, state);
948
968
  }
949
- function patch(value) {
950
- if (Array.isArray(value)) {
951
- const animation = [];
952
- for (const v of value) {
953
- animation.push(createPatch2(v));
954
- }
955
- state.patch(animation);
969
+ function patch(value, isAsync) {
970
+ if (isAsync) {
971
+ state.patch([createPatch2(value)]);
956
972
  } else {
957
973
  state.patch(createPatch2(value));
958
974
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryupold/vode",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
4
4
  "description": "a minimalist web framework",
5
5
  "author": "Michael Scherbakow (ryupold)",
6
6
  "license": "MIT",
@@ -46,12 +46,13 @@
46
46
  "release": "npm run build && npm run build-min && npm run build-classic && npm run build-classic-min && npm run babel && npm run babel-classic && npm run types",
47
47
  "publish": "npm publish --access public",
48
48
  "clean": "tsc -b --clean && rm dist/*",
49
- "watch": "tsc -b -w"
49
+ "watch": "tsc -b -w",
50
+ "test": "tsc -p tsconfig.test.json && esbuild test/index.ts --bundle --outfile=test/bundle.js --platform=node && node test/bundle.js"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@babel/cli": "7.28.6",
53
54
  "@babel/core": "7.29.0",
54
- "@babel/preset-env": "7.29.3",
55
+ "@babel/preset-env": "7.29.5",
55
56
  "babel-preset-minify": "0.5.2",
56
57
  "dts-bundle-generator": "9.5.1",
57
58
  "esbuild": "0.28.0",
@@ -1,10 +1,13 @@
1
1
  import { StyleProp } from "./vode";
2
2
 
3
- const tempDivForStyling = document.createElement('div');
3
+ let tempDivForStyling: HTMLElement | undefined;
4
4
 
5
5
  /** merge `StyleProps`s regardless of type
6
6
  * @returns {string} merged StyleProp */
7
7
  export function mergeStyle(...props: StyleProp[]): StyleProp {
8
+ if (!tempDivForStyling) {
9
+ tempDivForStyling = document.createElement('div');
10
+ }
8
11
  try{
9
12
  const merged = tempDivForStyling.style;
10
13
  for (const style of props) {
@@ -37,7 +37,7 @@ export interface SubContext<SubState> {
37
37
  *
38
38
  * @param value - The new value or partial update to apply
39
39
  */
40
- patch(value: SubState | Partial<SubState> | DeepPartial<SubState> | Array<DeepPartial<SubState>>): void;
40
+ patch(value: SubState | Partial<SubState> | DeepPartial<SubState> | Array<DeepPartial<SubState>>, isAsync?: boolean): void;
41
41
  }
42
42
 
43
43
  export type ProxyStateContext<S extends PatchableState, SubState> = StateContext<S, SubState> & {
@@ -137,13 +137,9 @@ class ProxyStateContextImpl<S extends PatchableState, SubState>
137
137
  putDeep(value, state);
138
138
  }
139
139
 
140
- function patch(value: SubState | DeepPartial<SubState> | Array<DeepPartial<SubState>> | undefined | null) {
141
- if (Array.isArray(value)) {
142
- const animation: AnimatedPatch<S> = [];
143
- for (const v of value) {
144
- animation.push(createPatch(v));
145
- }
146
- state.patch(animation);
140
+ function patch(value: SubState | DeepPartial<SubState> | Array<DeepPartial<SubState>> | undefined | null, isAsync?: boolean) {
141
+ if (isAsync) {
142
+ state.patch([createPatch(value as DeepPartial<SubState>)]);
147
143
  }
148
144
  else {
149
145
  state.patch(createPatch(value as DeepPartial<SubState>));
package/src/vode.ts CHANGED
@@ -78,8 +78,8 @@ export type PatchableState<S = object> = S & Patchable<S>;
78
78
 
79
79
  export const globals = {
80
80
  currentViewTransition: <ViewTransition | null | undefined>undefined,
81
- requestAnimationFrame: !!window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : ((cb: () => void) => cb()),
82
- startViewTransition: !!document.startViewTransition ? document.startViewTransition.bind(document) : null,
81
+ requestAnimationFrame: typeof window !== "undefined" && typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame.bind(window) : ((cb: () => void) => cb()),
82
+ startViewTransition: typeof document !== "undefined" && typeof document.startViewTransition === "function" ? document.startViewTransition.bind(document) : null,
83
83
  };
84
84
 
85
85
  export interface ContainerNode<S = PatchableState> extends HTMLElement {
@@ -122,7 +122,7 @@ export function vode<S = PatchableState>(tag: Tag | Vode<S>, props?: Props<S> |
122
122
  if (!tag) throw new Error("first argument to vode() must be a tag name or a vode");
123
123
 
124
124
  if (Array.isArray(tag)) return tag;
125
- else if (props) return [tag, props as Props<S>, ...children];
125
+ else if (typeof props === "object") return [tag, props as Props<S>, ...children];
126
126
  else return [tag, ...children];
127
127
  }
128
128
 
@@ -349,9 +349,6 @@ export function hydrate<S = PatchableState>(element: Element | Text, prepareForR
349
349
  return prepareForRender ? element as Text : (element as Text).nodeValue!;
350
350
  return undefined; //ignore (mostly html whitespace)
351
351
  }
352
- else if (element.nodeType === Node.COMMENT_NODE) {
353
- return undefined; //ignore (not interesting)
354
- }
355
352
  else if (element.nodeType === Node.ELEMENT_NODE) {
356
353
  const tag: Tag = (<Element>element).tagName.toLowerCase();
357
354
  const root: Vode<S> = [tag];
@@ -730,9 +727,31 @@ function remember<S>(state: S, present: any, past: any): ChildVode<S> | Attached
730
727
  }
731
728
  if (same) return past;
732
729
  }
733
- const newRender = unwrap(present, state);
730
+
731
+ const result = present(state);
732
+
733
+ if (typeof result === "function" && result?.__memo) {
734
+ const resultMemo = result.__memo;
735
+ if (Array.isArray(resultMemo) && Array.isArray(pastMemo) && resultMemo.length === pastMemo.length) {
736
+ let same = true;
737
+ for (let i = 0; i < resultMemo.length; i++) {
738
+ if (resultMemo[i] !== pastMemo[i]) {
739
+ same = false;
740
+ break;
741
+ }
742
+ }
743
+ if (same) return past;
744
+ }
745
+ const innerRender = result(state);
746
+ if (typeof innerRender === "object") {
747
+ innerRender.__memo = resultMemo;
748
+ }
749
+ return innerRender;
750
+ }
751
+
752
+ const newRender = typeof result === "function" ? unwrap(result, state) : result;
734
753
  if (typeof newRender === "object") {
735
- (<any>newRender).__memo = present?.__memo;
754
+ (<any>newRender).__memo = result?.__memo || present?.__memo;
736
755
  }
737
756
  return newRender;
738
757
  }
package/test/helper.ts ADDED
@@ -0,0 +1,168 @@
1
+ import { children, ChildVode, PatchableState, tag, Vode } from "../src/vode";
2
+ import { MockElement, MockText } from "./mocks";
3
+
4
+ export class Expectation {
5
+ constructor(public readonly what: any) { }
6
+
7
+ toBeA(type: "undefined" | "object" | "function" | "bigint" | "boolean" | "number" | "string" | "symbol") {
8
+ if (typeof this.what !== type) {
9
+ throw new ExpectationError(this, `expected \n\ntypeof ${this.what}\n\nto be \n\n${type}`);
10
+ }
11
+ }
12
+
13
+ toEqual(other: any) {
14
+ function deepCompare(a: any, b: any, path: string[]): string[] | null {
15
+ if (typeof a !== typeof b) {
16
+ if (path.length === 0) path.push(``);
17
+ path[path.length - 1] += ` (type: ${typeof a} != ${typeof b})`;
18
+ return path;
19
+ }
20
+
21
+ if (typeof a !== "object" || a === null) {
22
+ if (path.length === 0) path.push(``);
23
+ path[path.length - 1] += ` (value: ${a} != ${b})`;
24
+ return a !== b ? path : null;
25
+ }
26
+
27
+ for (const prop of Object.entries(a)) {
28
+ const [k, v] = prop;
29
+ const result = deepCompare(v, b[k], [...path, k]);
30
+ if (result) {
31
+ return result;
32
+ }
33
+ }
34
+
35
+ for (const prop of Object.entries(b)) {
36
+ const [k, v] = prop;
37
+ const result = deepCompare(a[k], v, [...path, k]);
38
+ if (result) {
39
+ return result;
40
+ }
41
+ }
42
+
43
+ return null;
44
+ }
45
+
46
+ if (typeof this.what === "object" && typeof other === "object" && this.what !== null && other !== null) {
47
+ const unequal = deepCompare(this.what, other, []);
48
+ if (unequal) {
49
+ throw new ExpectationError(this, `expected \n\n${JSON.stringify(this.what, null, 2)}\n\n to equal \n\n${JSON.stringify(other, null, 2)}\n\nThey differ in: ${unequal.join(".")}`);
50
+ }
51
+ }
52
+ else {
53
+ if (this.what !== other) {
54
+ throw new ExpectationError(this, `expected (${typeof this.what})\n\n${this.what}\n\nto equal (${typeof other})\n\n${other}`);
55
+ }
56
+ }
57
+ }
58
+
59
+ toSucceed<Result>(...args: any): Result {
60
+ if (typeof this.what !== "function") {
61
+ throw new ExpectationError(this, `expected a function\n\nbut it is a ${typeof this.what}`);
62
+ }
63
+ return this.what(...args);
64
+ }
65
+
66
+ toFail(...args: any): Error {
67
+ if (typeof this.what !== "function") {
68
+ throw new ExpectationError(this, `expected a function\n\nbut it is a ${typeof this.what}`);
69
+ }
70
+
71
+ let r: any;
72
+ try {
73
+ r = this.what(...args);
74
+ } catch (err: any) {
75
+ return err;
76
+ }
77
+ throw new ExpectationError(this, `expected function to fail\n\nbut it succeeded with a result of type ${typeof r}\n\n${r}`);
78
+ }
79
+
80
+ toMatch(v: ChildVode, state?: PatchableState) {
81
+ if (this.what instanceof MockElement || this.what instanceof MockText || typeof this.what === "string" || Array.isArray(this.what) || typeof this.what === "function") {
82
+ const that = this;
83
+ function deepCompare(e: MockElement | MockText | ChildVode, cv: ChildVode, path: string[]): string[] | null {
84
+
85
+ // unwrap component
86
+ while (typeof cv === "function") {
87
+ if (!state) {
88
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na Component\n\nbut got no state passed in [toMatch]`);
89
+ }
90
+ cv = cv(state);
91
+ }
92
+ while (typeof e === "function") {
93
+ if (!state) {
94
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na Component\n\nbut got no state passed in [toMatch]`);
95
+ }
96
+ e = e(state);
97
+ }
98
+
99
+ if (typeof cv === "string" && e instanceof MockText) {
100
+ if (cv !== e.wholeText) {
101
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na text node with\n${cv}\n\nbut text was\n${e.wholeText}`);
102
+ }
103
+ }
104
+ else if (typeof cv === "string" && typeof e === "string") {
105
+ if (cv !== e) {
106
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na text node with\n${cv}\n\nbut text was\n${e}`);
107
+ }
108
+ }
109
+
110
+ else if (Array.isArray(cv) && e instanceof MockElement) {
111
+ if (tag(cv)?.toLocaleUpperCase() !== e.tagName.toUpperCase()) {
112
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\nan element <${tag(cv)}>\n\nbut got <${e.tagName}>`);
113
+ }
114
+ const kids = children(cv) || [];
115
+ for (let i = 0; i < kids.length; i++) {
116
+ deepCompare(e.children[i], kids[i], [...path, `${tag(kids[i] as Vode) || "#text"}`]);
117
+ }
118
+ if (kids.length !== e.children.length) {
119
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\n${kids.length} children\n\nbut <${e.tagName}> has ${e.children.length} children`);
120
+ }
121
+ }
122
+ else if (Array.isArray(cv) && Array.isArray(e)) {
123
+ if (tag(cv)?.toLocaleUpperCase() !== tag(e)?.toUpperCase()) {
124
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\nan element [${tag(cv)}]\n\nbut got [${tag(e)}]`);
125
+ }
126
+ const kids = children(cv) || [];
127
+ const otherKids = children(e) || [];
128
+ for (let i = 0; i < kids.length; i++) {
129
+ deepCompare(otherKids[i], kids[i], [...path, `${tag(kids[i] as Vode) || "#text"}`]);
130
+ }
131
+ if (kids.length !== otherKids.length) {
132
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\n${kids.length} children\n\nbut [${tag(e)}] has ${otherKids.length} children`);
133
+ }
134
+ }
135
+
136
+ else if (typeof cv === "string" && e instanceof MockElement) {
137
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na text node\n\nbut got <${e.tagName}>`);
138
+ }
139
+ else if (typeof cv === "string" && Array.isArray(e)) {
140
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\na text node\n\nbut got [${tag(e)}]`);
141
+ }
142
+
143
+ else if (Array.isArray(cv) && e instanceof MockText) {
144
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\nan element <${tag(cv)}>\n\nbut got #text (${e.wholeText})`);
145
+ }
146
+ else if (Array.isArray(cv) && typeof e === "string") {
147
+ throw new ExpectationError(that, `expected at\n${path.join(" > ")}\n\nan element <${tag(cv)}>\n\nbut got #text (${e})`);
148
+ }
149
+
150
+ return null;
151
+ }
152
+
153
+ deepCompare(this.what, v, [tag(v as Vode) || "#text"]);
154
+ } else {
155
+ throw new ExpectationError(this, `expected an element or text node\n\nbut it is a ${typeof this.what}\n${this.what}`);
156
+ }
157
+ }
158
+ };
159
+
160
+ export class ExpectationError extends Error {
161
+ constructor(public readonly expectation: Expectation, message?: string) {
162
+ super(message)
163
+ }
164
+ }
165
+
166
+ export function expect(what: any) {
167
+ return new Expectation(what);
168
+ }
package/test/index.ts ADDED
@@ -0,0 +1,80 @@
1
+ import { resetMocks } from "./mocks";
2
+ import { ExpectationError } from "./helper";
3
+
4
+ //=== REGISTERED TESTS =========================================
5
+ import vodeTests from "./tests-vode";
6
+ import appTests from "./tests-app";
7
+ import defuseTests from "./tests-defuse";
8
+ import hydrateTests from "./tests-hydrate";
9
+ import memoTests from "./tests-memo";
10
+ import createStateTests from "./tests-createState";
11
+ import createPatchTests from "./tests-createPatch";
12
+ import tagTests from "./tests-tag";
13
+ import childrenTests from "./tests-children";
14
+ import propsTests from "./tests-props";
15
+ import mergeClassTests from "./tests-mergeClass";
16
+ import mergeStyleTests from "./tests-mergeStyle";
17
+ import mergePropsTests from "./tests-mergeProps";
18
+ import stateContextTests from "./tests-state-context";
19
+
20
+ const tests = {
21
+ ...vodeTests,
22
+ ...appTests,
23
+ ...defuseTests,
24
+ ...hydrateTests,
25
+ ...memoTests,
26
+
27
+ ...createStateTests,
28
+ ...createPatchTests,
29
+
30
+ ...tagTests,
31
+ ...propsTests,
32
+ ...childrenTests,
33
+
34
+ ...mergeClassTests,
35
+ ...mergeStyleTests,
36
+ ...mergePropsTests,
37
+
38
+ ...stateContextTests,
39
+ };
40
+ //===================================================
41
+
42
+ const count = {
43
+ total: 0,
44
+ passed: 0,
45
+ failed: <string[]>[],
46
+ }
47
+ const line = "----------------------------------";
48
+
49
+ for (const test of Object.entries(tests)) {
50
+ count.total++;
51
+ resetMocks();
52
+ try {
53
+ test[1]()
54
+ count.passed++;
55
+ console.log(`#${count.total} ${test[0]}\n-> 🟢 passed\n${line}`);
56
+ } catch (err: any) {
57
+ console.error(`#${count.total} ${test[0]}\n-> 🔴 failed`);
58
+ if (err instanceof ExpectationError) {
59
+ count.failed.push(`#${count.total} ${test[0]}\n-> 🔴 failed:\n${err.message}\n${line}`);
60
+ }
61
+ else {
62
+ count.failed.push(`#${count.total} ${test[0]}\n-> 🔴 failed:\n${err.message}\n${err.stack}\n${line}`);
63
+ }
64
+ }
65
+ }
66
+
67
+ console.log(`
68
+ total: ${count.total}
69
+ passed: ${count.passed}
70
+ failed: ${count.failed.length}
71
+ `);
72
+
73
+ if (count.passed === count.total) {
74
+ console.log("\n\nall tests passed\n");
75
+ }
76
+ else {
77
+ console.error(`${line.replaceAll("-", "=")}\nError summary:\n\n${count.failed.join(`\n${line}\n`)}`);
78
+
79
+ throw "\n\nsome tests failed (see output)\n";
80
+ }