eleva 1.0.0-rc.13 → 1.0.0-rc.14

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 (44) hide show
  1. package/README.md +20 -75
  2. package/dist/eleva-plugins.cjs.js +4 -653
  3. package/dist/eleva-plugins.cjs.js.map +1 -1
  4. package/dist/eleva-plugins.esm.js +5 -653
  5. package/dist/eleva-plugins.esm.js.map +1 -1
  6. package/dist/eleva-plugins.umd.js +4 -653
  7. package/dist/eleva-plugins.umd.js.map +1 -1
  8. package/dist/eleva-plugins.umd.min.js +1 -1
  9. package/dist/eleva-plugins.umd.min.js.map +1 -1
  10. package/dist/eleva.cjs.js +52 -110
  11. package/dist/eleva.cjs.js.map +1 -1
  12. package/dist/eleva.d.ts +47 -109
  13. package/dist/eleva.esm.js +52 -110
  14. package/dist/eleva.esm.js.map +1 -1
  15. package/dist/eleva.umd.js +52 -110
  16. package/dist/eleva.umd.js.map +1 -1
  17. package/dist/eleva.umd.min.js +1 -1
  18. package/dist/eleva.umd.min.js.map +1 -1
  19. package/dist/plugins/attr.umd.js +2 -2
  20. package/dist/plugins/attr.umd.js.map +1 -1
  21. package/dist/plugins/attr.umd.min.js +1 -1
  22. package/dist/plugins/attr.umd.min.js.map +1 -1
  23. package/dist/plugins/router.umd.js +1 -1
  24. package/dist/plugins/router.umd.js.map +1 -1
  25. package/dist/plugins/router.umd.min.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/core/Eleva.js +21 -15
  28. package/src/modules/TemplateEngine.js +36 -104
  29. package/src/plugins/Attr.js +2 -2
  30. package/src/plugins/Router.js +1 -1
  31. package/src/plugins/index.js +1 -1
  32. package/types/core/Eleva.d.ts +9 -5
  33. package/types/core/Eleva.d.ts.map +1 -1
  34. package/types/modules/TemplateEngine.d.ts +38 -104
  35. package/types/modules/TemplateEngine.d.ts.map +1 -1
  36. package/types/plugins/Router.d.ts +1 -1
  37. package/types/plugins/index.d.ts +0 -1
  38. package/dist/plugins/props.umd.js +0 -660
  39. package/dist/plugins/props.umd.js.map +0 -1
  40. package/dist/plugins/props.umd.min.js +0 -2
  41. package/dist/plugins/props.umd.min.js.map +0 -1
  42. package/src/plugins/Props.js +0 -602
  43. package/types/plugins/Props.d.ts +0 -49
  44. package/types/plugins/Props.d.ts.map +0 -1
@@ -1,2 +1,2 @@
1
- var t,e;t=this,e=function(t){"use strict";let e=/-([a-z])/g,r={handle(t,e,r={}){let i=Error(`[ElevaRouter] ${e}: ${t.message}`);throw i.originalError=t,i.context=e,i.details=r,i},warn(t,e={}){},log(t,e,r={}){}};class i{_validateOptions(){["hash","query","history"].includes(this.options.mode)||this.errorHandler.handle(Error(`Invalid routing mode: ${this.options.mode}. Must be "hash", "query", or "history".`),"Configuration validation failed")}_processRoutes(t){let e=[];for(let r of t)try{e.push({...r,segments:this._parsePathIntoSegments(r.path)})}catch(t){this.errorHandler.warn(`Invalid path in route definition "${r.path||"undefined"}": ${t.message}`,{route:r,error:t})}return e}_parsePathIntoSegments(t){t&&"string"==typeof t||this.errorHandler.handle(Error("Route path must be a non-empty string"),"Path parsing failed",{path:t});let e=t.replace(/\/+/g,"/").replace(/\/$/,"")||"/";return"/"===e?[]:e.split("/").filter(Boolean).map(e=>{if(e.startsWith(":")){let r=e.substring(1);return r||this.errorHandler.handle(Error(`Invalid parameter segment: ${e}`),"Path parsing failed",{segment:e,path:t}),{type:"param",name:r}}return{type:"static",value:e}})}_findViewElement(t){let e=this.options.viewSelector;return t.querySelector(`#${e}`)||t.querySelector(`.${e}`)||t.querySelector(`[data-${e}]`)||t.querySelector(e)||t}async start(){if(this.isStarted)return this.errorHandler.warn("Router is already started"),this;if("u"<typeof window)return this.errorHandler.warn("Router start skipped: `window` object not available (SSR environment)"),this;if("u">typeof document&&!document.querySelector(this.options.mount))return this.errorHandler.warn(`Mount element "${this.options.mount}" was not found in the DOM. The router will not start.`,{mountSelector:this.options.mount}),this;let t=()=>this._handleRouteChange();return"hash"===this.options.mode?(window.addEventListener("hashchange",t),this.eventListeners.push(()=>window.removeEventListener("hashchange",t))):(window.addEventListener("popstate",t),this.eventListeners.push(()=>window.removeEventListener("popstate",t))),this.isStarted=!0,await this._handleRouteChange(!1),this.isReady.value=!0,await this.emitter.emit("router:ready",this),this}async destroy(){if(this.isStarted){for(let t of this.plugins.values())if("function"==typeof t.destroy)try{await t.destroy(this)}catch(e){this.errorHandler.log(`Plugin ${t.name} destroy failed`,e)}this.eventListeners.forEach(t=>t()),this.eventListeners=[],this.currentLayout.value&&await this.currentLayout.value.unmount(),this.isStarted=!1,this.isReady.value=!1}}async stop(){return this.destroy()}async navigate(t,e={}){try{let r="string"==typeof t?{path:t,params:e}:t,i=this._buildPath(r.path,r.params||{}),n=r.query||{};if(Object.keys(n).length>0){let t=new URLSearchParams(n).toString();t&&(i+=`?${t}`)}if(this._isSameRoute(i,r.params,n))return!0;let a=await this._proceedWithNavigation(i);if(a){let t=++this._navigationId;this._isNavigating=!0;let e=r.state||{},n=r.replace||!1;if("hash"===this.options.mode)if(n){let t=`${window.location.pathname}${window.location.search}#${i}`;window.history.replaceState(e,"",t)}else window.location.hash=i;else{let t="query"===this.options.mode?this._buildQueryUrl(i):i;history[n?"replaceState":"pushState"](e,"",t)}queueMicrotask(()=>{this._navigationId===t&&(this._isNavigating=!1)})}return a}catch(t){return this.errorHandler.log("Navigation failed",t),await this.emitter.emit("router:onError",t),!1}}_buildQueryUrl(t){let e=new URLSearchParams(window.location.search);return e.set(this.options.queryParam,t.split("?")[0]),`${window.location.pathname}?${e.toString()}`}_isSameRoute(t,e,r){let i=this.currentRoute.value;if(!i)return!1;let[n,a]=t.split("?"),o=r||this._parseQuery(a||"");return i.path===n&&JSON.stringify(i.params)===JSON.stringify(e||{})&&JSON.stringify(i.query)===JSON.stringify(o)}_buildPath(t,e){let r=t;for(let[t,i]of Object.entries(e)){let e=encodeURIComponent(String(i));r=r.replace(RegExp(`:${t}\\b`,"g"),e)}return r}async _handleRouteChange(t=!0){if(!this._isNavigating)try{let e=this.currentRoute.value,r=this._getCurrentLocation();!await this._proceedWithNavigation(r.fullUrl,t)&&e&&this.navigate({path:e.path,query:e.query,replace:!0})}catch(t){this.errorHandler.log("Route change handling failed",t,{currentUrl:"u">typeof window?window.location.href:""}),await this.emitter.emit("router:onError",t)}}async _proceedWithNavigation(t,e=!1){let r=this.currentRoute.value,[i,n]=(t||"/").split("?"),a={path:i.startsWith("/")?i:`/${i}`,query:this._parseQuery(n),fullUrl:t},o=this._matchRoute(a.path);if(!o){let t=this.routes.find(t=>"*"===t.path);if(!t)return await this.emitter.emit("router:onError",Error(`Route not found: ${a.path}`),a,r),!1;o={route:t,params:{pathMatch:decodeURIComponent(a.path.substring(1))}}}let s={...a,params:o.params,meta:o.route.meta||{},name:o.route.name,matched:o.route};try{if(!await this._runGuards(s,r,o.route))return!1;r&&"u">typeof window&&this._scrollPositions.set(r.path,{x:window.scrollX||window.pageXOffset||0,y:window.scrollY||window.pageYOffset||0});let t={to:s,from:r,route:o.route,layoutComponent:null,pageComponent:null,cancelled:!1,redirectTo:null};if(await this.emitter.emit("router:beforeResolve",t),t.cancelled)return!1;if(t.redirectTo)return this.navigate(t.redirectTo),!1;let{layoutComponent:i,pageComponent:n}=await this._resolveComponents(o.route);if(t.layoutComponent=i,t.pageComponent=n,await this.emitter.emit("router:afterResolve",t),r){let t=o.route.layout||this.options.globalLayout,e=r.matched.layout||this.options.globalLayout,i=async t=>{if(t)try{await t.unmount()}catch(e){this.errorHandler.warn("Error during component unmount",{error:e,instance:t})}};t!==e?(await i(this.currentLayout.value),this.currentLayout.value=null):(await i(this.currentView.value),this.currentView.value=null),r.matched.afterLeave&&await r.matched.afterLeave(s,r),await this.emitter.emit("router:afterLeave",s,r)}this.previousRoute.value=r,this.currentRoute.value=s,this.currentParams.value=s.params||{},this.currentQuery.value=s.query||{};let a={to:s,from:r,layoutComponent:i,pageComponent:n};await this.emitter.emit("router:beforeRender",a),await this._render(i,n,s),await this.emitter.emit("router:afterRender",a);let l={to:s,from:r,savedPosition:e&&this._scrollPositions.get(s.path)||null};return await this.emitter.emit("router:scroll",l),o.route.afterEnter&&await o.route.afterEnter(s,r),await this.emitter.emit("router:afterEnter",s,r),await this.emitter.emit("router:afterEach",s,r),!0}catch(t){return this.errorHandler.log("Error during navigation",t,{to:s,from:r}),await this.emitter.emit("router:onError",t,s,r),!1}}async _runGuards(t,e,r){let i={to:t,from:e,cancelled:!1,redirectTo:null};if(await this.emitter.emit("router:beforeEach",i),i.cancelled)return!1;if(i.redirectTo)return this.navigate(i.redirectTo),!1;for(let i of[...this._beforeEachGuards,...e&&e.matched.beforeLeave?[e.matched.beforeLeave]:[],...r.beforeEnter?[r.beforeEnter]:[]]){let r=await i(t,e);if(!1===r)return!1;if("string"==typeof r||"object"==typeof r)return this.navigate(r),!1}return!0}_resolveStringComponent(t){let e=this.eleva._components.get(t);return e||this.errorHandler.handle(Error(`Component "${t}" not registered.`),"Component resolution failed",{componentName:t,availableComponents:Array.from(this.eleva._components.keys())}),e}async _resolveFunctionComponent(t){try{let e=t.toString(),r=e.includes("import(")||e.startsWith("() =>"),i=await t();return r&&i.default||i}catch(e){this.errorHandler.handle(Error(`Failed to load async component: ${e.message}`),"Component resolution failed",{function:t.toString(),error:e})}}_validateComponentDefinition(t){return t&&"object"==typeof t||this.errorHandler.handle(Error(`Invalid component definition: ${typeof t}`),"Component validation failed",{definition:t}),"function"!=typeof t.template&&"string"!=typeof t.template&&this.errorHandler.handle(Error("Component missing template property"),"Component validation failed",{definition:t}),t}async _resolveComponent(t){return null==t?null:"string"==typeof t?this._resolveStringComponent(t):"function"==typeof t?await this._resolveFunctionComponent(t):t&&"object"==typeof t?this._validateComponentDefinition(t):void this.errorHandler.handle(Error(`Invalid component definition: ${typeof t}`),"Component resolution failed",{definition:t})}async _resolveComponents(t){let e=t.layout||this.options.globalLayout;try{let[r,i]=await Promise.all([this._resolveComponent(e),this._resolveComponent(t.component)]);return i||this.errorHandler.handle(Error(`Page component is null or undefined for route: ${t.path}`),"Component resolution failed",{route:t.path}),{layoutComponent:r,pageComponent:i}}catch(e){throw this.errorHandler.log(`Error resolving components for route ${t.path}`,e,{route:t.path}),e}}async _render(t,e){let r=document.querySelector(this.options.mount);if(r||this.errorHandler.handle(Error(`Mount element "${this.options.mount}" not found.`),{mountSelector:this.options.mount}),t){let i=await this.eleva.mount(r,this._wrapComponentWithChildren(t));this.currentLayout.value=i;let n=this._findViewElement(i.container),a=await this.eleva.mount(n,this._wrapComponentWithChildren(e));this.currentView.value=a}else{let t=await this.eleva.mount(r,this._wrapComponentWithChildren(e));this.currentView.value=t,this.currentLayout.value=null}}_createRouteGetter(t,e){return()=>this.currentRoute.value?.[t]??e}_wrapComponent(t){let e=t.setup,r=this;return{...t,setup:async t=>(t.router={navigate:r.navigate.bind(r),current:r.currentRoute,previous:r.previousRoute,get params(){return r._createRouteGetter("params",{})()},get query(){return r._createRouteGetter("query",{})()},get path(){return r._createRouteGetter("path","/")()},get fullUrl(){return r._createRouteGetter("fullUrl",window.location.href)()},get meta(){return r._createRouteGetter("meta",{})()}},e?await e(t):{})}}_wrapComponentWithChildren(t){if("string"==typeof t||!t||"object"!=typeof t)return t;let e=this._wrapComponent(t);if(e.children&&"object"==typeof e.children){let t={};for(let[r,i]of Object.entries(e.children))t[r]=this._wrapComponentWithChildren(i);e.children=t}return e}_getCurrentLocation(){let t,e,r;if("u"<typeof window)return{path:"/",query:{},fullUrl:""};switch(this.options.mode){case"hash":r=window.location.hash.slice(1)||"/",[t,e]=r.split("?");break;case"query":t=new URLSearchParams(window.location.search).get(this.options.queryParam)||"/",e=window.location.search.slice(1),r=t;break;default:t=window.location.pathname||"/",e=window.location.search.slice(1),r=`${t}${e?"?"+e:""}`}return{path:t.startsWith("/")?t:`/${t}`,query:this._parseQuery(e),fullUrl:r}}_parseQuery(t){let e={};return t&&new URLSearchParams(t).forEach((t,r)=>{e[r]=t}),e}_matchRoute(t){let e=t.split("/").filter(Boolean);for(let t of this.routes){if("/"===t.path){if(0===e.length)return{route:t,params:{}};continue}if(t.segments.length!==e.length)continue;let r={},i=!0;for(let n=0;n<t.segments.length;n++){let a=t.segments[n],o=e[n];if("param"===a.type)r[a.name]=decodeURIComponent(o);else if(a.value!==o){i=!1;break}}if(i)return{route:t,params:r}}return null}addRoute(t,e=null){if(!t||!t.path)return this.errorHandler.warn("Invalid route definition: missing path",{route:t}),()=>{};if(this.hasRoute(t.path))return this.errorHandler.warn(`Route "${t.path}" already exists`,{route:t}),()=>{};let r={...t,segments:this._parsePathIntoSegments(t.path)},i=this.routes.findIndex(t=>"*"===t.path);return -1!==i?this.routes.splice(i,0,r):this.routes.push(r),this.emitter.emit("router:routeAdded",r),()=>this.removeRoute(t.path)}removeRoute(t){let e=this.routes.findIndex(e=>e.path===t);if(-1===e)return!1;let[r]=this.routes.splice(e,1);return this.emitter.emit("router:routeRemoved",r),!0}hasRoute(t){return this.routes.some(e=>e.path===t)}getRoutes(){return[...this.routes]}getRoute(t){return this.routes.find(e=>e.path===t)}onBeforeEach(t){return this._beforeEachGuards.push(t),()=>{let e=this._beforeEachGuards.indexOf(t);e>-1&&this._beforeEachGuards.splice(e,1)}}onAfterEnter(t){return this.emitter.on("router:afterEnter",t)}onAfterLeave(t){return this.emitter.on("router:afterLeave",t)}onAfterEach(t){return this.emitter.on("router:afterEach",t)}onError(t){return this.emitter.on("router:onError",t)}use(t,e={}){("function"!=typeof t.install&&this.errorHandler.handle(Error("Plugin must have an install method"),"Plugin registration failed",{plugin:t}),this.plugins.has(t.name))?this.errorHandler.warn(`Plugin "${t.name}" is already registered`,{existingPlugin:this.plugins.get(t.name)}):(this.plugins.set(t.name,t),t.install(this,e))}getPlugins(){return Array.from(this.plugins.values())}getPlugin(t){return this.plugins.get(t)}removePlugin(t){let e=this.plugins.get(t);if(!e)return!1;if("function"==typeof e.destroy)try{e.destroy(this)}catch(e){this.errorHandler.log(`Plugin ${t} destroy failed`,e)}return this.plugins.delete(t)}setErrorHandler(t){t&&"function"==typeof t.handle&&"function"==typeof t.warn&&"function"==typeof t.log&&(this.errorHandler=t)}constructor(t,e={}){this.eleva=t,this.options={mode:"hash",queryParam:"view",viewSelector:"root",...e},this.routes=this._processRoutes(e.routes||[]),this.emitter=this.eleva.emitter,this.isStarted=!1,this._isNavigating=!1,this._navigationId=0,this.eventListeners=[],this.currentRoute=new this.eleva.signal(null),this.previousRoute=new this.eleva.signal(null),this.currentParams=new this.eleva.signal({}),this.currentQuery=new this.eleva.signal({}),this.currentLayout=new this.eleva.signal(null),this.currentView=new this.eleva.signal(null),this.isReady=new this.eleva.signal(!1),this.plugins=new Map,this._beforeEachGuards=[],e.onBeforeEach&&this._beforeEachGuards.push(e.onBeforeEach),this.errorHandler=r,this._scrollPositions=new Map,this._validateOptions()}}class n{static parse(t,e){return"string"!=typeof t?t:t.replace(this.expressionPattern,(t,r)=>this.evaluate(r,e))}static evaluate(t,e){if("string"!=typeof t)return t;let r=this._functionCache.get(t);if(!r)try{r=Function("data",`with(data) { return ${t}; }`),this._functionCache.set(t,r)}catch{return""}try{return r(e)}catch{return""}}}n.expressionPattern=/\{\{\s*(.*?)\s*\}\}/g,n._functionCache=new Map,t.Attr={name:"attr",version:"1.0.0-rc.12",description:"Advanced attribute handling for Eleva components",install(t,r={}){let{enableAria:i=!0,enableData:n=!0,enableBoolean:a=!0,enableDynamic:o=!0}=r,s=(t,r)=>{let s=t.attributes,l=r.attributes;for(let r=0;r<l.length;r++){let{name:s,value:u}=l[r];if(!s.startsWith("@")&&t.getAttribute(s)!==u)if(i&&s.startsWith("aria-"))t["aria"+s.slice(5).replace(e,(t,e)=>e.toUpperCase())]=u,t.setAttribute(s,u);else if(n&&s.startsWith("data-"))t.dataset[s.slice(5)]=u,t.setAttribute(s,u);else{let r=s.replace(e,(t,e)=>e.toUpperCase());if(o&&!(r in t)&&!Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),r)){let e=Object.getOwnPropertyNames(Object.getPrototypeOf(t)).find(t=>t.toLowerCase()===s.toLowerCase()||t.toLowerCase().includes(s.toLowerCase())||s.toLowerCase().includes(t.toLowerCase()));e&&(r=e)}let i=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),r);if(r in t||i)if(a)if("boolean"==typeof t[r]||i?.get&&"boolean"==typeof i.get.call(t)){let e="false"!==u&&(""===u||u===r||"true"===u);t[r]=e,e?t.setAttribute(s,""):t.removeAttribute(s)}else t[r]=u,t.setAttribute(s,u);else t[r]=u,t.setAttribute(s,u);else t.setAttribute(s,u)}}for(let e=s.length-1;e>=0;e--){let i=s[e].name;r.hasAttribute(i)||t.removeAttribute(i)}};if(t.renderer){t.renderer.updateAttributes=s;let e=t.renderer._patchNode;t.renderer._originalPatchNode=e,t.renderer._patchNode=function(t,e){t?._eleva_instance||(3===t.nodeType?t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue):1===t.nodeType&&(s(t,e),this._diff(t,e)))}}t.plugins||(t.plugins=new Map),t.plugins.set(this.name,{name:this.name,version:this.version,description:this.description,options:r}),t.updateElementAttributes=s},uninstall(t){t.renderer&&t.renderer._originalPatchNode&&(t.renderer._patchNode=t.renderer._originalPatchNode,delete t.renderer._originalPatchNode),t.plugins&&t.plugins.delete(this.name),delete t.updateElementAttributes}},t.Props={name:"props",version:"1.0.0-rc.12",description:"Advanced props data handling for complex data structures with automatic type detection and reactivity",install(t,e={}){let{enableAutoParsing:r=!0,enableReactivity:i=!0,onError:a=null}=e,o=t=>{try{if("string"!=typeof t)return t;if("true"===t)return!0;if("false"===t)return!1;if("null"===t)return null;if("undefined"===t)return;if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){throw Error(`Invalid JSON: ${t}`)}if("1"===t)return!0;if("0"===t)return!1;if(""===t)return!0;if(!isNaN(t)&&""!==t&&!isNaN(parseFloat(t)))return Number(t);if(t.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)){let e=new Date(t);if(!isNaN(e.getTime()))return e}return t}catch(e){return a&&a(e,t),t}},s=e=>{let r={};return Object.entries(e).forEach(([e,i])=>{i&&"object"==typeof i&&"value"in i&&"watch"in i?r[e]=i:r[e]=new t.signal(i)}),r};t._extractProps=t=>{let e={},i=t.attributes;for(let n=i.length-1;n>=0;n--){let a=i[n];if(a.name.startsWith(":")){let i=a.name.slice(1),n=r?o(a.value):a.value;e[i]=n,t.removeAttribute(a.name)}}return e};let l=t.mount;t.mount=async(e,r,n={})=>{let a=i?s(n):n;return await l.call(t,e,r,a)};let u=t._mountComponents,h=new WeakMap,c=new Set;t._mountComponents=async(e,r,a)=>{for(let[n,o]of Object.entries(r))if(n)for(let r of e.querySelectorAll(n)){if(!(r instanceof HTMLElement))continue;let n=t._extractProps(r),l=n,u=h.get(e);if(!u){let t=e;for(;t&&!u;){if(t._eleva_instance&&t._eleva_instance.data){u=t._eleva_instance.data,h.set(e,u);break}t=t.parentElement}}if(i&&u){let e={};Object.keys(n).forEach(r=>{u[r]&&u[r]instanceof t.signal&&(e[r]=u[r])}),l={...n,...e}}let d=l;if(i){let t={};Object.entries(l).forEach(([e,r])=>{r&&"object"==typeof r&&"value"in r&&"watch"in r||(t[e]=r)}),d={...s(t),...l}}let p=await t.mount(r,o,d);p&&!a.includes(p)&&(a.push(p),i&&Object.keys(n).length>0&&!u&&c.add({instance:p,extractedProps:n,container:e,component:o}))}if(i&&c.size>0)for(let e of c){let{instance:r,extractedProps:i,container:a,component:o}=e,s=h.get(a);if(!s){let t=a;for(;t&&!s;){if(t._eleva_instance&&t._eleva_instance.data){s=t._eleva_instance.data,h.set(a,s);break}t=t.parentElement}}if(s){let a={};if(Object.keys(i).forEach(e=>{s[e]&&s[e]instanceof t.signal&&(a[e]=s[e])}),Object.keys(a).length>0){Object.assign(r.data,a);let e=!1,i=t._components.get(o)||o,s=()=>{e||(e=!0,queueMicrotask(()=>{if(e=!1,i&&i.template){let e="function"==typeof i.template?i.template(r.data):i.template,a=n.parse(e,r.data);t.renderer.patchDOM(r.container,a)}}))};if(Object.keys(a).forEach(t=>{let e=a[t];e&&"function"==typeof e.watch&&e.watch(s)}),i&&i.template){let e="function"==typeof i.template?i.template(r.data):i.template,a=n.parse(e,r.data);t.renderer.patchDOM(r.container,a)}}c.delete(e)}}},t.props={parse:t=>r?o(t):t,detectType:t=>null===t?"null":void 0===t?"undefined":"boolean"==typeof t?"boolean":"number"==typeof t?"number":"string"==typeof t?"string":"function"==typeof t?"function":t instanceof Date?"date":t instanceof Map?"map":t instanceof Set?"set":Array.isArray(t)?"array":"object"==typeof t?"object":"unknown"},t._originalExtractProps=t._extractProps,t._originalMount=l,t._originalMountComponents=u},uninstall(t){t._originalExtractProps&&(t._extractProps=t._originalExtractProps,delete t._originalExtractProps),t._originalMount&&(t.mount=t._originalMount,delete t._originalMount),t._originalMountComponents&&(t._mountComponents=t._originalMountComponents,delete t._originalMountComponents),t.props&&delete t.props}},t.Router={name:"router",version:"1.0.0-rc.12",description:"Client-side routing for Eleva applications",install(t,e={}){if(!e.mount)throw Error("[RouterPlugin] 'mount' option is required");if(!e.routes||!Array.isArray(e.routes))throw Error("[RouterPlugin] 'routes' option must be an array");let r=(e,r)=>{if(!e)return null;if("object"==typeof e&&null!==e&&!e.name){let i=`Eleva${r}Component_${Math.random().toString(36).slice(2,11)}`;try{return t.component(i,e),i}catch(t){throw Error(`[RouterPlugin] Failed to register ${r} component: ${t.message}`)}}return e};e.globalLayout&&(e.globalLayout=r(e.globalLayout,"GlobalLayout")),(e.routes||[]).forEach(t=>{t.component=r(t.component,"Route"),t.layout&&(t.layout=r(t.layout,"RouteLayout"))});let n=new i(t,e);return t.router=n,!1!==e.autoStart&&queueMicrotask(()=>n.start()),t.plugins||(t.plugins=new Map),t.plugins.set(this.name,{name:this.name,version:this.version,description:this.description,options:e}),t.navigate=n.navigate.bind(n),t.getCurrentRoute=()=>n.currentRoute.value,t.getRouteParams=()=>n.currentParams.value,t.getRouteQuery=()=>n.currentQuery.value,n},async uninstall(t){t.router&&(await t.router.destroy(),delete t.router),t.plugins&&t.plugins.delete(this.name),delete t.navigate,delete t.getCurrentRoute,delete t.getRouteParams,delete t.getRouteQuery}},t.Store={name:"store",version:"1.0.0-rc.12",description:"Reactive state management for sharing data across the entire Eleva application",install(t,e={}){let{state:r={},actions:i={},namespaces:n={},persistence:a={},devTools:o=!1,onError:s=null}=e,l=new class{_initializeState(e,r){Object.entries(e).forEach(([e,r])=>{this.state[e]=new t.signal(r)}),this.actions={...r}}_initializeNamespaces(e){Object.entries(e).forEach(([e,r])=>{let{state:i={},actions:n={}}=r;this.state[e]||(this.state[e]={}),this.actions[e]||(this.actions[e]={}),Object.entries(i).forEach(([r,i])=>{this.state[e][r]=new t.signal(i)}),this.actions[e]={...n}})}_loadPersistedState(){if(this.persistence.enabled&&"u">typeof window)try{let t=window[this.persistence.storage].getItem(this.persistence.key);if(t){let e=JSON.parse(t);this._applyPersistedData(e)}}catch(t){this.onError&&this.onError(t,"Failed to load persisted state")}}_applyPersistedData(t,e=this.state,r=""){Object.entries(t).forEach(([t,i])=>{let n=r?`${r}.${t}`:t;this._shouldPersist(n)&&(e[t]&&"object"==typeof e[t]&&"value"in e[t]?e[t].value=i:"object"==typeof i&&null!==i&&e[t]&&this._applyPersistedData(i,e[t],n))})}_shouldPersist(t){let{include:e,exclude:r}=this.persistence;return e&&e.length>0?e.some(e=>t.startsWith(e)):!r||!(r.length>0)||!r.some(e=>t.startsWith(e))}_saveState(){if(this.persistence.enabled&&"u">typeof window)try{let t=window[this.persistence.storage],e=this._extractPersistedData();t.setItem(this.persistence.key,JSON.stringify(e))}catch(t){this.onError&&this.onError(t,"Failed to save state")}}_extractPersistedData(t=this.state,e=""){let r={};return Object.entries(t).forEach(([t,i])=>{let n=e?`${e}.${t}`:t;if(this._shouldPersist(n)){if(i&&"object"==typeof i&&"value"in i)r[t]=i.value;else if("object"==typeof i&&null!==i){let e=this._extractPersistedData(i,n);Object.keys(e).length>0&&(r[t]=e)}}}),r}_setupDevTools(){this.devTools&&"u">typeof window&&window.__ELEVA_DEVTOOLS__&&window.__ELEVA_DEVTOOLS__.registerStore(this)}async dispatch(t,e){try{let r=this._getAction(t);if(!r){let e=Error(`Action "${t}" not found`);throw this.onError&&this.onError(e,t),e}let i={type:t,payload:e,timestamp:Date.now()};this.mutations.push(i),this.mutations.length>100&&this.mutations.shift();let n=await r.call(null,this.state,e);return this._saveState(),this.subscribers.forEach(t=>{try{t(i,this.state)}catch(t){this.onError&&this.onError(t,"Subscriber callback failed")}}),this.devTools&&"u">typeof window&&window.__ELEVA_DEVTOOLS__&&window.__ELEVA_DEVTOOLS__.notifyMutation(i,this.state),n}catch(e){throw this.onError&&this.onError(e,`Action dispatch failed: ${t}`),e}}_getAction(t){let e=t.split("."),r=this.actions;for(let t of e){if(void 0===r[t])return null;r=r[t]}return"function"==typeof r?r:null}subscribe(t){if("function"!=typeof t)throw Error("Subscribe callback must be a function");return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}getState(){return this._extractPersistedData()}replaceState(t){this._applyPersistedData(t),this._saveState()}clearPersistedState(){if(this.persistence.enabled&&"u">typeof window)try{window[this.persistence.storage].removeItem(this.persistence.key)}catch(t){this.onError&&this.onError(t,"Failed to clear persisted state")}}registerModule(t,e){this.state[t]||this.actions[t]||(this.state[t]={},this.actions[t]={},this._initializeNamespaces({[t]:e}),this._saveState())}unregisterModule(t){(this.state[t]||this.actions[t])&&(delete this.state[t],delete this.actions[t],this._saveState())}createState(e,r){return this.state[e]||(this.state[e]=new t.signal(r),this._saveState()),this.state[e]}createAction(t,e){if("function"!=typeof e)throw Error("Action must be a function");this.actions[t]=e}constructor(){this.state={},this.actions={},this.subscribers=new Set,this.mutations=[],this.persistence={enabled:!1,key:"eleva-store",storage:"localStorage",include:null,exclude:null,...a},this.devTools=o,this.onError=s,this._initializeState(r,i),this._initializeNamespaces(n),this._loadPersistedState(),this._setupDevTools()}},u=t.mount;t.mount=async(e,r,i={})=>{let n="string"==typeof r&&t._components.get(r)||r;if(!n)return await u.call(t,e,r,i);let a={...n,async setup(e){e.store={state:l.state,dispatch:l.dispatch.bind(l),subscribe:l.subscribe.bind(l),getState:l.getState.bind(l),registerModule:l.registerModule.bind(l),unregisterModule:l.unregisterModule.bind(l),createState:l.createState.bind(l),createAction:l.createAction.bind(l),signal:t.signal};let r=n.setup;return r?await r(e):{}}};return await u.call(t,e,a,i)};let h=t._mountComponents;t._mountComponents=async(e,r,i)=>{let n={};for(let[e,i]of Object.entries(r)){let r="string"==typeof i&&t._components.get(i)||i;r&&"object"==typeof r?n[e]={...r,async setup(e){e.store={state:l.state,dispatch:l.dispatch.bind(l),subscribe:l.subscribe.bind(l),getState:l.getState.bind(l),registerModule:l.registerModule.bind(l),unregisterModule:l.unregisterModule.bind(l),createState:l.createState.bind(l),createAction:l.createAction.bind(l),signal:t.signal};let i=r.setup;return i?await i(e):{}}}:n[e]=i}return await h.call(t,e,n,i)},t.store=l,t.createAction=(t,e)=>{l.actions[t]=e},t.dispatch=(t,e)=>l.dispatch(t,e),t.getState=()=>l.getState(),t.subscribe=t=>l.subscribe(t),t._originalMount=u,t._originalMountComponents=h},uninstall(t){t._originalMount&&(t.mount=t._originalMount,delete t._originalMount),t._originalMountComponents&&(t._mountComponents=t._originalMountComponents,delete t._originalMountComponents),t.store&&delete t.store,t.createAction&&delete t.createAction,t.dispatch&&delete t.dispatch,t.getState&&delete t.getState,t.subscribe&&delete t.subscribe}}},"object"==typeof exports&&"u">typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="u">typeof globalThis?globalThis:t||self).ElevaPlugins={});
1
+ var t,e;t=this,e=function(t){"use strict";let e=/-([a-z])/g,r={handle(t,e,r={}){let i=Error(`[ElevaRouter] ${e}: ${t.message}`);throw i.originalError=t,i.context=e,i.details=r,i},warn(t,e={}){},log(t,e,r={}){}};class i{_validateOptions(){["hash","query","history"].includes(this.options.mode)||this.errorHandler.handle(Error(`Invalid routing mode: ${this.options.mode}. Must be "hash", "query", or "history".`),"Configuration validation failed")}_processRoutes(t){let e=[];for(let r of t)try{e.push({...r,segments:this._parsePathIntoSegments(r.path)})}catch(t){this.errorHandler.warn(`Invalid path in route definition "${r.path||"undefined"}": ${t.message}`,{route:r,error:t})}return e}_parsePathIntoSegments(t){t&&"string"==typeof t||this.errorHandler.handle(Error("Route path must be a non-empty string"),"Path parsing failed",{path:t});let e=t.replace(/\/+/g,"/").replace(/\/$/,"")||"/";return"/"===e?[]:e.split("/").filter(Boolean).map(e=>{if(e.startsWith(":")){let r=e.substring(1);return r||this.errorHandler.handle(Error(`Invalid parameter segment: ${e}`),"Path parsing failed",{segment:e,path:t}),{type:"param",name:r}}return{type:"static",value:e}})}_findViewElement(t){let e=this.options.viewSelector;return t.querySelector(`#${e}`)||t.querySelector(`.${e}`)||t.querySelector(`[data-${e}]`)||t.querySelector(e)||t}async start(){if(this.isStarted)return this.errorHandler.warn("Router is already started"),this;if("u"<typeof window)return this.errorHandler.warn("Router start skipped: `window` object not available (SSR environment)"),this;if("u">typeof document&&!document.querySelector(this.options.mount))return this.errorHandler.warn(`Mount element "${this.options.mount}" was not found in the DOM. The router will not start.`,{mountSelector:this.options.mount}),this;let t=()=>this._handleRouteChange();return"hash"===this.options.mode?(window.addEventListener("hashchange",t),this.eventListeners.push(()=>window.removeEventListener("hashchange",t))):(window.addEventListener("popstate",t),this.eventListeners.push(()=>window.removeEventListener("popstate",t))),this.isStarted=!0,await this._handleRouteChange(!1),this.isReady.value=!0,await this.emitter.emit("router:ready",this),this}async destroy(){if(this.isStarted){for(let t of this.plugins.values())if("function"==typeof t.destroy)try{await t.destroy(this)}catch(e){this.errorHandler.log(`Plugin ${t.name} destroy failed`,e)}this.eventListeners.forEach(t=>t()),this.eventListeners=[],this.currentLayout.value&&await this.currentLayout.value.unmount(),this.isStarted=!1,this.isReady.value=!1}}async stop(){return this.destroy()}async navigate(t,e={}){try{let r="string"==typeof t?{path:t,params:e}:t,i=this._buildPath(r.path,r.params||{}),o=r.query||{};if(Object.keys(o).length>0){let t=new URLSearchParams(o).toString();t&&(i+=`?${t}`)}if(this._isSameRoute(i,r.params,o))return!0;let n=await this._proceedWithNavigation(i);if(n){let t=++this._navigationId;this._isNavigating=!0;let e=r.state||{},o=r.replace||!1;if("hash"===this.options.mode)if(o){let t=`${window.location.pathname}${window.location.search}#${i}`;window.history.replaceState(e,"",t)}else window.location.hash=i;else{let t="query"===this.options.mode?this._buildQueryUrl(i):i;history[o?"replaceState":"pushState"](e,"",t)}queueMicrotask(()=>{this._navigationId===t&&(this._isNavigating=!1)})}return n}catch(t){return this.errorHandler.log("Navigation failed",t),await this.emitter.emit("router:onError",t),!1}}_buildQueryUrl(t){let e=new URLSearchParams(window.location.search);return e.set(this.options.queryParam,t.split("?")[0]),`${window.location.pathname}?${e.toString()}`}_isSameRoute(t,e,r){let i=this.currentRoute.value;if(!i)return!1;let[o,n]=t.split("?"),a=r||this._parseQuery(n||"");return i.path===o&&JSON.stringify(i.params)===JSON.stringify(e||{})&&JSON.stringify(i.query)===JSON.stringify(a)}_buildPath(t,e){let r=t;for(let[t,i]of Object.entries(e)){let e=encodeURIComponent(String(i));r=r.replace(RegExp(`:${t}\\b`,"g"),e)}return r}async _handleRouteChange(t=!0){if(!this._isNavigating)try{let e=this.currentRoute.value,r=this._getCurrentLocation();!await this._proceedWithNavigation(r.fullUrl,t)&&e&&this.navigate({path:e.path,query:e.query,replace:!0})}catch(t){this.errorHandler.log("Route change handling failed",t,{currentUrl:"u">typeof window?window.location.href:""}),await this.emitter.emit("router:onError",t)}}async _proceedWithNavigation(t,e=!1){let r=this.currentRoute.value,[i,o]=(t||"/").split("?"),n={path:i.startsWith("/")?i:`/${i}`,query:this._parseQuery(o),fullUrl:t},a=this._matchRoute(n.path);if(!a){let t=this.routes.find(t=>"*"===t.path);if(!t)return await this.emitter.emit("router:onError",Error(`Route not found: ${n.path}`),n,r),!1;a={route:t,params:{pathMatch:decodeURIComponent(n.path.substring(1))}}}let s={...n,params:a.params,meta:a.route.meta||{},name:a.route.name,matched:a.route};try{if(!await this._runGuards(s,r,a.route))return!1;r&&"u">typeof window&&this._scrollPositions.set(r.path,{x:window.scrollX||window.pageXOffset||0,y:window.scrollY||window.pageYOffset||0});let t={to:s,from:r,route:a.route,layoutComponent:null,pageComponent:null,cancelled:!1,redirectTo:null};if(await this.emitter.emit("router:beforeResolve",t),t.cancelled)return!1;if(t.redirectTo)return this.navigate(t.redirectTo),!1;let{layoutComponent:i,pageComponent:o}=await this._resolveComponents(a.route);if(t.layoutComponent=i,t.pageComponent=o,await this.emitter.emit("router:afterResolve",t),r){let t=a.route.layout||this.options.globalLayout,e=r.matched.layout||this.options.globalLayout,i=async t=>{if(t)try{await t.unmount()}catch(e){this.errorHandler.warn("Error during component unmount",{error:e,instance:t})}};t!==e?(await i(this.currentLayout.value),this.currentLayout.value=null):(await i(this.currentView.value),this.currentView.value=null),r.matched.afterLeave&&await r.matched.afterLeave(s,r),await this.emitter.emit("router:afterLeave",s,r)}this.previousRoute.value=r,this.currentRoute.value=s,this.currentParams.value=s.params||{},this.currentQuery.value=s.query||{};let n={to:s,from:r,layoutComponent:i,pageComponent:o};await this.emitter.emit("router:beforeRender",n),await this._render(i,o,s),await this.emitter.emit("router:afterRender",n);let l={to:s,from:r,savedPosition:e&&this._scrollPositions.get(s.path)||null};return await this.emitter.emit("router:scroll",l),a.route.afterEnter&&await a.route.afterEnter(s,r),await this.emitter.emit("router:afterEnter",s,r),await this.emitter.emit("router:afterEach",s,r),!0}catch(t){return this.errorHandler.log("Error during navigation",t,{to:s,from:r}),await this.emitter.emit("router:onError",t,s,r),!1}}async _runGuards(t,e,r){let i={to:t,from:e,cancelled:!1,redirectTo:null};if(await this.emitter.emit("router:beforeEach",i),i.cancelled)return!1;if(i.redirectTo)return this.navigate(i.redirectTo),!1;for(let i of[...this._beforeEachGuards,...e&&e.matched.beforeLeave?[e.matched.beforeLeave]:[],...r.beforeEnter?[r.beforeEnter]:[]]){let r=await i(t,e);if(!1===r)return!1;if("string"==typeof r||"object"==typeof r)return this.navigate(r),!1}return!0}_resolveStringComponent(t){let e=this.eleva._components.get(t);return e||this.errorHandler.handle(Error(`Component "${t}" not registered.`),"Component resolution failed",{componentName:t,availableComponents:Array.from(this.eleva._components.keys())}),e}async _resolveFunctionComponent(t){try{let e=t.toString(),r=e.includes("import(")||e.startsWith("() =>"),i=await t();return r&&i.default||i}catch(e){this.errorHandler.handle(Error(`Failed to load async component: ${e.message}`),"Component resolution failed",{function:t.toString(),error:e})}}_validateComponentDefinition(t){return t&&"object"==typeof t||this.errorHandler.handle(Error(`Invalid component definition: ${typeof t}`),"Component validation failed",{definition:t}),"function"!=typeof t.template&&"string"!=typeof t.template&&this.errorHandler.handle(Error("Component missing template property"),"Component validation failed",{definition:t}),t}async _resolveComponent(t){return null==t?null:"string"==typeof t?this._resolveStringComponent(t):"function"==typeof t?await this._resolveFunctionComponent(t):t&&"object"==typeof t?this._validateComponentDefinition(t):void this.errorHandler.handle(Error(`Invalid component definition: ${typeof t}`),"Component resolution failed",{definition:t})}async _resolveComponents(t){let e=t.layout||this.options.globalLayout;try{let[r,i]=await Promise.all([this._resolveComponent(e),this._resolveComponent(t.component)]);return i||this.errorHandler.handle(Error(`Page component is null or undefined for route: ${t.path}`),"Component resolution failed",{route:t.path}),{layoutComponent:r,pageComponent:i}}catch(e){throw this.errorHandler.log(`Error resolving components for route ${t.path}`,e,{route:t.path}),e}}async _render(t,e){let r=document.querySelector(this.options.mount);if(r||this.errorHandler.handle(Error(`Mount element "${this.options.mount}" not found.`),{mountSelector:this.options.mount}),t){let i=await this.eleva.mount(r,this._wrapComponentWithChildren(t));this.currentLayout.value=i;let o=this._findViewElement(i.container),n=await this.eleva.mount(o,this._wrapComponentWithChildren(e));this.currentView.value=n}else{let t=await this.eleva.mount(r,this._wrapComponentWithChildren(e));this.currentView.value=t,this.currentLayout.value=null}}_createRouteGetter(t,e){return()=>this.currentRoute.value?.[t]??e}_wrapComponent(t){let e=t.setup,r=this;return{...t,setup:async t=>(t.router={navigate:r.navigate.bind(r),current:r.currentRoute,previous:r.previousRoute,get params(){return r._createRouteGetter("params",{})()},get query(){return r._createRouteGetter("query",{})()},get path(){return r._createRouteGetter("path","/")()},get fullUrl(){return r._createRouteGetter("fullUrl",window.location.href)()},get meta(){return r._createRouteGetter("meta",{})()}},e?await e(t):{})}}_wrapComponentWithChildren(t){if("string"==typeof t||!t||"object"!=typeof t)return t;let e=this._wrapComponent(t);if(e.children&&"object"==typeof e.children){let t={};for(let[r,i]of Object.entries(e.children))t[r]=this._wrapComponentWithChildren(i);e.children=t}return e}_getCurrentLocation(){let t,e,r;if("u"<typeof window)return{path:"/",query:{},fullUrl:""};switch(this.options.mode){case"hash":r=window.location.hash.slice(1)||"/",[t,e]=r.split("?");break;case"query":t=new URLSearchParams(window.location.search).get(this.options.queryParam)||"/",e=window.location.search.slice(1),r=t;break;default:t=window.location.pathname||"/",e=window.location.search.slice(1),r=`${t}${e?"?"+e:""}`}return{path:t.startsWith("/")?t:`/${t}`,query:this._parseQuery(e),fullUrl:r}}_parseQuery(t){let e={};return t&&new URLSearchParams(t).forEach((t,r)=>{e[r]=t}),e}_matchRoute(t){let e=t.split("/").filter(Boolean);for(let t of this.routes){if("/"===t.path){if(0===e.length)return{route:t,params:{}};continue}if(t.segments.length!==e.length)continue;let r={},i=!0;for(let o=0;o<t.segments.length;o++){let n=t.segments[o],a=e[o];if("param"===n.type)r[n.name]=decodeURIComponent(a);else if(n.value!==a){i=!1;break}}if(i)return{route:t,params:r}}return null}addRoute(t,e=null){if(!t||!t.path)return this.errorHandler.warn("Invalid route definition: missing path",{route:t}),()=>{};if(this.hasRoute(t.path))return this.errorHandler.warn(`Route "${t.path}" already exists`,{route:t}),()=>{};let r={...t,segments:this._parsePathIntoSegments(t.path)},i=this.routes.findIndex(t=>"*"===t.path);return -1!==i?this.routes.splice(i,0,r):this.routes.push(r),this.emitter.emit("router:routeAdded",r),()=>this.removeRoute(t.path)}removeRoute(t){let e=this.routes.findIndex(e=>e.path===t);if(-1===e)return!1;let[r]=this.routes.splice(e,1);return this.emitter.emit("router:routeRemoved",r),!0}hasRoute(t){return this.routes.some(e=>e.path===t)}getRoutes(){return[...this.routes]}getRoute(t){return this.routes.find(e=>e.path===t)}onBeforeEach(t){return this._beforeEachGuards.push(t),()=>{let e=this._beforeEachGuards.indexOf(t);e>-1&&this._beforeEachGuards.splice(e,1)}}onAfterEnter(t){return this.emitter.on("router:afterEnter",t)}onAfterLeave(t){return this.emitter.on("router:afterLeave",t)}onAfterEach(t){return this.emitter.on("router:afterEach",t)}onError(t){return this.emitter.on("router:onError",t)}use(t,e={}){("function"!=typeof t.install&&this.errorHandler.handle(Error("Plugin must have an install method"),"Plugin registration failed",{plugin:t}),this.plugins.has(t.name))?this.errorHandler.warn(`Plugin "${t.name}" is already registered`,{existingPlugin:this.plugins.get(t.name)}):(this.plugins.set(t.name,t),t.install(this,e))}getPlugins(){return Array.from(this.plugins.values())}getPlugin(t){return this.plugins.get(t)}removePlugin(t){let e=this.plugins.get(t);if(!e)return!1;if("function"==typeof e.destroy)try{e.destroy(this)}catch(e){this.errorHandler.log(`Plugin ${t} destroy failed`,e)}return this.plugins.delete(t)}setErrorHandler(t){t&&"function"==typeof t.handle&&"function"==typeof t.warn&&"function"==typeof t.log&&(this.errorHandler=t)}constructor(t,e={}){this.eleva=t,this.options={mode:"hash",queryParam:"view",viewSelector:"root",...e},this.routes=this._processRoutes(e.routes||[]),this.emitter=this.eleva.emitter,this.isStarted=!1,this._isNavigating=!1,this._navigationId=0,this.eventListeners=[],this.currentRoute=new this.eleva.signal(null),this.previousRoute=new this.eleva.signal(null),this.currentParams=new this.eleva.signal({}),this.currentQuery=new this.eleva.signal({}),this.currentLayout=new this.eleva.signal(null),this.currentView=new this.eleva.signal(null),this.isReady=new this.eleva.signal(!1),this.plugins=new Map,this._beforeEachGuards=[],e.onBeforeEach&&this._beforeEachGuards.push(e.onBeforeEach),this.errorHandler=r,this._scrollPositions=new Map,this._validateOptions()}}t.Attr={name:"attr",version:"1.0.0-rc.12",description:"Advanced attribute handling for Eleva components",install(t,r={}){let{enableAria:i=!0,enableData:o=!0,enableBoolean:n=!0,enableDynamic:a=!0}=r,s=(t,r)=>{let s=t.attributes,l=r.attributes;for(let r=0;r<l.length;r++){let{name:s,value:u}=l[r];if(!s.startsWith("@")&&t.getAttribute(s)!==u)if(i&&s.startsWith("aria-"))t["aria"+s.slice(5).replace(e,(t,e)=>e.toUpperCase())]=u,t.setAttribute(s,u);else if(o&&s.startsWith("data-"))t.dataset[s.slice(5)]=u,t.setAttribute(s,u);else{let r=s.replace(e,(t,e)=>e.toUpperCase());if(a&&!(r in t)&&!Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),r)){let e=Object.getOwnPropertyNames(Object.getPrototypeOf(t)).find(t=>t.toLowerCase()===s.toLowerCase()||t.toLowerCase().includes(s.toLowerCase())||s.toLowerCase().includes(t.toLowerCase()));e&&(r=e)}let i=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),r);if(r in t||i)if(n)if("boolean"==typeof t[r]||i?.get&&"boolean"==typeof i.get.call(t)){let e="false"!==u&&(""===u||u===r||"true"===u);t[r]=e,e?t.setAttribute(s,""):t.removeAttribute(s)}else t[r]=u,t.setAttribute(s,u);else t[r]=u,t.setAttribute(s,u);else t.setAttribute(s,u)}}for(let e=s.length-1;e>=0;e--){let i=s[e].name;r.hasAttribute(i)||t.removeAttribute(i)}};if(t.renderer){t.renderer.updateAttributes=s;let e=t.renderer._patchNode;t.renderer._originalPatchNode=e,t.renderer._patchNode=function(t,e){t?._eleva_instance||(t.nodeType===Node.TEXT_NODE?t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue):t.nodeType===Node.ELEMENT_NODE&&(s(t,e),this._diff(t,e)))}}t.plugins||(t.plugins=new Map),t.plugins.set(this.name,{name:this.name,version:this.version,description:this.description,options:r}),t.updateElementAttributes=s},uninstall(t){t.renderer&&t.renderer._originalPatchNode&&(t.renderer._patchNode=t.renderer._originalPatchNode,delete t.renderer._originalPatchNode),t.plugins&&t.plugins.delete(this.name),delete t.updateElementAttributes}},t.Router={name:"router",version:"1.0.0-rc.12",description:"Client-side routing for Eleva applications",install(t,e={}){if(!e.mount)throw Error("[RouterPlugin] 'mount' option is required");if(!e.routes||!Array.isArray(e.routes))throw Error("[RouterPlugin] 'routes' option must be an array");let r=(e,r)=>{if(!e)return null;if("object"==typeof e&&null!==e&&!e.name){let i=`Eleva${r}Component_${Math.random().toString(36).slice(2,11)}`;try{return t.component(i,e),i}catch(t){throw Error(`[RouterPlugin] Failed to register ${r} component: ${t.message}`)}}return e};e.globalLayout&&(e.globalLayout=r(e.globalLayout,"GlobalLayout")),(e.routes||[]).forEach(t=>{t.component=r(t.component,"Route"),t.layout&&(t.layout=r(t.layout,"RouteLayout"))});let o=new i(t,e);return t.router=o,!1!==e.autoStart&&queueMicrotask(()=>o.start()),t.plugins||(t.plugins=new Map),t.plugins.set(this.name,{name:this.name,version:this.version,description:this.description,options:e}),t.navigate=o.navigate.bind(o),t.getCurrentRoute=()=>o.currentRoute.value,t.getRouteParams=()=>o.currentParams.value,t.getRouteQuery=()=>o.currentQuery.value,o},async uninstall(t){t.router&&(await t.router.destroy(),delete t.router),t.plugins&&t.plugins.delete(this.name),delete t.navigate,delete t.getCurrentRoute,delete t.getRouteParams,delete t.getRouteQuery}},t.Store={name:"store",version:"1.0.0-rc.12",description:"Reactive state management for sharing data across the entire Eleva application",install(t,e={}){let{state:r={},actions:i={},namespaces:o={},persistence:n={},devTools:a=!1,onError:s=null}=e,l=new class{_initializeState(e,r){Object.entries(e).forEach(([e,r])=>{this.state[e]=new t.signal(r)}),this.actions={...r}}_initializeNamespaces(e){Object.entries(e).forEach(([e,r])=>{let{state:i={},actions:o={}}=r;this.state[e]||(this.state[e]={}),this.actions[e]||(this.actions[e]={}),Object.entries(i).forEach(([r,i])=>{this.state[e][r]=new t.signal(i)}),this.actions[e]={...o}})}_loadPersistedState(){if(this.persistence.enabled&&"u">typeof window)try{let t=window[this.persistence.storage].getItem(this.persistence.key);if(t){let e=JSON.parse(t);this._applyPersistedData(e)}}catch(t){this.onError&&this.onError(t,"Failed to load persisted state")}}_applyPersistedData(t,e=this.state,r=""){Object.entries(t).forEach(([t,i])=>{let o=r?`${r}.${t}`:t;this._shouldPersist(o)&&(e[t]&&"object"==typeof e[t]&&"value"in e[t]?e[t].value=i:"object"==typeof i&&null!==i&&e[t]&&this._applyPersistedData(i,e[t],o))})}_shouldPersist(t){let{include:e,exclude:r}=this.persistence;return e&&e.length>0?e.some(e=>t.startsWith(e)):!r||!(r.length>0)||!r.some(e=>t.startsWith(e))}_saveState(){if(this.persistence.enabled&&"u">typeof window)try{let t=window[this.persistence.storage],e=this._extractPersistedData();t.setItem(this.persistence.key,JSON.stringify(e))}catch(t){this.onError&&this.onError(t,"Failed to save state")}}_extractPersistedData(t=this.state,e=""){let r={};return Object.entries(t).forEach(([t,i])=>{let o=e?`${e}.${t}`:t;if(this._shouldPersist(o)){if(i&&"object"==typeof i&&"value"in i)r[t]=i.value;else if("object"==typeof i&&null!==i){let e=this._extractPersistedData(i,o);Object.keys(e).length>0&&(r[t]=e)}}}),r}_setupDevTools(){this.devTools&&"u">typeof window&&window.__ELEVA_DEVTOOLS__&&window.__ELEVA_DEVTOOLS__.registerStore(this)}async dispatch(t,e){try{let r=this._getAction(t);if(!r){let e=Error(`Action "${t}" not found`);throw this.onError&&this.onError(e,t),e}let i={type:t,payload:e,timestamp:Date.now()};this.mutations.push(i),this.mutations.length>100&&this.mutations.shift();let o=await r.call(null,this.state,e);return this._saveState(),this.subscribers.forEach(t=>{try{t(i,this.state)}catch(t){this.onError&&this.onError(t,"Subscriber callback failed")}}),this.devTools&&"u">typeof window&&window.__ELEVA_DEVTOOLS__&&window.__ELEVA_DEVTOOLS__.notifyMutation(i,this.state),o}catch(e){throw this.onError&&this.onError(e,`Action dispatch failed: ${t}`),e}}_getAction(t){let e=t.split("."),r=this.actions;for(let t of e){if(void 0===r[t])return null;r=r[t]}return"function"==typeof r?r:null}subscribe(t){if("function"!=typeof t)throw Error("Subscribe callback must be a function");return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}getState(){return this._extractPersistedData()}replaceState(t){this._applyPersistedData(t),this._saveState()}clearPersistedState(){if(this.persistence.enabled&&"u">typeof window)try{window[this.persistence.storage].removeItem(this.persistence.key)}catch(t){this.onError&&this.onError(t,"Failed to clear persisted state")}}registerModule(t,e){this.state[t]||this.actions[t]||(this.state[t]={},this.actions[t]={},this._initializeNamespaces({[t]:e}),this._saveState())}unregisterModule(t){(this.state[t]||this.actions[t])&&(delete this.state[t],delete this.actions[t],this._saveState())}createState(e,r){return this.state[e]||(this.state[e]=new t.signal(r),this._saveState()),this.state[e]}createAction(t,e){if("function"!=typeof e)throw Error("Action must be a function");this.actions[t]=e}constructor(){this.state={},this.actions={},this.subscribers=new Set,this.mutations=[],this.persistence={enabled:!1,key:"eleva-store",storage:"localStorage",include:null,exclude:null,...n},this.devTools=a,this.onError=s,this._initializeState(r,i),this._initializeNamespaces(o),this._loadPersistedState(),this._setupDevTools()}},u=t.mount;t.mount=async(e,r,i={})=>{let o="string"==typeof r&&t._components.get(r)||r;if(!o)return await u.call(t,e,r,i);let n={...o,async setup(e){e.store={state:l.state,dispatch:l.dispatch.bind(l),subscribe:l.subscribe.bind(l),getState:l.getState.bind(l),registerModule:l.registerModule.bind(l),unregisterModule:l.unregisterModule.bind(l),createState:l.createState.bind(l),createAction:l.createAction.bind(l),signal:t.signal};let r=o.setup;return r?await r(e):{}}};return await u.call(t,e,n,i)};let h=t._mountComponents;t._mountComponents=async(e,r,i)=>{let o={};for(let[e,i]of Object.entries(r)){let r="string"==typeof i&&t._components.get(i)||i;r&&"object"==typeof r?o[e]={...r,async setup(e){e.store={state:l.state,dispatch:l.dispatch.bind(l),subscribe:l.subscribe.bind(l),getState:l.getState.bind(l),registerModule:l.registerModule.bind(l),unregisterModule:l.unregisterModule.bind(l),createState:l.createState.bind(l),createAction:l.createAction.bind(l),signal:t.signal};let i=r.setup;return i?await i(e):{}}}:o[e]=i}return await h.call(t,e,o,i)},t.store=l,t.createAction=(t,e)=>{l.actions[t]=e},t.dispatch=(t,e)=>l.dispatch(t,e),t.getState=()=>l.getState(),t.subscribe=t=>l.subscribe(t),t._originalMount=u,t._originalMountComponents=h},uninstall(t){t._originalMount&&(t.mount=t._originalMount,delete t._originalMount),t._originalMountComponents&&(t._mountComponents=t._originalMountComponents,delete t._originalMountComponents),t.store&&delete t.store,t.createAction&&delete t.createAction,t.dispatch&&delete t.dispatch,t.getState&&delete t.getState,t.subscribe&&delete t.subscribe}}},"object"==typeof exports&&"u">typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="u">typeof globalThis?globalThis:t||self).ElevaPlugins={});
2
2
  //# sourceMappingURL=eleva-plugins.umd.min.js.map