elit 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +275 -128
  2. package/dist/build.d.mts +10 -1
  3. package/dist/build.d.ts +10 -1
  4. package/dist/build.js +670 -1
  5. package/dist/build.mjs +641 -1
  6. package/dist/chokidar.d.mts +134 -0
  7. package/dist/chokidar.d.ts +134 -0
  8. package/dist/chokidar.js +240 -0
  9. package/dist/chokidar.mjs +221 -0
  10. package/dist/cli.js +2792 -495
  11. package/dist/dom.d.mts +10 -3
  12. package/dist/dom.d.ts +10 -3
  13. package/dist/dom.js +676 -1
  14. package/dist/dom.mjs +647 -1
  15. package/dist/el.d.mts +16 -36
  16. package/dist/el.d.ts +16 -36
  17. package/dist/el.js +789 -1
  18. package/dist/el.mjs +583 -1
  19. package/dist/fs.d.mts +255 -0
  20. package/dist/fs.d.ts +255 -0
  21. package/dist/fs.js +513 -0
  22. package/dist/fs.mjs +469 -0
  23. package/dist/hmr.js +112 -1
  24. package/dist/hmr.mjs +91 -1
  25. package/dist/http.d.mts +163 -0
  26. package/dist/http.d.ts +163 -0
  27. package/dist/http.js +632 -0
  28. package/dist/http.mjs +605 -0
  29. package/dist/https.d.mts +108 -0
  30. package/dist/https.d.ts +108 -0
  31. package/dist/https.js +907 -0
  32. package/dist/https.mjs +901 -0
  33. package/dist/index.d.mts +613 -33
  34. package/dist/index.d.ts +613 -33
  35. package/dist/index.js +2589 -1
  36. package/dist/index.mjs +2312 -1
  37. package/dist/mime-types.d.mts +48 -0
  38. package/dist/mime-types.d.ts +48 -0
  39. package/dist/mime-types.js +197 -0
  40. package/dist/mime-types.mjs +166 -0
  41. package/dist/path.d.mts +163 -0
  42. package/dist/path.d.ts +163 -0
  43. package/dist/path.js +350 -0
  44. package/dist/path.mjs +310 -0
  45. package/dist/router.d.mts +3 -1
  46. package/dist/router.d.ts +3 -1
  47. package/dist/router.js +830 -1
  48. package/dist/router.mjs +801 -1
  49. package/dist/runtime.d.mts +97 -0
  50. package/dist/runtime.d.ts +97 -0
  51. package/dist/runtime.js +43 -0
  52. package/dist/runtime.mjs +15 -0
  53. package/dist/server.d.mts +5 -1
  54. package/dist/server.d.ts +5 -1
  55. package/dist/server.js +3267 -1
  56. package/dist/server.mjs +3241 -1
  57. package/dist/state.d.mts +3 -1
  58. package/dist/state.d.ts +3 -1
  59. package/dist/state.js +1036 -1
  60. package/dist/state.mjs +992 -1
  61. package/dist/style.d.mts +47 -1
  62. package/dist/style.d.ts +47 -1
  63. package/dist/style.js +551 -1
  64. package/dist/style.mjs +483 -1
  65. package/dist/{types-DOAdFFJB.d.ts → types-C0nGi6MX.d.mts} +29 -13
  66. package/dist/{types-DOAdFFJB.d.mts → types-Du6kfwTm.d.ts} +29 -13
  67. package/dist/types.d.mts +452 -3
  68. package/dist/types.d.ts +452 -3
  69. package/dist/types.js +18 -1
  70. package/dist/ws.d.mts +195 -0
  71. package/dist/ws.d.ts +195 -0
  72. package/dist/ws.js +380 -0
  73. package/dist/ws.mjs +358 -0
  74. package/dist/wss.d.mts +108 -0
  75. package/dist/wss.d.ts +108 -0
  76. package/dist/wss.js +1306 -0
  77. package/dist/wss.mjs +1300 -0
  78. package/package.json +53 -6
  79. package/dist/client.d.mts +0 -9
  80. package/dist/client.d.ts +0 -9
  81. package/dist/client.js +0 -1
  82. package/dist/client.mjs +0 -1
package/dist/router.js CHANGED
@@ -1 +1,830 @@
1
- "use strict";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:i}=e,l="svg"===r||"s"===r[0]&&"v"===r[1]&&"g"===r[2]||"http://www.w3.org/2000/svg"===t.namespaceURI,o=l?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;l?o.setAttribute("class",e):o.className=e}else if(115===r&&5===e.length)if("string"==typeof t)o.style.cssText=t;else{let e=o.style;for(let r in t)e[r]=t[r]}else 111===r&&110===e.charCodeAt(1)?o[e.toLowerCase()]=t:100===r&&e.length>20?o.innerHTML=t.__html:114===r&&3===e.length?setTimeout(()=>{"function"==typeof t?t(o):t.current=o},0):o.setAttribute(e,!0===t?"":String(t))}let a=i.length;if(!a)return void t.appendChild(o);let s=e=>{for(let t=0;t<a;t++){let r=i[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();s(e),o.appendChild(e)}else s(o);t.appendChild(o)}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(),i=0,l=1500,o=()=>{let a=Math.min(i+l,n);for(let r=i;r<a;r++)this.renderToDOM(t[r],e);i=a,i>=n?r.appendChild(e):requestAnimationFrame(o)};o()}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 i="string"==typeof e?document.getElementById(e.replace("#","")):e;if(!i)throw new Error(`Element not found: ${e}`);let l=t.length,o=0,a=()=>{let e=Math.min(o+r,l),s=document.createDocumentFragment();for(let r=o;r<e;r++)this.renderToDOM(t[r],s);i.appendChild(s),o=e,n&&n(o,l),o<l&&requestAnimationFrame(a)};return requestAnimationFrame(a),i}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,i=null,{throttle:l=0,deep:o=!1}=t,a=()=>n.forEach(e=>e(r));return{get value(){return r},set value(e){(o?JSON.stringify(r)!==JSON.stringify(e):r!==e)&&(r=e,l>0?i||(i=setTimeout(()=>{i=null,a()},l)):a())},subscribe:e=>(n.add(e),()=>n.delete(e)),destroy(){n.clear(),i&&clearTimeout(i)}}}computed(e,t){let r=e.map(e=>e.value),n=this.createState(t(...r));return e.forEach((e,i)=>{e.subscribe(e=>{r[i]=e,n.value=t(...r)})}),n}effect(e){e()}createVirtualList(e,t,r,n=50,i=5){let l=e.clientHeight,o=t.length*n,a=0,s=()=>{let{start:s,end:u}={start:Math.max(0,Math.floor(a/n)-i),end:Math.min(t.length,Math.ceil((a+l)/n)+i)},d=document.createElement("div");d.style.cssText=`height:${o}px;position:relative`;for(let e=s;e<u;e++){let i=document.createElement("div");i.style.cssText=`position:absolute;top:${e*n}px;height:${n}px;width:100%`,this.renderToDOM(r(t[e],e),i),d.appendChild(i)}e.innerHTML="",e.appendChild(d)},u=()=>{a=e.scrollTop,requestAnimationFrame(s)};return e.addEventListener("scroll",u),s(),{render:s,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,i=r?" ".repeat(n):"",l=r?"\n":"",o=this.resolveStateValue(e);if(o=this.unwrapReactive(o),Array.isArray(o))return o.map(e=>this.renderToString(e,t)).join("");if("object"!=typeof o||null===o)return null==o||!1===o?"":this.escapeHtml(String(o));let{tagName:a,props:s,children:u}=o,d=this.isSelfClosingTag(a),h=`${i}<${a}`,c=this.propsToAttributes(s);if(c&&(h+=` ${c}`),d)return h+=` />${l}`,h;if(h+=">",s.dangerouslySetInnerHTML)return h+=s.dangerouslySetInnerHTML.__html,h+=`</${a}>${l}`,h;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){h+=l;for(let t of e)if(null!=t&&!1!==t)if(Array.isArray(t))for(let e of t)null!=e&&!1!==e&&(h+=this.renderToString(e,{pretty:r,indent:n+1}));else h+=this.renderToString(t,{pretty:r,indent:n+1});h+=i}else for(let t of e)if(null!=t&&!1!==t)if(Array.isArray(t))for(let e of t)null!=e&&!1!==e&&(h+=this.renderToString(e,{pretty:!1,indent:0}));else h+=this.renderToString(t,{pretty:!1,indent:0})}return h+=`</${a}>${l}`,h}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={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"};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,i={};for(let e in r){let t=r[e];"class"===e?i.className=this.isState(t)?t.value:t:i[e]=this.isState(t)?t.value:t}let l=[];if(null!=n)if(Array.isArray(n))for(let e of n)if(this.isState(e))l.push(this.createReactiveChild(e,e=>e));else{let t=this.jsonToVNode(e);null!=t&&!1!==t&&l.push(t)}else if(this.isState(n))l.push(this.createReactiveChild(n,e=>e));else if("object"==typeof n&&"tag"in n){let e=this.jsonToVNode(n);null!=e&&!1!==e&&l.push(e)}else l.push(n);return{tagName:t,props:i,children:l}}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,i={};for(let e in r){let t=r[e];i[e]=this.isState(t)?t.value:t}let l=[];for(let e of n)if(this.isState(e))l.push(this.createReactiveChild(e,e=>e));else{let t=this.vNodeJsonToVNode(e);null!=t&&!1!==t&&l.push(t)}return{tagName:t,props:i,children:l}}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:i=[],scripts:l=[],styles:o=[],lang:a="en",head:s="",bodyAttrs:u={},pretty:d=!1}=t,h=d?"\n":"",c=d?" ":"",p=d?" ":"",f=`<!DOCTYPE html>${h}<html lang="${a}">${h}${c}<head>${h}${p}<meta charset="UTF-8">${h}${p}<meta name="viewport" content="width=device-width, initial-scale=1.0">${h}`;r&&(f+=`${p}<title>${this.escapeHtml(r)}</title>${h}`);for(let e of n){f+=`${p}<meta`;for(let t in e)f+=` ${t}="${this.escapeHtml(e[t])}"`;f+=`>${h}`}for(let e of i){f+=`${p}<link`;for(let t in e)f+=` ${t}="${this.escapeHtml(e[t])}"`;f+=`>${h}`}for(let e of o)e.href?f+=`${p}<link rel="stylesheet" href="${this.escapeHtml(e.href)}">${h}`:e.content&&(f+=`${p}<style>${e.content}</style>${h}`);s&&(f+=s+h),f+=`${c}</head>${h}${c}<body`;for(let e in u)f+=` ${e}="${this.escapeHtml(u[e])}"`;f+=`>${h}`,f+=this.renderToString(e,{pretty:d,indent:2});for(let e of l)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>${h}`:e.content?f+=`>${e.content}<\/script>${h}`:f+=`><\/script>${h}`;return f+=`${c}</body>${h}</html>`,f}getElementCache(){return this.elementCache}};function t(e,t){let r=e.split("/").filter(Boolean),n=t.split("/").filter(Boolean);if(e.endsWith("*")){let r=e.slice(0,-1);if(t.startsWith(r)||"/"===r||"*"===e)return{"*":t.slice(r.length)}}if(r.length!==n.length)return null;let i={};for(let e=0;e<r.length;e++){let t=r[e],l=n[e];if(t.startsWith(":"))i[t.slice(1)]=decodeURIComponent(l);else if(t!==l)return null}return i}exports.createRouter=function(r){let{mode:n="history",base:i="",routes:l}=r,o=[],a=e=>{let t={};return new URLSearchParams(e).forEach((e,r)=>{t[r]=e}),t},s=()=>"hash"===n?window.location.hash.slice(1)||"/":window.location.pathname.replace(i,"")||"/",u=e=>{let[t,r=""]=e.split("?"),[n,i=""]=t.split("#");return{path:n||"/",params:{},query:a(r),hash:i?"#"+i:""}},d=e=>{for(let r of l){let n=t(r.path,e);if(null!==n)return{route:r,params:n}}return null},h=e.createState(u(s())),c=(e,t=!1)=>{let r=u(e),l=d(r.path);l&&(r.params=l.params);for(let e of o){let n=e(r,h.value);if(!1===n)return;if("string"==typeof n)return void c(n,t)}if(l?.route.beforeEnter){let e=l.route.beforeEnter(r,h.value);if(!1===e)return;if("string"==typeof e)return void c(e,t)}let a="hash"===n?"#"+e:i+e;t?window.history.replaceState({path:e},"",a):window.history.pushState({path:e},"",a),h.value=r},p=()=>{let e=s(),t=u(e),r=d(t.path);r&&(t.params=r.params),h.value=t};return typeof window<"u"&&window.addEventListener("popstate",p),{currentRoute:h,push:e=>c(e,!1),replace:e=>c(e,!0),back:()=>window.history.back(),forward:()=>window.history.forward(),go:e=>window.history.go(e),beforeEach:e=>{o.push(e)},destroy:()=>{typeof window<"u"&&window.removeEventListener("popstate",p),h.destroy()}}},exports.createRouterView=function(e,r){let{routes:n,notFound:i}=r;return()=>{let r=e.currentRoute.value,l=n.find(e=>null!==t(e.path,r.path));if(l){let e=t(l.path,r.path)||{},n=l.component({...e,...r.query});return"object"==typeof n&&null!==n&&"tagName"in n?n:{tagName:"span",props:{},children:[n]}}if(i){let e=i(r.params);return"object"==typeof e&&null!==e&&"tagName"in e?e:{tagName:"span",props:{},children:[e]}}return{tagName:"div",props:{},children:["404 - Not Found"]}}},exports.routerLink=(e,t,...r)=>({tagName:"a",props:{...t,href:t.to,onclick:r=>{r.preventDefault(),e.push(t.to)}},children:r});
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/router.ts
21
+ var router_exports = {};
22
+ __export(router_exports, {
23
+ createRouter: () => createRouter,
24
+ createRouterView: () => createRouterView,
25
+ routerLink: () => routerLink
26
+ });
27
+ module.exports = __toCommonJS(router_exports);
28
+
29
+ // src/dom.ts
30
+ function resolveElement(rootElement) {
31
+ return typeof rootElement === "string" ? document.getElementById(rootElement.replace("#", "")) : rootElement;
32
+ }
33
+ function ensureElement(el, rootElement) {
34
+ if (!el) {
35
+ throw new Error(`Element not found: ${rootElement}`);
36
+ }
37
+ return el;
38
+ }
39
+ function shouldSkipChild(child) {
40
+ return child == null || child === false;
41
+ }
42
+ function isPrimitiveJson(json) {
43
+ return json == null || typeof json === "boolean" || typeof json === "string" || typeof json === "number";
44
+ }
45
+ var DomNode = class {
46
+ constructor() {
47
+ this.elementCache = /* @__PURE__ */ new WeakMap();
48
+ this.reactiveNodes = /* @__PURE__ */ new Map();
49
+ }
50
+ createElement(tagName, props = {}, children = []) {
51
+ return { tagName, props, children };
52
+ }
53
+ renderToDOM(vNode, parent) {
54
+ if (vNode == null || vNode === false) return;
55
+ if (typeof vNode !== "object") {
56
+ parent.appendChild(document.createTextNode(String(vNode)));
57
+ return;
58
+ }
59
+ const { tagName, props, children } = vNode;
60
+ const isSVG = tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
61
+ const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
62
+ for (const key in props) {
63
+ const value = props[key];
64
+ if (value == null || value === false) continue;
65
+ const c = key.charCodeAt(0);
66
+ if (c === 99 && (key.length < 6 || key[5] === "N")) {
67
+ const classValue = Array.isArray(value) ? value.join(" ") : value;
68
+ isSVG ? el.setAttribute("class", classValue) : el.className = classValue;
69
+ } else if (c === 115 && key.length === 5) {
70
+ if (typeof value === "string") {
71
+ el.style.cssText = value;
72
+ } else {
73
+ const s = el.style;
74
+ for (const k in value) s[k] = value[k];
75
+ }
76
+ } else if (c === 111 && key.charCodeAt(1) === 110) {
77
+ el[key.toLowerCase()] = value;
78
+ } else if (c === 100 && key.length > 20) {
79
+ el.innerHTML = value.__html;
80
+ } else if (c === 114 && key.length === 3) {
81
+ setTimeout(() => {
82
+ typeof value === "function" ? value(el) : value.current = el;
83
+ }, 0);
84
+ } else {
85
+ el.setAttribute(key, value === true ? "" : String(value));
86
+ }
87
+ }
88
+ const len = children.length;
89
+ if (!len) {
90
+ parent.appendChild(el);
91
+ return;
92
+ }
93
+ const renderChildren = (target) => {
94
+ for (let i = 0; i < len; i++) {
95
+ const child = children[i];
96
+ if (shouldSkipChild(child)) continue;
97
+ if (Array.isArray(child)) {
98
+ for (let j = 0, cLen = child.length; j < cLen; j++) {
99
+ const c = child[j];
100
+ !shouldSkipChild(c) && this.renderToDOM(c, target);
101
+ }
102
+ } else {
103
+ this.renderToDOM(child, target);
104
+ }
105
+ }
106
+ };
107
+ if (len > 30) {
108
+ const fragment = document.createDocumentFragment();
109
+ renderChildren(fragment);
110
+ el.appendChild(fragment);
111
+ } else {
112
+ renderChildren(el);
113
+ }
114
+ parent.appendChild(el);
115
+ }
116
+ render(rootElement, vNode) {
117
+ const el = ensureElement(resolveElement(rootElement), rootElement);
118
+ el.innerHTML = "";
119
+ if (vNode.children && vNode.children.length > 500) {
120
+ const fragment = document.createDocumentFragment();
121
+ this.renderToDOM(vNode, fragment);
122
+ el.appendChild(fragment);
123
+ } else {
124
+ this.renderToDOM(vNode, el);
125
+ }
126
+ return el;
127
+ }
128
+ batchRender(rootElement, vNodes) {
129
+ const el = ensureElement(resolveElement(rootElement), rootElement);
130
+ const len = vNodes.length;
131
+ if (len > 3e3) {
132
+ const fragment = document.createDocumentFragment();
133
+ let processed = 0;
134
+ const chunkSize = 1500;
135
+ const processChunk = () => {
136
+ const end = Math.min(processed + chunkSize, len);
137
+ for (let i = processed; i < end; i++) {
138
+ this.renderToDOM(vNodes[i], fragment);
139
+ }
140
+ processed = end;
141
+ if (processed >= len) {
142
+ el.appendChild(fragment);
143
+ } else {
144
+ requestAnimationFrame(processChunk);
145
+ }
146
+ };
147
+ processChunk();
148
+ } else {
149
+ const fragment = document.createDocumentFragment();
150
+ for (let i = 0; i < len; i++) {
151
+ this.renderToDOM(vNodes[i], fragment);
152
+ }
153
+ el.appendChild(fragment);
154
+ }
155
+ return el;
156
+ }
157
+ renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
158
+ const el = ensureElement(resolveElement(rootElement), rootElement);
159
+ const len = vNodes.length;
160
+ let index = 0;
161
+ const renderChunk = () => {
162
+ const end = Math.min(index + chunkSize, len);
163
+ const fragment = document.createDocumentFragment();
164
+ for (let i = index; i < end; i++) {
165
+ this.renderToDOM(vNodes[i], fragment);
166
+ }
167
+ el.appendChild(fragment);
168
+ index = end;
169
+ if (onProgress) onProgress(index, len);
170
+ if (index < len) {
171
+ requestAnimationFrame(renderChunk);
172
+ }
173
+ };
174
+ requestAnimationFrame(renderChunk);
175
+ return el;
176
+ }
177
+ renderToHead(...vNodes) {
178
+ const head = document.head;
179
+ if (head) {
180
+ for (const vNode of vNodes.flat()) {
181
+ vNode && this.renderToDOM(vNode, head);
182
+ }
183
+ }
184
+ return head;
185
+ }
186
+ addStyle(cssText) {
187
+ const el = document.createElement("style");
188
+ el.textContent = cssText;
189
+ return document.head.appendChild(el);
190
+ }
191
+ addMeta(attrs) {
192
+ const el = document.createElement("meta");
193
+ for (const k in attrs) el.setAttribute(k, attrs[k]);
194
+ return document.head.appendChild(el);
195
+ }
196
+ addLink(attrs) {
197
+ const el = document.createElement("link");
198
+ for (const k in attrs) el.setAttribute(k, attrs[k]);
199
+ return document.head.appendChild(el);
200
+ }
201
+ setTitle(text) {
202
+ return document.title = text;
203
+ }
204
+ // Reactive State Management
205
+ createState(initialValue, options = {}) {
206
+ let value = initialValue;
207
+ const listeners = /* @__PURE__ */ new Set();
208
+ let updateTimer = null;
209
+ const { throttle = 0, deep = false } = options;
210
+ const notify = () => listeners.forEach((fn) => fn(value));
211
+ const scheduleUpdate = () => {
212
+ if (throttle > 0) {
213
+ if (!updateTimer) {
214
+ updateTimer = setTimeout(() => {
215
+ updateTimer = null;
216
+ notify();
217
+ }, throttle);
218
+ }
219
+ } else {
220
+ notify();
221
+ }
222
+ };
223
+ return {
224
+ get value() {
225
+ return value;
226
+ },
227
+ set value(newValue) {
228
+ const changed = deep ? JSON.stringify(value) !== JSON.stringify(newValue) : value !== newValue;
229
+ if (changed) {
230
+ value = newValue;
231
+ scheduleUpdate();
232
+ }
233
+ },
234
+ subscribe(fn) {
235
+ listeners.add(fn);
236
+ return () => listeners.delete(fn);
237
+ },
238
+ destroy() {
239
+ listeners.clear();
240
+ updateTimer && clearTimeout(updateTimer);
241
+ }
242
+ };
243
+ }
244
+ computed(states, computeFn) {
245
+ const values = states.map((s) => s.value);
246
+ const result = this.createState(computeFn(...values));
247
+ states.forEach((state, index) => {
248
+ state.subscribe((newValue) => {
249
+ values[index] = newValue;
250
+ result.value = computeFn(...values);
251
+ });
252
+ });
253
+ return result;
254
+ }
255
+ effect(stateFn) {
256
+ stateFn();
257
+ }
258
+ // Virtual scrolling helper for large lists
259
+ createVirtualList(container, items, renderItem, itemHeight = 50, bufferSize = 5) {
260
+ const viewportHeight = container.clientHeight;
261
+ const totalHeight = items.length * itemHeight;
262
+ let scrollTop = 0;
263
+ const getVisibleRange = () => {
264
+ const start = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
265
+ const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
266
+ return { start, end };
267
+ };
268
+ const render2 = () => {
269
+ const { start, end } = getVisibleRange();
270
+ const wrapper = document.createElement("div");
271
+ wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
272
+ for (let i = start; i < end; i++) {
273
+ const itemEl = document.createElement("div");
274
+ itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
275
+ this.renderToDOM(renderItem(items[i], i), itemEl);
276
+ wrapper.appendChild(itemEl);
277
+ }
278
+ container.innerHTML = "";
279
+ container.appendChild(wrapper);
280
+ };
281
+ const scrollHandler = () => {
282
+ scrollTop = container.scrollTop;
283
+ requestAnimationFrame(render2);
284
+ };
285
+ container.addEventListener("scroll", scrollHandler);
286
+ render2();
287
+ return {
288
+ render: render2,
289
+ destroy: () => {
290
+ container.removeEventListener("scroll", scrollHandler);
291
+ container.innerHTML = "";
292
+ }
293
+ };
294
+ }
295
+ // Lazy load components
296
+ lazy(loadFn) {
297
+ let component = null;
298
+ let loading = false;
299
+ return async (...args) => {
300
+ if (!component && !loading) {
301
+ loading = true;
302
+ component = await loadFn();
303
+ loading = false;
304
+ }
305
+ return component ? component(...args) : { tagName: "div", props: { class: "loading" }, children: ["Loading..."] };
306
+ };
307
+ }
308
+ // Memory management - cleanup unused elements
309
+ cleanupUnusedElements(root) {
310
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
311
+ const toRemove = [];
312
+ while (walker.nextNode()) {
313
+ const node = walker.currentNode;
314
+ if (node.id && node.id.startsWith("r") && !this.elementCache.has(node)) {
315
+ toRemove.push(node);
316
+ }
317
+ }
318
+ toRemove.forEach((el) => el.remove());
319
+ return toRemove.length;
320
+ }
321
+ // Server-Side Rendering - convert VNode to HTML string
322
+ renderToString(vNode, options = {}) {
323
+ const { pretty = false, indent = 0 } = options;
324
+ const indentStr = pretty ? " ".repeat(indent) : "";
325
+ const newLine = pretty ? "\n" : "";
326
+ let resolvedVNode = this.resolveStateValue(vNode);
327
+ resolvedVNode = this.unwrapReactive(resolvedVNode);
328
+ if (Array.isArray(resolvedVNode)) {
329
+ return resolvedVNode.map((child) => this.renderToString(child, options)).join("");
330
+ }
331
+ if (typeof resolvedVNode !== "object" || resolvedVNode === null) {
332
+ if (resolvedVNode === null || resolvedVNode === void 0 || resolvedVNode === false) {
333
+ return "";
334
+ }
335
+ return this.escapeHtml(String(resolvedVNode));
336
+ }
337
+ const { tagName, props, children } = resolvedVNode;
338
+ const isSelfClosing = this.isSelfClosingTag(tagName);
339
+ let html = `${indentStr}<${tagName}`;
340
+ const attrs = this.propsToAttributes(props);
341
+ if (attrs) {
342
+ html += ` ${attrs}`;
343
+ }
344
+ if (isSelfClosing) {
345
+ html += ` />${newLine}`;
346
+ return html;
347
+ }
348
+ html += ">";
349
+ if (props.dangerouslySetInnerHTML) {
350
+ html += props.dangerouslySetInnerHTML.__html;
351
+ html += `</${tagName}>${newLine}`;
352
+ return html;
353
+ }
354
+ if (children && children.length > 0) {
355
+ const resolvedChildren = children.map((c) => {
356
+ const resolved = this.resolveStateValue(c);
357
+ return this.unwrapReactive(resolved);
358
+ });
359
+ const hasComplexChildren = resolvedChildren.some(
360
+ (c) => typeof c === "object" && c !== null && !Array.isArray(c) && "tagName" in c
361
+ );
362
+ if (pretty && hasComplexChildren) {
363
+ html += newLine;
364
+ for (const child of resolvedChildren) {
365
+ if (shouldSkipChild(child)) continue;
366
+ if (Array.isArray(child)) {
367
+ for (const c of child) {
368
+ if (!shouldSkipChild(c)) {
369
+ html += this.renderToString(c, { pretty, indent: indent + 1 });
370
+ }
371
+ }
372
+ } else {
373
+ html += this.renderToString(child, { pretty, indent: indent + 1 });
374
+ }
375
+ }
376
+ html += indentStr;
377
+ } else {
378
+ for (const child of resolvedChildren) {
379
+ if (shouldSkipChild(child)) continue;
380
+ if (Array.isArray(child)) {
381
+ for (const c of child) {
382
+ if (!shouldSkipChild(c)) {
383
+ html += this.renderToString(c, { pretty: false, indent: 0 });
384
+ }
385
+ }
386
+ } else {
387
+ html += this.renderToString(child, { pretty: false, indent: 0 });
388
+ }
389
+ }
390
+ }
391
+ }
392
+ html += `</${tagName}>${newLine}`;
393
+ return html;
394
+ }
395
+ resolveStateValue(value) {
396
+ if (value && typeof value === "object" && "value" in value && "subscribe" in value) {
397
+ return value.value;
398
+ }
399
+ return value;
400
+ }
401
+ isReactiveWrapper(vNode) {
402
+ if (!vNode || typeof vNode !== "object" || !vNode.tagName) {
403
+ return false;
404
+ }
405
+ return vNode.tagName === "span" && vNode.props?.id && typeof vNode.props.id === "string" && vNode.props.id.match(/^r[a-z0-9]{9}$/);
406
+ }
407
+ unwrapReactive(vNode) {
408
+ if (!this.isReactiveWrapper(vNode)) {
409
+ return vNode;
410
+ }
411
+ const children = vNode.children;
412
+ if (!children || children.length === 0) {
413
+ return "";
414
+ }
415
+ if (children.length === 1) {
416
+ const child = children[0];
417
+ if (child && typeof child === "object" && child.tagName === "span") {
418
+ const props = child.props;
419
+ const hasNoProps = !props || Object.keys(props).length === 0;
420
+ const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
421
+ if (hasNoProps && hasSingleStringChild) {
422
+ return child.children[0];
423
+ }
424
+ }
425
+ return this.unwrapReactive(child);
426
+ }
427
+ return children.map((c) => this.unwrapReactive(c));
428
+ }
429
+ escapeHtml(text) {
430
+ const htmlEscapes = {
431
+ "&": "&amp;",
432
+ "<": "&lt;",
433
+ ">": "&gt;",
434
+ '"': "&quot;",
435
+ "'": "&#x27;"
436
+ };
437
+ return text.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
438
+ }
439
+ isSelfClosingTag(tagName) {
440
+ const selfClosingTags = /* @__PURE__ */ new Set([
441
+ "area",
442
+ "base",
443
+ "br",
444
+ "col",
445
+ "embed",
446
+ "hr",
447
+ "img",
448
+ "input",
449
+ "link",
450
+ "meta",
451
+ "param",
452
+ "source",
453
+ "track",
454
+ "wbr"
455
+ ]);
456
+ return selfClosingTags.has(tagName.toLowerCase());
457
+ }
458
+ propsToAttributes(props) {
459
+ const attrs = [];
460
+ for (const key in props) {
461
+ if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref") {
462
+ continue;
463
+ }
464
+ let value = props[key];
465
+ value = this.resolveStateValue(value);
466
+ if (value == null || value === false) continue;
467
+ if (key.startsWith("on") && typeof value === "function") {
468
+ continue;
469
+ }
470
+ if (key === "className" || key === "class") {
471
+ const className = Array.isArray(value) ? value.join(" ") : value;
472
+ if (className) {
473
+ attrs.push(`class="${this.escapeHtml(String(className))}"`);
474
+ }
475
+ continue;
476
+ }
477
+ if (key === "style") {
478
+ const styleStr = this.styleToString(value);
479
+ if (styleStr) {
480
+ attrs.push(`style="${this.escapeHtml(styleStr)}"`);
481
+ }
482
+ continue;
483
+ }
484
+ if (value === true) {
485
+ attrs.push(key);
486
+ continue;
487
+ }
488
+ attrs.push(`${key}="${this.escapeHtml(String(value))}"`);
489
+ }
490
+ return attrs.join(" ");
491
+ }
492
+ styleToString(style) {
493
+ if (typeof style === "string") {
494
+ return style;
495
+ }
496
+ if (typeof style === "object" && style !== null) {
497
+ const styles = [];
498
+ for (const key in style) {
499
+ const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
500
+ styles.push(`${cssKey}:${style[key]}`);
501
+ }
502
+ return styles.join(";");
503
+ }
504
+ return "";
505
+ }
506
+ isState(value) {
507
+ return value && typeof value === "object" && "value" in value && "subscribe" in value && typeof value.subscribe === "function";
508
+ }
509
+ createReactiveChild(state, renderFn) {
510
+ const currentValue = renderFn(state.value);
511
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
512
+ const entry = { node: null, renderFn };
513
+ this.reactiveNodes.set(state, entry);
514
+ state.subscribe(() => {
515
+ if (entry.node && entry.node.parentNode) {
516
+ const newValue = renderFn(state.value);
517
+ entry.node.textContent = String(newValue ?? "");
518
+ }
519
+ });
520
+ }
521
+ return currentValue;
522
+ }
523
+ jsonToVNode(json) {
524
+ if (this.isState(json)) {
525
+ return this.createReactiveChild(json, (v) => v);
526
+ }
527
+ if (isPrimitiveJson(json)) {
528
+ return json;
529
+ }
530
+ const { tag, attributes = {}, children } = json;
531
+ const props = {};
532
+ for (const key in attributes) {
533
+ const value = attributes[key];
534
+ if (key === "class") {
535
+ props.className = this.isState(value) ? value.value : value;
536
+ } else {
537
+ props[key] = this.isState(value) ? value.value : value;
538
+ }
539
+ }
540
+ const childrenArray = [];
541
+ if (children != null) {
542
+ if (Array.isArray(children)) {
543
+ for (const child of children) {
544
+ if (this.isState(child)) {
545
+ childrenArray.push(this.createReactiveChild(child, (v) => v));
546
+ } else {
547
+ const converted = this.jsonToVNode(child);
548
+ if (converted != null && converted !== false) {
549
+ childrenArray.push(converted);
550
+ }
551
+ }
552
+ }
553
+ } else if (this.isState(children)) {
554
+ childrenArray.push(this.createReactiveChild(children, (v) => v));
555
+ } else if (typeof children === "object" && "tag" in children) {
556
+ const converted = this.jsonToVNode(children);
557
+ if (converted != null && converted !== false) {
558
+ childrenArray.push(converted);
559
+ }
560
+ } else {
561
+ childrenArray.push(children);
562
+ }
563
+ }
564
+ return { tagName: tag, props, children: childrenArray };
565
+ }
566
+ vNodeJsonToVNode(json) {
567
+ if (this.isState(json)) {
568
+ return this.createReactiveChild(json, (v) => v);
569
+ }
570
+ if (isPrimitiveJson(json)) {
571
+ return json;
572
+ }
573
+ const { tagName, props = {}, children = [] } = json;
574
+ const resolvedProps = {};
575
+ for (const key in props) {
576
+ const value = props[key];
577
+ resolvedProps[key] = this.isState(value) ? value.value : value;
578
+ }
579
+ const childrenArray = [];
580
+ for (const child of children) {
581
+ if (this.isState(child)) {
582
+ childrenArray.push(this.createReactiveChild(child, (v) => v));
583
+ } else {
584
+ const converted = this.vNodeJsonToVNode(child);
585
+ if (converted != null && converted !== false) {
586
+ childrenArray.push(converted);
587
+ }
588
+ }
589
+ }
590
+ return { tagName, props: resolvedProps, children: childrenArray };
591
+ }
592
+ renderJson(rootElement, json) {
593
+ const vNode = this.jsonToVNode(json);
594
+ if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
595
+ throw new Error("Invalid JSON structure");
596
+ }
597
+ return this.render(rootElement, vNode);
598
+ }
599
+ renderVNode(rootElement, json) {
600
+ const vNode = this.vNodeJsonToVNode(json);
601
+ if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
602
+ throw new Error("Invalid VNode JSON structure");
603
+ }
604
+ return this.render(rootElement, vNode);
605
+ }
606
+ renderJsonToString(json, options = {}) {
607
+ const vNode = this.jsonToVNode(json);
608
+ return this.renderToString(vNode, options);
609
+ }
610
+ renderVNodeToString(json, options = {}) {
611
+ const vNode = this.vNodeJsonToVNode(json);
612
+ return this.renderToString(vNode, options);
613
+ }
614
+ // Generate complete HTML document as string (for SSR)
615
+ renderToHTMLDocument(vNode, options = {}) {
616
+ const { title = "", meta = [], links = [], scripts = [], styles = [], lang = "en", head = "", bodyAttrs = {}, pretty = false } = options;
617
+ const nl = pretty ? "\n" : "";
618
+ const indent = pretty ? " " : "";
619
+ const indent2 = pretty ? " " : "";
620
+ 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}`;
621
+ if (title) html += `${indent2}<title>${this.escapeHtml(title)}</title>${nl}`;
622
+ for (const m of meta) {
623
+ html += `${indent2}<meta`;
624
+ for (const k in m) html += ` ${k}="${this.escapeHtml(m[k])}"`;
625
+ html += `>${nl}`;
626
+ }
627
+ for (const l of links) {
628
+ html += `${indent2}<link`;
629
+ for (const k in l) html += ` ${k}="${this.escapeHtml(l[k])}"`;
630
+ html += `>${nl}`;
631
+ }
632
+ for (const s of styles) {
633
+ if (s.href) {
634
+ html += `${indent2}<link rel="stylesheet" href="${this.escapeHtml(s.href)}">${nl}`;
635
+ } else if (s.content) {
636
+ html += `${indent2}<style>${s.content}</style>${nl}`;
637
+ }
638
+ }
639
+ if (head) html += head + nl;
640
+ html += `${indent}</head>${nl}${indent}<body`;
641
+ for (const k in bodyAttrs) html += ` ${k}="${this.escapeHtml(bodyAttrs[k])}"`;
642
+ html += `>${nl}`;
643
+ html += this.renderToString(vNode, { pretty, indent: 2 });
644
+ for (const script of scripts) {
645
+ html += `${indent2}<script`;
646
+ if (script.type) html += ` type="${this.escapeHtml(script.type)}"`;
647
+ if (script.async) html += ` async`;
648
+ if (script.defer) html += ` defer`;
649
+ if (script.src) {
650
+ html += ` src="${this.escapeHtml(script.src)}"></script>${nl}`;
651
+ } else if (script.content) {
652
+ html += `>${script.content}</script>${nl}`;
653
+ } else {
654
+ html += `></script>${nl}`;
655
+ }
656
+ }
657
+ html += `${indent}</body>${nl}</html>`;
658
+ return html;
659
+ }
660
+ // Expose elementCache for reactive updates
661
+ getElementCache() {
662
+ return this.elementCache;
663
+ }
664
+ };
665
+ var dom = new DomNode();
666
+ var render = dom.render.bind(dom);
667
+ var renderToString = dom.renderToString.bind(dom);
668
+
669
+ // src/router.ts
670
+ function matchRoute(pattern, path) {
671
+ const patternParts = pattern.split("/").filter(Boolean);
672
+ const pathParts = path.split("/").filter(Boolean);
673
+ if (pattern.endsWith("*")) {
674
+ const basePattern = pattern.slice(0, -1);
675
+ if (path.startsWith(basePattern) || basePattern === "/" || pattern === "*") {
676
+ return { "*": path.slice(basePattern.length) };
677
+ }
678
+ }
679
+ if (patternParts.length !== pathParts.length) return null;
680
+ const params = {};
681
+ for (let i = 0; i < patternParts.length; i++) {
682
+ const patternPart = patternParts[i];
683
+ const pathPart = pathParts[i];
684
+ if (patternPart.startsWith(":")) {
685
+ params[patternPart.slice(1)] = decodeURIComponent(pathPart);
686
+ } else if (patternPart !== pathPart) {
687
+ return null;
688
+ }
689
+ }
690
+ return params;
691
+ }
692
+ function executeGuard(guard, to, from, navigate, replace = false) {
693
+ const result = guard(to, from);
694
+ if (result === false) return false;
695
+ if (typeof result === "string") {
696
+ navigate(result, replace);
697
+ return false;
698
+ }
699
+ return true;
700
+ }
701
+ function wrapComponent(component) {
702
+ if (typeof component === "object" && component !== null && "tagName" in component) {
703
+ return component;
704
+ }
705
+ return { tagName: "span", props: {}, children: [component] };
706
+ }
707
+ function createRouter(options) {
708
+ const { mode = "history", base = "", routes } = options;
709
+ const globalGuards = [];
710
+ const parseQuery = (search) => {
711
+ const query = {};
712
+ const params = new URLSearchParams(search);
713
+ params.forEach((value, key) => {
714
+ query[key] = value;
715
+ });
716
+ return query;
717
+ };
718
+ const getCurrentPath = () => {
719
+ if (mode === "hash") {
720
+ return window.location.hash.slice(1) || "/";
721
+ }
722
+ return window.location.pathname.replace(base, "") || "/";
723
+ };
724
+ const parseLocation = (path) => {
725
+ const [pathPart, queryPart = ""] = path.split("?");
726
+ const [cleanPath, hash = ""] = pathPart.split("#");
727
+ return {
728
+ path: cleanPath || "/",
729
+ params: {},
730
+ query: parseQuery(queryPart),
731
+ hash: hash ? "#" + hash : ""
732
+ };
733
+ };
734
+ const findRoute = (path) => {
735
+ for (const route of routes) {
736
+ const params = matchRoute(route.path, path);
737
+ if (params !== null) {
738
+ return { route, params };
739
+ }
740
+ }
741
+ return null;
742
+ };
743
+ const currentRoute = dom.createState(parseLocation(getCurrentPath()));
744
+ const navigate = (path, replace = false) => {
745
+ const location = parseLocation(path);
746
+ const match = findRoute(location.path);
747
+ if (match) {
748
+ location.params = match.params;
749
+ }
750
+ for (const guard of globalGuards) {
751
+ if (!executeGuard(guard, location, currentRoute.value, navigate, replace)) return;
752
+ }
753
+ if (match?.route.beforeEnter) {
754
+ if (!executeGuard(match.route.beforeEnter, location, currentRoute.value, navigate, replace)) return;
755
+ }
756
+ const url = mode === "hash" ? "#" + path : base + path;
757
+ if (replace) {
758
+ window.history.replaceState({ path }, "", url);
759
+ } else {
760
+ window.history.pushState({ path }, "", url);
761
+ }
762
+ currentRoute.value = location;
763
+ };
764
+ const handlePopState = () => {
765
+ const path = getCurrentPath();
766
+ const location = parseLocation(path);
767
+ const match = findRoute(location.path);
768
+ if (match) {
769
+ location.params = match.params;
770
+ }
771
+ currentRoute.value = location;
772
+ };
773
+ if (typeof window !== "undefined") {
774
+ window.addEventListener("popstate", handlePopState);
775
+ }
776
+ return {
777
+ currentRoute,
778
+ push: (path) => navigate(path, false),
779
+ replace: (path) => navigate(path, true),
780
+ back: () => window.history.back(),
781
+ forward: () => window.history.forward(),
782
+ go: (delta) => window.history.go(delta),
783
+ beforeEach: (guard) => {
784
+ globalGuards.push(guard);
785
+ },
786
+ destroy: () => {
787
+ if (typeof window !== "undefined") {
788
+ window.removeEventListener("popstate", handlePopState);
789
+ }
790
+ currentRoute.destroy();
791
+ }
792
+ };
793
+ }
794
+ function createRouterView(router, options) {
795
+ const { routes, notFound } = options;
796
+ return () => {
797
+ const location = router.currentRoute.value;
798
+ const match = routes.find((r) => matchRoute(r.path, location.path) !== null);
799
+ if (match) {
800
+ const params = matchRoute(match.path, location.path) || {};
801
+ const component = match.component({ ...params, ...location.query });
802
+ return wrapComponent(component);
803
+ }
804
+ if (notFound) {
805
+ const component = notFound(location.params);
806
+ return wrapComponent(component);
807
+ }
808
+ return { tagName: "div", props: {}, children: ["404 - Not Found"] };
809
+ };
810
+ }
811
+ var routerLink = (router, props, ...children) => {
812
+ return {
813
+ tagName: "a",
814
+ props: {
815
+ ...props,
816
+ href: props.to,
817
+ onclick: (e) => {
818
+ e.preventDefault();
819
+ router.push(props.to);
820
+ }
821
+ },
822
+ children
823
+ };
824
+ };
825
+ // Annotate the CommonJS export names for ESM import in node:
826
+ 0 && (module.exports = {
827
+ createRouter,
828
+ createRouterView,
829
+ routerLink
830
+ });