eleva 1.0.0-rc.6 → 1.0.0-rc.9
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 +139 -10
- package/dist/eleva-plugins.cjs.js +675 -1
- package/dist/eleva-plugins.cjs.js.map +1 -1
- package/dist/eleva-plugins.esm.js +675 -2
- package/dist/eleva-plugins.esm.js.map +1 -1
- package/dist/eleva-plugins.umd.js +675 -1
- package/dist/eleva-plugins.umd.js.map +1 -1
- package/dist/eleva-plugins.umd.min.js +2 -2
- package/dist/eleva-plugins.umd.min.js.map +1 -1
- package/dist/eleva.cjs.js +39 -28
- package/dist/eleva.cjs.js.map +1 -1
- package/dist/eleva.d.ts +63 -2
- package/dist/eleva.esm.js +39 -28
- package/dist/eleva.esm.js.map +1 -1
- package/dist/eleva.umd.js +39 -28
- package/dist/eleva.umd.js.map +1 -1
- package/dist/eleva.umd.min.js +2 -2
- package/dist/eleva.umd.min.js.map +1 -1
- package/dist/plugins/store.umd.js +684 -0
- package/dist/plugins/store.umd.js.map +1 -0
- package/dist/plugins/store.umd.min.js +3 -0
- package/dist/plugins/store.umd.min.js.map +1 -0
- package/package.json +17 -16
- package/src/core/Eleva.js +42 -27
- package/src/plugins/Store.js +741 -0
- package/src/plugins/index.js +6 -1
- package/types/core/Eleva.d.ts +14 -2
- package/types/core/Eleva.d.ts.map +1 -1
- package/types/plugins/Store.d.ts +86 -0
- package/types/plugins/Store.d.ts.map +1 -0
- package/types/plugins/index.d.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eleva-plugins.umd.min.js","sources":["../src/plugins/Attr.js","../src/plugins/Router.js","../src/modules/TemplateEngine.js","../src/plugins/Props.js"],"sourcesContent":["\"use strict\";\n\n/**\n * A regular expression to match hyphenated lowercase letters.\n * @private\n * @type {RegExp}\n */\nconst CAMEL_RE = /-([a-z])/g;\n\n/**\n * @class 🎯 AttrPlugin\n * @classdesc A plugin that provides advanced attribute handling for Eleva components.\n * This plugin extends the renderer with sophisticated attribute processing including:\n * - ARIA attribute handling with proper property mapping\n * - Data attribute management\n * - Boolean attribute processing\n * - Dynamic property detection and mapping\n * - Attribute cleanup and removal\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n * app.use(AttrPlugin);\n *\n * // Use advanced attributes in components\n * app.component(\"myComponent\", {\n * template: (ctx) => `\n * <button\n * aria-expanded=\"${ctx.isExpanded.value}\"\n * data-user-id=\"${ctx.userId.value}\"\n * disabled=\"${ctx.isLoading.value}\"\n * class=\"btn ${ctx.variant.value}\"\n * >\n * ${ctx.text.value}\n * </button>\n * `\n * });\n */\nexport const AttrPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"attr\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.1\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description: \"Advanced attribute handling for Eleva components\",\n\n /**\n * Installs the plugin into the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n * @param {Object} options - Plugin configuration options\n * @param {boolean} [options.enableAria=true] - Enable ARIA attribute handling\n * @param {boolean} [options.enableData=true] - Enable data attribute handling\n * @param {boolean} [options.enableBoolean=true] - Enable boolean attribute handling\n * @param {boolean} [options.enableDynamic=true] - Enable dynamic property detection\n */\n install(eleva, options = {}) {\n const {\n enableAria = true,\n enableData = true,\n enableBoolean = true,\n enableDynamic = true,\n } = options;\n\n /**\n * Updates the attributes of an element to match a new element's attributes.\n * This method provides sophisticated attribute processing including:\n * - ARIA attribute handling with proper property mapping\n * - Data attribute management\n * - Boolean attribute processing\n * - Dynamic property detection and mapping\n * - Attribute cleanup and removal\n *\n * @param {HTMLElement} oldEl - The original element to update\n * @param {HTMLElement} newEl - The new element to update\n * @returns {void}\n */\n const updateAttributes = (oldEl, newEl) => {\n const oldAttrs = oldEl.attributes;\n const newAttrs = newEl.attributes;\n\n // Process new attributes\n for (let i = 0; i < newAttrs.length; i++) {\n const { name, value } = newAttrs[i];\n\n // Skip event attributes (handled by event system)\n if (name.startsWith(\"@\")) continue;\n\n // Skip if attribute hasn't changed\n if (oldEl.getAttribute(name) === value) continue;\n\n // Handle ARIA attributes\n if (enableAria && name.startsWith(\"aria-\")) {\n const prop =\n \"aria\" + name.slice(5).replace(CAMEL_RE, (_, l) => l.toUpperCase());\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n // Handle data attributes\n else if (enableData && name.startsWith(\"data-\")) {\n oldEl.dataset[name.slice(5)] = value;\n oldEl.setAttribute(name, value);\n }\n // Handle other attributes\n else {\n let prop = name.replace(CAMEL_RE, (_, l) => l.toUpperCase());\n\n // Dynamic property detection\n if (\n enableDynamic &&\n !(prop in oldEl) &&\n !Object.getOwnPropertyDescriptor(Object.getPrototypeOf(oldEl), prop)\n ) {\n const elementProps = Object.getOwnPropertyNames(\n Object.getPrototypeOf(oldEl)\n );\n const matchingProp = elementProps.find(\n (p) =>\n p.toLowerCase() === name.toLowerCase() ||\n p.toLowerCase().includes(name.toLowerCase()) ||\n name.toLowerCase().includes(p.toLowerCase())\n );\n\n if (matchingProp) {\n prop = matchingProp;\n }\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(\n Object.getPrototypeOf(oldEl),\n prop\n );\n const hasProperty = prop in oldEl || descriptor;\n\n if (hasProperty) {\n // Boolean attribute handling\n if (enableBoolean) {\n const isBoolean =\n typeof oldEl[prop] === \"boolean\" ||\n (descriptor?.get &&\n typeof descriptor.get.call(oldEl) === \"boolean\");\n\n if (isBoolean) {\n const boolValue =\n value !== \"false\" &&\n (value === \"\" || value === prop || value === \"true\");\n oldEl[prop] = boolValue;\n\n if (boolValue) {\n oldEl.setAttribute(name, \"\");\n } else {\n oldEl.removeAttribute(name);\n }\n } else {\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n } else {\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n } else {\n oldEl.setAttribute(name, value);\n }\n }\n }\n\n // Remove old attributes that are no longer present\n for (let i = oldAttrs.length - 1; i >= 0; i--) {\n const name = oldAttrs[i].name;\n if (!newEl.hasAttribute(name)) {\n oldEl.removeAttribute(name);\n }\n }\n };\n\n // Extend the renderer with the advanced attribute handler\n if (eleva.renderer) {\n eleva.renderer.updateAttributes = updateAttributes;\n\n // Store the original _patchNode method\n const originalPatchNode = eleva.renderer._patchNode;\n eleva.renderer._originalPatchNode = originalPatchNode;\n\n // Override the _patchNode method to use our attribute handler\n eleva.renderer._patchNode = function (oldNode, newNode) {\n if (oldNode?._eleva_instance) return;\n\n if (!this._isSameNode(oldNode, newNode)) {\n oldNode.replaceWith(newNode.cloneNode(true));\n return;\n }\n\n if (oldNode.nodeType === Node.ELEMENT_NODE) {\n updateAttributes(oldNode, newNode);\n this._diff(oldNode, newNode);\n } else if (\n oldNode.nodeType === Node.TEXT_NODE &&\n oldNode.nodeValue !== newNode.nodeValue\n ) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n };\n }\n\n // Add plugin metadata to the Eleva instance\n if (!eleva.plugins) {\n eleva.plugins = new Map();\n }\n eleva.plugins.set(this.name, {\n name: this.name,\n version: this.version,\n description: this.description,\n options,\n });\n\n // Add utility methods for manual attribute updates\n eleva.updateElementAttributes = updateAttributes;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n */\n uninstall(eleva) {\n // Restore original _patchNode method if it exists\n if (eleva.renderer && eleva.renderer._originalPatchNode) {\n eleva.renderer._patchNode = eleva.renderer._originalPatchNode;\n delete eleva.renderer._originalPatchNode;\n }\n\n // Remove plugin metadata\n if (eleva.plugins) {\n eleva.plugins.delete(this.name);\n }\n\n // Remove utility methods\n delete eleva.updateElementAttributes;\n },\n};\n","\"use strict\";\n\n/**\n * @typedef {import('eleva').Eleva} Eleva\n * @typedef {import('eleva').Signal} Signal\n * @typedef {import('eleva').ComponentDefinition} ComponentDefinition\n */\n\n/**\n * Simple error handler for the core router.\n * Can be overridden by error handling plugins.\n * Provides consistent error formatting and logging for router operations.\n * @private\n */\nconst CoreErrorHandler = {\n /**\n * Handles router errors with basic formatting.\n * @param {Error} error - The error to handle.\n * @param {string} context - The context where the error occurred.\n * @param {Object} details - Additional error details.\n * @throws {Error} The formatted error.\n */\n handle(error, context, details = {}) {\n const message = `[ElevaRouter] ${context}: ${error.message}`;\n const formattedError = new Error(message);\n\n // Preserve original error details\n formattedError.originalError = error;\n formattedError.context = context;\n formattedError.details = details;\n\n console.error(message, { error, context, details });\n throw formattedError;\n },\n\n /**\n * Logs a warning without throwing an error.\n * @param {string} message - The warning message.\n * @param {Object} details - Additional warning details.\n */\n warn(message, details = {}) {\n console.warn(`[ElevaRouter] ${message}`, details);\n },\n\n /**\n * Logs an error without throwing.\n * @param {string} message - The error message.\n * @param {Error} error - The original error.\n * @param {Object} details - Additional error details.\n */\n log(message, error, details = {}) {\n console.error(`[ElevaRouter] ${message}`, { error, details });\n },\n};\n\n/**\n * @typedef {Object} RouteLocation\n * @property {string} path - The path of the route (e.g., '/users/123').\n * @property {Object<string, string>} query - An object representing the query parameters.\n * @property {string} fullUrl - The complete URL including hash, path, and query string.\n * @property {Object<string, string>} params - An object containing dynamic route parameters.\n * @property {Object<string, any>} meta - The meta object associated with the matched route.\n * @property {string} [name] - The optional name of the matched route.\n * @property {RouteDefinition} matched - The raw route definition object that was matched.\n */\n\n/**\n * @typedef {(to: RouteLocation, from: RouteLocation | null) => boolean | string | {path: string} | void | Promise<boolean | string | {path: string} | void>} NavigationGuard\n * A function that acts as a guard for navigation. It runs *before* the navigation is confirmed.\n * It can return:\n * - `true` or `undefined`: to allow navigation.\n * - `false`: to abort the navigation.\n * - a `string` (path) or a `location object`: to redirect to a new route.\n */\n\n/**\n * @typedef {(...args: any[]) => void | Promise<void>} NavigationHook\n * A function that acts as a lifecycle hook, typically for side effects. It does not affect navigation flow.\n */\n\n/**\n * @typedef {Object} RouterPlugin\n * @property {string} name - The plugin name.\n * @property {string} [version] - The plugin version.\n * @property {Function} install - The install function that receives the router instance.\n * @property {Function} [destroy] - Optional cleanup function called when the router is destroyed.\n */\n\n/**\n * @typedef {Object} RouteDefinition\n * @property {string} path - The URL path pattern (e.g., '/', '/about', '/users/:id', '*').\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} component - The component to render. Can be a registered name, a definition object, or an async import function.\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [layout] - An optional layout component to wrap the route's component.\n * @property {string} [name] - An optional name for the route.\n * @property {Object<string, any>} [meta] - Optional metadata for the route (e.g., for titles, auth flags).\n * @property {NavigationGuard} [beforeEnter] - A route-specific guard executed before entering the route.\n * @property {NavigationHook} [afterEnter] - A hook executed *after* the route has been entered and the new component is mounted.\n * @property {NavigationGuard} [beforeLeave] - A guard executed *before* leaving the current route.\n * @property {NavigationHook} [afterLeave] - A hook executed *after* leaving the current route and its component has been unmounted.\n */\n\n/**\n * @class Router\n * @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.js.\n * This class manages all routing logic, including state, navigation, and rendering.\n * @private\n */\nclass Router {\n /**\n * Creates an instance of the Router.\n * @param {Eleva} eleva - The Eleva framework instance.\n * @param {RouterOptions} options - The configuration options for the router.\n */\n constructor(eleva, options = {}) {\n /** @type {Eleva} The Eleva framework instance. */\n this.eleva = eleva;\n\n /** @type {RouterOptions} The merged router options. */\n this.options = {\n mode: \"hash\",\n queryParam: \"view\",\n viewSelector: \"root\",\n ...options,\n };\n\n /** @private @type {RouteDefinition[]} The processed list of route definitions. */\n this.routes = this._processRoutes(options.routes || []);\n\n /** @private @type {import('eleva').Emitter} The shared Eleva event emitter for global hooks. */\n this.emitter = this.eleva.emitter;\n\n /** @private @type {boolean} A flag indicating if the router has been started. */\n this.isStarted = false;\n\n /** @private @type {boolean} A flag to prevent navigation loops from history events. */\n this._isNavigating = false;\n\n /** @private @type {Array<() => void>} A collection of cleanup functions for event listeners. */\n this.eventListeners = [];\n\n /** @type {Signal<RouteLocation | null>} A reactive signal holding the current route's information. */\n this.currentRoute = new this.eleva.signal(null);\n\n /** @type {Signal<RouteLocation | null>} A reactive signal holding the previous route's information. */\n this.previousRoute = new this.eleva.signal(null);\n\n /** @type {Signal<Object<string, string>>} A reactive signal holding the current route's parameters. */\n this.currentParams = new this.eleva.signal({});\n\n /** @type {Signal<Object<string, string>>} A reactive signal holding the current route's query parameters. */\n this.currentQuery = new this.eleva.signal({});\n\n /** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted layout instance. */\n this.currentLayout = new this.eleva.signal(null);\n\n /** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted view (page) instance. */\n this.currentView = new this.eleva.signal(null);\n\n /** @private @type {Map<string, RouterPlugin>} Map of registered plugins by name. */\n this.plugins = new Map();\n\n /** @type {Object} The error handler instance. Can be overridden by plugins. */\n this.errorHandler = CoreErrorHandler;\n\n this._validateOptions();\n }\n\n /**\n * Validates the provided router options.\n * @private\n * @throws {Error} If the routing mode is invalid.\n */\n _validateOptions() {\n if (![\"hash\", \"query\", \"history\"].includes(this.options.mode)) {\n this.errorHandler.handle(\n new Error(\n `Invalid routing mode: ${this.options.mode}. Must be \"hash\", \"query\", or \"history\".`\n ),\n \"Configuration validation failed\"\n );\n }\n }\n\n /**\n * Pre-processes route definitions to parse their path segments for efficient matching.\n * @private\n * @param {RouteDefinition[]} routes - The raw route definitions.\n * @returns {RouteDefinition[]} The processed routes.\n */\n _processRoutes(routes) {\n const processedRoutes = [];\n for (const route of routes) {\n try {\n processedRoutes.push({\n ...route,\n segments: this._parsePathIntoSegments(route.path),\n });\n } catch (error) {\n this.errorHandler.warn(\n `Invalid path in route definition \"${route.path || \"undefined\"}\": ${error.message}`,\n { route, error }\n );\n }\n }\n return processedRoutes;\n }\n\n /**\n * Parses a route path string into an array of static and parameter segments.\n * @private\n * @param {string} path - The path pattern to parse.\n * @returns {Array<{type: 'static' | 'param', value?: string, name?: string}>} An array of segment objects.\n * @throws {Error} If the route path is not a valid string.\n */\n _parsePathIntoSegments(path) {\n if (!path || typeof path !== \"string\") {\n this.errorHandler.handle(\n new Error(\"Route path must be a non-empty string\"),\n \"Path parsing failed\",\n { path }\n );\n }\n\n const normalizedPath = path.replace(/\\/+/g, \"/\").replace(/\\/$/, \"\") || \"/\";\n\n if (normalizedPath === \"/\") {\n return [];\n }\n\n return normalizedPath\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment.startsWith(\":\")) {\n const paramName = segment.substring(1);\n if (!paramName) {\n this.errorHandler.handle(\n new Error(`Invalid parameter segment: ${segment}`),\n \"Path parsing failed\",\n { segment, path }\n );\n }\n return { type: \"param\", name: paramName };\n }\n return { type: \"static\", value: segment };\n });\n }\n\n /**\n * Finds the view element within a container using multiple selector strategies.\n * @private\n * @param {HTMLElement} container - The parent element to search within.\n * @returns {HTMLElement} The found view element or the container itself as a fallback.\n */\n _findViewElement(container) {\n const selector = this.options.viewSelector;\n return (\n container.querySelector(`#${selector}`) ||\n container.querySelector(`.${selector}`) ||\n container.querySelector(`[data-${selector}]`) ||\n container.querySelector(selector) ||\n container\n );\n }\n\n /**\n * Starts the router, initializes event listeners, and performs the initial navigation.\n * @returns {Promise<void>}\n */\n async start() {\n if (this.isStarted) {\n this.errorHandler.warn(\"Router is already started\");\n return;\n }\n if (typeof window === \"undefined\") {\n this.errorHandler.warn(\n \"Router start skipped: `window` object not available (SSR environment)\"\n );\n return;\n }\n if (\n typeof document !== \"undefined\" &&\n !document.querySelector(this.options.mount)\n ) {\n this.errorHandler.warn(\n `Mount element \"${this.options.mount}\" was not found in the DOM. The router will not start.`,\n { mountSelector: this.options.mount }\n );\n return;\n }\n const handler = () => this._handleRouteChange();\n if (this.options.mode === \"hash\") {\n window.addEventListener(\"hashchange\", handler);\n this.eventListeners.push(() =>\n window.removeEventListener(\"hashchange\", handler)\n );\n } else {\n window.addEventListener(\"popstate\", handler);\n this.eventListeners.push(() =>\n window.removeEventListener(\"popstate\", handler)\n );\n }\n this.isStarted = true;\n await this._handleRouteChange();\n }\n\n /**\n * Stops the router and cleans up all event listeners and mounted components.\n * @returns {Promise<void>}\n */\n async destroy() {\n if (!this.isStarted) return;\n\n // Clean up plugins\n for (const plugin of this.plugins.values()) {\n if (typeof plugin.destroy === \"function\") {\n try {\n await plugin.destroy(this);\n } catch (error) {\n this.errorHandler.log(`Plugin ${plugin.name} destroy failed`, error);\n }\n }\n }\n\n this.eventListeners.forEach((cleanup) => cleanup());\n this.eventListeners = [];\n if (this.currentLayout.value) {\n await this.currentLayout.value.unmount();\n }\n this.isStarted = false;\n }\n\n /**\n * Programmatically navigates to a new route.\n * @param {string | {path: string, query?: object, params?: object, replace?: boolean, state?: object}} location - The target location as a string or object.\n * @param {object} [params] - Optional route parameters (for string-based location).\n * @returns {Promise<void>}\n */\n async navigate(location, params = {}) {\n try {\n const target =\n typeof location === \"string\" ? { path: location, params } : location;\n let path = this._buildPath(target.path, target.params || {});\n const query = target.query || {};\n\n if (Object.keys(query).length > 0) {\n const queryString = new URLSearchParams(query).toString();\n if (queryString) path += `?${queryString}`;\n }\n\n if (this._isSameRoute(path, target.params, query)) {\n return;\n }\n\n const navigationSuccessful = await this._proceedWithNavigation(path);\n\n if (navigationSuccessful) {\n this._isNavigating = true;\n const state = target.state || {};\n const replace = target.replace || false;\n const historyMethod = replace ? \"replaceState\" : \"pushState\";\n\n if (this.options.mode === \"hash\") {\n if (replace) {\n const newUrl = `${window.location.pathname}${window.location.search}#${path}`;\n window.history.replaceState(state, \"\", newUrl);\n } else {\n window.location.hash = path;\n }\n } else {\n const url =\n this.options.mode === \"query\" ? this._buildQueryUrl(path) : path;\n history[historyMethod](state, \"\", url);\n }\n queueMicrotask(() => {\n this._isNavigating = false;\n });\n }\n } catch (error) {\n this.errorHandler.log(\"Navigation failed\", error);\n await this.emitter.emit(\"router:onError\", error);\n }\n }\n\n /**\n * Builds a URL for query mode.\n * @private\n * @param {string} path - The path to set as the query parameter.\n * @returns {string} The full URL with the updated query string.\n */\n _buildQueryUrl(path) {\n const urlParams = new URLSearchParams(window.location.search);\n urlParams.set(this.options.queryParam, path.split(\"?\")[0]);\n return `${window.location.pathname}?${urlParams.toString()}`;\n }\n\n /**\n * Checks if the target route is identical to the current route.\n * @private\n * @param {string} path - The target path with query string.\n * @param {object} params - The target params.\n * @param {object} query - The target query.\n * @returns {boolean} - True if the routes are the same.\n */\n _isSameRoute(path, params, query) {\n const current = this.currentRoute.value;\n if (!current) return false;\n const [targetPath, queryString] = path.split(\"?\");\n const targetQuery = query || this._parseQuery(queryString || \"\");\n return (\n current.path === targetPath &&\n JSON.stringify(current.params) === JSON.stringify(params || {}) &&\n JSON.stringify(current.query) === JSON.stringify(targetQuery)\n );\n }\n\n /**\n * Injects dynamic parameters into a path string.\n * @private\n */\n _buildPath(path, params) {\n let result = path;\n for (const [key, value] of Object.entries(params)) {\n // Fix: Handle special characters and ensure proper encoding\n const encodedValue = encodeURIComponent(String(value));\n result = result.replace(new RegExp(`:${key}\\\\b`, \"g\"), encodedValue);\n }\n return result;\n }\n\n /**\n * The handler for browser-initiated route changes (e.g., back/forward buttons).\n * @private\n */\n async _handleRouteChange() {\n if (this._isNavigating) return;\n const from = this.currentRoute.value;\n const toLocation = this._getCurrentLocation();\n\n const navigationSuccessful = await this._proceedWithNavigation(\n toLocation.fullUrl\n );\n\n // If navigation was blocked by a guard, revert the URL change\n if (!navigationSuccessful && from) {\n this.navigate({ path: from.path, query: from.query, replace: true });\n }\n }\n\n /**\n * Manages the core navigation lifecycle. Runs guards before committing changes.\n * @private\n * @param {string} fullPath - The full path (e.g., '/users/123?foo=bar') to navigate to.\n * @returns {Promise<boolean>} - `true` if navigation succeeded, `false` if aborted.\n */\n async _proceedWithNavigation(fullPath) {\n const from = this.currentRoute.value;\n const [path, queryString] = (fullPath || \"/\").split(\"?\");\n const toLocation = {\n path: path.startsWith(\"/\") ? path : `/${path}`,\n query: this._parseQuery(queryString),\n fullUrl: fullPath,\n };\n\n let toMatch = this._matchRoute(toLocation.path);\n\n if (!toMatch) {\n const notFoundRoute = this.routes.find((route) => route.path === \"*\");\n if (notFoundRoute) {\n toMatch = {\n route: notFoundRoute,\n params: { pathMatch: toLocation.path.substring(1) },\n };\n } else {\n await this.emitter.emit(\n \"router:onError\",\n new Error(`Route not found: ${toLocation.path}`),\n toLocation,\n from\n );\n return false;\n }\n }\n\n const to = {\n ...toLocation,\n params: toMatch.params,\n meta: toMatch.route.meta || {},\n name: toMatch.route.name,\n matched: toMatch.route,\n };\n\n try {\n // 1. Run all *pre-navigation* guards.\n const canNavigate = await this._runGuards(to, from, toMatch.route);\n if (!canNavigate) return false;\n\n // 2. Resolve async components *before* touching the DOM.\n const { layoutComponent, pageComponent } = await this._resolveComponents(\n toMatch.route\n );\n\n // 3. Unmount the previous view/layout.\n if (from) {\n const toLayout = toMatch.route.layout || this.options.globalLayout;\n const fromLayout = from.matched.layout || this.options.globalLayout;\n\n const tryUnmount = async (instance) => {\n if (!instance) return;\n\n try {\n await instance.unmount();\n } catch (error) {\n this.errorHandler.warn(\"Error during component unmount\", {\n error,\n instance,\n });\n }\n };\n\n if (toLayout !== fromLayout) {\n await tryUnmount(this.currentLayout.value);\n this.currentLayout.value = null;\n } else {\n await tryUnmount(this.currentView.value);\n this.currentView.value = null;\n }\n\n // 4. Call `afterLeave` hook *after* the old component has been unmounted.\n if (from.matched.afterLeave) {\n await from.matched.afterLeave(to, from);\n await this.emitter.emit(\"router:afterLeave\", to, from);\n }\n }\n\n // 5. Update reactive state.\n this.previousRoute.value = from;\n this.currentRoute.value = to;\n this.currentParams.value = to.params || {};\n this.currentQuery.value = to.query || {};\n\n // 6. Render the new components.\n await this._render(layoutComponent, pageComponent, to);\n\n // 7. Run post-navigation hooks.\n if (toMatch.route.afterEnter) {\n await toMatch.route.afterEnter(to, from);\n await this.emitter.emit(\"router:afterEnter\", to, from);\n }\n await this.emitter.emit(\"router:afterEach\", to, from);\n\n return true;\n } catch (error) {\n this.errorHandler.log(\"Error during navigation\", error, { to, from });\n await this.emitter.emit(\"router:onError\", error, to, from);\n return false;\n }\n }\n\n /**\n * Executes all applicable navigation guards for a transition in order.\n * @private\n * @returns {Promise<boolean>} - `false` if navigation should be aborted.\n */\n async _runGuards(to, from, route) {\n const guards = [\n ...(this.options.onBeforeEach ? [this.options.onBeforeEach] : []),\n ...(from && from.matched.beforeLeave ? [from.matched.beforeLeave] : []),\n ...(route.beforeEnter ? [route.beforeEnter] : []),\n ];\n for (const guard of guards) {\n const result = await guard(to, from);\n if (result === false) return false;\n if (typeof result === \"string\" || typeof result === \"object\") {\n this.navigate(result);\n return false;\n }\n }\n return true;\n }\n\n /**\n * Resolves a string component definition to a component object.\n * @private\n * @param {string} def - The component name to resolve.\n * @returns {ComponentDefinition} The resolved component.\n * @throws {Error} If the component is not registered.\n */\n _resolveStringComponent(def) {\n const componentDef = this.eleva._components.get(def);\n if (!componentDef) {\n this.errorHandler.handle(\n new Error(`Component \"${def}\" not registered.`),\n \"Component resolution failed\",\n {\n componentName: def,\n availableComponents: Array.from(this.eleva._components.keys()),\n }\n );\n }\n return componentDef;\n }\n\n /**\n * Resolves a function component definition to a component object.\n * @private\n * @param {Function} def - The function to resolve.\n * @returns {Promise<ComponentDefinition>} The resolved component.\n * @throws {Error} If the function fails to load the component.\n */\n async _resolveFunctionComponent(def) {\n try {\n const funcStr = def.toString();\n const isAsyncImport =\n funcStr.includes(\"import(\") || funcStr.startsWith(\"() =>\");\n\n const result = await def();\n return isAsyncImport ? result.default || result : result;\n } catch (error) {\n this.errorHandler.handle(\n new Error(`Failed to load async component: ${error.message}`),\n \"Component resolution failed\",\n { function: def.toString(), error }\n );\n }\n }\n\n /**\n * Validates a component definition object.\n * @private\n * @param {any} def - The component definition to validate.\n * @returns {ComponentDefinition} The validated component.\n * @throws {Error} If the component definition is invalid.\n */\n _validateComponentDefinition(def) {\n if (!def || typeof def !== \"object\") {\n this.errorHandler.handle(\n new Error(`Invalid component definition: ${typeof def}`),\n \"Component validation failed\",\n { definition: def }\n );\n }\n\n if (\n typeof def.template !== \"function\" &&\n typeof def.template !== \"string\"\n ) {\n this.errorHandler.handle(\n new Error(\"Component missing template property\"),\n \"Component validation failed\",\n { definition: def }\n );\n }\n\n return def;\n }\n\n /**\n * Resolves a component definition to a component object.\n * @private\n * @param {any} def - The component definition to resolve.\n * @returns {Promise<ComponentDefinition | null>} The resolved component or null.\n */\n async _resolveComponent(def) {\n if (def === null || def === undefined) {\n return null;\n }\n\n if (typeof def === \"string\") {\n return this._resolveStringComponent(def);\n }\n\n if (typeof def === \"function\") {\n return await this._resolveFunctionComponent(def);\n }\n\n if (def && typeof def === \"object\") {\n return this._validateComponentDefinition(def);\n }\n\n this.errorHandler.handle(\n new Error(`Invalid component definition: ${typeof def}`),\n \"Component resolution failed\",\n { definition: def }\n );\n }\n\n /**\n * Asynchronously resolves the layout and page components for a route.\n * @private\n * @param {RouteDefinition} route - The route to resolve components for.\n * @returns {Promise<{layoutComponent: ComponentDefinition | null, pageComponent: ComponentDefinition}>}\n */\n async _resolveComponents(route) {\n const effectiveLayout = route.layout || this.options.globalLayout;\n\n try {\n const [layoutComponent, pageComponent] = await Promise.all([\n this._resolveComponent(effectiveLayout),\n this._resolveComponent(route.component),\n ]);\n\n if (!pageComponent) {\n this.errorHandler.handle(\n new Error(\n `Page component is null or undefined for route: ${route.path}`\n ),\n \"Component resolution failed\",\n { route: route.path }\n );\n }\n\n return { layoutComponent, pageComponent };\n } catch (error) {\n this.errorHandler.log(\n `Error resolving components for route ${route.path}`,\n error,\n { route: route.path }\n );\n throw error;\n }\n }\n\n /**\n * Renders the components for the current route into the DOM.\n * @private\n * @param {ComponentDefinition | null} layoutComponent - The pre-loaded layout component.\n * @param {ComponentDefinition} pageComponent - The pre-loaded page component.\n */\n async _render(layoutComponent, pageComponent) {\n const mountEl = document.querySelector(this.options.mount);\n if (!mountEl) {\n this.errorHandler.handle(\n new Error(`Mount element \"${this.options.mount}\" not found.`),\n { mountSelector: this.options.mount }\n );\n }\n\n if (layoutComponent) {\n const layoutInstance = await this.eleva.mount(\n mountEl,\n this._wrapComponentWithChildren(layoutComponent)\n );\n this.currentLayout.value = layoutInstance;\n const viewEl = this._findViewElement(layoutInstance.container);\n const viewInstance = await this.eleva.mount(\n viewEl,\n this._wrapComponentWithChildren(pageComponent)\n );\n this.currentView.value = viewInstance;\n } else {\n const viewInstance = await this.eleva.mount(\n mountEl,\n this._wrapComponentWithChildren(pageComponent)\n );\n this.currentView.value = viewInstance;\n this.currentLayout.value = null;\n }\n }\n\n /**\n * Creates a getter function for router context properties.\n * @private\n * @param {string} property - The property name to access.\n * @param {any} defaultValue - The default value if property is undefined.\n * @returns {Function} A getter function.\n */\n _createRouteGetter(property, defaultValue) {\n return () => this.currentRoute.value?.[property] ?? defaultValue;\n }\n\n /**\n * Wraps a component definition to inject router-specific context into its setup function.\n * @private\n * @param {ComponentDefinition} component - The component to wrap.\n * @returns {ComponentDefinition} The wrapped component definition.\n */\n _wrapComponent(component) {\n const originalSetup = component.setup;\n const self = this;\n\n return {\n ...component,\n async setup(ctx) {\n ctx.router = {\n navigate: self.navigate.bind(self),\n current: self.currentRoute,\n previous: self.previousRoute,\n\n // Route property getters\n get params() {\n return self._createRouteGetter(\"params\", {})();\n },\n get query() {\n return self._createRouteGetter(\"query\", {})();\n },\n get path() {\n return self._createRouteGetter(\"path\", \"/\")();\n },\n get fullUrl() {\n return self._createRouteGetter(\"fullUrl\", window.location.href)();\n },\n get meta() {\n return self._createRouteGetter(\"meta\", {})();\n },\n };\n\n return originalSetup ? await originalSetup(ctx) : {};\n },\n };\n }\n\n /**\n * Recursively wraps all child components to ensure they have access to router context.\n * @private\n * @param {ComponentDefinition} component - The component to wrap.\n * @returns {ComponentDefinition} The wrapped component definition.\n */\n _wrapComponentWithChildren(component) {\n const wrappedComponent = this._wrapComponent(component);\n\n // If the component has children, wrap them too\n if (\n wrappedComponent.children &&\n typeof wrappedComponent.children === \"object\"\n ) {\n const wrappedChildren = {};\n for (const [selector, childComponent] of Object.entries(\n wrappedComponent.children\n )) {\n wrappedChildren[selector] =\n this._wrapComponentWithChildren(childComponent);\n }\n wrappedComponent.children = wrappedChildren;\n }\n\n return wrappedComponent;\n }\n\n /**\n * Gets the current location information from the browser's window object.\n * @private\n * @returns {Omit<RouteLocation, 'params' | 'meta' | 'name' | 'matched'>}\n */\n _getCurrentLocation() {\n if (typeof window === \"undefined\")\n return { path: \"/\", query: {}, fullUrl: \"\" };\n let path, queryString, fullUrl;\n switch (this.options.mode) {\n case \"hash\":\n fullUrl = window.location.hash.slice(1) || \"/\";\n [path, queryString] = fullUrl.split(\"?\");\n break;\n case \"query\":\n const urlParams = new URLSearchParams(window.location.search);\n path = urlParams.get(this.options.queryParam) || \"/\";\n queryString = window.location.search.slice(1);\n fullUrl = path;\n break;\n default: // 'history' mode\n path = window.location.pathname || \"/\";\n queryString = window.location.search.slice(1);\n fullUrl = `${path}${queryString ? \"?\" + queryString : \"\"}`;\n }\n return {\n path: path.startsWith(\"/\") ? path : `/${path}`,\n query: this._parseQuery(queryString),\n fullUrl,\n };\n }\n\n /**\n * Parses a query string into a key-value object.\n * @private\n */\n _parseQuery(queryString) {\n const query = {};\n if (queryString) {\n new URLSearchParams(queryString).forEach((value, key) => {\n query[key] = value;\n });\n }\n return query;\n }\n\n /**\n * Matches a given path against the registered routes.\n * @private\n * @param {string} path - The path to match.\n * @returns {{route: RouteDefinition, params: Object<string, string>} | null} The matched route and its params, or null.\n */\n _matchRoute(path) {\n const pathSegments = path.split(\"/\").filter(Boolean);\n\n for (const route of this.routes) {\n // Handle the root path as a special case.\n if (route.path === \"/\") {\n if (pathSegments.length === 0) return { route, params: {} };\n continue;\n }\n\n if (route.segments.length !== pathSegments.length) continue;\n\n const params = {};\n let isMatch = true;\n for (let i = 0; i < route.segments.length; i++) {\n const routeSegment = route.segments[i];\n const pathSegment = pathSegments[i];\n if (routeSegment.type === \"param\") {\n params[routeSegment.name] = decodeURIComponent(pathSegment);\n } else if (routeSegment.value !== pathSegment) {\n isMatch = false;\n break;\n }\n }\n if (isMatch) return { route, params };\n }\n return null;\n }\n\n /** Registers a global pre-navigation guard. */\n onBeforeEach(guard) {\n this.options.onBeforeEach = guard;\n }\n /** Registers a global hook that runs after a new route component has been mounted *if* the route has an `afterEnter` hook. */\n onAfterEnter(hook) {\n this.emitter.on(\"router:afterEnter\", hook);\n }\n /** Registers a global hook that runs after a route component has been unmounted *if* the route has an `afterLeave` hook. */\n onAfterLeave(hook) {\n this.emitter.on(\"router:afterLeave\", hook);\n }\n /** Registers a global hook that runs after a navigation has been confirmed and all hooks have completed. */\n onAfterEach(hook) {\n this.emitter.on(\"router:afterEach\", hook);\n }\n /** Registers a global error handler for navigation. */\n onError(handler) {\n this.emitter.on(\"router:onError\", handler);\n }\n\n /**\n * Registers a plugin with the router.\n * @param {RouterPlugin} plugin - The plugin to register.\n */\n use(plugin, options = {}) {\n if (typeof plugin.install !== \"function\") {\n this.errorHandler.handle(\n new Error(\"Plugin must have an install method\"),\n \"Plugin registration failed\",\n { plugin }\n );\n }\n\n // Check if plugin is already registered\n if (this.plugins.has(plugin.name)) {\n this.errorHandler.warn(`Plugin \"${plugin.name}\" is already registered`, {\n existingPlugin: this.plugins.get(plugin.name),\n });\n return;\n }\n\n this.plugins.set(plugin.name, plugin);\n plugin.install(this, options);\n }\n\n /**\n * Gets all registered plugins.\n * @returns {RouterPlugin[]} Array of registered plugins.\n */\n getPlugins() {\n return Array.from(this.plugins.values());\n }\n\n /**\n * Gets a plugin by name.\n * @param {string} name - The plugin name.\n * @returns {RouterPlugin | undefined} The plugin or undefined.\n */\n getPlugin(name) {\n return this.plugins.get(name);\n }\n\n /**\n * Removes a plugin from the router.\n * @param {string} name - The plugin name.\n * @returns {boolean} True if the plugin was removed.\n */\n removePlugin(name) {\n const plugin = this.plugins.get(name);\n if (!plugin) return false;\n\n // Call destroy if available\n if (typeof plugin.destroy === \"function\") {\n try {\n plugin.destroy(this);\n } catch (error) {\n this.errorHandler.log(`Plugin ${name} destroy failed`, error);\n }\n }\n\n return this.plugins.delete(name);\n }\n\n /**\n * Sets a custom error handler. Used by error handling plugins.\n * @param {Object} errorHandler - The error handler object with handle, warn, and log methods.\n */\n setErrorHandler(errorHandler) {\n if (\n errorHandler &&\n typeof errorHandler.handle === \"function\" &&\n typeof errorHandler.warn === \"function\" &&\n typeof errorHandler.log === \"function\"\n ) {\n this.errorHandler = errorHandler;\n } else {\n console.warn(\n \"[ElevaRouter] Invalid error handler provided. Must have handle, warn, and log methods.\"\n );\n }\n }\n}\n\n/**\n * @typedef {Object} RouterOptions\n * @property {string} mount - A CSS selector for the main element where the app is mounted.\n * @property {RouteDefinition[]} routes - An array of route definitions.\n * @property {'hash' | 'query' | 'history'} [mode='hash'] - The routing mode.\n * @property {string} [queryParam='page'] - The query parameter to use in 'query' mode.\n * @property {string} [viewSelector='view'] - The selector for the view element within a layout.\n * @property {boolean} [autoStart=true] - Whether to start the router automatically.\n * @property {NavigationGuard} [onBeforeEach] - A global guard executed before every navigation.\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [globalLayout] - A global layout for all routes. Can be overridden by a route's specific layout.\n */\n\n/**\n * @class 🚀 RouterPlugin\n * @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.js applications.\n * This plugin provides comprehensive client-side routing functionality including:\n * - Multiple routing modes (hash, history, query)\n * - Navigation guards and lifecycle hooks\n * - Reactive state management\n * - Component resolution and lazy loading\n * - Layout and page component separation\n * - Plugin system for extensibility\n * - Advanced error handling\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n *\n * const HomePage = { template: () => `<h1>Home</h1>` };\n * const AboutPage = { template: () => `<h1>About Us</h1>` };\n * const UserPage = {\n * template: (ctx) => `<h1>User: ${ctx.router.params.id}</h1>`\n * };\n *\n * app.use(RouterPlugin, {\n * mount: '#app',\n * mode: 'hash',\n * routes: [\n * { path: '/', component: HomePage },\n * { path: '/about', component: AboutPage },\n * { path: '/users/:id', component: UserPage }\n * ]\n * });\n */\nexport const RouterPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"router\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.1\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description: \"Client-side routing for Eleva applications\",\n\n /**\n * Installs the RouterPlugin into an Eleva instance.\n *\n * @param {Eleva} eleva - The Eleva instance\n * @param {RouterOptions} options - Router configuration options\n * @param {string} options.mount - A CSS selector for the main element where the app is mounted\n * @param {RouteDefinition[]} options.routes - An array of route definitions\n * @param {'hash' | 'query' | 'history'} [options.mode='hash'] - The routing mode\n * @param {string} [options.queryParam='page'] - The query parameter to use in 'query' mode\n * @param {string} [options.viewSelector='view'] - The selector for the view element within a layout\n * @param {boolean} [options.autoStart=true] - Whether to start the router automatically\n * @param {NavigationGuard} [options.onBeforeEach] - A global guard executed before every navigation\n * @param {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [options.globalLayout] - A global layout for all routes\n *\n * @example\n * // main.js\n * import Eleva from './eleva.js';\n * import { RouterPlugin } from './plugins/RouterPlugin.js';\n *\n * const app = new Eleva('myApp');\n *\n * const HomePage = { template: () => `<h1>Home</h1>` };\n * const AboutPage = { template: () => `<h1>About Us</h1>` };\n *\n * app.use(RouterPlugin, {\n * mount: '#app',\n * routes: [\n * { path: '/', component: HomePage },\n * { path: '/about', component: AboutPage }\n * ]\n * });\n */\n install(eleva, options = {}) {\n if (!options.mount) {\n throw new Error(\"[RouterPlugin] 'mount' option is required\");\n }\n\n if (!options.routes || !Array.isArray(options.routes)) {\n throw new Error(\"[RouterPlugin] 'routes' option must be an array\");\n }\n\n /**\n * Registers a component definition with the Eleva instance.\n * This method handles both inline component objects and pre-registered component names.\n *\n * @param {any} def - The component definition to register\n * @param {string} type - The type of component for naming (e.g., \"Route\", \"Layout\")\n * @returns {string | null} The registered component name or null if no definition provided\n */\n const register = (def, type) => {\n if (!def) return null;\n\n if (typeof def === \"object\" && def !== null && !def.name) {\n const name = `Eleva${type}Component_${Math.random()\n .toString(36)\n .slice(2, 11)}`;\n\n try {\n eleva.component(name, def);\n return name;\n } catch (error) {\n throw new Error(\n `[RouterPlugin] Failed to register ${type} component: ${error.message}`\n );\n }\n }\n return def;\n };\n\n if (options.globalLayout) {\n options.globalLayout = register(options.globalLayout, \"GlobalLayout\");\n }\n\n (options.routes || []).forEach((route) => {\n route.component = register(route.component, \"Route\");\n if (route.layout) {\n route.layout = register(route.layout, \"RouteLayout\");\n }\n });\n\n const router = new Router(eleva, options);\n eleva.router = router;\n\n if (options.autoStart !== false) {\n queueMicrotask(() => router.start());\n }\n\n // Add plugin metadata to the Eleva instance\n if (!eleva.plugins) {\n eleva.plugins = new Map();\n }\n eleva.plugins.set(this.name, {\n name: this.name,\n version: this.version,\n description: this.description,\n options,\n });\n\n // Add utility methods for manual router access\n eleva.navigate = router.navigate.bind(router);\n eleva.getCurrentRoute = () => router.currentRoute.value;\n eleva.getRouteParams = () => router.currentParams.value;\n eleva.getRouteQuery = () => router.currentQuery.value;\n\n return router;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Eleva} eleva - The Eleva instance\n */\n async uninstall(eleva) {\n if (eleva.router) {\n await eleva.router.destroy();\n delete eleva.router;\n }\n\n // Remove plugin metadata\n if (eleva.plugins) {\n eleva.plugins.delete(this.name);\n }\n\n // Remove utility methods\n delete eleva.navigate;\n delete eleva.getCurrentRoute;\n delete eleva.getRouteParams;\n delete eleva.getRouteQuery;\n },\n};\n","\"use strict\";\n\n/**\n * @class 🔒 TemplateEngine\n * @classdesc A secure template engine that handles interpolation and dynamic attribute parsing.\n * Provides a safe way to evaluate expressions in templates while preventing XSS attacks.\n * All methods are static and can be called directly on the class.\n *\n * @example\n * const template = \"Hello, {{name}}!\";\n * const data = { name: \"World\" };\n * const result = TemplateEngine.parse(template, data); // Returns: \"Hello, World!\"\n */\nexport class TemplateEngine {\n /**\n * @private {RegExp} Regular expression for matching template expressions in the format {{ expression }}\n * @type {RegExp}\n */\n static expressionPattern = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\n /**\n * Parses a template string, replacing expressions with their evaluated values.\n * Expressions are evaluated in the provided data context.\n *\n * @public\n * @static\n * @param {string} template - The template string to parse.\n * @param {Record<string, unknown>} data - The data context for evaluating expressions.\n * @returns {string} The parsed template with expressions replaced by their values.\n * @example\n * const result = TemplateEngine.parse(\"{{user.name}} is {{user.age}} years old\", {\n * user: { name: \"John\", age: 30 }\n * }); // Returns: \"John is 30 years old\"\n */\n static parse(template, data) {\n if (typeof template !== \"string\") return template;\n return template.replace(this.expressionPattern, (_, expression) =>\n this.evaluate(expression, data)\n );\n }\n\n /**\n * Evaluates an expression in the context of the provided data object.\n * Note: This does not provide a true sandbox and evaluated expressions may access global scope.\n * The use of the `with` statement is necessary for expression evaluation but has security implications.\n * Expressions should be carefully validated before evaluation.\n *\n * @public\n * @static\n * @param {string} expression - The expression to evaluate.\n * @param {Record<string, unknown>} data - The data context for evaluation.\n * @returns {unknown} The result of the evaluation, or an empty string if evaluation fails.\n * @example\n * const result = TemplateEngine.evaluate(\"user.name\", { user: { name: \"John\" } }); // Returns: \"John\"\n * const age = TemplateEngine.evaluate(\"user.age\", { user: { age: 30 } }); // Returns: 30\n */\n static evaluate(expression, data) {\n if (typeof expression !== \"string\") return expression;\n try {\n return new Function(\"data\", `with(data) { return ${expression}; }`)(data);\n } catch {\n return \"\";\n }\n }\n}\n","\"use strict\";\n\nimport { TemplateEngine } from \"../modules/TemplateEngine.js\";\n\n/**\n * @class 🎯 PropsPlugin\n * @classdesc A plugin that extends Eleva's props data handling to support any type of data structure\n * with automatic type detection, parsing, and reactive prop updates. This plugin enables seamless\n * passing of complex data types from parent to child components without manual parsing.\n *\n * Core Features:\n * - Automatic type detection and parsing (strings, numbers, booleans, objects, arrays, dates, etc.)\n * - Support for complex data structures including nested objects and arrays\n * - Reactive props that automatically update when parent data changes\n * - Comprehensive error handling with custom error callbacks\n * - Simple configuration with minimal setup required\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n * app.use(PropsPlugin, {\n * enableAutoParsing: true,\n * enableReactivity: true,\n * onError: (error, value) => {\n * console.error('Props parsing error:', error, value);\n * }\n * });\n *\n * // Use complex props in components\n * app.component(\"UserCard\", {\n * template: (ctx) => `\n * <div class=\"user-info-container\"\n * :user='${JSON.stringify(ctx.user.value)}'\n * :permissions='${JSON.stringify(ctx.permissions.value)}'\n * :settings='${JSON.stringify(ctx.settings.value)}'>\n * </div>\n * `,\n * children: {\n * '.user-info-container': 'UserInfo'\n * }\n * });\n *\n * app.component(\"UserInfo\", {\n * setup({ props }) {\n * return {\n * user: props.user, // Automatically parsed object\n * permissions: props.permissions, // Automatically parsed array\n * settings: props.settings // Automatically parsed object\n * };\n * }\n * });\n */\nexport const PropsPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"props\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.2\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description:\n \"Advanced props data handling for complex data structures with automatic type detection and reactivity\",\n\n /**\n * Installs the plugin into the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n * @param {Object} options - Plugin configuration options\n * @param {boolean} [options.enableAutoParsing=true] - Enable automatic type detection and parsing\n * @param {boolean} [options.enableReactivity=true] - Enable reactive prop updates using Eleva's signal system\n * @param {Function} [options.onError=null] - Error handler function called when parsing fails\n *\n * @example\n * // Basic installation\n * app.use(PropsPlugin);\n *\n * // Installation with custom options\n * app.use(PropsPlugin, {\n * enableAutoParsing: true,\n * enableReactivity: false,\n * onError: (error, value) => {\n * console.error('Props parsing error:', error, value);\n * }\n * });\n */\n install(eleva, options = {}) {\n const {\n enableAutoParsing = true,\n enableReactivity = true,\n onError = null,\n } = options;\n\n /**\n * Detects the type of a given value\n * @private\n * @param {any} value - The value to detect type for\n * @returns {string} The detected type ('string', 'number', 'boolean', 'object', 'array', 'date', 'map', 'set', 'function', 'null', 'undefined', 'unknown')\n *\n * @example\n * detectType(\"hello\") // → \"string\"\n * detectType(42) // → \"number\"\n * detectType(true) // → \"boolean\"\n * detectType([1, 2, 3]) // → \"array\"\n * detectType({}) // → \"object\"\n * detectType(new Date()) // → \"date\"\n * detectType(null) // → \"null\"\n */\n const detectType = (value) => {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"function\") return \"function\";\n if (value instanceof Date) return \"date\";\n if (value instanceof Map) return \"map\";\n if (value instanceof Set) return \"set\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\") return \"object\";\n return \"unknown\";\n };\n\n /**\n * Parses a prop value with automatic type detection\n * @private\n * @param {any} value - The value to parse\n * @returns {any} The parsed value with appropriate type\n *\n * @description\n * This function automatically detects and parses different data types from string values:\n * - Special strings: \"true\" → true, \"false\" → false, \"null\" → null, \"undefined\" → undefined\n * - JSON objects/arrays: '{\"key\": \"value\"}' → {key: \"value\"}, '[1, 2, 3]' → [1, 2, 3]\n * - Boolean-like strings: \"1\" → true, \"0\" → false, \"\" → true\n * - Numeric strings: \"42\" → 42, \"3.14\" → 3.14\n * - Date strings: \"2023-01-01T00:00:00.000Z\" → Date object\n * - Other strings: returned as-is\n *\n * @example\n * parsePropValue(\"true\") // → true\n * parsePropValue(\"42\") // → 42\n * parsePropValue('{\"key\": \"val\"}') // → {key: \"val\"}\n * parsePropValue('[1, 2, 3]') // → [1, 2, 3]\n * parsePropValue(\"hello\") // → \"hello\"\n */\n const parsePropValue = (value) => {\n try {\n // Handle non-string values - return as-is\n if (typeof value !== \"string\") {\n return value;\n }\n\n // Handle special string patterns first\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n if (value === \"null\") return null;\n if (value === \"undefined\") return undefined;\n\n // Try to parse as JSON (for objects and arrays)\n // This handles complex data structures like objects and arrays\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch (e) {\n // Not valid JSON, throw error to trigger error handler\n throw new Error(`Invalid JSON: ${value}`);\n }\n }\n\n // Handle boolean-like strings (including \"1\" and \"0\")\n // These are common in HTML attributes and should be treated as booleans\n if (value === \"1\") return true;\n if (value === \"0\") return false;\n if (value === \"\") return true; // Empty string is truthy in HTML attributes\n\n // Handle numeric strings (after boolean check to avoid conflicts)\n // This ensures \"0\" is treated as boolean false, not number 0\n if (!isNaN(value) && value !== \"\" && !isNaN(parseFloat(value))) {\n return Number(value);\n }\n\n // Handle date strings (ISO format)\n // Recognizes standard ISO date format and converts to Date object\n if (value.match(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)) {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date;\n }\n }\n\n // Return as string if no other parsing applies\n // This is the fallback for regular text strings\n return value;\n } catch (error) {\n // Call error handler if provided\n if (onError) {\n onError(error, value);\n }\n // Fallback to original value to prevent breaking the application\n return value;\n }\n };\n\n /**\n * Enhanced props extraction with automatic type detection\n * @private\n * @param {HTMLElement} element - The DOM element to extract props from\n * @returns {Object} Object containing parsed props with appropriate types\n *\n * @description\n * Extracts props from DOM element attributes that start with \":\" and automatically\n * parses them to their appropriate types. Removes the attributes from the element\n * after extraction.\n *\n * @example\n * // HTML: <div :name=\"John\" :age=\"30\" :active=\"true\" :data='{\"key\": \"value\"}'></div>\n * const props = extractProps(element);\n * // Result: { name: \"John\", age: 30, active: true, data: {key: \"value\"} }\n */\n const extractProps = (element) => {\n const props = {};\n const attrs = element.attributes;\n\n // Iterate through attributes in reverse order to handle removal correctly\n for (let i = attrs.length - 1; i >= 0; i--) {\n const attr = attrs[i];\n // Only process attributes that start with \":\" (prop attributes)\n if (attr.name.startsWith(\":\")) {\n const propName = attr.name.slice(1); // Remove the \":\" prefix\n // Parse the value if auto-parsing is enabled, otherwise use as-is\n const parsedValue = enableAutoParsing\n ? parsePropValue(attr.value)\n : attr.value;\n props[propName] = parsedValue;\n // Remove the attribute from the DOM element after extraction\n element.removeAttribute(attr.name);\n }\n }\n\n return props;\n };\n\n /**\n * Creates reactive props using Eleva's signal system\n * @private\n * @param {Object} props - The props object to make reactive\n * @returns {Object} Object containing reactive props (Eleva signals)\n *\n * @description\n * Converts regular prop values into Eleva signals for reactive updates.\n * If a value is already a signal, it's passed through unchanged.\n *\n * @example\n * const props = { name: \"John\", age: 30, active: true };\n * const reactiveProps = createReactiveProps(props);\n * // Result: {\n * // name: Signal(\"John\"),\n * // age: Signal(30),\n * // active: Signal(true)\n * // }\n */\n const createReactiveProps = (props) => {\n const reactiveProps = {};\n\n // Convert each prop value to a reactive signal\n Object.entries(props).forEach(([key, value]) => {\n // Check if value is already a signal (has 'value' and 'watch' properties)\n if (\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"watch\" in value\n ) {\n // Value is already a signal, use it as-is\n reactiveProps[key] = value;\n } else {\n // Create new signal for the prop value to make it reactive\n reactiveProps[key] = new eleva.signal(value);\n }\n });\n\n return reactiveProps;\n };\n\n // Override Eleva's internal _extractProps method with our enhanced version\n eleva._extractProps = extractProps;\n\n // Override Eleva's mount method to apply enhanced prop handling\n const originalMount = eleva.mount;\n eleva.mount = async (container, compName, props = {}) => {\n // Create reactive props if reactivity is enabled\n const enhancedProps = enableReactivity\n ? createReactiveProps(props)\n : props;\n\n // Call the original mount method with enhanced props\n return await originalMount.call(\n eleva,\n container,\n compName,\n enhancedProps\n );\n };\n\n // Override Eleva's _mountComponents method to enable signal reference passing\n const originalMountComponents = eleva._mountComponents;\n\n // Cache to store parent contexts by container element\n const parentContextCache = new WeakMap();\n // Store child instances that need signal linking\n const pendingSignalLinks = new Set();\n\n eleva._mountComponents = async (container, children, childInstances) => {\n for (const [selector, component] of Object.entries(children)) {\n if (!selector) continue;\n for (const el of container.querySelectorAll(selector)) {\n if (!(el instanceof HTMLElement)) continue;\n\n // Extract props from DOM attributes\n const extractedProps = eleva._extractProps(el);\n\n // Get parent context to check for signal references\n let enhancedProps = extractedProps;\n\n // Try to find parent context by looking up the DOM tree\n let parentContext = parentContextCache.get(container);\n if (!parentContext) {\n let currentElement = container;\n while (currentElement && !parentContext) {\n if (\n currentElement._eleva_instance &&\n currentElement._eleva_instance.data\n ) {\n parentContext = currentElement._eleva_instance.data;\n // Cache the parent context for future use\n parentContextCache.set(container, parentContext);\n break;\n }\n currentElement = currentElement.parentElement;\n }\n }\n\n if (enableReactivity && parentContext) {\n const signalProps = {};\n\n // Check each extracted prop to see if there's a matching signal in parent context\n Object.keys(extractedProps).forEach((propName) => {\n if (\n parentContext[propName] &&\n parentContext[propName] instanceof eleva.signal\n ) {\n // Found a signal in parent context with the same name as the prop\n // Pass the signal reference instead of creating a new one\n signalProps[propName] = parentContext[propName];\n }\n });\n\n // Merge signal props with regular props (signal props take precedence)\n enhancedProps = {\n ...extractedProps,\n ...signalProps,\n };\n }\n\n // Create reactive props for non-signal props only\n let finalProps = enhancedProps;\n if (enableReactivity) {\n // Only create reactive props for values that aren't already signals\n const nonSignalProps = {};\n Object.entries(enhancedProps).forEach(([key, value]) => {\n if (\n !(\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"watch\" in value\n )\n ) {\n // This is not a signal, create a reactive prop for it\n nonSignalProps[key] = value;\n }\n });\n\n // Create reactive props only for non-signal values\n const reactiveNonSignalProps = createReactiveProps(nonSignalProps);\n\n // Merge signal props with reactive non-signal props\n finalProps = {\n ...reactiveNonSignalProps,\n ...enhancedProps, // Signal props take precedence\n };\n }\n\n /** @type {MountResult} */\n const instance = await eleva.mount(el, component, finalProps);\n if (instance && !childInstances.includes(instance)) {\n childInstances.push(instance);\n\n // If we have extracted props but no parent context yet, mark for later signal linking\n if (\n enableReactivity &&\n Object.keys(extractedProps).length > 0 &&\n !parentContext\n ) {\n pendingSignalLinks.add({\n instance,\n extractedProps,\n container,\n component,\n });\n }\n }\n }\n }\n\n // After mounting all children, try to link signals for pending instances\n if (enableReactivity && pendingSignalLinks.size > 0) {\n for (const pending of pendingSignalLinks) {\n const { instance, extractedProps, container, component } = pending;\n\n // Try to find parent context again\n let parentContext = parentContextCache.get(container);\n if (!parentContext) {\n let currentElement = container;\n while (currentElement && !parentContext) {\n if (\n currentElement._eleva_instance &&\n currentElement._eleva_instance.data\n ) {\n parentContext = currentElement._eleva_instance.data;\n parentContextCache.set(container, parentContext);\n break;\n }\n currentElement = currentElement.parentElement;\n }\n }\n\n if (parentContext) {\n const signalProps = {};\n\n // Check each extracted prop to see if there's a matching signal in parent context\n Object.keys(extractedProps).forEach((propName) => {\n if (\n parentContext[propName] &&\n parentContext[propName] instanceof eleva.signal\n ) {\n signalProps[propName] = parentContext[propName];\n }\n });\n\n // Update the child instance's data with signal references\n if (Object.keys(signalProps).length > 0) {\n Object.assign(instance.data, signalProps);\n\n // Set up signal watchers for the newly linked signals\n Object.keys(signalProps).forEach((propName) => {\n const signal = signalProps[propName];\n if (signal && typeof signal.watch === \"function\") {\n signal.watch((newValue) => {\n // Trigger a re-render of the child component when the signal changes\n const childComponent =\n eleva._components.get(component) || component;\n if (childComponent && childComponent.template) {\n const templateResult =\n typeof childComponent.template === \"function\"\n ? childComponent.template(instance.data)\n : childComponent.template;\n const newHtml = TemplateEngine.parse(\n templateResult,\n instance.data\n );\n eleva.renderer.patchDOM(instance.container, newHtml);\n }\n });\n }\n });\n\n // Initial re-render to show the correct signal values\n const childComponent =\n eleva._components.get(component) || component;\n if (childComponent && childComponent.template) {\n const templateResult =\n typeof childComponent.template === \"function\"\n ? childComponent.template(instance.data)\n : childComponent.template;\n const newHtml = TemplateEngine.parse(\n templateResult,\n instance.data\n );\n eleva.renderer.patchDOM(instance.container, newHtml);\n }\n }\n\n // Remove from pending list\n pendingSignalLinks.delete(pending);\n }\n }\n }\n };\n\n /**\n * Expose utility methods on the Eleva instance\n * @namespace eleva.props\n */\n eleva.props = {\n /**\n * Parse a single value with automatic type detection\n * @param {any} value - The value to parse\n * @returns {any} The parsed value with appropriate type\n *\n * @example\n * app.props.parse(\"42\") // → 42\n * app.props.parse(\"true\") // → true\n * app.props.parse('{\"key\": \"val\"}') // → {key: \"val\"}\n */\n parse: (value) => {\n // Return value as-is if auto parsing is disabled\n if (!enableAutoParsing) {\n return value;\n }\n // Use our enhanced parsing function\n return parsePropValue(value);\n },\n\n /**\n * Detect the type of a value\n * @param {any} value - The value to detect type for\n * @returns {string} The detected type\n *\n * @example\n * app.props.detectType(\"hello\") // → \"string\"\n * app.props.detectType(42) // → \"number\"\n * app.props.detectType([1, 2, 3]) // → \"array\"\n */\n detectType,\n };\n\n // Store original methods for uninstall\n eleva._originalExtractProps = eleva._extractProps;\n eleva._originalMount = originalMount;\n eleva._originalMountComponents = originalMountComponents;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n *\n * @description\n * Restores the original Eleva methods and removes all plugin-specific\n * functionality. This method should be called when the plugin is no\n * longer needed.\n *\n * @example\n * // Uninstall the plugin\n * PropsPlugin.uninstall(app);\n */\n uninstall(eleva) {\n // Restore original _extractProps method\n if (eleva._originalExtractProps) {\n eleva._extractProps = eleva._originalExtractProps;\n delete eleva._originalExtractProps;\n }\n\n // Restore original mount method\n if (eleva._originalMount) {\n eleva.mount = eleva._originalMount;\n delete eleva._originalMount;\n }\n\n // Restore original _mountComponents method\n if (eleva._originalMountComponents) {\n eleva._mountComponents = eleva._originalMountComponents;\n delete eleva._originalMountComponents;\n }\n\n // Remove plugin utility methods\n if (eleva.props) {\n delete eleva.props;\n }\n },\n};\n"],"names":["CAMEL_RE","AttrPlugin","name","version","description","install","eleva","options","enableAria","enableData","enableBoolean","enableDynamic","updateAttributes","oldEl","newEl","oldAttrs","attributes","newAttrs","i","length","value","startsWith","getAttribute","slice","replace","_","l","toUpperCase","setAttribute","dataset","prop","Object","getOwnPropertyDescriptor","getPrototypeOf","matchingProp","getOwnPropertyNames","find","p","toLowerCase","includes","descriptor","get","call","boolValue","removeAttribute","hasAttribute","renderer","_originalPatchNode","_patchNode","oldNode","newNode","_eleva_instance","this","_isSameNode","nodeType","Node","ELEMENT_NODE","_diff","TEXT_NODE","nodeValue","replaceWith","cloneNode","plugins","Map","set","updateElementAttributes","uninstall","delete","CoreErrorHandler","handle","error","context","details","formattedError","Error","message","originalError","warn","log","Router","constructor","mode","queryParam","viewSelector","routes","_processRoutes","emitter","isStarted","_isNavigating","eventListeners","currentRoute","signal","previousRoute","currentParams","currentQuery","currentLayout","currentView","errorHandler","_validateOptions","processedRoutes","route","push","segments","_parsePathIntoSegments","path","normalizedPath","split","filter","Boolean","map","segment","paramName","substring","type","_findViewElement","container","selector","querySelector","start","window","document","mount","mountSelector","handler","_handleRouteChange","addEventListener","removeEventListener","destroy","plugin","values","forEach","cleanup","unmount","navigate","location","params","target","_buildPath","query","keys","queryString","URLSearchParams","toString","_isSameRoute","_proceedWithNavigation","state","historyMethod","newUrl","pathname","search","history","replaceState","hash","url","_buildQueryUrl","queueMicrotask","emit","urlParams","current","targetPath","targetQuery","_parseQuery","JSON","stringify","result","key","entries","encodedValue","encodeURIComponent","String","RegExp","from","toLocation","_getCurrentLocation","fullUrl","fullPath","toMatch","_matchRoute","notFoundRoute","pathMatch","to","meta","matched","_runGuards","layoutComponent","pageComponent","_resolveComponents","tryUnmount","async","instance","layout","globalLayout","afterLeave","_render","afterEnter","guards","onBeforeEach","beforeLeave","beforeEnter","guard","_resolveStringComponent","def","componentDef","_components","componentName","availableComponents","Array","_resolveFunctionComponent","funcStr","isAsyncImport","default","function","_validateComponentDefinition","definition","template","_resolveComponent","effectiveLayout","Promise","all","component","mountEl","layoutInstance","_wrapComponentWithChildren","viewEl","viewInstance","_createRouteGetter","property","defaultValue","_wrapComponent","originalSetup","setup","self","ctx","router","bind","previous","href","wrappedComponent","children","wrappedChildren","childComponent","pathSegments","isMatch","routeSegment","pathSegment","decodeURIComponent","onAfterEnter","hook","on","onAfterLeave","onAfterEach","onError","use","has","existingPlugin","getPlugins","getPlugin","removePlugin","setErrorHandler","RouterPlugin","isArray","register","Math","random","autoStart","getCurrentRoute","getRouteParams","getRouteQuery","TemplateEngine","static","parse","data","expressionPattern","expression","evaluate","Function","PropsPlugin","enableAutoParsing","enableReactivity","parsePropValue","e","isNaN","parseFloat","Number","match","date","Date","getTime","createReactiveProps","props","reactiveProps","_extractProps","element","attrs","attr","propName","parsedValue","originalMount","compName","enhancedProps","originalMountComponents","_mountComponents","parentContextCache","WeakMap","pendingSignalLinks","Set","childInstances","el","querySelectorAll","HTMLElement","extractedProps","parentContext","currentElement","parentElement","signalProps","finalProps","nonSignalProps","add","size","pending","assign","watch","newValue","templateResult","newHtml","patchDOM","detectType","undefined","_originalExtractProps","_originalMount","_originalMountComponents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"eleva-plugins.umd.min.js","sources":["../src/plugins/Attr.js","../src/plugins/Router.js","../src/modules/TemplateEngine.js","../src/plugins/Props.js","../src/plugins/Store.js"],"sourcesContent":["\"use strict\";\n\n/**\n * A regular expression to match hyphenated lowercase letters.\n * @private\n * @type {RegExp}\n */\nconst CAMEL_RE = /-([a-z])/g;\n\n/**\n * @class 🎯 AttrPlugin\n * @classdesc A plugin that provides advanced attribute handling for Eleva components.\n * This plugin extends the renderer with sophisticated attribute processing including:\n * - ARIA attribute handling with proper property mapping\n * - Data attribute management\n * - Boolean attribute processing\n * - Dynamic property detection and mapping\n * - Attribute cleanup and removal\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n * app.use(AttrPlugin);\n *\n * // Use advanced attributes in components\n * app.component(\"myComponent\", {\n * template: (ctx) => `\n * <button\n * aria-expanded=\"${ctx.isExpanded.value}\"\n * data-user-id=\"${ctx.userId.value}\"\n * disabled=\"${ctx.isLoading.value}\"\n * class=\"btn ${ctx.variant.value}\"\n * >\n * ${ctx.text.value}\n * </button>\n * `\n * });\n */\nexport const AttrPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"attr\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.1\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description: \"Advanced attribute handling for Eleva components\",\n\n /**\n * Installs the plugin into the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n * @param {Object} options - Plugin configuration options\n * @param {boolean} [options.enableAria=true] - Enable ARIA attribute handling\n * @param {boolean} [options.enableData=true] - Enable data attribute handling\n * @param {boolean} [options.enableBoolean=true] - Enable boolean attribute handling\n * @param {boolean} [options.enableDynamic=true] - Enable dynamic property detection\n */\n install(eleva, options = {}) {\n const {\n enableAria = true,\n enableData = true,\n enableBoolean = true,\n enableDynamic = true,\n } = options;\n\n /**\n * Updates the attributes of an element to match a new element's attributes.\n * This method provides sophisticated attribute processing including:\n * - ARIA attribute handling with proper property mapping\n * - Data attribute management\n * - Boolean attribute processing\n * - Dynamic property detection and mapping\n * - Attribute cleanup and removal\n *\n * @param {HTMLElement} oldEl - The original element to update\n * @param {HTMLElement} newEl - The new element to update\n * @returns {void}\n */\n const updateAttributes = (oldEl, newEl) => {\n const oldAttrs = oldEl.attributes;\n const newAttrs = newEl.attributes;\n\n // Process new attributes\n for (let i = 0; i < newAttrs.length; i++) {\n const { name, value } = newAttrs[i];\n\n // Skip event attributes (handled by event system)\n if (name.startsWith(\"@\")) continue;\n\n // Skip if attribute hasn't changed\n if (oldEl.getAttribute(name) === value) continue;\n\n // Handle ARIA attributes\n if (enableAria && name.startsWith(\"aria-\")) {\n const prop =\n \"aria\" + name.slice(5).replace(CAMEL_RE, (_, l) => l.toUpperCase());\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n // Handle data attributes\n else if (enableData && name.startsWith(\"data-\")) {\n oldEl.dataset[name.slice(5)] = value;\n oldEl.setAttribute(name, value);\n }\n // Handle other attributes\n else {\n let prop = name.replace(CAMEL_RE, (_, l) => l.toUpperCase());\n\n // Dynamic property detection\n if (\n enableDynamic &&\n !(prop in oldEl) &&\n !Object.getOwnPropertyDescriptor(Object.getPrototypeOf(oldEl), prop)\n ) {\n const elementProps = Object.getOwnPropertyNames(\n Object.getPrototypeOf(oldEl)\n );\n const matchingProp = elementProps.find(\n (p) =>\n p.toLowerCase() === name.toLowerCase() ||\n p.toLowerCase().includes(name.toLowerCase()) ||\n name.toLowerCase().includes(p.toLowerCase())\n );\n\n if (matchingProp) {\n prop = matchingProp;\n }\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(\n Object.getPrototypeOf(oldEl),\n prop\n );\n const hasProperty = prop in oldEl || descriptor;\n\n if (hasProperty) {\n // Boolean attribute handling\n if (enableBoolean) {\n const isBoolean =\n typeof oldEl[prop] === \"boolean\" ||\n (descriptor?.get &&\n typeof descriptor.get.call(oldEl) === \"boolean\");\n\n if (isBoolean) {\n const boolValue =\n value !== \"false\" &&\n (value === \"\" || value === prop || value === \"true\");\n oldEl[prop] = boolValue;\n\n if (boolValue) {\n oldEl.setAttribute(name, \"\");\n } else {\n oldEl.removeAttribute(name);\n }\n } else {\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n } else {\n oldEl[prop] = value;\n oldEl.setAttribute(name, value);\n }\n } else {\n oldEl.setAttribute(name, value);\n }\n }\n }\n\n // Remove old attributes that are no longer present\n for (let i = oldAttrs.length - 1; i >= 0; i--) {\n const name = oldAttrs[i].name;\n if (!newEl.hasAttribute(name)) {\n oldEl.removeAttribute(name);\n }\n }\n };\n\n // Extend the renderer with the advanced attribute handler\n if (eleva.renderer) {\n eleva.renderer.updateAttributes = updateAttributes;\n\n // Store the original _patchNode method\n const originalPatchNode = eleva.renderer._patchNode;\n eleva.renderer._originalPatchNode = originalPatchNode;\n\n // Override the _patchNode method to use our attribute handler\n eleva.renderer._patchNode = function (oldNode, newNode) {\n if (oldNode?._eleva_instance) return;\n\n if (!this._isSameNode(oldNode, newNode)) {\n oldNode.replaceWith(newNode.cloneNode(true));\n return;\n }\n\n if (oldNode.nodeType === Node.ELEMENT_NODE) {\n updateAttributes(oldNode, newNode);\n this._diff(oldNode, newNode);\n } else if (\n oldNode.nodeType === Node.TEXT_NODE &&\n oldNode.nodeValue !== newNode.nodeValue\n ) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n };\n }\n\n // Add plugin metadata to the Eleva instance\n if (!eleva.plugins) {\n eleva.plugins = new Map();\n }\n eleva.plugins.set(this.name, {\n name: this.name,\n version: this.version,\n description: this.description,\n options,\n });\n\n // Add utility methods for manual attribute updates\n eleva.updateElementAttributes = updateAttributes;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n */\n uninstall(eleva) {\n // Restore original _patchNode method if it exists\n if (eleva.renderer && eleva.renderer._originalPatchNode) {\n eleva.renderer._patchNode = eleva.renderer._originalPatchNode;\n delete eleva.renderer._originalPatchNode;\n }\n\n // Remove plugin metadata\n if (eleva.plugins) {\n eleva.plugins.delete(this.name);\n }\n\n // Remove utility methods\n delete eleva.updateElementAttributes;\n },\n};\n","\"use strict\";\n\n/**\n * @typedef {import('eleva').Eleva} Eleva\n * @typedef {import('eleva').Signal} Signal\n * @typedef {import('eleva').ComponentDefinition} ComponentDefinition\n */\n\n/**\n * Simple error handler for the core router.\n * Can be overridden by error handling plugins.\n * Provides consistent error formatting and logging for router operations.\n * @private\n */\nconst CoreErrorHandler = {\n /**\n * Handles router errors with basic formatting.\n * @param {Error} error - The error to handle.\n * @param {string} context - The context where the error occurred.\n * @param {Object} details - Additional error details.\n * @throws {Error} The formatted error.\n */\n handle(error, context, details = {}) {\n const message = `[ElevaRouter] ${context}: ${error.message}`;\n const formattedError = new Error(message);\n\n // Preserve original error details\n formattedError.originalError = error;\n formattedError.context = context;\n formattedError.details = details;\n\n console.error(message, { error, context, details });\n throw formattedError;\n },\n\n /**\n * Logs a warning without throwing an error.\n * @param {string} message - The warning message.\n * @param {Object} details - Additional warning details.\n */\n warn(message, details = {}) {\n console.warn(`[ElevaRouter] ${message}`, details);\n },\n\n /**\n * Logs an error without throwing.\n * @param {string} message - The error message.\n * @param {Error} error - The original error.\n * @param {Object} details - Additional error details.\n */\n log(message, error, details = {}) {\n console.error(`[ElevaRouter] ${message}`, { error, details });\n },\n};\n\n/**\n * @typedef {Object} RouteLocation\n * @property {string} path - The path of the route (e.g., '/users/123').\n * @property {Object<string, string>} query - An object representing the query parameters.\n * @property {string} fullUrl - The complete URL including hash, path, and query string.\n * @property {Object<string, string>} params - An object containing dynamic route parameters.\n * @property {Object<string, any>} meta - The meta object associated with the matched route.\n * @property {string} [name] - The optional name of the matched route.\n * @property {RouteDefinition} matched - The raw route definition object that was matched.\n */\n\n/**\n * @typedef {(to: RouteLocation, from: RouteLocation | null) => boolean | string | {path: string} | void | Promise<boolean | string | {path: string} | void>} NavigationGuard\n * A function that acts as a guard for navigation. It runs *before* the navigation is confirmed.\n * It can return:\n * - `true` or `undefined`: to allow navigation.\n * - `false`: to abort the navigation.\n * - a `string` (path) or a `location object`: to redirect to a new route.\n */\n\n/**\n * @typedef {(...args: any[]) => void | Promise<void>} NavigationHook\n * A function that acts as a lifecycle hook, typically for side effects. It does not affect navigation flow.\n */\n\n/**\n * @typedef {Object} RouterPlugin\n * @property {string} name - The plugin name.\n * @property {string} [version] - The plugin version.\n * @property {Function} install - The install function that receives the router instance.\n * @property {Function} [destroy] - Optional cleanup function called when the router is destroyed.\n */\n\n/**\n * @typedef {Object} RouteDefinition\n * @property {string} path - The URL path pattern (e.g., '/', '/about', '/users/:id', '*').\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} component - The component to render. Can be a registered name, a definition object, or an async import function.\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [layout] - An optional layout component to wrap the route's component.\n * @property {string} [name] - An optional name for the route.\n * @property {Object<string, any>} [meta] - Optional metadata for the route (e.g., for titles, auth flags).\n * @property {NavigationGuard} [beforeEnter] - A route-specific guard executed before entering the route.\n * @property {NavigationHook} [afterEnter] - A hook executed *after* the route has been entered and the new component is mounted.\n * @property {NavigationGuard} [beforeLeave] - A guard executed *before* leaving the current route.\n * @property {NavigationHook} [afterLeave] - A hook executed *after* leaving the current route and its component has been unmounted.\n */\n\n/**\n * @class Router\n * @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.js.\n * This class manages all routing logic, including state, navigation, and rendering.\n * @private\n */\nclass Router {\n /**\n * Creates an instance of the Router.\n * @param {Eleva} eleva - The Eleva framework instance.\n * @param {RouterOptions} options - The configuration options for the router.\n */\n constructor(eleva, options = {}) {\n /** @type {Eleva} The Eleva framework instance. */\n this.eleva = eleva;\n\n /** @type {RouterOptions} The merged router options. */\n this.options = {\n mode: \"hash\",\n queryParam: \"view\",\n viewSelector: \"root\",\n ...options,\n };\n\n /** @private @type {RouteDefinition[]} The processed list of route definitions. */\n this.routes = this._processRoutes(options.routes || []);\n\n /** @private @type {import('eleva').Emitter} The shared Eleva event emitter for global hooks. */\n this.emitter = this.eleva.emitter;\n\n /** @private @type {boolean} A flag indicating if the router has been started. */\n this.isStarted = false;\n\n /** @private @type {boolean} A flag to prevent navigation loops from history events. */\n this._isNavigating = false;\n\n /** @private @type {Array<() => void>} A collection of cleanup functions for event listeners. */\n this.eventListeners = [];\n\n /** @type {Signal<RouteLocation | null>} A reactive signal holding the current route's information. */\n this.currentRoute = new this.eleva.signal(null);\n\n /** @type {Signal<RouteLocation | null>} A reactive signal holding the previous route's information. */\n this.previousRoute = new this.eleva.signal(null);\n\n /** @type {Signal<Object<string, string>>} A reactive signal holding the current route's parameters. */\n this.currentParams = new this.eleva.signal({});\n\n /** @type {Signal<Object<string, string>>} A reactive signal holding the current route's query parameters. */\n this.currentQuery = new this.eleva.signal({});\n\n /** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted layout instance. */\n this.currentLayout = new this.eleva.signal(null);\n\n /** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted view (page) instance. */\n this.currentView = new this.eleva.signal(null);\n\n /** @private @type {Map<string, RouterPlugin>} Map of registered plugins by name. */\n this.plugins = new Map();\n\n /** @type {Object} The error handler instance. Can be overridden by plugins. */\n this.errorHandler = CoreErrorHandler;\n\n this._validateOptions();\n }\n\n /**\n * Validates the provided router options.\n * @private\n * @throws {Error} If the routing mode is invalid.\n */\n _validateOptions() {\n if (![\"hash\", \"query\", \"history\"].includes(this.options.mode)) {\n this.errorHandler.handle(\n new Error(\n `Invalid routing mode: ${this.options.mode}. Must be \"hash\", \"query\", or \"history\".`\n ),\n \"Configuration validation failed\"\n );\n }\n }\n\n /**\n * Pre-processes route definitions to parse their path segments for efficient matching.\n * @private\n * @param {RouteDefinition[]} routes - The raw route definitions.\n * @returns {RouteDefinition[]} The processed routes.\n */\n _processRoutes(routes) {\n const processedRoutes = [];\n for (const route of routes) {\n try {\n processedRoutes.push({\n ...route,\n segments: this._parsePathIntoSegments(route.path),\n });\n } catch (error) {\n this.errorHandler.warn(\n `Invalid path in route definition \"${route.path || \"undefined\"}\": ${error.message}`,\n { route, error }\n );\n }\n }\n return processedRoutes;\n }\n\n /**\n * Parses a route path string into an array of static and parameter segments.\n * @private\n * @param {string} path - The path pattern to parse.\n * @returns {Array<{type: 'static' | 'param', value?: string, name?: string}>} An array of segment objects.\n * @throws {Error} If the route path is not a valid string.\n */\n _parsePathIntoSegments(path) {\n if (!path || typeof path !== \"string\") {\n this.errorHandler.handle(\n new Error(\"Route path must be a non-empty string\"),\n \"Path parsing failed\",\n { path }\n );\n }\n\n const normalizedPath = path.replace(/\\/+/g, \"/\").replace(/\\/$/, \"\") || \"/\";\n\n if (normalizedPath === \"/\") {\n return [];\n }\n\n return normalizedPath\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment.startsWith(\":\")) {\n const paramName = segment.substring(1);\n if (!paramName) {\n this.errorHandler.handle(\n new Error(`Invalid parameter segment: ${segment}`),\n \"Path parsing failed\",\n { segment, path }\n );\n }\n return { type: \"param\", name: paramName };\n }\n return { type: \"static\", value: segment };\n });\n }\n\n /**\n * Finds the view element within a container using multiple selector strategies.\n * @private\n * @param {HTMLElement} container - The parent element to search within.\n * @returns {HTMLElement} The found view element or the container itself as a fallback.\n */\n _findViewElement(container) {\n const selector = this.options.viewSelector;\n return (\n container.querySelector(`#${selector}`) ||\n container.querySelector(`.${selector}`) ||\n container.querySelector(`[data-${selector}]`) ||\n container.querySelector(selector) ||\n container\n );\n }\n\n /**\n * Starts the router, initializes event listeners, and performs the initial navigation.\n * @returns {Promise<void>}\n */\n async start() {\n if (this.isStarted) {\n this.errorHandler.warn(\"Router is already started\");\n return;\n }\n if (typeof window === \"undefined\") {\n this.errorHandler.warn(\n \"Router start skipped: `window` object not available (SSR environment)\"\n );\n return;\n }\n if (\n typeof document !== \"undefined\" &&\n !document.querySelector(this.options.mount)\n ) {\n this.errorHandler.warn(\n `Mount element \"${this.options.mount}\" was not found in the DOM. The router will not start.`,\n { mountSelector: this.options.mount }\n );\n return;\n }\n const handler = () => this._handleRouteChange();\n if (this.options.mode === \"hash\") {\n window.addEventListener(\"hashchange\", handler);\n this.eventListeners.push(() =>\n window.removeEventListener(\"hashchange\", handler)\n );\n } else {\n window.addEventListener(\"popstate\", handler);\n this.eventListeners.push(() =>\n window.removeEventListener(\"popstate\", handler)\n );\n }\n this.isStarted = true;\n await this._handleRouteChange();\n }\n\n /**\n * Stops the router and cleans up all event listeners and mounted components.\n * @returns {Promise<void>}\n */\n async destroy() {\n if (!this.isStarted) return;\n\n // Clean up plugins\n for (const plugin of this.plugins.values()) {\n if (typeof plugin.destroy === \"function\") {\n try {\n await plugin.destroy(this);\n } catch (error) {\n this.errorHandler.log(`Plugin ${plugin.name} destroy failed`, error);\n }\n }\n }\n\n this.eventListeners.forEach((cleanup) => cleanup());\n this.eventListeners = [];\n if (this.currentLayout.value) {\n await this.currentLayout.value.unmount();\n }\n this.isStarted = false;\n }\n\n /**\n * Programmatically navigates to a new route.\n * @param {string | {path: string, query?: object, params?: object, replace?: boolean, state?: object}} location - The target location as a string or object.\n * @param {object} [params] - Optional route parameters (for string-based location).\n * @returns {Promise<void>}\n */\n async navigate(location, params = {}) {\n try {\n const target =\n typeof location === \"string\" ? { path: location, params } : location;\n let path = this._buildPath(target.path, target.params || {});\n const query = target.query || {};\n\n if (Object.keys(query).length > 0) {\n const queryString = new URLSearchParams(query).toString();\n if (queryString) path += `?${queryString}`;\n }\n\n if (this._isSameRoute(path, target.params, query)) {\n return;\n }\n\n const navigationSuccessful = await this._proceedWithNavigation(path);\n\n if (navigationSuccessful) {\n this._isNavigating = true;\n const state = target.state || {};\n const replace = target.replace || false;\n const historyMethod = replace ? \"replaceState\" : \"pushState\";\n\n if (this.options.mode === \"hash\") {\n if (replace) {\n const newUrl = `${window.location.pathname}${window.location.search}#${path}`;\n window.history.replaceState(state, \"\", newUrl);\n } else {\n window.location.hash = path;\n }\n } else {\n const url =\n this.options.mode === \"query\" ? this._buildQueryUrl(path) : path;\n history[historyMethod](state, \"\", url);\n }\n queueMicrotask(() => {\n this._isNavigating = false;\n });\n }\n } catch (error) {\n this.errorHandler.log(\"Navigation failed\", error);\n await this.emitter.emit(\"router:onError\", error);\n }\n }\n\n /**\n * Builds a URL for query mode.\n * @private\n * @param {string} path - The path to set as the query parameter.\n * @returns {string} The full URL with the updated query string.\n */\n _buildQueryUrl(path) {\n const urlParams = new URLSearchParams(window.location.search);\n urlParams.set(this.options.queryParam, path.split(\"?\")[0]);\n return `${window.location.pathname}?${urlParams.toString()}`;\n }\n\n /**\n * Checks if the target route is identical to the current route.\n * @private\n * @param {string} path - The target path with query string.\n * @param {object} params - The target params.\n * @param {object} query - The target query.\n * @returns {boolean} - True if the routes are the same.\n */\n _isSameRoute(path, params, query) {\n const current = this.currentRoute.value;\n if (!current) return false;\n const [targetPath, queryString] = path.split(\"?\");\n const targetQuery = query || this._parseQuery(queryString || \"\");\n return (\n current.path === targetPath &&\n JSON.stringify(current.params) === JSON.stringify(params || {}) &&\n JSON.stringify(current.query) === JSON.stringify(targetQuery)\n );\n }\n\n /**\n * Injects dynamic parameters into a path string.\n * @private\n */\n _buildPath(path, params) {\n let result = path;\n for (const [key, value] of Object.entries(params)) {\n // Fix: Handle special characters and ensure proper encoding\n const encodedValue = encodeURIComponent(String(value));\n result = result.replace(new RegExp(`:${key}\\\\b`, \"g\"), encodedValue);\n }\n return result;\n }\n\n /**\n * The handler for browser-initiated route changes (e.g., back/forward buttons).\n * @private\n */\n async _handleRouteChange() {\n if (this._isNavigating) return;\n const from = this.currentRoute.value;\n const toLocation = this._getCurrentLocation();\n\n const navigationSuccessful = await this._proceedWithNavigation(\n toLocation.fullUrl\n );\n\n // If navigation was blocked by a guard, revert the URL change\n if (!navigationSuccessful && from) {\n this.navigate({ path: from.path, query: from.query, replace: true });\n }\n }\n\n /**\n * Manages the core navigation lifecycle. Runs guards before committing changes.\n * @private\n * @param {string} fullPath - The full path (e.g., '/users/123?foo=bar') to navigate to.\n * @returns {Promise<boolean>} - `true` if navigation succeeded, `false` if aborted.\n */\n async _proceedWithNavigation(fullPath) {\n const from = this.currentRoute.value;\n const [path, queryString] = (fullPath || \"/\").split(\"?\");\n const toLocation = {\n path: path.startsWith(\"/\") ? path : `/${path}`,\n query: this._parseQuery(queryString),\n fullUrl: fullPath,\n };\n\n let toMatch = this._matchRoute(toLocation.path);\n\n if (!toMatch) {\n const notFoundRoute = this.routes.find((route) => route.path === \"*\");\n if (notFoundRoute) {\n toMatch = {\n route: notFoundRoute,\n params: { pathMatch: toLocation.path.substring(1) },\n };\n } else {\n await this.emitter.emit(\n \"router:onError\",\n new Error(`Route not found: ${toLocation.path}`),\n toLocation,\n from\n );\n return false;\n }\n }\n\n const to = {\n ...toLocation,\n params: toMatch.params,\n meta: toMatch.route.meta || {},\n name: toMatch.route.name,\n matched: toMatch.route,\n };\n\n try {\n // 1. Run all *pre-navigation* guards.\n const canNavigate = await this._runGuards(to, from, toMatch.route);\n if (!canNavigate) return false;\n\n // 2. Resolve async components *before* touching the DOM.\n const { layoutComponent, pageComponent } = await this._resolveComponents(\n toMatch.route\n );\n\n // 3. Unmount the previous view/layout.\n if (from) {\n const toLayout = toMatch.route.layout || this.options.globalLayout;\n const fromLayout = from.matched.layout || this.options.globalLayout;\n\n const tryUnmount = async (instance) => {\n if (!instance) return;\n\n try {\n await instance.unmount();\n } catch (error) {\n this.errorHandler.warn(\"Error during component unmount\", {\n error,\n instance,\n });\n }\n };\n\n if (toLayout !== fromLayout) {\n await tryUnmount(this.currentLayout.value);\n this.currentLayout.value = null;\n } else {\n await tryUnmount(this.currentView.value);\n this.currentView.value = null;\n }\n\n // 4. Call `afterLeave` hook *after* the old component has been unmounted.\n if (from.matched.afterLeave) {\n await from.matched.afterLeave(to, from);\n await this.emitter.emit(\"router:afterLeave\", to, from);\n }\n }\n\n // 5. Update reactive state.\n this.previousRoute.value = from;\n this.currentRoute.value = to;\n this.currentParams.value = to.params || {};\n this.currentQuery.value = to.query || {};\n\n // 6. Render the new components.\n await this._render(layoutComponent, pageComponent, to);\n\n // 7. Run post-navigation hooks.\n if (toMatch.route.afterEnter) {\n await toMatch.route.afterEnter(to, from);\n await this.emitter.emit(\"router:afterEnter\", to, from);\n }\n await this.emitter.emit(\"router:afterEach\", to, from);\n\n return true;\n } catch (error) {\n this.errorHandler.log(\"Error during navigation\", error, { to, from });\n await this.emitter.emit(\"router:onError\", error, to, from);\n return false;\n }\n }\n\n /**\n * Executes all applicable navigation guards for a transition in order.\n * @private\n * @returns {Promise<boolean>} - `false` if navigation should be aborted.\n */\n async _runGuards(to, from, route) {\n const guards = [\n ...(this.options.onBeforeEach ? [this.options.onBeforeEach] : []),\n ...(from && from.matched.beforeLeave ? [from.matched.beforeLeave] : []),\n ...(route.beforeEnter ? [route.beforeEnter] : []),\n ];\n for (const guard of guards) {\n const result = await guard(to, from);\n if (result === false) return false;\n if (typeof result === \"string\" || typeof result === \"object\") {\n this.navigate(result);\n return false;\n }\n }\n return true;\n }\n\n /**\n * Resolves a string component definition to a component object.\n * @private\n * @param {string} def - The component name to resolve.\n * @returns {ComponentDefinition} The resolved component.\n * @throws {Error} If the component is not registered.\n */\n _resolveStringComponent(def) {\n const componentDef = this.eleva._components.get(def);\n if (!componentDef) {\n this.errorHandler.handle(\n new Error(`Component \"${def}\" not registered.`),\n \"Component resolution failed\",\n {\n componentName: def,\n availableComponents: Array.from(this.eleva._components.keys()),\n }\n );\n }\n return componentDef;\n }\n\n /**\n * Resolves a function component definition to a component object.\n * @private\n * @param {Function} def - The function to resolve.\n * @returns {Promise<ComponentDefinition>} The resolved component.\n * @throws {Error} If the function fails to load the component.\n */\n async _resolveFunctionComponent(def) {\n try {\n const funcStr = def.toString();\n const isAsyncImport =\n funcStr.includes(\"import(\") || funcStr.startsWith(\"() =>\");\n\n const result = await def();\n return isAsyncImport ? result.default || result : result;\n } catch (error) {\n this.errorHandler.handle(\n new Error(`Failed to load async component: ${error.message}`),\n \"Component resolution failed\",\n { function: def.toString(), error }\n );\n }\n }\n\n /**\n * Validates a component definition object.\n * @private\n * @param {any} def - The component definition to validate.\n * @returns {ComponentDefinition} The validated component.\n * @throws {Error} If the component definition is invalid.\n */\n _validateComponentDefinition(def) {\n if (!def || typeof def !== \"object\") {\n this.errorHandler.handle(\n new Error(`Invalid component definition: ${typeof def}`),\n \"Component validation failed\",\n { definition: def }\n );\n }\n\n if (\n typeof def.template !== \"function\" &&\n typeof def.template !== \"string\"\n ) {\n this.errorHandler.handle(\n new Error(\"Component missing template property\"),\n \"Component validation failed\",\n { definition: def }\n );\n }\n\n return def;\n }\n\n /**\n * Resolves a component definition to a component object.\n * @private\n * @param {any} def - The component definition to resolve.\n * @returns {Promise<ComponentDefinition | null>} The resolved component or null.\n */\n async _resolveComponent(def) {\n if (def === null || def === undefined) {\n return null;\n }\n\n if (typeof def === \"string\") {\n return this._resolveStringComponent(def);\n }\n\n if (typeof def === \"function\") {\n return await this._resolveFunctionComponent(def);\n }\n\n if (def && typeof def === \"object\") {\n return this._validateComponentDefinition(def);\n }\n\n this.errorHandler.handle(\n new Error(`Invalid component definition: ${typeof def}`),\n \"Component resolution failed\",\n { definition: def }\n );\n }\n\n /**\n * Asynchronously resolves the layout and page components for a route.\n * @private\n * @param {RouteDefinition} route - The route to resolve components for.\n * @returns {Promise<{layoutComponent: ComponentDefinition | null, pageComponent: ComponentDefinition}>}\n */\n async _resolveComponents(route) {\n const effectiveLayout = route.layout || this.options.globalLayout;\n\n try {\n const [layoutComponent, pageComponent] = await Promise.all([\n this._resolveComponent(effectiveLayout),\n this._resolveComponent(route.component),\n ]);\n\n if (!pageComponent) {\n this.errorHandler.handle(\n new Error(\n `Page component is null or undefined for route: ${route.path}`\n ),\n \"Component resolution failed\",\n { route: route.path }\n );\n }\n\n return { layoutComponent, pageComponent };\n } catch (error) {\n this.errorHandler.log(\n `Error resolving components for route ${route.path}`,\n error,\n { route: route.path }\n );\n throw error;\n }\n }\n\n /**\n * Renders the components for the current route into the DOM.\n * @private\n * @param {ComponentDefinition | null} layoutComponent - The pre-loaded layout component.\n * @param {ComponentDefinition} pageComponent - The pre-loaded page component.\n */\n async _render(layoutComponent, pageComponent) {\n const mountEl = document.querySelector(this.options.mount);\n if (!mountEl) {\n this.errorHandler.handle(\n new Error(`Mount element \"${this.options.mount}\" not found.`),\n { mountSelector: this.options.mount }\n );\n }\n\n if (layoutComponent) {\n const layoutInstance = await this.eleva.mount(\n mountEl,\n this._wrapComponentWithChildren(layoutComponent)\n );\n this.currentLayout.value = layoutInstance;\n const viewEl = this._findViewElement(layoutInstance.container);\n const viewInstance = await this.eleva.mount(\n viewEl,\n this._wrapComponentWithChildren(pageComponent)\n );\n this.currentView.value = viewInstance;\n } else {\n const viewInstance = await this.eleva.mount(\n mountEl,\n this._wrapComponentWithChildren(pageComponent)\n );\n this.currentView.value = viewInstance;\n this.currentLayout.value = null;\n }\n }\n\n /**\n * Creates a getter function for router context properties.\n * @private\n * @param {string} property - The property name to access.\n * @param {any} defaultValue - The default value if property is undefined.\n * @returns {Function} A getter function.\n */\n _createRouteGetter(property, defaultValue) {\n return () => this.currentRoute.value?.[property] ?? defaultValue;\n }\n\n /**\n * Wraps a component definition to inject router-specific context into its setup function.\n * @private\n * @param {ComponentDefinition} component - The component to wrap.\n * @returns {ComponentDefinition} The wrapped component definition.\n */\n _wrapComponent(component) {\n const originalSetup = component.setup;\n const self = this;\n\n return {\n ...component,\n async setup(ctx) {\n ctx.router = {\n navigate: self.navigate.bind(self),\n current: self.currentRoute,\n previous: self.previousRoute,\n\n // Route property getters\n get params() {\n return self._createRouteGetter(\"params\", {})();\n },\n get query() {\n return self._createRouteGetter(\"query\", {})();\n },\n get path() {\n return self._createRouteGetter(\"path\", \"/\")();\n },\n get fullUrl() {\n return self._createRouteGetter(\"fullUrl\", window.location.href)();\n },\n get meta() {\n return self._createRouteGetter(\"meta\", {})();\n },\n };\n\n return originalSetup ? await originalSetup(ctx) : {};\n },\n };\n }\n\n /**\n * Recursively wraps all child components to ensure they have access to router context.\n * @private\n * @param {ComponentDefinition} component - The component to wrap.\n * @returns {ComponentDefinition} The wrapped component definition.\n */\n _wrapComponentWithChildren(component) {\n const wrappedComponent = this._wrapComponent(component);\n\n // If the component has children, wrap them too\n if (\n wrappedComponent.children &&\n typeof wrappedComponent.children === \"object\"\n ) {\n const wrappedChildren = {};\n for (const [selector, childComponent] of Object.entries(\n wrappedComponent.children\n )) {\n wrappedChildren[selector] =\n this._wrapComponentWithChildren(childComponent);\n }\n wrappedComponent.children = wrappedChildren;\n }\n\n return wrappedComponent;\n }\n\n /**\n * Gets the current location information from the browser's window object.\n * @private\n * @returns {Omit<RouteLocation, 'params' | 'meta' | 'name' | 'matched'>}\n */\n _getCurrentLocation() {\n if (typeof window === \"undefined\")\n return { path: \"/\", query: {}, fullUrl: \"\" };\n let path, queryString, fullUrl;\n switch (this.options.mode) {\n case \"hash\":\n fullUrl = window.location.hash.slice(1) || \"/\";\n [path, queryString] = fullUrl.split(\"?\");\n break;\n case \"query\":\n const urlParams = new URLSearchParams(window.location.search);\n path = urlParams.get(this.options.queryParam) || \"/\";\n queryString = window.location.search.slice(1);\n fullUrl = path;\n break;\n default: // 'history' mode\n path = window.location.pathname || \"/\";\n queryString = window.location.search.slice(1);\n fullUrl = `${path}${queryString ? \"?\" + queryString : \"\"}`;\n }\n return {\n path: path.startsWith(\"/\") ? path : `/${path}`,\n query: this._parseQuery(queryString),\n fullUrl,\n };\n }\n\n /**\n * Parses a query string into a key-value object.\n * @private\n */\n _parseQuery(queryString) {\n const query = {};\n if (queryString) {\n new URLSearchParams(queryString).forEach((value, key) => {\n query[key] = value;\n });\n }\n return query;\n }\n\n /**\n * Matches a given path against the registered routes.\n * @private\n * @param {string} path - The path to match.\n * @returns {{route: RouteDefinition, params: Object<string, string>} | null} The matched route and its params, or null.\n */\n _matchRoute(path) {\n const pathSegments = path.split(\"/\").filter(Boolean);\n\n for (const route of this.routes) {\n // Handle the root path as a special case.\n if (route.path === \"/\") {\n if (pathSegments.length === 0) return { route, params: {} };\n continue;\n }\n\n if (route.segments.length !== pathSegments.length) continue;\n\n const params = {};\n let isMatch = true;\n for (let i = 0; i < route.segments.length; i++) {\n const routeSegment = route.segments[i];\n const pathSegment = pathSegments[i];\n if (routeSegment.type === \"param\") {\n params[routeSegment.name] = decodeURIComponent(pathSegment);\n } else if (routeSegment.value !== pathSegment) {\n isMatch = false;\n break;\n }\n }\n if (isMatch) return { route, params };\n }\n return null;\n }\n\n /** Registers a global pre-navigation guard. */\n onBeforeEach(guard) {\n this.options.onBeforeEach = guard;\n }\n /** Registers a global hook that runs after a new route component has been mounted *if* the route has an `afterEnter` hook. */\n onAfterEnter(hook) {\n this.emitter.on(\"router:afterEnter\", hook);\n }\n /** Registers a global hook that runs after a route component has been unmounted *if* the route has an `afterLeave` hook. */\n onAfterLeave(hook) {\n this.emitter.on(\"router:afterLeave\", hook);\n }\n /** Registers a global hook that runs after a navigation has been confirmed and all hooks have completed. */\n onAfterEach(hook) {\n this.emitter.on(\"router:afterEach\", hook);\n }\n /** Registers a global error handler for navigation. */\n onError(handler) {\n this.emitter.on(\"router:onError\", handler);\n }\n\n /**\n * Registers a plugin with the router.\n * @param {RouterPlugin} plugin - The plugin to register.\n */\n use(plugin, options = {}) {\n if (typeof plugin.install !== \"function\") {\n this.errorHandler.handle(\n new Error(\"Plugin must have an install method\"),\n \"Plugin registration failed\",\n { plugin }\n );\n }\n\n // Check if plugin is already registered\n if (this.plugins.has(plugin.name)) {\n this.errorHandler.warn(`Plugin \"${plugin.name}\" is already registered`, {\n existingPlugin: this.plugins.get(plugin.name),\n });\n return;\n }\n\n this.plugins.set(plugin.name, plugin);\n plugin.install(this, options);\n }\n\n /**\n * Gets all registered plugins.\n * @returns {RouterPlugin[]} Array of registered plugins.\n */\n getPlugins() {\n return Array.from(this.plugins.values());\n }\n\n /**\n * Gets a plugin by name.\n * @param {string} name - The plugin name.\n * @returns {RouterPlugin | undefined} The plugin or undefined.\n */\n getPlugin(name) {\n return this.plugins.get(name);\n }\n\n /**\n * Removes a plugin from the router.\n * @param {string} name - The plugin name.\n * @returns {boolean} True if the plugin was removed.\n */\n removePlugin(name) {\n const plugin = this.plugins.get(name);\n if (!plugin) return false;\n\n // Call destroy if available\n if (typeof plugin.destroy === \"function\") {\n try {\n plugin.destroy(this);\n } catch (error) {\n this.errorHandler.log(`Plugin ${name} destroy failed`, error);\n }\n }\n\n return this.plugins.delete(name);\n }\n\n /**\n * Sets a custom error handler. Used by error handling plugins.\n * @param {Object} errorHandler - The error handler object with handle, warn, and log methods.\n */\n setErrorHandler(errorHandler) {\n if (\n errorHandler &&\n typeof errorHandler.handle === \"function\" &&\n typeof errorHandler.warn === \"function\" &&\n typeof errorHandler.log === \"function\"\n ) {\n this.errorHandler = errorHandler;\n } else {\n console.warn(\n \"[ElevaRouter] Invalid error handler provided. Must have handle, warn, and log methods.\"\n );\n }\n }\n}\n\n/**\n * @typedef {Object} RouterOptions\n * @property {string} mount - A CSS selector for the main element where the app is mounted.\n * @property {RouteDefinition[]} routes - An array of route definitions.\n * @property {'hash' | 'query' | 'history'} [mode='hash'] - The routing mode.\n * @property {string} [queryParam='page'] - The query parameter to use in 'query' mode.\n * @property {string} [viewSelector='view'] - The selector for the view element within a layout.\n * @property {boolean} [autoStart=true] - Whether to start the router automatically.\n * @property {NavigationGuard} [onBeforeEach] - A global guard executed before every navigation.\n * @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [globalLayout] - A global layout for all routes. Can be overridden by a route's specific layout.\n */\n\n/**\n * @class 🚀 RouterPlugin\n * @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.js applications.\n * This plugin provides comprehensive client-side routing functionality including:\n * - Multiple routing modes (hash, history, query)\n * - Navigation guards and lifecycle hooks\n * - Reactive state management\n * - Component resolution and lazy loading\n * - Layout and page component separation\n * - Plugin system for extensibility\n * - Advanced error handling\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n *\n * const HomePage = { template: () => `<h1>Home</h1>` };\n * const AboutPage = { template: () => `<h1>About Us</h1>` };\n * const UserPage = {\n * template: (ctx) => `<h1>User: ${ctx.router.params.id}</h1>`\n * };\n *\n * app.use(RouterPlugin, {\n * mount: '#app',\n * mode: 'hash',\n * routes: [\n * { path: '/', component: HomePage },\n * { path: '/about', component: AboutPage },\n * { path: '/users/:id', component: UserPage }\n * ]\n * });\n */\nexport const RouterPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"router\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.1\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description: \"Client-side routing for Eleva applications\",\n\n /**\n * Installs the RouterPlugin into an Eleva instance.\n *\n * @param {Eleva} eleva - The Eleva instance\n * @param {RouterOptions} options - Router configuration options\n * @param {string} options.mount - A CSS selector for the main element where the app is mounted\n * @param {RouteDefinition[]} options.routes - An array of route definitions\n * @param {'hash' | 'query' | 'history'} [options.mode='hash'] - The routing mode\n * @param {string} [options.queryParam='page'] - The query parameter to use in 'query' mode\n * @param {string} [options.viewSelector='view'] - The selector for the view element within a layout\n * @param {boolean} [options.autoStart=true] - Whether to start the router automatically\n * @param {NavigationGuard} [options.onBeforeEach] - A global guard executed before every navigation\n * @param {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [options.globalLayout] - A global layout for all routes\n *\n * @example\n * // main.js\n * import Eleva from './eleva.js';\n * import { RouterPlugin } from './plugins/RouterPlugin.js';\n *\n * const app = new Eleva('myApp');\n *\n * const HomePage = { template: () => `<h1>Home</h1>` };\n * const AboutPage = { template: () => `<h1>About Us</h1>` };\n *\n * app.use(RouterPlugin, {\n * mount: '#app',\n * routes: [\n * { path: '/', component: HomePage },\n * { path: '/about', component: AboutPage }\n * ]\n * });\n */\n install(eleva, options = {}) {\n if (!options.mount) {\n throw new Error(\"[RouterPlugin] 'mount' option is required\");\n }\n\n if (!options.routes || !Array.isArray(options.routes)) {\n throw new Error(\"[RouterPlugin] 'routes' option must be an array\");\n }\n\n /**\n * Registers a component definition with the Eleva instance.\n * This method handles both inline component objects and pre-registered component names.\n *\n * @param {any} def - The component definition to register\n * @param {string} type - The type of component for naming (e.g., \"Route\", \"Layout\")\n * @returns {string | null} The registered component name or null if no definition provided\n */\n const register = (def, type) => {\n if (!def) return null;\n\n if (typeof def === \"object\" && def !== null && !def.name) {\n const name = `Eleva${type}Component_${Math.random()\n .toString(36)\n .slice(2, 11)}`;\n\n try {\n eleva.component(name, def);\n return name;\n } catch (error) {\n throw new Error(\n `[RouterPlugin] Failed to register ${type} component: ${error.message}`\n );\n }\n }\n return def;\n };\n\n if (options.globalLayout) {\n options.globalLayout = register(options.globalLayout, \"GlobalLayout\");\n }\n\n (options.routes || []).forEach((route) => {\n route.component = register(route.component, \"Route\");\n if (route.layout) {\n route.layout = register(route.layout, \"RouteLayout\");\n }\n });\n\n const router = new Router(eleva, options);\n eleva.router = router;\n\n if (options.autoStart !== false) {\n queueMicrotask(() => router.start());\n }\n\n // Add plugin metadata to the Eleva instance\n if (!eleva.plugins) {\n eleva.plugins = new Map();\n }\n eleva.plugins.set(this.name, {\n name: this.name,\n version: this.version,\n description: this.description,\n options,\n });\n\n // Add utility methods for manual router access\n eleva.navigate = router.navigate.bind(router);\n eleva.getCurrentRoute = () => router.currentRoute.value;\n eleva.getRouteParams = () => router.currentParams.value;\n eleva.getRouteQuery = () => router.currentQuery.value;\n\n return router;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Eleva} eleva - The Eleva instance\n */\n async uninstall(eleva) {\n if (eleva.router) {\n await eleva.router.destroy();\n delete eleva.router;\n }\n\n // Remove plugin metadata\n if (eleva.plugins) {\n eleva.plugins.delete(this.name);\n }\n\n // Remove utility methods\n delete eleva.navigate;\n delete eleva.getCurrentRoute;\n delete eleva.getRouteParams;\n delete eleva.getRouteQuery;\n },\n};\n","\"use strict\";\n\n/**\n * @class 🔒 TemplateEngine\n * @classdesc A secure template engine that handles interpolation and dynamic attribute parsing.\n * Provides a safe way to evaluate expressions in templates while preventing XSS attacks.\n * All methods are static and can be called directly on the class.\n *\n * @example\n * const template = \"Hello, {{name}}!\";\n * const data = { name: \"World\" };\n * const result = TemplateEngine.parse(template, data); // Returns: \"Hello, World!\"\n */\nexport class TemplateEngine {\n /**\n * @private {RegExp} Regular expression for matching template expressions in the format {{ expression }}\n * @type {RegExp}\n */\n static expressionPattern = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\n /**\n * Parses a template string, replacing expressions with their evaluated values.\n * Expressions are evaluated in the provided data context.\n *\n * @public\n * @static\n * @param {string} template - The template string to parse.\n * @param {Record<string, unknown>} data - The data context for evaluating expressions.\n * @returns {string} The parsed template with expressions replaced by their values.\n * @example\n * const result = TemplateEngine.parse(\"{{user.name}} is {{user.age}} years old\", {\n * user: { name: \"John\", age: 30 }\n * }); // Returns: \"John is 30 years old\"\n */\n static parse(template, data) {\n if (typeof template !== \"string\") return template;\n return template.replace(this.expressionPattern, (_, expression) =>\n this.evaluate(expression, data)\n );\n }\n\n /**\n * Evaluates an expression in the context of the provided data object.\n * Note: This does not provide a true sandbox and evaluated expressions may access global scope.\n * The use of the `with` statement is necessary for expression evaluation but has security implications.\n * Expressions should be carefully validated before evaluation.\n *\n * @public\n * @static\n * @param {string} expression - The expression to evaluate.\n * @param {Record<string, unknown>} data - The data context for evaluation.\n * @returns {unknown} The result of the evaluation, or an empty string if evaluation fails.\n * @example\n * const result = TemplateEngine.evaluate(\"user.name\", { user: { name: \"John\" } }); // Returns: \"John\"\n * const age = TemplateEngine.evaluate(\"user.age\", { user: { age: 30 } }); // Returns: 30\n */\n static evaluate(expression, data) {\n if (typeof expression !== \"string\") return expression;\n try {\n return new Function(\"data\", `with(data) { return ${expression}; }`)(data);\n } catch {\n return \"\";\n }\n }\n}\n","\"use strict\";\n\nimport { TemplateEngine } from \"../modules/TemplateEngine.js\";\n\n/**\n * @class 🎯 PropsPlugin\n * @classdesc A plugin that extends Eleva's props data handling to support any type of data structure\n * with automatic type detection, parsing, and reactive prop updates. This plugin enables seamless\n * passing of complex data types from parent to child components without manual parsing.\n *\n * Core Features:\n * - Automatic type detection and parsing (strings, numbers, booleans, objects, arrays, dates, etc.)\n * - Support for complex data structures including nested objects and arrays\n * - Reactive props that automatically update when parent data changes\n * - Comprehensive error handling with custom error callbacks\n * - Simple configuration with minimal setup required\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n * app.use(PropsPlugin, {\n * enableAutoParsing: true,\n * enableReactivity: true,\n * onError: (error, value) => {\n * console.error('Props parsing error:', error, value);\n * }\n * });\n *\n * // Use complex props in components\n * app.component(\"UserCard\", {\n * template: (ctx) => `\n * <div class=\"user-info-container\"\n * :user='${JSON.stringify(ctx.user.value)}'\n * :permissions='${JSON.stringify(ctx.permissions.value)}'\n * :settings='${JSON.stringify(ctx.settings.value)}'>\n * </div>\n * `,\n * children: {\n * '.user-info-container': 'UserInfo'\n * }\n * });\n *\n * app.component(\"UserInfo\", {\n * setup({ props }) {\n * return {\n * user: props.user, // Automatically parsed object\n * permissions: props.permissions, // Automatically parsed array\n * settings: props.settings // Automatically parsed object\n * };\n * }\n * });\n */\nexport const PropsPlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"props\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.2\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description:\n \"Advanced props data handling for complex data structures with automatic type detection and reactivity\",\n\n /**\n * Installs the plugin into the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n * @param {Object} options - Plugin configuration options\n * @param {boolean} [options.enableAutoParsing=true] - Enable automatic type detection and parsing\n * @param {boolean} [options.enableReactivity=true] - Enable reactive prop updates using Eleva's signal system\n * @param {Function} [options.onError=null] - Error handler function called when parsing fails\n *\n * @example\n * // Basic installation\n * app.use(PropsPlugin);\n *\n * // Installation with custom options\n * app.use(PropsPlugin, {\n * enableAutoParsing: true,\n * enableReactivity: false,\n * onError: (error, value) => {\n * console.error('Props parsing error:', error, value);\n * }\n * });\n */\n install(eleva, options = {}) {\n const {\n enableAutoParsing = true,\n enableReactivity = true,\n onError = null,\n } = options;\n\n /**\n * Detects the type of a given value\n * @private\n * @param {any} value - The value to detect type for\n * @returns {string} The detected type ('string', 'number', 'boolean', 'object', 'array', 'date', 'map', 'set', 'function', 'null', 'undefined', 'unknown')\n *\n * @example\n * detectType(\"hello\") // → \"string\"\n * detectType(42) // → \"number\"\n * detectType(true) // → \"boolean\"\n * detectType([1, 2, 3]) // → \"array\"\n * detectType({}) // → \"object\"\n * detectType(new Date()) // → \"date\"\n * detectType(null) // → \"null\"\n */\n const detectType = (value) => {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"function\") return \"function\";\n if (value instanceof Date) return \"date\";\n if (value instanceof Map) return \"map\";\n if (value instanceof Set) return \"set\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\") return \"object\";\n return \"unknown\";\n };\n\n /**\n * Parses a prop value with automatic type detection\n * @private\n * @param {any} value - The value to parse\n * @returns {any} The parsed value with appropriate type\n *\n * @description\n * This function automatically detects and parses different data types from string values:\n * - Special strings: \"true\" → true, \"false\" → false, \"null\" → null, \"undefined\" → undefined\n * - JSON objects/arrays: '{\"key\": \"value\"}' → {key: \"value\"}, '[1, 2, 3]' → [1, 2, 3]\n * - Boolean-like strings: \"1\" → true, \"0\" → false, \"\" → true\n * - Numeric strings: \"42\" → 42, \"3.14\" → 3.14\n * - Date strings: \"2023-01-01T00:00:00.000Z\" → Date object\n * - Other strings: returned as-is\n *\n * @example\n * parsePropValue(\"true\") // → true\n * parsePropValue(\"42\") // → 42\n * parsePropValue('{\"key\": \"val\"}') // → {key: \"val\"}\n * parsePropValue('[1, 2, 3]') // → [1, 2, 3]\n * parsePropValue(\"hello\") // → \"hello\"\n */\n const parsePropValue = (value) => {\n try {\n // Handle non-string values - return as-is\n if (typeof value !== \"string\") {\n return value;\n }\n\n // Handle special string patterns first\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n if (value === \"null\") return null;\n if (value === \"undefined\") return undefined;\n\n // Try to parse as JSON (for objects and arrays)\n // This handles complex data structures like objects and arrays\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch (e) {\n // Not valid JSON, throw error to trigger error handler\n throw new Error(`Invalid JSON: ${value}`);\n }\n }\n\n // Handle boolean-like strings (including \"1\" and \"0\")\n // These are common in HTML attributes and should be treated as booleans\n if (value === \"1\") return true;\n if (value === \"0\") return false;\n if (value === \"\") return true; // Empty string is truthy in HTML attributes\n\n // Handle numeric strings (after boolean check to avoid conflicts)\n // This ensures \"0\" is treated as boolean false, not number 0\n if (!isNaN(value) && value !== \"\" && !isNaN(parseFloat(value))) {\n return Number(value);\n }\n\n // Handle date strings (ISO format)\n // Recognizes standard ISO date format and converts to Date object\n if (value.match(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)) {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date;\n }\n }\n\n // Return as string if no other parsing applies\n // This is the fallback for regular text strings\n return value;\n } catch (error) {\n // Call error handler if provided\n if (onError) {\n onError(error, value);\n }\n // Fallback to original value to prevent breaking the application\n return value;\n }\n };\n\n /**\n * Enhanced props extraction with automatic type detection\n * @private\n * @param {HTMLElement} element - The DOM element to extract props from\n * @returns {Object} Object containing parsed props with appropriate types\n *\n * @description\n * Extracts props from DOM element attributes that start with \":\" and automatically\n * parses them to their appropriate types. Removes the attributes from the element\n * after extraction.\n *\n * @example\n * // HTML: <div :name=\"John\" :age=\"30\" :active=\"true\" :data='{\"key\": \"value\"}'></div>\n * const props = extractProps(element);\n * // Result: { name: \"John\", age: 30, active: true, data: {key: \"value\"} }\n */\n const extractProps = (element) => {\n const props = {};\n const attrs = element.attributes;\n\n // Iterate through attributes in reverse order to handle removal correctly\n for (let i = attrs.length - 1; i >= 0; i--) {\n const attr = attrs[i];\n // Only process attributes that start with \":\" (prop attributes)\n if (attr.name.startsWith(\":\")) {\n const propName = attr.name.slice(1); // Remove the \":\" prefix\n // Parse the value if auto-parsing is enabled, otherwise use as-is\n const parsedValue = enableAutoParsing\n ? parsePropValue(attr.value)\n : attr.value;\n props[propName] = parsedValue;\n // Remove the attribute from the DOM element after extraction\n element.removeAttribute(attr.name);\n }\n }\n\n return props;\n };\n\n /**\n * Creates reactive props using Eleva's signal system\n * @private\n * @param {Object} props - The props object to make reactive\n * @returns {Object} Object containing reactive props (Eleva signals)\n *\n * @description\n * Converts regular prop values into Eleva signals for reactive updates.\n * If a value is already a signal, it's passed through unchanged.\n *\n * @example\n * const props = { name: \"John\", age: 30, active: true };\n * const reactiveProps = createReactiveProps(props);\n * // Result: {\n * // name: Signal(\"John\"),\n * // age: Signal(30),\n * // active: Signal(true)\n * // }\n */\n const createReactiveProps = (props) => {\n const reactiveProps = {};\n\n // Convert each prop value to a reactive signal\n Object.entries(props).forEach(([key, value]) => {\n // Check if value is already a signal (has 'value' and 'watch' properties)\n if (\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"watch\" in value\n ) {\n // Value is already a signal, use it as-is\n reactiveProps[key] = value;\n } else {\n // Create new signal for the prop value to make it reactive\n reactiveProps[key] = new eleva.signal(value);\n }\n });\n\n return reactiveProps;\n };\n\n // Override Eleva's internal _extractProps method with our enhanced version\n eleva._extractProps = extractProps;\n\n // Override Eleva's mount method to apply enhanced prop handling\n const originalMount = eleva.mount;\n eleva.mount = async (container, compName, props = {}) => {\n // Create reactive props if reactivity is enabled\n const enhancedProps = enableReactivity\n ? createReactiveProps(props)\n : props;\n\n // Call the original mount method with enhanced props\n return await originalMount.call(\n eleva,\n container,\n compName,\n enhancedProps\n );\n };\n\n // Override Eleva's _mountComponents method to enable signal reference passing\n const originalMountComponents = eleva._mountComponents;\n\n // Cache to store parent contexts by container element\n const parentContextCache = new WeakMap();\n // Store child instances that need signal linking\n const pendingSignalLinks = new Set();\n\n eleva._mountComponents = async (container, children, childInstances) => {\n for (const [selector, component] of Object.entries(children)) {\n if (!selector) continue;\n for (const el of container.querySelectorAll(selector)) {\n if (!(el instanceof HTMLElement)) continue;\n\n // Extract props from DOM attributes\n const extractedProps = eleva._extractProps(el);\n\n // Get parent context to check for signal references\n let enhancedProps = extractedProps;\n\n // Try to find parent context by looking up the DOM tree\n let parentContext = parentContextCache.get(container);\n if (!parentContext) {\n let currentElement = container;\n while (currentElement && !parentContext) {\n if (\n currentElement._eleva_instance &&\n currentElement._eleva_instance.data\n ) {\n parentContext = currentElement._eleva_instance.data;\n // Cache the parent context for future use\n parentContextCache.set(container, parentContext);\n break;\n }\n currentElement = currentElement.parentElement;\n }\n }\n\n if (enableReactivity && parentContext) {\n const signalProps = {};\n\n // Check each extracted prop to see if there's a matching signal in parent context\n Object.keys(extractedProps).forEach((propName) => {\n if (\n parentContext[propName] &&\n parentContext[propName] instanceof eleva.signal\n ) {\n // Found a signal in parent context with the same name as the prop\n // Pass the signal reference instead of creating a new one\n signalProps[propName] = parentContext[propName];\n }\n });\n\n // Merge signal props with regular props (signal props take precedence)\n enhancedProps = {\n ...extractedProps,\n ...signalProps,\n };\n }\n\n // Create reactive props for non-signal props only\n let finalProps = enhancedProps;\n if (enableReactivity) {\n // Only create reactive props for values that aren't already signals\n const nonSignalProps = {};\n Object.entries(enhancedProps).forEach(([key, value]) => {\n if (\n !(\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"watch\" in value\n )\n ) {\n // This is not a signal, create a reactive prop for it\n nonSignalProps[key] = value;\n }\n });\n\n // Create reactive props only for non-signal values\n const reactiveNonSignalProps = createReactiveProps(nonSignalProps);\n\n // Merge signal props with reactive non-signal props\n finalProps = {\n ...reactiveNonSignalProps,\n ...enhancedProps, // Signal props take precedence\n };\n }\n\n /** @type {MountResult} */\n const instance = await eleva.mount(el, component, finalProps);\n if (instance && !childInstances.includes(instance)) {\n childInstances.push(instance);\n\n // If we have extracted props but no parent context yet, mark for later signal linking\n if (\n enableReactivity &&\n Object.keys(extractedProps).length > 0 &&\n !parentContext\n ) {\n pendingSignalLinks.add({\n instance,\n extractedProps,\n container,\n component,\n });\n }\n }\n }\n }\n\n // After mounting all children, try to link signals for pending instances\n if (enableReactivity && pendingSignalLinks.size > 0) {\n for (const pending of pendingSignalLinks) {\n const { instance, extractedProps, container, component } = pending;\n\n // Try to find parent context again\n let parentContext = parentContextCache.get(container);\n if (!parentContext) {\n let currentElement = container;\n while (currentElement && !parentContext) {\n if (\n currentElement._eleva_instance &&\n currentElement._eleva_instance.data\n ) {\n parentContext = currentElement._eleva_instance.data;\n parentContextCache.set(container, parentContext);\n break;\n }\n currentElement = currentElement.parentElement;\n }\n }\n\n if (parentContext) {\n const signalProps = {};\n\n // Check each extracted prop to see if there's a matching signal in parent context\n Object.keys(extractedProps).forEach((propName) => {\n if (\n parentContext[propName] &&\n parentContext[propName] instanceof eleva.signal\n ) {\n signalProps[propName] = parentContext[propName];\n }\n });\n\n // Update the child instance's data with signal references\n if (Object.keys(signalProps).length > 0) {\n Object.assign(instance.data, signalProps);\n\n // Set up signal watchers for the newly linked signals\n Object.keys(signalProps).forEach((propName) => {\n const signal = signalProps[propName];\n if (signal && typeof signal.watch === \"function\") {\n signal.watch((newValue) => {\n // Trigger a re-render of the child component when the signal changes\n const childComponent =\n eleva._components.get(component) || component;\n if (childComponent && childComponent.template) {\n const templateResult =\n typeof childComponent.template === \"function\"\n ? childComponent.template(instance.data)\n : childComponent.template;\n const newHtml = TemplateEngine.parse(\n templateResult,\n instance.data\n );\n eleva.renderer.patchDOM(instance.container, newHtml);\n }\n });\n }\n });\n\n // Initial re-render to show the correct signal values\n const childComponent =\n eleva._components.get(component) || component;\n if (childComponent && childComponent.template) {\n const templateResult =\n typeof childComponent.template === \"function\"\n ? childComponent.template(instance.data)\n : childComponent.template;\n const newHtml = TemplateEngine.parse(\n templateResult,\n instance.data\n );\n eleva.renderer.patchDOM(instance.container, newHtml);\n }\n }\n\n // Remove from pending list\n pendingSignalLinks.delete(pending);\n }\n }\n }\n };\n\n /**\n * Expose utility methods on the Eleva instance\n * @namespace eleva.props\n */\n eleva.props = {\n /**\n * Parse a single value with automatic type detection\n * @param {any} value - The value to parse\n * @returns {any} The parsed value with appropriate type\n *\n * @example\n * app.props.parse(\"42\") // → 42\n * app.props.parse(\"true\") // → true\n * app.props.parse('{\"key\": \"val\"}') // → {key: \"val\"}\n */\n parse: (value) => {\n // Return value as-is if auto parsing is disabled\n if (!enableAutoParsing) {\n return value;\n }\n // Use our enhanced parsing function\n return parsePropValue(value);\n },\n\n /**\n * Detect the type of a value\n * @param {any} value - The value to detect type for\n * @returns {string} The detected type\n *\n * @example\n * app.props.detectType(\"hello\") // → \"string\"\n * app.props.detectType(42) // → \"number\"\n * app.props.detectType([1, 2, 3]) // → \"array\"\n */\n detectType,\n };\n\n // Store original methods for uninstall\n eleva._originalExtractProps = eleva._extractProps;\n eleva._originalMount = originalMount;\n eleva._originalMountComponents = originalMountComponents;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n *\n * @description\n * Restores the original Eleva methods and removes all plugin-specific\n * functionality. This method should be called when the plugin is no\n * longer needed.\n *\n * @example\n * // Uninstall the plugin\n * PropsPlugin.uninstall(app);\n */\n uninstall(eleva) {\n // Restore original _extractProps method\n if (eleva._originalExtractProps) {\n eleva._extractProps = eleva._originalExtractProps;\n delete eleva._originalExtractProps;\n }\n\n // Restore original mount method\n if (eleva._originalMount) {\n eleva.mount = eleva._originalMount;\n delete eleva._originalMount;\n }\n\n // Restore original _mountComponents method\n if (eleva._originalMountComponents) {\n eleva._mountComponents = eleva._originalMountComponents;\n delete eleva._originalMountComponents;\n }\n\n // Remove plugin utility methods\n if (eleva.props) {\n delete eleva.props;\n }\n },\n};\n","\"use strict\";\n\n/**\n * @class 🏪 StorePlugin\n * @classdesc A powerful reactive state management plugin for Eleva.js that enables sharing\n * reactive data across the entire application. The Store plugin provides a centralized,\n * reactive data store that can be accessed from any component's setup function.\n *\n * Core Features:\n * - Centralized reactive state management using Eleva's signal system\n * - Global state accessibility through component setup functions\n * - Namespace support for organizing store modules\n * - Built-in persistence with localStorage/sessionStorage support\n * - Action-based state mutations with validation\n * - Subscription system for reactive updates\n * - DevTools integration for debugging\n * - Plugin architecture for extensibility\n *\n * @example\n * // Install the plugin\n * const app = new Eleva(\"myApp\");\n * app.use(StorePlugin, {\n * state: {\n * user: { name: \"John\", email: \"john@example.com\" },\n * counter: 0,\n * todos: []\n * },\n * actions: {\n * increment: (state) => state.counter.value++,\n * addTodo: (state, todo) => state.todos.value.push(todo),\n * setUser: (state, user) => state.user.value = user\n * },\n * persistence: {\n * enabled: true,\n * key: \"myApp-store\",\n * storage: \"localStorage\"\n * }\n * });\n *\n * // Use store in components\n * app.component(\"Counter\", {\n * setup({ store }) {\n * return {\n * count: store.state.counter,\n * increment: () => store.dispatch(\"increment\"),\n * user: store.state.user\n * };\n * },\n * template: (ctx) => `\n * <div>\n * <p>Hello ${ctx.user.value.name}!</p>\n * <p>Count: ${ctx.count.value}</p>\n * <button onclick=\"ctx.increment()\">+</button>\n * </div>\n * `\n * });\n */\nexport const StorePlugin = {\n /**\n * Unique identifier for the plugin\n * @type {string}\n */\n name: \"store\",\n\n /**\n * Plugin version\n * @type {string}\n */\n version: \"1.0.0-rc.1\",\n\n /**\n * Plugin description\n * @type {string}\n */\n description:\n \"Reactive state management for sharing data across the entire Eleva application\",\n\n /**\n * Installs the plugin into the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n * @param {Object} options - Plugin configuration options\n * @param {Object} [options.state={}] - Initial state object\n * @param {Object} [options.actions={}] - Action functions for state mutations\n * @param {Object} [options.namespaces={}] - Namespaced modules for organizing store\n * @param {Object} [options.persistence] - Persistence configuration\n * @param {boolean} [options.persistence.enabled=false] - Enable state persistence\n * @param {string} [options.persistence.key=\"eleva-store\"] - Storage key\n * @param {\"localStorage\" | \"sessionStorage\"} [options.persistence.storage=\"localStorage\"] - Storage type\n * @param {Array<string>} [options.persistence.include] - State keys to persist (if not provided, all state is persisted)\n * @param {Array<string>} [options.persistence.exclude] - State keys to exclude from persistence\n * @param {boolean} [options.devTools=false] - Enable development tools integration\n * @param {Function} [options.onError=null] - Error handler function\n *\n * @example\n * // Basic installation\n * app.use(StorePlugin, {\n * state: { count: 0, user: null },\n * actions: {\n * increment: (state) => state.count.value++,\n * setUser: (state, user) => state.user.value = user\n * }\n * });\n *\n * // Advanced installation with persistence and namespaces\n * app.use(StorePlugin, {\n * state: { theme: \"light\" },\n * namespaces: {\n * auth: {\n * state: { user: null, token: null },\n * actions: {\n * login: (state, { user, token }) => {\n * state.user.value = user;\n * state.token.value = token;\n * },\n * logout: (state) => {\n * state.user.value = null;\n * state.token.value = null;\n * }\n * }\n * }\n * },\n * persistence: {\n * enabled: true,\n * include: [\"theme\", \"auth.user\"]\n * }\n * });\n */\n install(eleva, options = {}) {\n const {\n state = {},\n actions = {},\n namespaces = {},\n persistence = {},\n devTools = false,\n onError = null,\n } = options;\n\n /**\n * Store instance that manages all state and provides the API\n * @private\n */\n class Store {\n constructor() {\n this.state = {};\n this.actions = {};\n this.subscribers = new Set();\n this.mutations = [];\n this.persistence = {\n enabled: false,\n key: \"eleva-store\",\n storage: \"localStorage\",\n include: null,\n exclude: null,\n ...persistence,\n };\n this.devTools = devTools;\n this.onError = onError;\n\n this._initializeState(state, actions);\n this._initializeNamespaces(namespaces);\n this._loadPersistedState();\n this._setupDevTools();\n }\n\n /**\n * Initializes the root state and actions\n * @private\n */\n _initializeState(initialState, initialActions) {\n // Create reactive signals for each state property\n Object.entries(initialState).forEach(([key, value]) => {\n this.state[key] = new eleva.signal(value);\n });\n\n // Set up actions\n this.actions = { ...initialActions };\n }\n\n /**\n * Initializes namespaced modules\n * @private\n */\n _initializeNamespaces(namespaces) {\n Object.entries(namespaces).forEach(([namespace, module]) => {\n const { state: moduleState = {}, actions: moduleActions = {} } =\n module;\n\n // Create namespace object if it doesn't exist\n if (!this.state[namespace]) {\n this.state[namespace] = {};\n }\n if (!this.actions[namespace]) {\n this.actions[namespace] = {};\n }\n\n // Initialize namespaced state\n Object.entries(moduleState).forEach(([key, value]) => {\n this.state[namespace][key] = new eleva.signal(value);\n });\n\n // Set up namespaced actions\n this.actions[namespace] = { ...moduleActions };\n });\n }\n\n /**\n * Loads persisted state from storage\n * @private\n */\n _loadPersistedState() {\n if (!this.persistence.enabled || typeof window === \"undefined\") {\n return;\n }\n\n try {\n const storage = window[this.persistence.storage];\n const persistedData = storage.getItem(this.persistence.key);\n\n if (persistedData) {\n const data = JSON.parse(persistedData);\n this._applyPersistedData(data);\n }\n } catch (error) {\n if (this.onError) {\n this.onError(error, \"Failed to load persisted state\");\n } else {\n console.warn(\n \"[StorePlugin] Failed to load persisted state:\",\n error\n );\n }\n }\n }\n\n /**\n * Applies persisted data to the current state\n * @private\n */\n _applyPersistedData(data, currentState = this.state, path = \"\") {\n Object.entries(data).forEach(([key, value]) => {\n const fullPath = path ? `${path}.${key}` : key;\n\n if (this._shouldPersist(fullPath)) {\n if (\n currentState[key] &&\n typeof currentState[key] === \"object\" &&\n \"value\" in currentState[key]\n ) {\n // This is a signal, update its value\n currentState[key].value = value;\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n currentState[key]\n ) {\n // This is a nested object, recurse\n this._applyPersistedData(value, currentState[key], fullPath);\n }\n }\n });\n }\n\n /**\n * Determines if a state path should be persisted\n * @private\n */\n _shouldPersist(path) {\n const { include, exclude } = this.persistence;\n\n if (include && include.length > 0) {\n return include.some((includePath) => path.startsWith(includePath));\n }\n\n if (exclude && exclude.length > 0) {\n return !exclude.some((excludePath) => path.startsWith(excludePath));\n }\n\n return true;\n }\n\n /**\n * Saves current state to storage\n * @private\n */\n _saveState() {\n if (!this.persistence.enabled || typeof window === \"undefined\") {\n return;\n }\n\n try {\n const storage = window[this.persistence.storage];\n const dataToSave = this._extractPersistedData();\n storage.setItem(this.persistence.key, JSON.stringify(dataToSave));\n } catch (error) {\n if (this.onError) {\n this.onError(error, \"Failed to save state\");\n } else {\n console.warn(\"[StorePlugin] Failed to save state:\", error);\n }\n }\n }\n\n /**\n * Extracts data that should be persisted\n * @private\n */\n _extractPersistedData(currentState = this.state, path = \"\") {\n const result = {};\n\n Object.entries(currentState).forEach(([key, value]) => {\n const fullPath = path ? `${path}.${key}` : key;\n\n if (this._shouldPersist(fullPath)) {\n if (value && typeof value === \"object\" && \"value\" in value) {\n // This is a signal, extract its value\n result[key] = value.value;\n } else if (typeof value === \"object\" && value !== null) {\n // This is a nested object, recurse\n const nestedData = this._extractPersistedData(value, fullPath);\n if (Object.keys(nestedData).length > 0) {\n result[key] = nestedData;\n }\n }\n }\n });\n\n return result;\n }\n\n /**\n * Sets up development tools integration\n * @private\n */\n _setupDevTools() {\n if (\n !this.devTools ||\n typeof window === \"undefined\" ||\n !window.__ELEVA_DEVTOOLS__\n ) {\n return;\n }\n\n window.__ELEVA_DEVTOOLS__.registerStore(this);\n }\n\n /**\n * Dispatches an action to mutate the state\n * @param {string} actionName - The name of the action to dispatch (supports namespaced actions like \"auth.login\")\n * @param {any} payload - The payload to pass to the action\n * @returns {Promise<any>} The result of the action\n */\n async dispatch(actionName, payload) {\n try {\n const action = this._getAction(actionName);\n\n if (!action) {\n const error = new Error(`Action \"${actionName}\" not found`);\n if (this.onError) {\n this.onError(error, actionName);\n }\n throw error;\n }\n\n const mutation = {\n type: actionName,\n payload,\n timestamp: Date.now(),\n };\n\n // Record mutation for devtools\n this.mutations.push(mutation);\n if (this.mutations.length > 100) {\n this.mutations.shift(); // Keep only last 100 mutations\n }\n\n // Execute the action\n const result = await action.call(null, this.state, payload);\n\n // Save state if persistence is enabled\n this._saveState();\n\n // Notify subscribers\n this.subscribers.forEach((callback) => {\n try {\n callback(mutation, this.state);\n } catch (error) {\n if (this.onError) {\n this.onError(error, \"Subscriber callback failed\");\n }\n }\n });\n\n // Notify devtools\n if (\n this.devTools &&\n typeof window !== \"undefined\" &&\n window.__ELEVA_DEVTOOLS__\n ) {\n window.__ELEVA_DEVTOOLS__.notifyMutation(mutation, this.state);\n }\n\n return result;\n } catch (error) {\n if (this.onError) {\n this.onError(error, `Action dispatch failed: ${actionName}`);\n }\n throw error;\n }\n }\n\n /**\n * Gets an action by name (supports namespaced actions)\n * @private\n */\n _getAction(actionName) {\n const parts = actionName.split(\".\");\n let current = this.actions;\n\n for (const part of parts) {\n if (current[part] === undefined) {\n return null;\n }\n current = current[part];\n }\n\n return typeof current === \"function\" ? current : null;\n }\n\n /**\n * Subscribes to store mutations\n * @param {Function} callback - Callback function to call on mutations\n * @returns {Function} Unsubscribe function\n */\n subscribe(callback) {\n if (typeof callback !== \"function\") {\n throw new Error(\"Subscribe callback must be a function\");\n }\n\n this.subscribers.add(callback);\n\n // Return unsubscribe function\n return () => {\n this.subscribers.delete(callback);\n };\n }\n\n /**\n * Gets a deep copy of the current state values (not signals)\n * @returns {Object} The current state values\n */\n getState() {\n return this._extractPersistedData();\n }\n\n /**\n * Replaces the entire state (useful for testing or state hydration)\n * @param {Object} newState - The new state object\n */\n replaceState(newState) {\n this._applyPersistedData(newState);\n this._saveState();\n }\n\n /**\n * Clears persisted state from storage\n */\n clearPersistedState() {\n if (!this.persistence.enabled || typeof window === \"undefined\") {\n return;\n }\n\n try {\n const storage = window[this.persistence.storage];\n storage.removeItem(this.persistence.key);\n } catch (error) {\n if (this.onError) {\n this.onError(error, \"Failed to clear persisted state\");\n }\n }\n }\n\n /**\n * Registers a new namespaced module at runtime\n * @param {string} namespace - The namespace for the module\n * @param {Object} module - The module definition\n * @param {Object} module.state - The module's initial state\n * @param {Object} module.actions - The module's actions\n */\n registerModule(namespace, module) {\n if (this.state[namespace] || this.actions[namespace]) {\n console.warn(`[StorePlugin] Module \"${namespace}\" already exists`);\n return;\n }\n\n // Initialize the module\n this.state[namespace] = {};\n this.actions[namespace] = {};\n\n const namespaces = { [namespace]: module };\n this._initializeNamespaces(namespaces);\n\n this._saveState();\n }\n\n /**\n * Unregisters a namespaced module\n * @param {string} namespace - The namespace to unregister\n */\n unregisterModule(namespace) {\n if (!this.state[namespace] && !this.actions[namespace]) {\n console.warn(`[StorePlugin] Module \"${namespace}\" does not exist`);\n return;\n }\n\n delete this.state[namespace];\n delete this.actions[namespace];\n this._saveState();\n }\n\n /**\n * Creates a new reactive state property at runtime\n * @param {string} key - The state key\n * @param {*} initialValue - The initial value\n * @returns {Object} The created signal\n */\n createState(key, initialValue) {\n if (this.state[key]) {\n return this.state[key]; // Return existing state\n }\n\n this.state[key] = new eleva.signal(initialValue);\n this._saveState();\n return this.state[key];\n }\n\n /**\n * Creates a new action at runtime\n * @param {string} name - The action name\n * @param {Function} actionFn - The action function\n */\n createAction(name, actionFn) {\n if (typeof actionFn !== \"function\") {\n throw new Error(\"Action must be a function\");\n }\n\n this.actions[name] = actionFn;\n }\n }\n\n // Create the store instance\n const store = new Store();\n\n // Store the original mount method to override it\n const originalMount = eleva.mount;\n\n /**\n * Override the mount method to inject store context into components\n */\n eleva.mount = async (container, compName, props = {}) => {\n // Get the component definition\n const componentDef =\n typeof compName === \"string\"\n ? eleva._components.get(compName) || compName\n : compName;\n\n if (!componentDef) {\n return await originalMount.call(eleva, container, compName, props);\n }\n\n // Create a wrapped component that injects store into setup\n const wrappedComponent = {\n ...componentDef,\n async setup(ctx) {\n // Inject store into the context with enhanced API\n ctx.store = {\n // Core store functionality\n state: store.state,\n dispatch: store.dispatch.bind(store),\n subscribe: store.subscribe.bind(store),\n getState: store.getState.bind(store),\n\n // Module management\n registerModule: store.registerModule.bind(store),\n unregisterModule: store.unregisterModule.bind(store),\n\n // Utilities for dynamic state/action creation\n createState: store.createState.bind(store),\n createAction: store.createAction.bind(store),\n\n // Access to signal constructor for manual state creation\n signal: eleva.signal,\n };\n\n // Call original setup if it exists\n const originalSetup = componentDef.setup;\n const result = originalSetup ? await originalSetup(ctx) : {};\n\n return result;\n },\n };\n\n // Call original mount with wrapped component\n return await originalMount.call(\n eleva,\n container,\n wrappedComponent,\n props\n );\n };\n\n // Override _mountComponents to ensure child components also get store context\n const originalMountComponents = eleva._mountComponents;\n eleva._mountComponents = async (container, children, childInstances) => {\n // Create wrapped children with store injection\n const wrappedChildren = {};\n\n for (const [selector, childComponent] of Object.entries(children)) {\n const componentDef =\n typeof childComponent === \"string\"\n ? eleva._components.get(childComponent) || childComponent\n : childComponent;\n\n if (componentDef && typeof componentDef === \"object\") {\n wrappedChildren[selector] = {\n ...componentDef,\n async setup(ctx) {\n // Inject store into the context with enhanced API\n ctx.store = {\n // Core store functionality\n state: store.state,\n dispatch: store.dispatch.bind(store),\n subscribe: store.subscribe.bind(store),\n getState: store.getState.bind(store),\n\n // Module management\n registerModule: store.registerModule.bind(store),\n unregisterModule: store.unregisterModule.bind(store),\n\n // Utilities for dynamic state/action creation\n createState: store.createState.bind(store),\n createAction: store.createAction.bind(store),\n\n // Access to signal constructor for manual state creation\n signal: eleva.signal,\n };\n\n // Call original setup if it exists\n const originalSetup = componentDef.setup;\n const result = originalSetup ? await originalSetup(ctx) : {};\n\n return result;\n },\n };\n } else {\n wrappedChildren[selector] = childComponent;\n }\n }\n\n // Call original _mountComponents with wrapped children\n return await originalMountComponents.call(\n eleva,\n container,\n wrappedChildren,\n childInstances\n );\n };\n\n // Expose store instance and utilities on the Eleva instance\n eleva.store = store;\n\n /**\n * Expose utility methods on the Eleva instance\n * @namespace eleva.store\n */\n eleva.createAction = (name, actionFn) => {\n store.actions[name] = actionFn;\n };\n\n eleva.dispatch = (actionName, payload) => {\n return store.dispatch(actionName, payload);\n };\n\n eleva.getState = () => {\n return store.getState();\n };\n\n eleva.subscribe = (callback) => {\n return store.subscribe(callback);\n };\n\n // Store original methods for cleanup\n eleva._originalMount = originalMount;\n eleva._originalMountComponents = originalMountComponents;\n },\n\n /**\n * Uninstalls the plugin from the Eleva instance\n *\n * @param {Object} eleva - The Eleva instance\n *\n * @description\n * Restores the original Eleva methods and removes all plugin-specific\n * functionality. This method should be called when the plugin is no\n * longer needed.\n *\n * @example\n * // Uninstall the plugin\n * StorePlugin.uninstall(app);\n */\n uninstall(eleva) {\n // Restore original mount method\n if (eleva._originalMount) {\n eleva.mount = eleva._originalMount;\n delete eleva._originalMount;\n }\n\n // Restore original _mountComponents method\n if (eleva._originalMountComponents) {\n eleva._mountComponents = eleva._originalMountComponents;\n delete eleva._originalMountComponents;\n }\n\n // Remove store instance and utility methods\n if (eleva.store) {\n delete eleva.store;\n }\n if (eleva.createAction) {\n delete eleva.createAction;\n }\n if (eleva.dispatch) {\n delete eleva.dispatch;\n }\n if (eleva.getState) {\n delete eleva.getState;\n }\n if (eleva.subscribe) {\n delete eleva.subscribe;\n }\n },\n};\n"],"names":["CAMEL_RE","AttrPlugin","name","version","description","install","eleva","options","enableAria","enableData","enableBoolean","enableDynamic","updateAttributes","oldEl","newEl","oldAttrs","attributes","newAttrs","i","length","value","startsWith","getAttribute","slice","replace","_","l","toUpperCase","setAttribute","dataset","prop","Object","getOwnPropertyDescriptor","getPrototypeOf","matchingProp","getOwnPropertyNames","find","p","toLowerCase","includes","descriptor","get","call","boolValue","removeAttribute","hasAttribute","renderer","_originalPatchNode","_patchNode","oldNode","newNode","_eleva_instance","this","_isSameNode","nodeType","Node","ELEMENT_NODE","_diff","TEXT_NODE","nodeValue","replaceWith","cloneNode","plugins","Map","set","updateElementAttributes","uninstall","delete","CoreErrorHandler","handle","error","context","details","formattedError","Error","message","originalError","warn","log","Router","constructor","mode","queryParam","viewSelector","routes","_processRoutes","emitter","isStarted","_isNavigating","eventListeners","currentRoute","signal","previousRoute","currentParams","currentQuery","currentLayout","currentView","errorHandler","_validateOptions","processedRoutes","route","push","segments","_parsePathIntoSegments","path","normalizedPath","split","filter","Boolean","map","segment","paramName","substring","type","_findViewElement","container","selector","querySelector","start","window","document","mount","mountSelector","handler","_handleRouteChange","addEventListener","removeEventListener","destroy","plugin","values","forEach","cleanup","unmount","navigate","location","params","target","_buildPath","query","keys","queryString","URLSearchParams","toString","_isSameRoute","_proceedWithNavigation","state","historyMethod","newUrl","pathname","search","history","replaceState","hash","url","_buildQueryUrl","queueMicrotask","emit","urlParams","current","targetPath","targetQuery","_parseQuery","JSON","stringify","result","key","entries","encodedValue","encodeURIComponent","String","RegExp","from","toLocation","_getCurrentLocation","fullUrl","fullPath","toMatch","_matchRoute","notFoundRoute","pathMatch","to","meta","matched","_runGuards","layoutComponent","pageComponent","_resolveComponents","tryUnmount","async","instance","layout","globalLayout","afterLeave","_render","afterEnter","guards","onBeforeEach","beforeLeave","beforeEnter","guard","_resolveStringComponent","def","componentDef","_components","componentName","availableComponents","Array","_resolveFunctionComponent","funcStr","isAsyncImport","default","function","_validateComponentDefinition","definition","template","_resolveComponent","effectiveLayout","Promise","all","component","mountEl","layoutInstance","_wrapComponentWithChildren","viewEl","viewInstance","_createRouteGetter","property","defaultValue","_wrapComponent","originalSetup","setup","self","ctx","router","bind","previous","href","wrappedComponent","children","wrappedChildren","childComponent","pathSegments","isMatch","routeSegment","pathSegment","decodeURIComponent","onAfterEnter","hook","on","onAfterLeave","onAfterEach","onError","use","has","existingPlugin","getPlugins","getPlugin","removePlugin","setErrorHandler","RouterPlugin","isArray","register","Math","random","autoStart","getCurrentRoute","getRouteParams","getRouteQuery","TemplateEngine","static","parse","data","expressionPattern","expression","evaluate","Function","PropsPlugin","enableAutoParsing","enableReactivity","parsePropValue","e","isNaN","parseFloat","Number","match","date","Date","getTime","createReactiveProps","props","reactiveProps","_extractProps","element","attrs","attr","propName","parsedValue","originalMount","compName","enhancedProps","originalMountComponents","_mountComponents","parentContextCache","WeakMap","pendingSignalLinks","Set","childInstances","el","querySelectorAll","HTMLElement","extractedProps","parentContext","currentElement","parentElement","signalProps","finalProps","nonSignalProps","add","size","pending","assign","watch","newValue","templateResult","newHtml","patchDOM","detectType","undefined","_originalExtractProps","_originalMount","_originalMountComponents","StorePlugin","actions","namespaces","persistence","devTools","store","subscribers","mutations","enabled","storage","include","exclude","_initializeState","_initializeNamespaces","_loadPersistedState","_setupDevTools","initialState","initialActions","namespace","module","moduleState","moduleActions","persistedData","getItem","_applyPersistedData","currentState","_shouldPersist","some","includePath","excludePath","_saveState","dataToSave","_extractPersistedData","setItem","nestedData","__ELEVA_DEVTOOLS__","registerStore","dispatch","actionName","payload","action","_getAction","mutation","timestamp","now","shift","callback","notifyMutation","parts","part","subscribe","getState","newState","clearPersistedState","removeItem","registerModule","unregisterModule","createState","initialValue","createAction","actionFn"],"mappings":"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"}
|