elit 2.0.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +275 -128
- package/dist/build.d.mts +10 -1
- package/dist/build.d.ts +10 -1
- package/dist/build.js +670 -1
- package/dist/build.mjs +641 -1
- package/dist/chokidar.d.mts +134 -0
- package/dist/chokidar.d.ts +134 -0
- package/dist/chokidar.js +240 -0
- package/dist/chokidar.mjs +221 -0
- package/dist/cli.js +2792 -495
- package/dist/dom.d.mts +10 -3
- package/dist/dom.d.ts +10 -3
- package/dist/dom.js +676 -1
- package/dist/dom.mjs +647 -1
- package/dist/el.d.mts +16 -36
- package/dist/el.d.ts +16 -36
- package/dist/el.js +789 -1
- package/dist/el.mjs +583 -1
- package/dist/fs.d.mts +255 -0
- package/dist/fs.d.ts +255 -0
- package/dist/fs.js +513 -0
- package/dist/fs.mjs +469 -0
- package/dist/hmr.js +112 -1
- package/dist/hmr.mjs +91 -1
- package/dist/http.d.mts +163 -0
- package/dist/http.d.ts +163 -0
- package/dist/http.js +632 -0
- package/dist/http.mjs +605 -0
- package/dist/https.d.mts +108 -0
- package/dist/https.d.ts +108 -0
- package/dist/https.js +907 -0
- package/dist/https.mjs +901 -0
- package/dist/index.d.mts +613 -33
- package/dist/index.d.ts +613 -33
- package/dist/index.js +2589 -1
- package/dist/index.mjs +2312 -1
- package/dist/mime-types.d.mts +48 -0
- package/dist/mime-types.d.ts +48 -0
- package/dist/mime-types.js +197 -0
- package/dist/mime-types.mjs +166 -0
- package/dist/path.d.mts +163 -0
- package/dist/path.d.ts +163 -0
- package/dist/path.js +350 -0
- package/dist/path.mjs +310 -0
- package/dist/router.d.mts +3 -1
- package/dist/router.d.ts +3 -1
- package/dist/router.js +830 -1
- package/dist/router.mjs +801 -1
- package/dist/runtime.d.mts +97 -0
- package/dist/runtime.d.ts +97 -0
- package/dist/runtime.js +43 -0
- package/dist/runtime.mjs +15 -0
- package/dist/server.d.mts +5 -1
- package/dist/server.d.ts +5 -1
- package/dist/server.js +3267 -1
- package/dist/server.mjs +3241 -1
- package/dist/state.d.mts +3 -1
- package/dist/state.d.ts +3 -1
- package/dist/state.js +1036 -1
- package/dist/state.mjs +992 -1
- package/dist/style.d.mts +47 -1
- package/dist/style.d.ts +47 -1
- package/dist/style.js +551 -1
- package/dist/style.mjs +483 -1
- package/dist/{types-DOAdFFJB.d.ts → types-C0nGi6MX.d.mts} +29 -13
- package/dist/{types-DOAdFFJB.d.mts → types-Du6kfwTm.d.ts} +29 -13
- package/dist/types.d.mts +452 -3
- package/dist/types.d.ts +452 -3
- package/dist/types.js +18 -1
- package/dist/ws.d.mts +195 -0
- package/dist/ws.d.ts +195 -0
- package/dist/ws.js +380 -0
- package/dist/ws.mjs +358 -0
- package/dist/wss.d.mts +108 -0
- package/dist/wss.d.ts +108 -0
- package/dist/wss.js +1306 -0
- package/dist/wss.mjs +1300 -0
- package/package.json +53 -6
- package/dist/client.d.mts +0 -9
- package/dist/client.d.ts +0 -9
- package/dist/client.js +0 -1
- package/dist/client.mjs +0 -1
package/dist/state.mjs
CHANGED
|
@@ -1 +1,992 @@
|
|
|
1
|
-
var e=new class{constructor(){this.elementCache=new WeakMap,this.reactiveNodes=new Map}createElement(e,t={},r=[]){return{tagName:e,props:t,children:r}}renderToDOM(e,t){if(null==e||!1===e)return;if("object"!=typeof e)return void t.appendChild(document.createTextNode(String(e)));let{tagName:r,props:n,children:s}=e,i="svg"===r||"s"===r[0]&&"v"===r[1]&&"g"===r[2]||"http://www.w3.org/2000/svg"===t.namespaceURI,l=i?document.createElementNS("http://www.w3.org/2000/svg",r.replace("svg","").toLowerCase()||r):document.createElement(r);for(let e in n){let t=n[e];if(null==t||!1===t)continue;let r=e.charCodeAt(0);if(99===r&&(e.length<6||"N"===e[5])){let e=Array.isArray(t)?t.join(" "):t;i?l.setAttribute("class",e):l.className=e}else if(115===r&&5===e.length)if("string"==typeof t)l.style.cssText=t;else{let e=l.style;for(let r in t)e[r]=t[r]}else 111===r&&110===e.charCodeAt(1)?l[e.toLowerCase()]=t:100===r&&e.length>20?l.innerHTML=t.__html:114===r&&3===e.length?setTimeout(()=>{"function"==typeof t?t(l):t.current=l},0):l.setAttribute(e,!0===t?"":String(t))}let a=s.length;if(!a)return void t.appendChild(l);let o=e=>{for(let t=0;t<a;t++){let r=s[t];if(null!=r&&!1!==r)if(Array.isArray(r))for(let t=0,n=r.length;t<n;t++){let n=r[t];null!=n&&!1!==n&&this.renderToDOM(n,e)}else this.renderToDOM(r,e)}};if(a>30){let e=document.createDocumentFragment();o(e),l.appendChild(e)}else o(l);t.appendChild(l)}render(e,t){let r="string"==typeof e?document.getElementById(e.replace("#","")):e;if(!r)throw new Error(`Element not found: ${e}`);if(t.children&&t.children.length>500){let e=document.createDocumentFragment();this.renderToDOM(t,e),r.appendChild(e)}else this.renderToDOM(t,r);return r}batchRender(e,t){let r="string"==typeof e?document.getElementById(e.replace("#","")):e;if(!r)throw new Error(`Element not found: ${e}`);let n=t.length;if(n>3e3){let e=document.createDocumentFragment(),s=0,i=1500,l=()=>{let a=Math.min(s+i,n);for(let r=s;r<a;r++)this.renderToDOM(t[r],e);s=a,s>=n?r.appendChild(e):requestAnimationFrame(l)};l()}else{let e=document.createDocumentFragment();for(let r=0;r<n;r++)this.renderToDOM(t[r],e);r.appendChild(e)}return r}renderChunked(e,t,r=5e3,n){let s="string"==typeof e?document.getElementById(e.replace("#","")):e;if(!s)throw new Error(`Element not found: ${e}`);let i=t.length,l=0,a=()=>{let e=Math.min(l+r,i),o=document.createDocumentFragment();for(let r=l;r<e;r++)this.renderToDOM(t[r],o);s.appendChild(o),l=e,n&&n(l,i),l<i&&requestAnimationFrame(a)};return requestAnimationFrame(a),s}renderToHead(...e){let t=document.head;if(t)for(let r of e.flat())r&&this.renderToDOM(r,t);return t}addStyle(e){let t=document.createElement("style");return t.textContent=e,document.head.appendChild(t)}addMeta(e){let t=document.createElement("meta");for(let r in e)t.setAttribute(r,e[r]);return document.head.appendChild(t)}addLink(e){let t=document.createElement("link");for(let r in e)t.setAttribute(r,e[r]);return document.head.appendChild(t)}setTitle(e){return document.title=e}createState(e,t={}){let r=e,n=new Set,s=null,{throttle:i=0,deep:l=!1}=t,a=()=>n.forEach(e=>e(r));return{get value(){return r},set value(e){(l?JSON.stringify(r)!==JSON.stringify(e):r!==e)&&(r=e,i>0?s||(s=setTimeout(()=>{s=null,a()},i)):a())},subscribe:e=>(n.add(e),()=>n.delete(e)),destroy(){n.clear(),s&&clearTimeout(s)}}}computed(e,t){let r=e.map(e=>e.value),n=this.createState(t(...r));return e.forEach((e,s)=>{e.subscribe(e=>{r[s]=e,n.value=t(...r)})}),n}effect(e){e()}createVirtualList(e,t,r,n=50,s=5){let i=e.clientHeight,l=t.length*n,a=0,o=()=>{let{start:o,end:u}={start:Math.max(0,Math.floor(a/n)-s),end:Math.min(t.length,Math.ceil((a+i)/n)+s)},d=document.createElement("div");d.style.cssText=`height:${l}px;position:relative`;for(let e=o;e<u;e++){let s=document.createElement("div");s.style.cssText=`position:absolute;top:${e*n}px;height:${n}px;width:100%`,this.renderToDOM(r(t[e],e),s),d.appendChild(s)}e.innerHTML="",e.appendChild(d)},u=()=>{a=e.scrollTop,requestAnimationFrame(o)};return e.addEventListener("scroll",u),o(),{render:o,destroy:()=>{e.removeEventListener("scroll",u),e.innerHTML=""}}}lazy(e){let t=null,r=!1;return async(...n)=>(!t&&!r&&(r=!0,t=await e(),r=!1),t?t(...n):{tagName:"div",props:{class:"loading"},children:["Loading..."]})}cleanupUnusedElements(e){let t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),r=[];for(;t.nextNode();){let e=t.currentNode;e.id&&e.id.startsWith("r")&&!this.elementCache.has(e)&&r.push(e)}return r.forEach(e=>e.remove()),r.length}renderToString(e,t={}){let{pretty:r=!1,indent:n=0}=t,s=r?" ".repeat(n):"",i=r?"\n":"",l=this.resolveStateValue(e);if(l=this.unwrapReactive(l),Array.isArray(l))return l.map(e=>this.renderToString(e,t)).join("");if("object"!=typeof l||null===l)return null==l||!1===l?"":this.escapeHtml(String(l));let{tagName:a,props:o,children:u}=l,d=this.isSelfClosingTag(a),c=`${s}<${a}`,h=this.propsToAttributes(o);if(h&&(c+=` ${h}`),d)return c+=` />${i}`,c;if(c+=">",o.dangerouslySetInnerHTML)return c+=o.dangerouslySetInnerHTML.__html,c+=`</${a}>${i}`,c;if(u&&u.length>0){let e=u.map(e=>{let t=this.resolveStateValue(e);return this.unwrapReactive(t)}),t=e.some(e=>"object"==typeof e&&null!==e&&!Array.isArray(e)&&"tagName"in e);if(r&&t){c+=i;for(let t of e)if(null!=t&&!1!==t)if(Array.isArray(t))for(let e of t)null!=e&&!1!==e&&(c+=this.renderToString(e,{pretty:r,indent:n+1}));else c+=this.renderToString(t,{pretty:r,indent:n+1});c+=s}else for(let t of e)if(null!=t&&!1!==t)if(Array.isArray(t))for(let e of t)null!=e&&!1!==e&&(c+=this.renderToString(e,{pretty:!1,indent:0}));else c+=this.renderToString(t,{pretty:!1,indent:0})}return c+=`</${a}>${i}`,c}resolveStateValue(e){return e&&"object"==typeof e&&"value"in e&&"subscribe"in e?e.value:e}isReactiveWrapper(e){return!(!e||"object"!=typeof e||!e.tagName)&&("span"===e.tagName&&e.props?.id&&"string"==typeof e.props.id&&e.props.id.match(/^r[a-z0-9]{9}$/))}unwrapReactive(e){if(!this.isReactiveWrapper(e))return e;let t=e.children;if(!t||0===t.length)return"";if(1===t.length){let e=t[0];if(e&&"object"==typeof e&&"span"===e.tagName){let t=e.props,r=!t||0===Object.keys(t).length,n=e.children&&1===e.children.length&&"string"==typeof e.children[0];if(r&&n)return e.children[0]}return this.unwrapReactive(e)}return t.map(e=>this.unwrapReactive(e))}escapeHtml(e){let t={"&":"&","<":"<",">":">",'"':""","'":"'"};return e.replace(/[&<>"']/g,e=>t[e])}isSelfClosingTag(e){return new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]).has(e.toLowerCase())}propsToAttributes(e){let t=[];for(let r in e){if("children"===r||"dangerouslySetInnerHTML"===r||"ref"===r)continue;let n=e[r];if(n=this.resolveStateValue(n),null!=n&&!1!==n&&(!r.startsWith("on")||"function"!=typeof n)){if("className"===r||"class"===r){let e=Array.isArray(n)?n.join(" "):n;e&&t.push(`class="${this.escapeHtml(String(e))}"`);continue}if("style"===r){let e=this.styleToString(n);e&&t.push(`style="${this.escapeHtml(e)}"`);continue}if(!0===n){t.push(r);continue}t.push(`${r}="${this.escapeHtml(String(n))}"`)}}return t.join(" ")}styleToString(e){if("string"==typeof e)return e;if("object"==typeof e&&null!==e){let t=[];for(let r in e){let n=r.replace(/([A-Z])/g,"-$1").toLowerCase();t.push(`${n}:${e[r]}`)}return t.join(";")}return""}isState(e){return e&&"object"==typeof e&&"value"in e&&"subscribe"in e&&"function"==typeof e.subscribe}createReactiveChild(e,t){let r=t(e.value);if(typeof window<"u"&&typeof document<"u"){let r={node:null,renderFn:t};this.reactiveNodes.set(e,r),e.subscribe(()=>{if(r.node&&r.node.parentNode){let n=t(e.value);r.node.textContent=String(n??"")}})}return r}jsonToVNode(e){if(this.isState(e))return this.createReactiveChild(e,e=>e);if(null==e||"boolean"==typeof e||"string"==typeof e||"number"==typeof e)return e;let{tag:t,attributes:r={},children:n}=e,s={};for(let e in r){let t=r[e];"class"===e?s.className=this.isState(t)?t.value:t:s[e]=this.isState(t)?t.value:t}let i=[];if(null!=n)if(Array.isArray(n))for(let e of n)if(this.isState(e))i.push(this.createReactiveChild(e,e=>e));else{let t=this.jsonToVNode(e);null!=t&&!1!==t&&i.push(t)}else if(this.isState(n))i.push(this.createReactiveChild(n,e=>e));else if("object"==typeof n&&"tag"in n){let e=this.jsonToVNode(n);null!=e&&!1!==e&&i.push(e)}else i.push(n);return{tagName:t,props:s,children:i}}vNodeJsonToVNode(e){if(this.isState(e))return this.createReactiveChild(e,e=>e);if(null==e||"boolean"==typeof e||"string"==typeof e||"number"==typeof e)return e;let{tagName:t,props:r={},children:n=[]}=e,s={};for(let e in r){let t=r[e];s[e]=this.isState(t)?t.value:t}let i=[];for(let e of n)if(this.isState(e))i.push(this.createReactiveChild(e,e=>e));else{let t=this.vNodeJsonToVNode(e);null!=t&&!1!==t&&i.push(t)}return{tagName:t,props:s,children:i}}renderJson(e,t){let r=this.jsonToVNode(t);if(!r||"object"!=typeof r||!("tagName"in r))throw new Error("Invalid JSON structure");return this.render(e,r)}renderVNode(e,t){let r=this.vNodeJsonToVNode(t);if(!r||"object"!=typeof r||!("tagName"in r))throw new Error("Invalid VNode JSON structure");return this.render(e,r)}renderJsonToString(e,t={}){let r=this.jsonToVNode(e);return this.renderToString(r,t)}renderVNodeToString(e,t={}){let r=this.vNodeJsonToVNode(e);return this.renderToString(r,t)}renderServer(e){if("object"!=typeof e||null===e||!("tagName"in e))throw new Error("renderServer requires a VNode with html tag");if("html"!==e.tagName)throw new Error("renderServer requires a VNode with html tag as root");let t=e,r=null,n=null;for(let e of t.children||[])"object"==typeof e&&null!==e&&"tagName"in e&&("head"===e.tagName&&(r=e),"body"===e.tagName&&(n=e));if(t.props)for(let e in t.props){let r=t.props[e];null!=r&&!1!==r&&document.documentElement.setAttribute(e,String(r))}if(r){document.head.innerHTML="";for(let e of r.children||[])this.renderToDOM(e,document.head)}if(n){if(document.body.innerHTML="",n.props)for(let e in n.props){let t=n.props[e];null!=t&&!1!==t&&document.body.setAttribute(e,String(t))}for(let e of n.children||[])this.renderToDOM(e,document.body)}}renderToHTMLDocument(e,t={}){let{title:r="",meta:n=[],links:s=[],scripts:i=[],styles:l=[],lang:a="en",head:o="",bodyAttrs:u={},pretty:d=!1}=t,c=d?"\n":"",h=d?" ":"",p=d?" ":"",f=`<!DOCTYPE html>${c}<html lang="${a}">${c}${h}<head>${c}${p}<meta charset="UTF-8">${c}${p}<meta name="viewport" content="width=device-width, initial-scale=1.0">${c}`;r&&(f+=`${p}<title>${this.escapeHtml(r)}</title>${c}`);for(let e of n){f+=`${p}<meta`;for(let t in e)f+=` ${t}="${this.escapeHtml(e[t])}"`;f+=`>${c}`}for(let e of s){f+=`${p}<link`;for(let t in e)f+=` ${t}="${this.escapeHtml(e[t])}"`;f+=`>${c}`}for(let e of l)e.href?f+=`${p}<link rel="stylesheet" href="${this.escapeHtml(e.href)}">${c}`:e.content&&(f+=`${p}<style>${e.content}</style>${c}`);o&&(f+=o+c),f+=`${h}</head>${c}${h}<body`;for(let e in u)f+=` ${e}="${this.escapeHtml(u[e])}"`;f+=`>${c}`,f+=this.renderToString(e,{pretty:d,indent:2});for(let e of i)f+=`${p}<script`,e.type&&(f+=` type="${this.escapeHtml(e.type)}"`),e.async&&(f+=" async"),e.defer&&(f+=" defer"),e.src?f+=` src="${this.escapeHtml(e.src)}"><\/script>${c}`:e.content?f+=`>${e.content}<\/script>${c}`:f+=`><\/script>${c}`;return f+=`${h}</body>${c}</html>`,f}getElementCache(){return this.elementCache}},t=(t,r)=>e.createState(t,r),r=(t,r)=>e.computed(t,r),n=t=>e.effect(t),s=(t,r)=>e.batchRender(t,r),i=(t,r,n,s)=>e.renderChunked(t,r,n,s),l=(t,r,n,s,i)=>e.createVirtualList(t,r,n,s,i),a=t=>e.lazy(t),o=t=>e.cleanupUnusedElements(t),u=(e,t)=>{let r=null;return(...n)=>{r||(r=setTimeout(()=>{r=null,e(...n)},t))}},d=(e,t)=>{let r=null;return(...n)=>{r&&clearTimeout(r),r=setTimeout(()=>e(...n),t)}},c=class{constructor(e,r,n){this.key=e,this.wsUrl=n,this.ws=null,this.pendingUpdates=[],this.localState=t(r),this.previousValue=r,this.connect()}get value(){return this.localState.value}set value(e){this.previousValue=this.localState.value,this.localState.value=e,this.sendToServer(e)}get state(){return this.localState}onChange(e){return this.localState.subscribe(t=>{let r=this.previousValue;this.previousValue=t,e(t,r)})}update(e){this.value=e(this.value)}connect(){if(typeof window>"u")return;let e=this.wsUrl||`ws://${location.host}`;this.ws=new WebSocket(e),this.ws.addEventListener("open",()=>{for(this.subscribe();this.pendingUpdates.length>0;){let e=this.pendingUpdates.shift();this.sendToServer(e)}}),this.ws.addEventListener("message",e=>{this.handleMessage(e.data)}),this.ws.addEventListener("close",()=>{setTimeout(()=>this.connect(),1e3)}),this.ws.addEventListener("error",e=>{console.error("[SharedState] WebSocket error:",e)})}subscribe(){!this.ws||this.ws.readyState!==WebSocket.OPEN||this.ws.send(JSON.stringify({type:"state:subscribe",key:this.key}))}handleMessage(e){try{let t=JSON.parse(e);if(t.key!==this.key)return;("state:init"===t.type||"state:update"===t.type)&&(this.localState.value=t.value)}catch{}}sendToServer(e){if(this.ws){if(this.ws.readyState!==WebSocket.OPEN)return void this.pendingUpdates.push(e);this.ws.send(JSON.stringify({type:"state:change",key:this.key,value:e}))}}disconnect(){this.ws&&(this.ws.close(),this.ws=null)}destroy(){this.disconnect(),this.localState.destroy()}};function h(e,t,r){return new c(e,t,r)}var p=new class{constructor(){this.states=new Map}create(e,t,r){if(this.states.has(e))return this.states.get(e);let n=new c(e,t,r);return this.states.set(e,n),n}get(e){return this.states.get(e)}delete(e){let t=this.states.get(e);return!!t&&(t.destroy(),this.states.delete(e))}clear(){this.states.forEach(e=>e.destroy()),this.states.clear()}},f=(t,r)=>{let n=null,s=null,i=null,l=!0,a=r(t.value),o=a&&"object"==typeof a&&"tagName"in a,u=null==a||!1===a;t.subscribe(()=>{n&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{(()=>{if(!s&&!i)return;let n=r(t.value);if(null==n||!1===n)l&&s&&(i=document.createComment("reactive"),s.parentNode?.replaceChild(i,s),l=!1);else if(!l&&i&&s&&(i.parentNode?.replaceChild(s,i),i=null,l=!0),s){let t=document.createDocumentFragment();if(o&&n&&"object"==typeof n&&"tagName"in n){let{props:r,children:i}=n;for(let e in r){let t=r[e];if("ref"!==e)if("class"===e||"className"===e)s.className=Array.isArray(t)?t.join(" "):t||"";else if("style"===e&&"object"==typeof t){let e=s.style;for(let r in t)e[r]=t[r]}else e.startsWith("on")?s[e.toLowerCase()]=t:null!=t&&!1!==t?s.setAttribute(e,String(!0===t?"":t)):s.removeAttribute(e)}for(let r of i)e.renderToDOM(r,t)}else e.renderToDOM(n,t);s.textContent="",s.appendChild(t),e.getElementCache().set(s,!0)}})(),n=null})});let d=e=>{s=e,u&&e.parentNode&&(i=document.createComment("reactive"),e.parentNode.replaceChild(i,e),l=!1)};if(o){let e=a;return{tagName:e.tagName,props:{...e.props,ref:d},children:e.children}}return{tagName:"span",props:{ref:d},children:[a]}},m=(t,r,n,s={})=>{let i=null,l=null;return r.subscribe(()=>{i&&cancelAnimationFrame(i),i=requestAnimationFrame(()=>{if(l){let t=document.createDocumentFragment(),s=n(r.value);null==s||!1===s?(l.style.display="none",l.textContent=""):(l.style.display="",e.renderToDOM(s,t),l.textContent="",l.appendChild(t)),e.getElementCache().set(l,!0)}i=null})}),{tagName:t,props:{...s,ref:e=>{l=e}},children:[n(r.value)]}},g=e=>e&&void 0!==e.value?f(e,e=>({tagName:"span",props:{},children:[String(e)]})):String(e),y=e=>({value:e.value,oninput:t=>{e.value=t.target.value}}),v=e=>({checked:e.value,onchange:t=>{e.value=t.target.checked}});export{c as SharedState,s as batchRender,v as bindChecked,y as bindValue,o as cleanupUnused,r as computed,h as createSharedState,t as createState,l as createVirtualList,d as debounce,n as effect,a as lazy,f as reactive,m as reactiveAs,i as renderChunked,p as sharedStateManager,g as text,u as throttle};
|
|
1
|
+
// src/dom.ts
|
|
2
|
+
function resolveElement(rootElement) {
|
|
3
|
+
return typeof rootElement === "string" ? document.getElementById(rootElement.replace("#", "")) : rootElement;
|
|
4
|
+
}
|
|
5
|
+
function ensureElement(el, rootElement) {
|
|
6
|
+
if (!el) {
|
|
7
|
+
throw new Error(`Element not found: ${rootElement}`);
|
|
8
|
+
}
|
|
9
|
+
return el;
|
|
10
|
+
}
|
|
11
|
+
function shouldSkipChild(child) {
|
|
12
|
+
return child == null || child === false;
|
|
13
|
+
}
|
|
14
|
+
function isPrimitiveJson(json) {
|
|
15
|
+
return json == null || typeof json === "boolean" || typeof json === "string" || typeof json === "number";
|
|
16
|
+
}
|
|
17
|
+
var DomNode = class {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.elementCache = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
this.reactiveNodes = /* @__PURE__ */ new Map();
|
|
21
|
+
}
|
|
22
|
+
createElement(tagName, props = {}, children = []) {
|
|
23
|
+
return { tagName, props, children };
|
|
24
|
+
}
|
|
25
|
+
renderToDOM(vNode, parent) {
|
|
26
|
+
if (vNode == null || vNode === false) return;
|
|
27
|
+
if (typeof vNode !== "object") {
|
|
28
|
+
parent.appendChild(document.createTextNode(String(vNode)));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const { tagName, props, children } = vNode;
|
|
32
|
+
const isSVG = tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
|
|
33
|
+
const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
|
|
34
|
+
for (const key in props) {
|
|
35
|
+
const value = props[key];
|
|
36
|
+
if (value == null || value === false) continue;
|
|
37
|
+
const c = key.charCodeAt(0);
|
|
38
|
+
if (c === 99 && (key.length < 6 || key[5] === "N")) {
|
|
39
|
+
const classValue = Array.isArray(value) ? value.join(" ") : value;
|
|
40
|
+
isSVG ? el.setAttribute("class", classValue) : el.className = classValue;
|
|
41
|
+
} else if (c === 115 && key.length === 5) {
|
|
42
|
+
if (typeof value === "string") {
|
|
43
|
+
el.style.cssText = value;
|
|
44
|
+
} else {
|
|
45
|
+
const s = el.style;
|
|
46
|
+
for (const k in value) s[k] = value[k];
|
|
47
|
+
}
|
|
48
|
+
} else if (c === 111 && key.charCodeAt(1) === 110) {
|
|
49
|
+
el[key.toLowerCase()] = value;
|
|
50
|
+
} else if (c === 100 && key.length > 20) {
|
|
51
|
+
el.innerHTML = value.__html;
|
|
52
|
+
} else if (c === 114 && key.length === 3) {
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
typeof value === "function" ? value(el) : value.current = el;
|
|
55
|
+
}, 0);
|
|
56
|
+
} else {
|
|
57
|
+
el.setAttribute(key, value === true ? "" : String(value));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const len = children.length;
|
|
61
|
+
if (!len) {
|
|
62
|
+
parent.appendChild(el);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const renderChildren = (target) => {
|
|
66
|
+
for (let i = 0; i < len; i++) {
|
|
67
|
+
const child = children[i];
|
|
68
|
+
if (shouldSkipChild(child)) continue;
|
|
69
|
+
if (Array.isArray(child)) {
|
|
70
|
+
for (let j = 0, cLen = child.length; j < cLen; j++) {
|
|
71
|
+
const c = child[j];
|
|
72
|
+
!shouldSkipChild(c) && this.renderToDOM(c, target);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
this.renderToDOM(child, target);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
if (len > 30) {
|
|
80
|
+
const fragment = document.createDocumentFragment();
|
|
81
|
+
renderChildren(fragment);
|
|
82
|
+
el.appendChild(fragment);
|
|
83
|
+
} else {
|
|
84
|
+
renderChildren(el);
|
|
85
|
+
}
|
|
86
|
+
parent.appendChild(el);
|
|
87
|
+
}
|
|
88
|
+
render(rootElement, vNode) {
|
|
89
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
90
|
+
el.innerHTML = "";
|
|
91
|
+
if (vNode.children && vNode.children.length > 500) {
|
|
92
|
+
const fragment = document.createDocumentFragment();
|
|
93
|
+
this.renderToDOM(vNode, fragment);
|
|
94
|
+
el.appendChild(fragment);
|
|
95
|
+
} else {
|
|
96
|
+
this.renderToDOM(vNode, el);
|
|
97
|
+
}
|
|
98
|
+
return el;
|
|
99
|
+
}
|
|
100
|
+
batchRender(rootElement, vNodes) {
|
|
101
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
102
|
+
const len = vNodes.length;
|
|
103
|
+
if (len > 3e3) {
|
|
104
|
+
const fragment = document.createDocumentFragment();
|
|
105
|
+
let processed = 0;
|
|
106
|
+
const chunkSize = 1500;
|
|
107
|
+
const processChunk = () => {
|
|
108
|
+
const end = Math.min(processed + chunkSize, len);
|
|
109
|
+
for (let i = processed; i < end; i++) {
|
|
110
|
+
this.renderToDOM(vNodes[i], fragment);
|
|
111
|
+
}
|
|
112
|
+
processed = end;
|
|
113
|
+
if (processed >= len) {
|
|
114
|
+
el.appendChild(fragment);
|
|
115
|
+
} else {
|
|
116
|
+
requestAnimationFrame(processChunk);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
processChunk();
|
|
120
|
+
} else {
|
|
121
|
+
const fragment = document.createDocumentFragment();
|
|
122
|
+
for (let i = 0; i < len; i++) {
|
|
123
|
+
this.renderToDOM(vNodes[i], fragment);
|
|
124
|
+
}
|
|
125
|
+
el.appendChild(fragment);
|
|
126
|
+
}
|
|
127
|
+
return el;
|
|
128
|
+
}
|
|
129
|
+
renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
|
|
130
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
131
|
+
const len = vNodes.length;
|
|
132
|
+
let index = 0;
|
|
133
|
+
const renderChunk = () => {
|
|
134
|
+
const end = Math.min(index + chunkSize, len);
|
|
135
|
+
const fragment = document.createDocumentFragment();
|
|
136
|
+
for (let i = index; i < end; i++) {
|
|
137
|
+
this.renderToDOM(vNodes[i], fragment);
|
|
138
|
+
}
|
|
139
|
+
el.appendChild(fragment);
|
|
140
|
+
index = end;
|
|
141
|
+
if (onProgress) onProgress(index, len);
|
|
142
|
+
if (index < len) {
|
|
143
|
+
requestAnimationFrame(renderChunk);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
requestAnimationFrame(renderChunk);
|
|
147
|
+
return el;
|
|
148
|
+
}
|
|
149
|
+
renderToHead(...vNodes) {
|
|
150
|
+
const head = document.head;
|
|
151
|
+
if (head) {
|
|
152
|
+
for (const vNode of vNodes.flat()) {
|
|
153
|
+
vNode && this.renderToDOM(vNode, head);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return head;
|
|
157
|
+
}
|
|
158
|
+
addStyle(cssText) {
|
|
159
|
+
const el = document.createElement("style");
|
|
160
|
+
el.textContent = cssText;
|
|
161
|
+
return document.head.appendChild(el);
|
|
162
|
+
}
|
|
163
|
+
addMeta(attrs) {
|
|
164
|
+
const el = document.createElement("meta");
|
|
165
|
+
for (const k in attrs) el.setAttribute(k, attrs[k]);
|
|
166
|
+
return document.head.appendChild(el);
|
|
167
|
+
}
|
|
168
|
+
addLink(attrs) {
|
|
169
|
+
const el = document.createElement("link");
|
|
170
|
+
for (const k in attrs) el.setAttribute(k, attrs[k]);
|
|
171
|
+
return document.head.appendChild(el);
|
|
172
|
+
}
|
|
173
|
+
setTitle(text2) {
|
|
174
|
+
return document.title = text2;
|
|
175
|
+
}
|
|
176
|
+
// Reactive State Management
|
|
177
|
+
createState(initialValue, options = {}) {
|
|
178
|
+
let value = initialValue;
|
|
179
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
180
|
+
let updateTimer = null;
|
|
181
|
+
const { throttle: throttle2 = 0, deep = false } = options;
|
|
182
|
+
const notify = () => listeners.forEach((fn) => fn(value));
|
|
183
|
+
const scheduleUpdate = () => {
|
|
184
|
+
if (throttle2 > 0) {
|
|
185
|
+
if (!updateTimer) {
|
|
186
|
+
updateTimer = setTimeout(() => {
|
|
187
|
+
updateTimer = null;
|
|
188
|
+
notify();
|
|
189
|
+
}, throttle2);
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
notify();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
return {
|
|
196
|
+
get value() {
|
|
197
|
+
return value;
|
|
198
|
+
},
|
|
199
|
+
set value(newValue) {
|
|
200
|
+
const changed = deep ? JSON.stringify(value) !== JSON.stringify(newValue) : value !== newValue;
|
|
201
|
+
if (changed) {
|
|
202
|
+
value = newValue;
|
|
203
|
+
scheduleUpdate();
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
subscribe(fn) {
|
|
207
|
+
listeners.add(fn);
|
|
208
|
+
return () => listeners.delete(fn);
|
|
209
|
+
},
|
|
210
|
+
destroy() {
|
|
211
|
+
listeners.clear();
|
|
212
|
+
updateTimer && clearTimeout(updateTimer);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
computed(states, computeFn) {
|
|
217
|
+
const values = states.map((s) => s.value);
|
|
218
|
+
const result = this.createState(computeFn(...values));
|
|
219
|
+
states.forEach((state, index) => {
|
|
220
|
+
state.subscribe((newValue) => {
|
|
221
|
+
values[index] = newValue;
|
|
222
|
+
result.value = computeFn(...values);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
effect(stateFn) {
|
|
228
|
+
stateFn();
|
|
229
|
+
}
|
|
230
|
+
// Virtual scrolling helper for large lists
|
|
231
|
+
createVirtualList(container, items, renderItem, itemHeight = 50, bufferSize = 5) {
|
|
232
|
+
const viewportHeight = container.clientHeight;
|
|
233
|
+
const totalHeight = items.length * itemHeight;
|
|
234
|
+
let scrollTop = 0;
|
|
235
|
+
const getVisibleRange = () => {
|
|
236
|
+
const start = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
|
|
237
|
+
const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
|
|
238
|
+
return { start, end };
|
|
239
|
+
};
|
|
240
|
+
const render2 = () => {
|
|
241
|
+
const { start, end } = getVisibleRange();
|
|
242
|
+
const wrapper = document.createElement("div");
|
|
243
|
+
wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
|
|
244
|
+
for (let i = start; i < end; i++) {
|
|
245
|
+
const itemEl = document.createElement("div");
|
|
246
|
+
itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
|
|
247
|
+
this.renderToDOM(renderItem(items[i], i), itemEl);
|
|
248
|
+
wrapper.appendChild(itemEl);
|
|
249
|
+
}
|
|
250
|
+
container.innerHTML = "";
|
|
251
|
+
container.appendChild(wrapper);
|
|
252
|
+
};
|
|
253
|
+
const scrollHandler = () => {
|
|
254
|
+
scrollTop = container.scrollTop;
|
|
255
|
+
requestAnimationFrame(render2);
|
|
256
|
+
};
|
|
257
|
+
container.addEventListener("scroll", scrollHandler);
|
|
258
|
+
render2();
|
|
259
|
+
return {
|
|
260
|
+
render: render2,
|
|
261
|
+
destroy: () => {
|
|
262
|
+
container.removeEventListener("scroll", scrollHandler);
|
|
263
|
+
container.innerHTML = "";
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// Lazy load components
|
|
268
|
+
lazy(loadFn) {
|
|
269
|
+
let component = null;
|
|
270
|
+
let loading = false;
|
|
271
|
+
return async (...args) => {
|
|
272
|
+
if (!component && !loading) {
|
|
273
|
+
loading = true;
|
|
274
|
+
component = await loadFn();
|
|
275
|
+
loading = false;
|
|
276
|
+
}
|
|
277
|
+
return component ? component(...args) : { tagName: "div", props: { class: "loading" }, children: ["Loading..."] };
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
// Memory management - cleanup unused elements
|
|
281
|
+
cleanupUnusedElements(root) {
|
|
282
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
283
|
+
const toRemove = [];
|
|
284
|
+
while (walker.nextNode()) {
|
|
285
|
+
const node = walker.currentNode;
|
|
286
|
+
if (node.id && node.id.startsWith("r") && !this.elementCache.has(node)) {
|
|
287
|
+
toRemove.push(node);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
toRemove.forEach((el) => el.remove());
|
|
291
|
+
return toRemove.length;
|
|
292
|
+
}
|
|
293
|
+
// Server-Side Rendering - convert VNode to HTML string
|
|
294
|
+
renderToString(vNode, options = {}) {
|
|
295
|
+
const { pretty = false, indent = 0 } = options;
|
|
296
|
+
const indentStr = pretty ? " ".repeat(indent) : "";
|
|
297
|
+
const newLine = pretty ? "\n" : "";
|
|
298
|
+
let resolvedVNode = this.resolveStateValue(vNode);
|
|
299
|
+
resolvedVNode = this.unwrapReactive(resolvedVNode);
|
|
300
|
+
if (Array.isArray(resolvedVNode)) {
|
|
301
|
+
return resolvedVNode.map((child) => this.renderToString(child, options)).join("");
|
|
302
|
+
}
|
|
303
|
+
if (typeof resolvedVNode !== "object" || resolvedVNode === null) {
|
|
304
|
+
if (resolvedVNode === null || resolvedVNode === void 0 || resolvedVNode === false) {
|
|
305
|
+
return "";
|
|
306
|
+
}
|
|
307
|
+
return this.escapeHtml(String(resolvedVNode));
|
|
308
|
+
}
|
|
309
|
+
const { tagName, props, children } = resolvedVNode;
|
|
310
|
+
const isSelfClosing = this.isSelfClosingTag(tagName);
|
|
311
|
+
let html = `${indentStr}<${tagName}`;
|
|
312
|
+
const attrs = this.propsToAttributes(props);
|
|
313
|
+
if (attrs) {
|
|
314
|
+
html += ` ${attrs}`;
|
|
315
|
+
}
|
|
316
|
+
if (isSelfClosing) {
|
|
317
|
+
html += ` />${newLine}`;
|
|
318
|
+
return html;
|
|
319
|
+
}
|
|
320
|
+
html += ">";
|
|
321
|
+
if (props.dangerouslySetInnerHTML) {
|
|
322
|
+
html += props.dangerouslySetInnerHTML.__html;
|
|
323
|
+
html += `</${tagName}>${newLine}`;
|
|
324
|
+
return html;
|
|
325
|
+
}
|
|
326
|
+
if (children && children.length > 0) {
|
|
327
|
+
const resolvedChildren = children.map((c) => {
|
|
328
|
+
const resolved = this.resolveStateValue(c);
|
|
329
|
+
return this.unwrapReactive(resolved);
|
|
330
|
+
});
|
|
331
|
+
const hasComplexChildren = resolvedChildren.some(
|
|
332
|
+
(c) => typeof c === "object" && c !== null && !Array.isArray(c) && "tagName" in c
|
|
333
|
+
);
|
|
334
|
+
if (pretty && hasComplexChildren) {
|
|
335
|
+
html += newLine;
|
|
336
|
+
for (const child of resolvedChildren) {
|
|
337
|
+
if (shouldSkipChild(child)) continue;
|
|
338
|
+
if (Array.isArray(child)) {
|
|
339
|
+
for (const c of child) {
|
|
340
|
+
if (!shouldSkipChild(c)) {
|
|
341
|
+
html += this.renderToString(c, { pretty, indent: indent + 1 });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
html += this.renderToString(child, { pretty, indent: indent + 1 });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
html += indentStr;
|
|
349
|
+
} else {
|
|
350
|
+
for (const child of resolvedChildren) {
|
|
351
|
+
if (shouldSkipChild(child)) continue;
|
|
352
|
+
if (Array.isArray(child)) {
|
|
353
|
+
for (const c of child) {
|
|
354
|
+
if (!shouldSkipChild(c)) {
|
|
355
|
+
html += this.renderToString(c, { pretty: false, indent: 0 });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
} else {
|
|
359
|
+
html += this.renderToString(child, { pretty: false, indent: 0 });
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
html += `</${tagName}>${newLine}`;
|
|
365
|
+
return html;
|
|
366
|
+
}
|
|
367
|
+
resolveStateValue(value) {
|
|
368
|
+
if (value && typeof value === "object" && "value" in value && "subscribe" in value) {
|
|
369
|
+
return value.value;
|
|
370
|
+
}
|
|
371
|
+
return value;
|
|
372
|
+
}
|
|
373
|
+
isReactiveWrapper(vNode) {
|
|
374
|
+
if (!vNode || typeof vNode !== "object" || !vNode.tagName) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
return vNode.tagName === "span" && vNode.props?.id && typeof vNode.props.id === "string" && vNode.props.id.match(/^r[a-z0-9]{9}$/);
|
|
378
|
+
}
|
|
379
|
+
unwrapReactive(vNode) {
|
|
380
|
+
if (!this.isReactiveWrapper(vNode)) {
|
|
381
|
+
return vNode;
|
|
382
|
+
}
|
|
383
|
+
const children = vNode.children;
|
|
384
|
+
if (!children || children.length === 0) {
|
|
385
|
+
return "";
|
|
386
|
+
}
|
|
387
|
+
if (children.length === 1) {
|
|
388
|
+
const child = children[0];
|
|
389
|
+
if (child && typeof child === "object" && child.tagName === "span") {
|
|
390
|
+
const props = child.props;
|
|
391
|
+
const hasNoProps = !props || Object.keys(props).length === 0;
|
|
392
|
+
const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
|
|
393
|
+
if (hasNoProps && hasSingleStringChild) {
|
|
394
|
+
return child.children[0];
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return this.unwrapReactive(child);
|
|
398
|
+
}
|
|
399
|
+
return children.map((c) => this.unwrapReactive(c));
|
|
400
|
+
}
|
|
401
|
+
escapeHtml(text2) {
|
|
402
|
+
const htmlEscapes = {
|
|
403
|
+
"&": "&",
|
|
404
|
+
"<": "<",
|
|
405
|
+
">": ">",
|
|
406
|
+
'"': """,
|
|
407
|
+
"'": "'"
|
|
408
|
+
};
|
|
409
|
+
return text2.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
|
|
410
|
+
}
|
|
411
|
+
isSelfClosingTag(tagName) {
|
|
412
|
+
const selfClosingTags = /* @__PURE__ */ new Set([
|
|
413
|
+
"area",
|
|
414
|
+
"base",
|
|
415
|
+
"br",
|
|
416
|
+
"col",
|
|
417
|
+
"embed",
|
|
418
|
+
"hr",
|
|
419
|
+
"img",
|
|
420
|
+
"input",
|
|
421
|
+
"link",
|
|
422
|
+
"meta",
|
|
423
|
+
"param",
|
|
424
|
+
"source",
|
|
425
|
+
"track",
|
|
426
|
+
"wbr"
|
|
427
|
+
]);
|
|
428
|
+
return selfClosingTags.has(tagName.toLowerCase());
|
|
429
|
+
}
|
|
430
|
+
propsToAttributes(props) {
|
|
431
|
+
const attrs = [];
|
|
432
|
+
for (const key in props) {
|
|
433
|
+
if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref") {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
let value = props[key];
|
|
437
|
+
value = this.resolveStateValue(value);
|
|
438
|
+
if (value == null || value === false) continue;
|
|
439
|
+
if (key.startsWith("on") && typeof value === "function") {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (key === "className" || key === "class") {
|
|
443
|
+
const className = Array.isArray(value) ? value.join(" ") : value;
|
|
444
|
+
if (className) {
|
|
445
|
+
attrs.push(`class="${this.escapeHtml(String(className))}"`);
|
|
446
|
+
}
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (key === "style") {
|
|
450
|
+
const styleStr = this.styleToString(value);
|
|
451
|
+
if (styleStr) {
|
|
452
|
+
attrs.push(`style="${this.escapeHtml(styleStr)}"`);
|
|
453
|
+
}
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (value === true) {
|
|
457
|
+
attrs.push(key);
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
attrs.push(`${key}="${this.escapeHtml(String(value))}"`);
|
|
461
|
+
}
|
|
462
|
+
return attrs.join(" ");
|
|
463
|
+
}
|
|
464
|
+
styleToString(style) {
|
|
465
|
+
if (typeof style === "string") {
|
|
466
|
+
return style;
|
|
467
|
+
}
|
|
468
|
+
if (typeof style === "object" && style !== null) {
|
|
469
|
+
const styles = [];
|
|
470
|
+
for (const key in style) {
|
|
471
|
+
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
472
|
+
styles.push(`${cssKey}:${style[key]}`);
|
|
473
|
+
}
|
|
474
|
+
return styles.join(";");
|
|
475
|
+
}
|
|
476
|
+
return "";
|
|
477
|
+
}
|
|
478
|
+
isState(value) {
|
|
479
|
+
return value && typeof value === "object" && "value" in value && "subscribe" in value && typeof value.subscribe === "function";
|
|
480
|
+
}
|
|
481
|
+
createReactiveChild(state, renderFn) {
|
|
482
|
+
const currentValue = renderFn(state.value);
|
|
483
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
484
|
+
const entry = { node: null, renderFn };
|
|
485
|
+
this.reactiveNodes.set(state, entry);
|
|
486
|
+
state.subscribe(() => {
|
|
487
|
+
if (entry.node && entry.node.parentNode) {
|
|
488
|
+
const newValue = renderFn(state.value);
|
|
489
|
+
entry.node.textContent = String(newValue ?? "");
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
return currentValue;
|
|
494
|
+
}
|
|
495
|
+
jsonToVNode(json) {
|
|
496
|
+
if (this.isState(json)) {
|
|
497
|
+
return this.createReactiveChild(json, (v) => v);
|
|
498
|
+
}
|
|
499
|
+
if (isPrimitiveJson(json)) {
|
|
500
|
+
return json;
|
|
501
|
+
}
|
|
502
|
+
const { tag, attributes = {}, children } = json;
|
|
503
|
+
const props = {};
|
|
504
|
+
for (const key in attributes) {
|
|
505
|
+
const value = attributes[key];
|
|
506
|
+
if (key === "class") {
|
|
507
|
+
props.className = this.isState(value) ? value.value : value;
|
|
508
|
+
} else {
|
|
509
|
+
props[key] = this.isState(value) ? value.value : value;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
const childrenArray = [];
|
|
513
|
+
if (children != null) {
|
|
514
|
+
if (Array.isArray(children)) {
|
|
515
|
+
for (const child of children) {
|
|
516
|
+
if (this.isState(child)) {
|
|
517
|
+
childrenArray.push(this.createReactiveChild(child, (v) => v));
|
|
518
|
+
} else {
|
|
519
|
+
const converted = this.jsonToVNode(child);
|
|
520
|
+
if (converted != null && converted !== false) {
|
|
521
|
+
childrenArray.push(converted);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
} else if (this.isState(children)) {
|
|
526
|
+
childrenArray.push(this.createReactiveChild(children, (v) => v));
|
|
527
|
+
} else if (typeof children === "object" && "tag" in children) {
|
|
528
|
+
const converted = this.jsonToVNode(children);
|
|
529
|
+
if (converted != null && converted !== false) {
|
|
530
|
+
childrenArray.push(converted);
|
|
531
|
+
}
|
|
532
|
+
} else {
|
|
533
|
+
childrenArray.push(children);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return { tagName: tag, props, children: childrenArray };
|
|
537
|
+
}
|
|
538
|
+
vNodeJsonToVNode(json) {
|
|
539
|
+
if (this.isState(json)) {
|
|
540
|
+
return this.createReactiveChild(json, (v) => v);
|
|
541
|
+
}
|
|
542
|
+
if (isPrimitiveJson(json)) {
|
|
543
|
+
return json;
|
|
544
|
+
}
|
|
545
|
+
const { tagName, props = {}, children = [] } = json;
|
|
546
|
+
const resolvedProps = {};
|
|
547
|
+
for (const key in props) {
|
|
548
|
+
const value = props[key];
|
|
549
|
+
resolvedProps[key] = this.isState(value) ? value.value : value;
|
|
550
|
+
}
|
|
551
|
+
const childrenArray = [];
|
|
552
|
+
for (const child of children) {
|
|
553
|
+
if (this.isState(child)) {
|
|
554
|
+
childrenArray.push(this.createReactiveChild(child, (v) => v));
|
|
555
|
+
} else {
|
|
556
|
+
const converted = this.vNodeJsonToVNode(child);
|
|
557
|
+
if (converted != null && converted !== false) {
|
|
558
|
+
childrenArray.push(converted);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return { tagName, props: resolvedProps, children: childrenArray };
|
|
563
|
+
}
|
|
564
|
+
renderJson(rootElement, json) {
|
|
565
|
+
const vNode = this.jsonToVNode(json);
|
|
566
|
+
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
567
|
+
throw new Error("Invalid JSON structure");
|
|
568
|
+
}
|
|
569
|
+
return this.render(rootElement, vNode);
|
|
570
|
+
}
|
|
571
|
+
renderVNode(rootElement, json) {
|
|
572
|
+
const vNode = this.vNodeJsonToVNode(json);
|
|
573
|
+
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
574
|
+
throw new Error("Invalid VNode JSON structure");
|
|
575
|
+
}
|
|
576
|
+
return this.render(rootElement, vNode);
|
|
577
|
+
}
|
|
578
|
+
renderJsonToString(json, options = {}) {
|
|
579
|
+
const vNode = this.jsonToVNode(json);
|
|
580
|
+
return this.renderToString(vNode, options);
|
|
581
|
+
}
|
|
582
|
+
renderVNodeToString(json, options = {}) {
|
|
583
|
+
const vNode = this.vNodeJsonToVNode(json);
|
|
584
|
+
return this.renderToString(vNode, options);
|
|
585
|
+
}
|
|
586
|
+
// Generate complete HTML document as string (for SSR)
|
|
587
|
+
renderToHTMLDocument(vNode, options = {}) {
|
|
588
|
+
const { title = "", meta = [], links = [], scripts = [], styles = [], lang = "en", head = "", bodyAttrs = {}, pretty = false } = options;
|
|
589
|
+
const nl = pretty ? "\n" : "";
|
|
590
|
+
const indent = pretty ? " " : "";
|
|
591
|
+
const indent2 = pretty ? " " : "";
|
|
592
|
+
let html = `<!DOCTYPE html>${nl}<html lang="${lang}">${nl}${indent}<head>${nl}${indent2}<meta charset="UTF-8">${nl}${indent2}<meta name="viewport" content="width=device-width, initial-scale=1.0">${nl}`;
|
|
593
|
+
if (title) html += `${indent2}<title>${this.escapeHtml(title)}</title>${nl}`;
|
|
594
|
+
for (const m of meta) {
|
|
595
|
+
html += `${indent2}<meta`;
|
|
596
|
+
for (const k in m) html += ` ${k}="${this.escapeHtml(m[k])}"`;
|
|
597
|
+
html += `>${nl}`;
|
|
598
|
+
}
|
|
599
|
+
for (const l of links) {
|
|
600
|
+
html += `${indent2}<link`;
|
|
601
|
+
for (const k in l) html += ` ${k}="${this.escapeHtml(l[k])}"`;
|
|
602
|
+
html += `>${nl}`;
|
|
603
|
+
}
|
|
604
|
+
for (const s of styles) {
|
|
605
|
+
if (s.href) {
|
|
606
|
+
html += `${indent2}<link rel="stylesheet" href="${this.escapeHtml(s.href)}">${nl}`;
|
|
607
|
+
} else if (s.content) {
|
|
608
|
+
html += `${indent2}<style>${s.content}</style>${nl}`;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (head) html += head + nl;
|
|
612
|
+
html += `${indent}</head>${nl}${indent}<body`;
|
|
613
|
+
for (const k in bodyAttrs) html += ` ${k}="${this.escapeHtml(bodyAttrs[k])}"`;
|
|
614
|
+
html += `>${nl}`;
|
|
615
|
+
html += this.renderToString(vNode, { pretty, indent: 2 });
|
|
616
|
+
for (const script of scripts) {
|
|
617
|
+
html += `${indent2}<script`;
|
|
618
|
+
if (script.type) html += ` type="${this.escapeHtml(script.type)}"`;
|
|
619
|
+
if (script.async) html += ` async`;
|
|
620
|
+
if (script.defer) html += ` defer`;
|
|
621
|
+
if (script.src) {
|
|
622
|
+
html += ` src="${this.escapeHtml(script.src)}"></script>${nl}`;
|
|
623
|
+
} else if (script.content) {
|
|
624
|
+
html += `>${script.content}</script>${nl}`;
|
|
625
|
+
} else {
|
|
626
|
+
html += `></script>${nl}`;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
html += `${indent}</body>${nl}</html>`;
|
|
630
|
+
return html;
|
|
631
|
+
}
|
|
632
|
+
// Expose elementCache for reactive updates
|
|
633
|
+
getElementCache() {
|
|
634
|
+
return this.elementCache;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
var dom = new DomNode();
|
|
638
|
+
var render = dom.render.bind(dom);
|
|
639
|
+
var renderToString = dom.renderToString.bind(dom);
|
|
640
|
+
|
|
641
|
+
// src/state.ts
|
|
642
|
+
var createState = (initial, options) => dom.createState(initial, options);
|
|
643
|
+
var computed = (states, fn) => dom.computed(states, fn);
|
|
644
|
+
var effect = (fn) => dom.effect(fn);
|
|
645
|
+
var batchRender = (container, vNodes) => dom.batchRender(container, vNodes);
|
|
646
|
+
var renderChunked = (container, vNodes, chunkSize, onProgress) => dom.renderChunked(container, vNodes, chunkSize, onProgress);
|
|
647
|
+
var createVirtualList = (container, items, renderItem, itemHeight, bufferSize) => dom.createVirtualList(container, items, renderItem, itemHeight, bufferSize);
|
|
648
|
+
var lazy = (loadFn) => dom.lazy(loadFn);
|
|
649
|
+
var cleanupUnused = (root) => dom.cleanupUnusedElements(root);
|
|
650
|
+
var throttle = (fn, delay) => {
|
|
651
|
+
let timer = null;
|
|
652
|
+
return (...args) => {
|
|
653
|
+
if (!timer) {
|
|
654
|
+
timer = setTimeout(() => {
|
|
655
|
+
timer = null;
|
|
656
|
+
fn(...args);
|
|
657
|
+
}, delay);
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
var debounce = (fn, delay) => {
|
|
662
|
+
let timer = null;
|
|
663
|
+
return (...args) => {
|
|
664
|
+
timer && clearTimeout(timer);
|
|
665
|
+
timer = setTimeout(() => fn(...args), delay);
|
|
666
|
+
};
|
|
667
|
+
};
|
|
668
|
+
var SharedState = class {
|
|
669
|
+
constructor(key, defaultValue, wsUrl) {
|
|
670
|
+
this.key = key;
|
|
671
|
+
this.wsUrl = wsUrl;
|
|
672
|
+
this.ws = null;
|
|
673
|
+
this.pendingUpdates = [];
|
|
674
|
+
this.localState = createState(defaultValue);
|
|
675
|
+
this.previousValue = defaultValue;
|
|
676
|
+
this.connect();
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Get current value
|
|
680
|
+
*/
|
|
681
|
+
get value() {
|
|
682
|
+
return this.localState.value;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Set new value and sync to server
|
|
686
|
+
*/
|
|
687
|
+
set value(newValue) {
|
|
688
|
+
this.previousValue = this.localState.value;
|
|
689
|
+
this.localState.value = newValue;
|
|
690
|
+
this.sendToServer(newValue);
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Get the underlying Elit State (for reactive binding)
|
|
694
|
+
*/
|
|
695
|
+
get state() {
|
|
696
|
+
return this.localState;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Subscribe to changes (returns Elit State for reactive)
|
|
700
|
+
*/
|
|
701
|
+
onChange(callback) {
|
|
702
|
+
return this.localState.subscribe((newValue) => {
|
|
703
|
+
const oldValue = this.previousValue;
|
|
704
|
+
this.previousValue = newValue;
|
|
705
|
+
callback(newValue, oldValue);
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Update value using a function
|
|
710
|
+
*/
|
|
711
|
+
update(updater) {
|
|
712
|
+
this.value = updater(this.value);
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Connect to WebSocket
|
|
716
|
+
*/
|
|
717
|
+
connect() {
|
|
718
|
+
if (typeof window === "undefined") return;
|
|
719
|
+
const url = this.wsUrl || `ws://${location.host}`;
|
|
720
|
+
this.ws = new WebSocket(url);
|
|
721
|
+
this.ws.addEventListener("open", () => {
|
|
722
|
+
this.subscribe();
|
|
723
|
+
while (this.pendingUpdates.length > 0) {
|
|
724
|
+
const value = this.pendingUpdates.shift();
|
|
725
|
+
this.sendToServer(value);
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
this.ws.addEventListener("message", (event) => {
|
|
729
|
+
this.handleMessage(event.data);
|
|
730
|
+
});
|
|
731
|
+
this.ws.addEventListener("close", () => {
|
|
732
|
+
setTimeout(() => this.connect(), 1e3);
|
|
733
|
+
});
|
|
734
|
+
this.ws.addEventListener("error", (error) => {
|
|
735
|
+
console.error("[SharedState] WebSocket error:", error);
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Subscribe to server state
|
|
740
|
+
*/
|
|
741
|
+
subscribe() {
|
|
742
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
|
|
743
|
+
this.ws.send(JSON.stringify({
|
|
744
|
+
type: "state:subscribe",
|
|
745
|
+
key: this.key
|
|
746
|
+
}));
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Handle message from server
|
|
750
|
+
*/
|
|
751
|
+
handleMessage(data) {
|
|
752
|
+
try {
|
|
753
|
+
const msg = JSON.parse(data);
|
|
754
|
+
if (msg.key !== this.key) return;
|
|
755
|
+
if (msg.type === "state:init" || msg.type === "state:update") {
|
|
756
|
+
this.localState.value = msg.value;
|
|
757
|
+
}
|
|
758
|
+
} catch (error) {
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Send value to server
|
|
763
|
+
*/
|
|
764
|
+
sendToServer(value) {
|
|
765
|
+
if (!this.ws) return;
|
|
766
|
+
if (this.ws.readyState !== WebSocket.OPEN) {
|
|
767
|
+
this.pendingUpdates.push(value);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
this.ws.send(JSON.stringify({
|
|
771
|
+
type: "state:change",
|
|
772
|
+
key: this.key,
|
|
773
|
+
value
|
|
774
|
+
}));
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Disconnect
|
|
778
|
+
*/
|
|
779
|
+
disconnect() {
|
|
780
|
+
if (this.ws) {
|
|
781
|
+
this.ws.close();
|
|
782
|
+
this.ws = null;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Destroy state and cleanup
|
|
787
|
+
*/
|
|
788
|
+
destroy() {
|
|
789
|
+
this.disconnect();
|
|
790
|
+
this.localState.destroy();
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
function createSharedState(key, defaultValue, wsUrl) {
|
|
794
|
+
return new SharedState(key, defaultValue, wsUrl);
|
|
795
|
+
}
|
|
796
|
+
var SharedStateManager = class {
|
|
797
|
+
constructor() {
|
|
798
|
+
this.states = /* @__PURE__ */ new Map();
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Create or get a shared state
|
|
802
|
+
*/
|
|
803
|
+
create(key, defaultValue, wsUrl) {
|
|
804
|
+
if (this.states.has(key)) {
|
|
805
|
+
return this.states.get(key);
|
|
806
|
+
}
|
|
807
|
+
const state = new SharedState(key, defaultValue, wsUrl);
|
|
808
|
+
this.states.set(key, state);
|
|
809
|
+
return state;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Get existing state
|
|
813
|
+
*/
|
|
814
|
+
get(key) {
|
|
815
|
+
return this.states.get(key);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Delete a state
|
|
819
|
+
*/
|
|
820
|
+
delete(key) {
|
|
821
|
+
const state = this.states.get(key);
|
|
822
|
+
if (state) {
|
|
823
|
+
state.destroy();
|
|
824
|
+
return this.states.delete(key);
|
|
825
|
+
}
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Clear all states
|
|
830
|
+
*/
|
|
831
|
+
clear() {
|
|
832
|
+
this.states.forEach((state) => state.destroy());
|
|
833
|
+
this.states.clear();
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
var sharedStateManager = new SharedStateManager();
|
|
837
|
+
var scheduleRAFUpdate = (rafId, updateFn) => {
|
|
838
|
+
rafId && cancelAnimationFrame(rafId);
|
|
839
|
+
return requestAnimationFrame(() => {
|
|
840
|
+
updateFn();
|
|
841
|
+
});
|
|
842
|
+
};
|
|
843
|
+
var renderToFragment = (content, isVNode) => {
|
|
844
|
+
const fragment = document.createDocumentFragment();
|
|
845
|
+
if (isVNode && content && typeof content === "object" && "tagName" in content) {
|
|
846
|
+
const { children } = content;
|
|
847
|
+
for (const child of children) {
|
|
848
|
+
dom.renderToDOM(child, fragment);
|
|
849
|
+
}
|
|
850
|
+
} else {
|
|
851
|
+
dom.renderToDOM(content, fragment);
|
|
852
|
+
}
|
|
853
|
+
return fragment;
|
|
854
|
+
};
|
|
855
|
+
var updateElementProps = (element, props) => {
|
|
856
|
+
for (const key in props) {
|
|
857
|
+
const value = props[key];
|
|
858
|
+
if (key === "ref") continue;
|
|
859
|
+
if (key === "class" || key === "className") {
|
|
860
|
+
element.className = Array.isArray(value) ? value.join(" ") : value || "";
|
|
861
|
+
} else if (key === "style" && typeof value === "object") {
|
|
862
|
+
const s = element.style;
|
|
863
|
+
for (const k in value) s[k] = value[k];
|
|
864
|
+
} else if (key.startsWith("on")) {
|
|
865
|
+
element[key.toLowerCase()] = value;
|
|
866
|
+
} else if (value != null && value !== false) {
|
|
867
|
+
element.setAttribute(key, String(value === true ? "" : value));
|
|
868
|
+
} else {
|
|
869
|
+
element.removeAttribute(key);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
var reactive = (state, renderFn) => {
|
|
874
|
+
let rafId = null;
|
|
875
|
+
let elementRef = null;
|
|
876
|
+
let placeholder = null;
|
|
877
|
+
let isInDOM = true;
|
|
878
|
+
const initialResult = renderFn(state.value);
|
|
879
|
+
const isVNodeResult = initialResult && typeof initialResult === "object" && "tagName" in initialResult;
|
|
880
|
+
const initialIsNull = initialResult == null || initialResult === false;
|
|
881
|
+
const updateElement = () => {
|
|
882
|
+
if (!elementRef && !placeholder) return;
|
|
883
|
+
const newResult = renderFn(state.value);
|
|
884
|
+
const resultIsNull = newResult == null || newResult === false;
|
|
885
|
+
if (resultIsNull) {
|
|
886
|
+
if (isInDOM && elementRef) {
|
|
887
|
+
placeholder = document.createComment("reactive");
|
|
888
|
+
elementRef.parentNode?.replaceChild(placeholder, elementRef);
|
|
889
|
+
isInDOM = false;
|
|
890
|
+
}
|
|
891
|
+
} else {
|
|
892
|
+
if (!isInDOM && placeholder && elementRef) {
|
|
893
|
+
placeholder.parentNode?.replaceChild(elementRef, placeholder);
|
|
894
|
+
placeholder = null;
|
|
895
|
+
isInDOM = true;
|
|
896
|
+
}
|
|
897
|
+
if (elementRef) {
|
|
898
|
+
const isCurrentVNode = !!(isVNodeResult && newResult && typeof newResult === "object" && "tagName" in newResult);
|
|
899
|
+
if (isCurrentVNode) {
|
|
900
|
+
const { props } = newResult;
|
|
901
|
+
updateElementProps(elementRef, props);
|
|
902
|
+
}
|
|
903
|
+
const fragment = renderToFragment(newResult, isCurrentVNode);
|
|
904
|
+
elementRef.textContent = "";
|
|
905
|
+
elementRef.appendChild(fragment);
|
|
906
|
+
dom.getElementCache().set(elementRef, true);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
state.subscribe(() => {
|
|
911
|
+
rafId = scheduleRAFUpdate(rafId, () => {
|
|
912
|
+
updateElement();
|
|
913
|
+
rafId = null;
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
const refCallback = (el) => {
|
|
917
|
+
elementRef = el;
|
|
918
|
+
if (initialIsNull && el.parentNode) {
|
|
919
|
+
placeholder = document.createComment("reactive");
|
|
920
|
+
el.parentNode.replaceChild(placeholder, el);
|
|
921
|
+
isInDOM = false;
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
if (isVNodeResult) {
|
|
925
|
+
const vnode = initialResult;
|
|
926
|
+
return {
|
|
927
|
+
tagName: vnode.tagName,
|
|
928
|
+
props: { ...vnode.props, ref: refCallback },
|
|
929
|
+
children: vnode.children
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
return { tagName: "span", props: { ref: refCallback }, children: [initialResult] };
|
|
933
|
+
};
|
|
934
|
+
var reactiveAs = (tagName, state, renderFn, props = {}) => {
|
|
935
|
+
let rafId = null;
|
|
936
|
+
let elementRef = null;
|
|
937
|
+
state.subscribe(() => {
|
|
938
|
+
rafId = scheduleRAFUpdate(rafId, () => {
|
|
939
|
+
if (elementRef) {
|
|
940
|
+
const newResult = renderFn(state.value);
|
|
941
|
+
if (newResult == null || newResult === false) {
|
|
942
|
+
elementRef.style.display = "none";
|
|
943
|
+
elementRef.textContent = "";
|
|
944
|
+
} else {
|
|
945
|
+
elementRef.style.display = "";
|
|
946
|
+
const fragment = renderToFragment(newResult, false);
|
|
947
|
+
elementRef.textContent = "";
|
|
948
|
+
elementRef.appendChild(fragment);
|
|
949
|
+
}
|
|
950
|
+
dom.getElementCache().set(elementRef, true);
|
|
951
|
+
}
|
|
952
|
+
rafId = null;
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
const refCallback = (el) => {
|
|
956
|
+
elementRef = el;
|
|
957
|
+
};
|
|
958
|
+
return { tagName, props: { ...props, ref: refCallback }, children: [renderFn(state.value)] };
|
|
959
|
+
};
|
|
960
|
+
var text = (state) => state && state.value !== void 0 ? reactive(state, (v) => ({ tagName: "span", props: {}, children: [String(v)] })) : String(state);
|
|
961
|
+
var bindValue = (state) => ({
|
|
962
|
+
value: state.value,
|
|
963
|
+
oninput: (e) => {
|
|
964
|
+
state.value = e.target.value;
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
var bindChecked = (state) => ({
|
|
968
|
+
checked: state.value,
|
|
969
|
+
onchange: (e) => {
|
|
970
|
+
state.value = e.target.checked;
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
export {
|
|
974
|
+
SharedState,
|
|
975
|
+
batchRender,
|
|
976
|
+
bindChecked,
|
|
977
|
+
bindValue,
|
|
978
|
+
cleanupUnused,
|
|
979
|
+
computed,
|
|
980
|
+
createSharedState,
|
|
981
|
+
createState,
|
|
982
|
+
createVirtualList,
|
|
983
|
+
debounce,
|
|
984
|
+
effect,
|
|
985
|
+
lazy,
|
|
986
|
+
reactive,
|
|
987
|
+
reactiveAs,
|
|
988
|
+
renderChunked,
|
|
989
|
+
sharedStateManager,
|
|
990
|
+
text,
|
|
991
|
+
throttle
|
|
992
|
+
};
|