olova 1.0.12 → 1.0.13

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 CHANGED
@@ -3,26 +3,16 @@
3
3
  ```html
4
4
  <div id="app">
5
5
  <template>
6
- <div>
6
+ <div i-data="{count : 0}">
7
7
  <div>{ count }</div>
8
- <button @click="increment">Increment</button>
8
+ <button @click="count++">Increment</button>
9
9
  </div>
10
10
  </template>
11
11
  </div>
12
12
 
13
13
  <script type="module">
14
14
  import { createApp } from "//unpkg.com/olova";
15
-
16
- const app = createApp({
17
- data: {
18
- count: 0,
19
- },
20
- methods: {
21
- increment() {
22
- this.count++;
23
- },
24
- },
25
- });
15
+ const app = createApp();
26
16
  app.mount("#app");
27
17
  </script>
28
18
  ```
package/dist/olova.js CHANGED
@@ -1 +1 @@
1
- const createApp=({data:e={},computed:t={},methods:n={},watch:r={},mounted:o,beforeMount:a,beforeUpdate:i,template:c,plugins:s=[],components:l={},mixins:u=[],directives:d={}}={})=>{let f;const p={},h={},m={},y={},E={...d},b=new Map,g=new Map,w=(e,t)=>{g.set(e,t)},v=(e,t)=>{E[e]=t},A=e=>{Array.from(e.attributes).forEach((t=>{const n=t.name.startsWith("i-")?t.name.slice(1):null;n&&E[n]&&(E[n](e,t.value,S),e.removeAttribute(t.name))}))},T=e=>new Proxy(e,{get:(e,t)=>"object"==typeof e[t]&&null!==e[t]?T(e[t]):e[t],set:(e,t,n)=>(e[t]!==n&&(e[t]=n,C(t)),!0)});Error;class L extends Error{constructor(e){super(e),this.name="StateError"}}const x=(e,t,n=Error)=>function(...r){try{return e.apply(this,r)}catch(e){throw new n(`${t}: ${e.message}`)}};a&&x(a,"Error in beforeMount hook",L).call(S),new Set;const M=e=>{p[e]&&p[e].forEach(x((t=>{t.node?t.node.textContent=t.originalText.replace(/\{(.*?)\}/g,((e,t)=>{try{return new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)(S,oe)}catch(e){return console.error(`Error evaluating expression: ${t}`,e),""}})):t.element&&t.attrName?(t.element.setAttribute(t.attrName,S[e]),t.element.removeAttribute(`:${t.attrName}`)):t.update&&t.update()}),"Error updating bindings"))},C=e=>{i&&x(i,"Error in beforeUpdate hook").call(S,e),M(e),N(e),m.__updated__?.forEach((e=>e.callback.call(S)))},N=e=>{m[e]&&m[e].forEach((t=>{t.debounce?(clearTimeout(t.timeout),t.timeout=setTimeout((()=>t.callback.call(S,S[e])),t.debounce)):t.throttle?(!t.lastCalled||Date.now()-t.lastCalled>t.throttle)&&(t.callback.call(S,S[e]),t.lastCalled=Date.now()):t.callback.call(S,S[e])}))};r&&Object.entries(r).forEach((([e,t])=>{m[e]=Array.isArray(t)?t.map((e=>({callback:e}))):["function"==typeof t?{callback:t}:{...t}]}));const S=T({...e,$refs:new Proxy(y,{get:(e,t)=>{const n=e[t];return n instanceof HTMLElement?new Proxy(n,{get:(e,t)=>"function"==typeof e[t]?e[t].bind(e):e[t]}):n},set:()=>{throw new Error("$refs is read-only")}})}),$={},H={};t&&Object.entries(t).forEach((([e,t])=>{$[e]=[],Object.defineProperty(S,e,{get:()=>"function"==typeof t&&"AsyncFunction"===t.constructor.name?(H[e]||(h[e]=new Proxy(S,{get:(t,n)=>($[e].includes(n)||$[e].push(n),t[n])}),H[e]=t.call(S).then((t=>(h[e]=t,delete H[e],M(e),t))).catch((t=>{console.error(`Error in async computed property "${e}":`,t)}))),H[e]):(h.hasOwnProperty(e)||(h[e]=new Proxy(S,{get:(t,n)=>($[e].includes(n)||$[e].push(n),t[n])}),h[e]=t.call(S)),h[e]),enumerable:!0})}));const k=e=>{Object.entries($).forEach((([t,n])=>{n.includes(e)&&(delete h[t],M(t))}))},O=()=>{f.querySelectorAll("[\\i-ref]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-ref");t&&(y[t]=e,e.removeAttribute("i-ref"))}))},j=()=>{const e=new WeakMap,t={};f.querySelectorAll("[\\i-model]").forEach((n=>{const r=n.getAttribute("i-model");if(!r)return;const o=()=>{const e=(e=>e instanceof HTMLInputElement?"checkbox"===e.type?e.checked:"radio"===e.type?e.checked?e.value:void 0:e.value:e instanceof HTMLSelectElement?e.multiple?Array.from(e.selectedOptions).map((e=>e.value)):e.value:e instanceof HTMLTextAreaElement?e.value:void 0)(n);void 0!==e&&(S[r]=e,C(r))},a=()=>{((e,t)=>{e instanceof HTMLInputElement?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t:e.value=t:e instanceof HTMLSelectElement?e.multiple?Array.from(e.options).forEach((e=>{e.selected=t.includes(e.value)})):e.value=t:e instanceof HTMLTextAreaElement&&(e.value=t)})(n,S[r])};e.has(n)&&e.get(n).forEach((([e,t])=>{n.removeEventListener(e,t)}));const i=[];if(n instanceof HTMLSelectElement||"checkbox"===n.type||"radio"===n.type){const e=()=>o();n.addEventListener("change",e),i.push(["change",e])}else{const e=()=>o();n.addEventListener("input",e),i.push(["input",e])}e.set(n,i),n instanceof HTMLInputElement&&"radio"===n.type&&(t[r]||(t[r]=[]),t[r].push(n),n.name=`radio-group-${r}`),(p[r]??=[]).push({element:n,updateModel:a}),a(),n.removeAttribute("i-model")})),Object.entries(t).forEach((([e,t])=>{(p[e]??=[]).push({updateModel:()=>{t.forEach((t=>{t.checked=t.value===S[e]}))}})}))},F=e=>{try{return new Function("state","helpers",`with(state) { with(helpers) { return ${e} } }`)(S,oe)}catch(t){return console.error(`Error evaluating expression: ${e}`,t),""}},_=()=>{const e="string"==typeof c?c.trim():c instanceof HTMLElement?c.innerHTML:f.innerHTML.trim();if(!e)throw new Error("No template provided and container is empty");const t=document.createElement("template");t.innerHTML=e,f.innerHTML="",f.appendChild(t.content.cloneNode(!0));const n=e=>{e.nodeType===Node.ELEMENT_NODE&&((e=(e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e.tagName.toLowerCase();if(g.has(t)){const n=g.get(t)(Array.from(e.attributes).reduce(((e,t)=>({...e,[t.name]:t.value})),{})),r=document.createElement("div");r.innerHTML=n;const o=r.firstElementChild;if(o)return e.parentNode?.replaceChild(o,e),o}}return e})(e))instanceof HTMLElement&&(e.hasAttribute("i-if")&&(e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-if");if(!t)return;const n=e.nextElementSibling?.hasAttribute("i-else")?e.nextElementSibling:null,r=e.parentNode,o=document.createComment("i-if placeholder");r?.insertBefore(o,e);const a=()=>{try{F(t)?(e.isConnected||r?.insertBefore(e,o.nextSibling),n?.isConnected&&r?.removeChild(n)):(e.isConnected&&r?.removeChild(e),n&&!n.isConnected&&r?.insertBefore(n,o.nextSibling))}catch(e){console.error("Error evaluating i-if directive:",e)}};a(),(p[t]??=[]).push({element:e,update:a}),e.removeAttribute("i-if"),n?.removeAttribute("i-else")})(e),e.hasAttribute("i-for")&&K(e),e.hasAttribute("i-show")&&X(e),A(e)),Array.from(e.childNodes).forEach(n))};Array.from(f.childNodes).forEach(n),f.querySelectorAll("*").forEach((e=>{if(e instanceof HTMLElement){A(e);const t=e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const n=t.split(/(\{.*?\})/),r=document.createDocumentFragment();n.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),n=document.createTextNode("");r.appendChild(n);const o=()=>{n.textContent=F(t)};o(),D(t).forEach((e=>{(p[e]??=[]).push({update:o})}))}else r.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(r,e)}};e.childNodes.forEach((e=>{e.nodeType===Node.TEXT_NODE&&t(e)}))}}))},D=e=>{const t=e.match(/\b\w+\b/g);return t?t.filter((e=>e in S)):[]};Object.entries(l).forEach((([e,t])=>{w(e,t)}));const q=()=>{f.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("@")){const[r,...o]=t.name.slice(1).split("."),a=t.value.trim(),i={capture:o.includes("capture"),once:o.includes("once"),passive:o.includes("passive")},c=t=>{try{if(o.includes("stop")&&t.stopPropagation(),o.includes("prevent")&&t.preventDefault(),o.includes("self")&&t.target!==e)return;if(t instanceof KeyboardEvent){const e=o.filter((e=>["ctrl","alt","shift","meta","Tab","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e))),n=e.every((e=>t[`${e}Key`]));if(e.length>0&&!n)return;const r=o.find((e=>/^[0-9]+$/.test(e)));if(r&&t.keyCode!==parseInt(r))return;const a=o.find((t=>!e.includes(t)&&!/^[0-9]+$/.test(t)));if(a&&t.key.toLowerCase()!==a.toLowerCase())return}if(t instanceof MouseEvent){const e={left:0,middle:1,right:2},n=o.find((t=>Object.keys(e).includes(t)));if(n&&t.button!==e[n])return}n&&n[a]?n[a].call(S,t):new Function("state","event",`with(state) { ${a} }`).call(S,S,t),C()}catch(e){console.error(`Error executing event handler: ${a}`,e)}};let s=c;if(o.includes("debounce")){const e=parseInt(o[o.indexOf("debounce")+1])||300;s=debounce(c,e)}if(o.includes("throttle")){const e=parseInt(o[o.indexOf("throttle")+1])||300;s=throttle(c,e)}e.addEventListener(r,s,i),e.removeAttribute(t.name)}}))}))},P={beforeCreate:[],created:[],beforeMount:[],mounted:[],beforeUpdate:[],updated:[],beforeUnmount:[],unmounted:[]},W=(e,t)=>{P[e]&&P[e].push(t)},U=e=>{P[e]?.forEach((e=>e.call(S)))},I=e=>{e.data&&Object.assign(S,e.data()),e.methods&&Object.assign(n,e.methods),e.computed&&Object.assign(t,e.computed),e.watch&&Object.entries(e.watch).forEach((([e,t])=>{(r[e]??=[]).push(t)})),e.mounted&&W("mounted",e.mounted)};u.forEach(I),window.addEventListener("error",(e=>{console.error("Global error:",e)}));const B=()=>{f.querySelectorAll("[\\i-html]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-html");if(!t)return;const n=()=>{try{let n=new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)(S,oe);n=n.replace(/\{(.*?)\}/g,((e,t)=>new Function("state",`with(state) { return ${t} }`)(S))),e.innerHTML=n,e.querySelectorAll("*").forEach((e=>{e instanceof HTMLElement&&r(e)}))}catch(e){console.error("Error applying i-html directive:",e)}},r=e=>{Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE&&o(e)})),Array.from(e.attributes).forEach((t=>{t.value.includes("{")&&t.value.includes("}")&&a(e,t)}))},o=e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const n=t.split(/(\{.*?\})/),r=document.createDocumentFragment();n.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),n=document.createTextNode("");r.appendChild(n);const o=()=>{n.textContent=F(t)};o(),Object.keys(S).forEach((e=>{(p[e]??=[]).push({update:o})}))}else r.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(r,e)}},a=(e,t)=>{const n=t.value,r=()=>{const r=n.replace(/\{(.*?)\}/g,((e,t)=>new Function("state",`with(state) { return ${t} }`)(S)));e.setAttribute(t.name,r)};r(),Object.keys(S).forEach((e=>{(p[e]??=[]).push({update:r})}))};n(),Object.keys(S).forEach((e=>{(p[e]??=[]).push({update:n})})),e.removeAttribute("i-html")}))},Y={beforeEnter:e=>{e.style.opacity="0",e.style.transform="translateY(-20px)",e.style.display=""},enter:(e,t)=>{const n=1e3*parseFloat(getComputedStyle(e).transitionDuration);requestAnimationFrame((()=>{e.style.opacity="1",e.style.transform="translateY(0)",setTimeout(t,n)}))},afterEnter:e=>{e.style.opacity="",e.style.transform=""},enterCancelled:e=>{e.style.opacity="",e.style.transform=""},beforeLeave:e=>{e.style.opacity="1",e.style.transform="translateY(0)"},leave:(e,t)=>{const n=1e3*parseFloat(getComputedStyle(e).transitionDuration);requestAnimationFrame((()=>{e.style.opacity="0",e.style.transform="translateY(-20px)",setTimeout(t,n)}))},afterLeave:e=>{e.style.display="none",e.style.opacity="",e.style.transform=""},leaveCancelled:e=>{e.style.opacity="",e.style.transform=""}},R=()=>{f.querySelectorAll("[i-transition]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-transition");if(!t)return;const[n,r,o]=t.split(",").map((e=>e.trim())),a=r?`${r}ms`:"300ms",i=o||"ease";e.style.transition=`opacity ${a} ${i}, transform ${a} ${i}`;const c=(t,n)=>new Promise((r=>{let o=!1;return t.before(e),t.during(e,(()=>{o||(t.after(e),n&&n(),r())})),()=>{o=!0,t.cancelled(e),r()}}));e._transitionShow=async t=>{e.style.display="",await c({before:Y.beforeEnter,during:Y.enter,after:Y.afterEnter,cancelled:Y.enterCancelled},t)},e._transitionHide=async e=>{await c({before:Y.beforeLeave,during:Y.leave,after:Y.afterLeave,cancelled:Y.leaveCancelled},e)},e.style.display="none",e.removeAttribute("i-transition")}))},X=e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-show");if(!t)return;let n=null;const r=async()=>{try{const r=new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)(S,oe);e._transitionShow&&e._transitionHide?(n&&(await n,n=null),n=r?e._transitionShow():e._transitionHide(),await n):e.style.display=r?"":"none"}catch(e){console.error("Error evaluating i-show directive:",e)}};r(),(p[t]??=[]).push({element:e,update:r}),e.removeAttribute("i-show")},K=e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-for");if(!t)return;const n=t.match(/(\w+)(?:,\s*(\w+))?\s+(?:in|of)\s+(.+)/);if(!n)return void console.error("Invalid i-for expression:",t);const[,r,o,a]=n,i=e.getAttribute("i-key")||null,c=e.parentNode,s=document.createComment(`i-for: ${t}`);c?.insertBefore(s,e);const l=e.cloneNode(!0);l.removeAttribute("i-for"),l.removeAttribute("i-key");const u=()=>{try{const e=new Function("state","helpers",`with(state) { with(helpers) { return ${a} } }`)(S,oe),t=document.createDocumentFragment(),n=new Map;let u=s.nextSibling;for(;u&&u.hasAttribute&&u.hasAttribute("data-i-for-id");)n.set(u.getAttribute("data-i-for-id"),u),u=u.nextSibling;for(e.forEach(((e,c)=>{const s=i?e[i]:JSON.stringify(e),u=`${a}-${s}`;let f=n.get(u);f?n.delete(u):(f=l.cloneNode(!0),f.setAttribute("data-i-for-id",u));const p={...S,[r]:e,...o?{[o]:c}:{index:c}};d(f,p),t.appendChild(f)})),n.forEach((e=>e.remove()));s.nextSibling&&s.nextSibling.hasAttribute&&s.nextSibling.hasAttribute("data-i-for-id");)c.removeChild(s.nextSibling);c.insertBefore(t,s.nextSibling)}catch(e){console.error("Error evaluating i-for directive:",e)}},d=(e,t)=>{e.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((n=>{if(n.value.includes("{")&&n.value.includes("}")){const r=n.value.replace(/\{(.*?)\}/g,((e,n)=>new Function("state",`with(state) { return ${n} }`)(t)));e.setAttribute(n.name,r)}}))})),e.childNodes.forEach((e=>{e.nodeType===Node.TEXT_NODE&&(e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const n=t.split(/(\{.*?\})/),r=document.createDocumentFragment();n.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),n=document.createTextNode("");r.appendChild(n),n.textContent=F(t)}else r.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(r,e)}})(e)}))};u(),(p[a]??=[]).push({update:u}),e.remove()},G=()=>{f.querySelectorAll("*").forEach((e=>{e instanceof HTMLElement&&Array.from(e.attributes).forEach((t=>{const n=t.name.match(/^(?:i-bind:|:)(.+)$/);if(!n)return;const[,r]=n,o=t.value,a=()=>{try{let t=new Function("state","helpers",`with(state) { with(helpers) { return ${o} } }`)(S,oe);"class"===r?"object"==typeof t&&null!==t?Object.entries(t).forEach((([t,n])=>{e.classList.toggle(t,!!n)})):e.className=t:"style"===r?"object"==typeof t&&null!==t?Object.entries(t).forEach((([t,n])=>{e.style[t]=n})):e.setAttribute("style",t):!1===t?e.removeAttribute(r):e.setAttribute(r,!0===t?"":t)}catch(e){console.error(`Error applying bind directive for ${r}:`,e)}};a(),(p[o]??=[]).push({update:a}),e.removeAttribute(t.name)}))}))},J=new Map,z={value:null};let Q={template:"<h1>404 - Page Not Found</h1>",mounted(){console.log("404 page mounted")}};const V=e=>e.split("/").map((e=>e.startsWith(":")?{type:"param",name:e.slice(1)}:{type:"static",value:e})),Z=e=>{for(const[t,n]of J.entries()){const r=V(t),o=e.split("/");if(r.length!==o.length)continue;const a={};if(r.every(((e,t)=>"static"===e.type?e.value===o[t]:"param"===e.type&&(a[e.name]=o[t],!0))))return{config:n,params:a}}return null},ee=e=>{const t=Z(e);t?(z.value=e,window.history.pushState(null,"",e),te(t.config,t.params)):(z.value="404",window.history.pushState(null,"",e),re())},te=(e,t)=>{if(e){let n=e.template;Object.entries(t).forEach((([e,t])=>{n=n.replace(new RegExp(`{${e}}`,"g"),t)})),f.innerHTML=n,_(),q(),O(),j(),B(),K(),R(),G(),k(),f.querySelectorAll("[\\i-show]").forEach((e=>{e instanceof HTMLElement&&X(e)})),e.mounted&&e.mounted.call({...S,params:t})}},ne=()=>{const e=window.location.pathname,t=Z(e);t?(z.value=e,te(t.config,t.params)):J.has("/")?(z.value="/",window.history.replaceState(null,"","/"),te(J.get("/"),{})):(z.value="404",re())},re=()=>{f.innerHTML=Q.template,_(),q(),O(),j(),B(),K(),R(),G(),k(),f.querySelectorAll("[\\i-show]").forEach((e=>{e instanceof HTMLElement&&X(e)})),Q.mounted&&Q.mounted.call(S)},oe={};return{mount:x((function(e){if(f=document.querySelector(e),!f)throw new Error(`Element with selector "${e}" not found.`);U("beforeCreate"),U("created"),a&&a.call(S),U("beforeMount"),s.forEach((e=>{"function"==typeof e&&e({createPlugin:v,state:S,bindings:p})})),ne(),window.addEventListener("popstate",(()=>{ne(),te()})),f.addEventListener("click",(e=>{if("A"===e.target.tagName&&e.target.href){const t=new URL(e.target.href);t.origin===window.location.origin&&(e.preventDefault(),ee(t.pathname))}})),te(),o&&o.call(S),U("mounted"),Object.keys(S).forEach((e=>M(e)))}),"Error mounting application"),onUpdated:e=>{if("function"==typeof e){const t=x(e,"Error in onUpdated callback");(m.__updated__??=[]).push({callback:t})}},createPlugin:v,emit:(e,t)=>{(b.get(e)??[]).forEach((e=>e(t)))},on:(e,t)=>(b.has(e)||b.set(e,[]),b.get(e).push(t),()=>{const n=b.get(e),r=n.indexOf(t);-1!==r&&n.splice(r,1)}),addLifecycleHook:W,applyMixin:I,component:w,render:e=>{const t=document.createElement("template");return t.innerHTML=e.trim(),t.content},route:(e,t)=>{J.set(e,t)},navigateTo:ee,NotFound:e=>{Q=e},power:e=>{Object.entries(e).forEach((([e,t])=>{oe[e]="function"==typeof t?(...n)=>{try{return t(...n.map((e=>"string"==typeof e&&e.includes("{")&&e.includes("}")?new Function("state","helpers",`with(state) { with(helpers) { return ${e.slice(1,-1)} } }`)(S,oe):e)))}catch(t){return console.error(`Error in helper function '${e}':`,t),""}}:t}))}}};export{createApp};const debounce=(e,t)=>{let n;return function(...r){clearTimeout(n),n=setTimeout((()=>{clearTimeout(n),e(...r)}),t)}},throttle=(e,t)=>{let n;return function(...r){n||(e(...r),n=!0,setTimeout((()=>n=!1),t))}};
1
+ const createApp=({data:e={},computed:t={},methods:r={},watch:n={},mounted:o,beforeMount:i,beforeUpdate:a,template:c,plugins:s=[],components:l={},mixins:u=[],directives:d={},setup:f}={})=>{let h;const p={},m={},b={},y={},E={...d},v=new Map,g=new Map,w=(e,t)=>{g.set(e,t)},A=(e,t)=>{E[e]=t},T=e=>new Proxy(e,{get:(e,t)=>"object"==typeof e[t]&&null!==e[t]?T(e[t]):e[t],set:(e,t,r)=>(e[t]!==r&&(e[t]=r,M(t)),!0)});Error;class x extends Error{constructor(e){super(e),this.name="StateError"}}const C=(e,t,r=Error)=>function(...n){try{return e.apply(this,n)}catch(e){throw new r(`${t}: ${e.message}`)}};i&&C(i,"Error in beforeMount hook",x).call($);new Set;const L=e=>{p[e]&&p[e].forEach(C((t=>{t.node?t.node.textContent=t.originalText.replace(/\{(.*?)\}/g,((e,t)=>{try{return new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)($,K)}catch(e){return console.error(`Error evaluating expression: ${t}`,e),""}})):t.element&&t.attrName?(t.element.setAttribute(t.attrName,$[e]),t.element.removeAttribute(`:${t.attrName}`)):t.update&&t.update()}),"Error updating bindings"))},M=e=>{a&&C(a,"Error in beforeUpdate hook").call($,e),L(e),N(e),b.__updated__?.forEach((e=>e.callback.call($)))},N=e=>{b[e]&&b[e].forEach((t=>{t.debounce?(clearTimeout(t.timeout),t.timeout=setTimeout((()=>t.callback.call($,$[e])),t.debounce)):t.throttle?(!t.lastCalled||Date.now()-t.lastCalled>t.throttle)&&(t.callback.call($,$[e]),t.lastCalled=Date.now()):t.callback.call($,$[e])}))};n&&Object.entries(n).forEach((([e,t])=>{b[e]=Array.isArray(t)?t.map((e=>({callback:e}))):["function"==typeof t?{callback:t}:{...t}]}));const $=T({...e,$refs:new Proxy(y,{get:(e,t)=>{const r=e[t];return r instanceof HTMLElement?new Proxy(r,{get:(e,t)=>"function"==typeof e[t]?e[t].bind(e):e[t]}):r},set:()=>{throw new Error("$refs is read-only")}})}),S={},O={};t&&Object.entries(t).forEach((([e,t])=>{S[e]=[],Object.defineProperty($,e,{get:()=>"function"==typeof t&&"AsyncFunction"===t.constructor.name?(O[e]||(m[e]=new Proxy($,{get:(t,r)=>(S[e].includes(r)||S[e].push(r),t[r])}),O[e]=t.call($).then((t=>(m[e]=t,delete O[e],L(e),t))).catch((t=>{console.error(`Error in async computed property "${e}":`,t)}))),O[e]):(m.hasOwnProperty(e)||(m[e]=new Proxy($,{get:(t,r)=>(S[e].includes(r)||S[e].push(r),t[r])}),m[e]=t.call($)),m[e]),enumerable:!0})}));const k=()=>{const e=new WeakMap,t={};h.querySelectorAll("[\\i-model]").forEach((r=>{const n=r.getAttribute("i-model");if(!n)return;const o=()=>{const e=(e=>e instanceof HTMLInputElement?"checkbox"===e.type?e.checked:"radio"===e.type?e.checked?e.value:void 0:e.value:e instanceof HTMLSelectElement?e.multiple?Array.from(e.selectedOptions).map((e=>e.value)):e.value:e instanceof HTMLTextAreaElement?e.value:void 0)(r);void 0!==e&&($[n]=e,M(n))},i=()=>{((e,t)=>{e instanceof HTMLInputElement?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t:e.value=t:e instanceof HTMLSelectElement?e.multiple?Array.from(e.options).forEach((e=>{e.selected=t.includes(e.value)})):e.value=t:e instanceof HTMLTextAreaElement&&(e.value=t)})(r,$[n])};if(e.has(r)){e.get(r).forEach((([e,t])=>{r.removeEventListener(e,t)}))}const a=[];if(r instanceof HTMLSelectElement||"checkbox"===r.type||"radio"===r.type){const e=()=>o();r.addEventListener("change",e),a.push(["change",e])}else{const e=()=>o();r.addEventListener("input",e),a.push(["input",e])}e.set(r,a),r instanceof HTMLInputElement&&"radio"===r.type&&(t[n]||(t[n]=[]),t[n].push(r),r.name=`radio-group-${n}`),(p[n]??=[]).push({element:r,updateModel:i}),i(),r.removeAttribute("i-model")})),Object.entries(t).forEach((([e,t])=>{(p[e]??=[]).push({updateModel:()=>{t.forEach((t=>{t.checked=t.value===$[e]}))}})}))},_=e=>{try{return new Function("state","helpers",`with(state) { with(helpers) { return ${e} } }`)($,K)}catch(t){return console.error(`Error evaluating expression: ${e}`,t),""}},H=e=>{var t;e.nodeType===Node.ELEMENT_NODE?(e=(e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e.tagName.toLowerCase();if(g.has(t)){const r=g.get(t)(Array.from(e.attributes).reduce(((e,t)=>({...e,[t.name]:t.value})),{})),n=document.createElement("div");n.innerHTML=r;const o=n.firstElementChild;if(o)return e.parentNode?.replaceChild(o,e),o}}return e})(e))instanceof HTMLElement&&(e.hasAttribute("i-data")&&J(e),t=e,Array.from(t.attributes).forEach((e=>{const r=e.name.startsWith("i-")?e.name.slice(1):null;r&&E[r]&&(E[r](t,e.value,$),t.removeAttribute(e.name))})),e.hasAttribute("i-if")&&(e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-if");if(!t)return;const r=[];let n=null,o=e.nextElementSibling;for(;o&&(o.hasAttribute("i-else-if")||o.hasAttribute("i-else"));){if(o.hasAttribute("i-else-if"))r.push(o);else if(o.hasAttribute("i-else")){n=o;break}o=o.nextElementSibling}const i=e.parentNode,a=document.createComment("i-if placeholder");i?.insertBefore(a,e);const c=()=>{try{if(_(t))e.isConnected||i?.insertBefore(e,a.nextSibling),r.forEach((e=>{e.isConnected&&i?.removeChild(e)})),n?.isConnected&&i?.removeChild(n);else{let t=!1;e.isConnected&&i?.removeChild(e);for(const e of r){const r=e.getAttribute("i-else-if");if(_(r)){e.isConnected||i?.insertBefore(e,a.nextSibling),t=!0;break}e.isConnected&&i?.removeChild(e)}!t&&n?n.isConnected||i?.insertBefore(n,a.nextSibling):n?.isConnected&&i?.removeChild(n)}}catch(e){console.error("Error evaluating i-if directive:",e)}};c(),(p[t]??=[]).push({element:e,update:c}),e.removeAttribute("i-if"),r.forEach((e=>e.removeAttribute("i-else-if"))),n?.removeAttribute("i-else")})(e),e.hasAttribute("i-for")&&Y(e),e.hasAttribute("i-show")&&X(e),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE&&j(e)})),Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("@")||t.name.startsWith("i-on:")){const r=t.name.startsWith("@")?t.name.slice(1):t.name.slice(5);z(e,r,t.value),e.removeAttribute(t.name)}else t.value.includes("{")&&t.value.includes("}")&&processAttribute(e,t)})),Array.from(e.childNodes).forEach(H)):e.nodeType===Node.TEXT_NODE&&j(e)},j=e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const r=t.split(/(\{.*?\})/),n=document.createDocumentFragment();r.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),r=document.createTextNode("");n.appendChild(r);const o=()=>{r.textContent=_(t)};o();F(t).forEach((e=>{(p[e]??=[]).push({update:o})}))}else n.appendChild(document.createTextNode(e))})),e.parentNode?.replaceChild(n,e)}},F=e=>{const t=e.match(/\b\w+\b/g);return t?t.filter((e=>e in $)):[]};Object.entries(l).forEach((([e,t])=>{w(e,t)}));const D=(e,t)=>{(v.get(e)??[]).forEach((e=>e(t)))},q=(e,t)=>(v.has(e)||v.set(e,[]),v.get(e).push(t),()=>{const r=v.get(e),n=r.indexOf(t);-1!==n&&r.splice(n,1)}),P={beforeCreate:[],created:[],beforeMount:[],mounted:[],beforeUpdate:[],updated:[],beforeUnmount:[],unmounted:[]},W=(e,t)=>{P[e]&&P[e].push(t)},U=e=>{P[e]?.forEach((e=>e.call($)))},B=e=>{e.data&&Object.assign($,e.data()),e.methods&&Object.assign(r,e.methods),e.computed&&Object.assign(t,e.computed),e.watch&&Object.entries(e.watch).forEach((([e,t])=>{(n[e]??=[]).push(t)})),e.mounted&&W("mounted",e.mounted)};u.forEach(B);window.addEventListener("error",(e=>{console.error("Global error:",e)}));const I={beforeEnter:e=>{e.style.opacity="0",e.style.transform="translateY(-20px)",e.style.display=""},enter:(e,t)=>{const r=1e3*parseFloat(getComputedStyle(e).transitionDuration);requestAnimationFrame((()=>{e.style.opacity="1",e.style.transform="translateY(0)",setTimeout(t,r)}))},afterEnter:e=>{e.style.opacity="",e.style.transform=""},enterCancelled:e=>{e.style.opacity="",e.style.transform=""},beforeLeave:e=>{e.style.opacity="1",e.style.transform="translateY(0)"},leave:(e,t)=>{const r=1e3*parseFloat(getComputedStyle(e).transitionDuration);requestAnimationFrame((()=>{e.style.opacity="0",e.style.transform="translateY(-20px)",setTimeout(t,r)}))},afterLeave:e=>{e.style.display="none",e.style.opacity="",e.style.transform=""},leaveCancelled:e=>{e.style.opacity="",e.style.transform=""}},X=e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-show");if(!t)return;let r=null;const n=async()=>{try{const n=new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)($,K);e._transitionShow&&e._transitionHide?(r&&(await r,r=null),r=n?e._transitionShow():e._transitionHide(),await r):e.style.display=n?"":"none"}catch(e){console.error("Error evaluating i-show directive:",e)}};n(),(p[t]??=[]).push({element:e,update:n}),e.removeAttribute("i-show")},Y=e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-for");if(!t)return;const r=t.match(/(\(?\s*(\w+)(?:\s*,\s*(\w+))?\s*\)?)\s+(?:in|of)\s+(.+)/);if(!r)return void console.error("Invalid i-for expression:",t);const[,,n,o,i]=r,a=e.getAttribute("i-key")||null,c=e.parentNode,s=document.createComment(`i-for: ${t}`);c?.insertBefore(s,e);const l=e.cloneNode(!0);l.removeAttribute("i-for"),l.removeAttribute("i-key");const u=()=>{try{const e=new Function("state","helpers",`with(state) { with(helpers) { return ${i} } }`)($,K),t=document.createDocumentFragment(),r=new Map;let u=s.nextSibling;for(;u&&u.hasAttribute&&u.hasAttribute("data-i-for-id");)r.set(u.getAttribute("data-i-for-id"),u),u=u.nextSibling;for(e.forEach(((e,c)=>{const s=a?e[a]:JSON.stringify(e),u=`${i}-${s}`;let f=r.get(u);f?r.delete(u):(f=l.cloneNode(!0),f.setAttribute("data-i-for-id",u));const h=((e,t)=>{const r={...$};if(n.includes(",")){const[t,o]=n.split(",").map((e=>e.trim()));r[t]=Object.keys(e)[0],r[o]=Object.values(e)[0]}else r[n]=e;return o&&(r[o]=t),r})(e,c);d(f,h),t.appendChild(f)})),r.forEach((e=>e.remove()));s.nextSibling&&s.nextSibling.hasAttribute&&s.nextSibling.hasAttribute("data-i-for-id");)c.removeChild(s.nextSibling);c.insertBefore(t,s.nextSibling)}catch(e){console.error("Error evaluating i-for directive:",e)}},d=(e,t)=>{e.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((r=>{if(r.value.includes("{")&&r.value.includes("}")){const n=r.value.replace(/\{(.*?)\}/g,((e,r)=>new Function("state",`with(state) { return ${r} }`)(t)));e.setAttribute(r.name,n)}}))}));e.childNodes.forEach((e=>{e.nodeType===Node.TEXT_NODE&&(e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const r=t.split(/(\{.*?\})/),n=document.createDocumentFragment();r.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),r=document.createTextNode("");n.appendChild(r),r.textContent=_(t)}else n.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(n,e)}})(e)}))};u(),(p[i]??=[]).push({update:u}),e.remove()},K={},R={use:e=>({_value:e,get value(){return this._value},set value(e){this._value!==e&&(this._value=e,M("value"))}}),watch:(e,t,r={})=>{"function"==typeof e?b[e.toString()]=[{callback:t,...r}]:e&&"object"==typeof e&&"_value"in e&&(b[e._value]=[{callback:t,...r}])},computed:e=>({_cached:void 0,_dirty:!0,get value(){return this._dirty&&(this._cached=e(),this._dirty=!1),this._cached}}),onMounted:e=>{W("mounted",e)},onBeforeMount:e=>{W("beforeMount",e)},onUpdated:e=>{W("updated",e)},onBeforeUpdate:e=>{W("beforeUpdate",e)},emit:D,on:q,useState:e=>{const t=R.use(e);return[t,e=>{t.value="function"==typeof e?e(t.value):e}]},effect:(e,t=[])=>{const r=()=>{try{e()}catch(e){console.error("Error in effect:",e)}};t.forEach((e=>{e&&"object"==typeof e&&"_value"in e&&R.watch(e,r)})),r()},useRef:()=>({current:null,set value(e){this.current=e},get value(){return this.current}})};let G={};if(f)try{G=f(R)||{},Object.entries(G).forEach((([e,t])=>{t&&"object"==typeof t&&"_value"in t?Object.defineProperty($,e,{get:()=>t.value,set:e=>{t.value=e},enumerable:!0}):$[e]=t}))}catch(e){console.error("Error in setup function:",e)}const J=e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-data");if(t){try{const e=new Function("return "+t)();Object.assign($,T(e))}catch(e){console.error("Error evaluating i-data directive:",e)}e.removeAttribute("i-data")}},z=(e,t,r)=>{const[n,...o]=t.split("."),i={capture:o.includes("capture"),once:o.includes("once"),passive:o.includes("passive")};e.addEventListener(n,(e=>{try{if(r.includes("++")||r.includes("--")){const e=r.replace(/[\+\-]+/g,"").trim(),t=r.includes("++");return $[e]=$[e]||0,$[e]=t?$[e]+1:$[e]-1,void M(e)}new Function("state","event",`with(state) { ${r} }`).call($,$,e),M()}catch(e){console.error(`Error in event handler "${r}":`,e)}}),i)};return{mount:C((function(e){if(h=document.querySelector(e),!h)throw new Error(`Element with selector "${e}" not found.`);var t;U("beforeCreate"),U("created"),i&&i.call($),U("beforeMount"),s.forEach((e=>{"function"==typeof e&&e({createPlugin:A,state:$,bindings:p})})),(()=>{const e=h.querySelector("template"),t=e?e.innerHTML.trim():"string"==typeof c?c.trim():h.innerHTML.trim();if(!t)throw new Error("No template provided and container is empty");h.innerHTML="",h.innerHTML=t,Array.from(h.childNodes).forEach(H)})(),h.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("@")){const[n,...o]=t.name.slice(1).split("."),i=t.value.trim(),a={capture:o.includes("capture"),once:o.includes("once"),passive:o.includes("passive")},c=t=>{try{if(o.includes("stop")&&t.stopPropagation(),o.includes("prevent")&&t.preventDefault(),o.includes("self")&&t.target!==e)return;if(t instanceof KeyboardEvent){const e=o.filter((e=>["ctrl","alt","shift","meta","Tab","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e))),r=e.every((e=>t[`${e}Key`]));if(e.length>0&&!r)return;const n=o.find((e=>/^[0-9]+$/.test(e)));if(n&&t.keyCode!==parseInt(n))return;const i=o.find((t=>!e.includes(t)&&!/^[0-9]+$/.test(t)));if(i&&t.key.toLowerCase()!==i.toLowerCase())return}if(t instanceof MouseEvent){const e={left:0,middle:1,right:2},r=o.find((t=>Object.keys(e).includes(t)));if(r&&t.button!==e[r])return}r&&r[i]?r[i].call($,t):new Function("state","event",`with(state) { ${i} }`).call($,$,t),M()}catch(e){console.error(`Error executing event handler: ${i}`,e)}};let s=c;if(o.includes("debounce")){const e=parseInt(o[o.indexOf("debounce")+1])||300;s=debounce(c,e)}if(o.includes("throttle")){const e=parseInt(o[o.indexOf("throttle")+1])||300;s=throttle(c,e)}e.addEventListener(n,s,a),e.removeAttribute(t.name)}}))})),h.querySelectorAll("[\\i-ref]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-ref");t&&(y[t]=e,e.removeAttribute("i-ref"))})),k(),h.querySelectorAll("[\\i-html]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-html");if(!t)return;const r=()=>{try{let r=new Function("state","helpers",`with(state) { with(helpers) { return ${t} } }`)($,K);r=r.replace(/\{(.*?)\}/g,((e,t)=>new Function("state",`with(state) { return ${t} }`)($))),e.innerHTML=r,e.querySelectorAll("*").forEach((e=>{e instanceof HTMLElement&&n(e)}))}catch(e){console.error("Error applying i-html directive:",e)}},n=e=>{Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE&&o(e)})),Array.from(e.attributes).forEach((t=>{t.value.includes("{")&&t.value.includes("}")&&i(e,t)}))},o=e=>{const t=e.textContent||"";if(t.includes("{")&&t.includes("}")){const r=t.split(/(\{.*?\})/),n=document.createDocumentFragment();r.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1).trim(),r=document.createTextNode("");n.appendChild(r);const o=()=>{r.textContent=_(t)};o(),Object.keys($).forEach((e=>{(p[e]??=[]).push({update:o})}))}else n.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(n,e)}},i=(e,t)=>{const r=t.value,n=()=>{const n=r.replace(/\{(.*?)\}/g,((e,t)=>new Function("state",`with(state) { return ${t} }`)($)));e.setAttribute(t.name,n)};n(),Object.keys($).forEach((e=>{(p[e]??=[]).push({update:n})}))};r(),Object.keys($).forEach((e=>{(p[e]??=[]).push({update:r})})),e.removeAttribute("i-html")})),h.querySelectorAll("[i-transition]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("i-transition");if(!t)return;const[r,n,o]=t.split(",").map((e=>e.trim())),i=n?`${n}ms`:"300ms",a=o||"ease";e.style.transition=`opacity ${i} ${a}, transform ${i} ${a}`;const c=(t,r)=>new Promise((n=>{let o=!1;return t.before(e),t.during(e,(()=>{o||(t.after(e),r&&r(),n())})),()=>{o=!0,t.cancelled(e),n()}}));e._transitionShow=async t=>{e.style.display="",await c({before:I.beforeEnter,during:I.enter,after:I.afterEnter,cancelled:I.enterCancelled},t)},e._transitionHide=async e=>{await c({before:I.beforeLeave,during:I.leave,after:I.afterLeave,cancelled:I.leaveCancelled},e)},e.style.display="none",e.removeAttribute("i-transition")})),h.querySelectorAll("*").forEach((e=>{e instanceof HTMLElement&&Array.from(e.attributes).forEach((t=>{const r=t.name.match(/^(?:i-bind:|:)(.+)$/);if(!r)return;const[,n]=r,o=t.value,i=()=>{try{let t=new Function("state","helpers",`with(state) { with(helpers) { return ${o} } }`)($,K);"class"===n?"object"==typeof t&&null!==t?Object.entries(t).forEach((([t,r])=>{e.classList.toggle(t,!!r)})):e.className=t:"style"===n?"object"==typeof t&&null!==t?Object.entries(t).forEach((([t,r])=>{e.style[t]=r})):e.setAttribute("style",t):!1===t?e.removeAttribute(n):e.setAttribute(n,!0===t?"":t)}catch(e){console.error(`Error applying bind directive for ${n}:`,e)}};i(),(p[o]??=[]).push({update:i}),e.removeAttribute(t.name)}))})),Object.entries(S).forEach((([e,r])=>{r.includes(t)&&(delete m[e],L(e))})),h.querySelectorAll("[\\i-show]").forEach((e=>{e instanceof HTMLElement&&X(e)})),o&&o.call($),U("mounted"),Object.keys($).forEach((e=>L(e)))}),"Error mounting application"),onUpdated:e=>{if("function"==typeof e){const t=C(e,"Error in onUpdated callback");(b.__updated__??=[]).push({callback:t})}},createPlugin:A,emit:D,on:q,addLifecycleHook:W,applyMixin:B,component:w,render:e=>{const t=document.createElement("template");return t.innerHTML=e.trim(),t.content},power:e=>{Object.entries(e).forEach((([e,t])=>{K[e]="function"==typeof t?(...r)=>{try{return t(...r.map((e=>"string"==typeof e&&e.includes("{")&&e.includes("}")?new Function("state","helpers",`with(state) { with(helpers) { return ${e.slice(1,-1)} } }`)($,K):e)))}catch(t){return console.error(`Error in helper function '${e}':`,t),""}}:t}))}}};export const debounce=(e,t)=>{let r;return function(...n){clearTimeout(r),r=setTimeout((()=>{clearTimeout(r),e(...n)}),t)}};export const throttle=(e,t)=>{let r;return function(...n){r||(e(...n),r=!0,setTimeout((()=>r=!1),t))}};export{createApp};
package/dist/router.js ADDED
@@ -0,0 +1,40 @@
1
+ import { createApp } from "./olova.js";
2
+ class Router {
3
+ constructor() {
4
+ (this.routes = new Map()), (this.currentApp = null), this.init();
5
+ }
6
+ init() {
7
+ window.addEventListener("popstate", () => this.handleRoute()),
8
+ document.addEventListener("click", (t) => {
9
+ if (t.target.matches("a")) {
10
+ t.preventDefault();
11
+ const e = t.target.getAttribute("href");
12
+ this.navigate(e);
13
+ }
14
+ }),
15
+ window.addEventListener("load", () => {
16
+ this.handleRoute();
17
+ });
18
+ }
19
+ add(t, e) {
20
+ return this.routes.set(t, e), this;
21
+ }
22
+ navigate(t) {
23
+ window.history.pushState(null, "", t), this.handleRoute();
24
+ }
25
+ handleRoute() {
26
+ const t = window.location.pathname,
27
+ e = this.routes.get(t),
28
+ n = document.querySelector("[i-view]");
29
+ if (n)
30
+ if (e) {
31
+ this.currentApp && (n.innerHTML = "");
32
+ const t = document.createElement("div");
33
+ (t.id = "route-container"),
34
+ n.appendChild(t),
35
+ (this.currentApp = createApp({ ...e })),
36
+ this.currentApp.mount("#route-container");
37
+ } else n.innerHTML = "<h1>404 Not Found</h1>";
38
+ }
39
+ }
40
+ export const router = new Router();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olova",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "A lightweight JavaScript framework for building reactive applications.",
5
5
  "main": "dist/olova.js",
6
6
  "keywords": [