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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +20 -75
  2. package/dist/eleva-plugins.cjs.js +4 -653
  3. package/dist/eleva-plugins.cjs.js.map +1 -1
  4. package/dist/eleva-plugins.esm.js +5 -653
  5. package/dist/eleva-plugins.esm.js.map +1 -1
  6. package/dist/eleva-plugins.umd.js +4 -653
  7. package/dist/eleva-plugins.umd.js.map +1 -1
  8. package/dist/eleva-plugins.umd.min.js +1 -1
  9. package/dist/eleva-plugins.umd.min.js.map +1 -1
  10. package/dist/eleva.cjs.js +52 -110
  11. package/dist/eleva.cjs.js.map +1 -1
  12. package/dist/eleva.d.ts +47 -109
  13. package/dist/eleva.esm.js +52 -110
  14. package/dist/eleva.esm.js.map +1 -1
  15. package/dist/eleva.umd.js +52 -110
  16. package/dist/eleva.umd.js.map +1 -1
  17. package/dist/eleva.umd.min.js +1 -1
  18. package/dist/eleva.umd.min.js.map +1 -1
  19. package/dist/plugins/attr.umd.js +2 -2
  20. package/dist/plugins/attr.umd.js.map +1 -1
  21. package/dist/plugins/attr.umd.min.js +1 -1
  22. package/dist/plugins/attr.umd.min.js.map +1 -1
  23. package/dist/plugins/router.umd.js +1 -1
  24. package/dist/plugins/router.umd.js.map +1 -1
  25. package/dist/plugins/router.umd.min.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/core/Eleva.js +21 -15
  28. package/src/modules/TemplateEngine.js +36 -104
  29. package/src/plugins/Attr.js +2 -2
  30. package/src/plugins/Router.js +1 -1
  31. package/src/plugins/index.js +1 -1
  32. package/types/core/Eleva.d.ts +9 -5
  33. package/types/core/Eleva.d.ts.map +1 -1
  34. package/types/modules/TemplateEngine.d.ts +38 -104
  35. package/types/modules/TemplateEngine.d.ts.map +1 -1
  36. package/types/plugins/Router.d.ts +1 -1
  37. package/types/plugins/index.d.ts +0 -1
  38. package/dist/plugins/props.umd.js +0 -660
  39. package/dist/plugins/props.umd.js.map +0 -1
  40. package/dist/plugins/props.umd.min.js +0 -2
  41. package/dist/plugins/props.umd.min.js.map +0 -1
  42. package/src/plugins/Props.js +0 -602
  43. package/types/plugins/Props.d.ts +0 -49
  44. package/types/plugins/Props.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"props.umd.js","sources":["../../src/modules/TemplateEngine.js","../../src/plugins/Props.js"],"sourcesContent":["\"use strict\";\n\n// ============================================================================\n// TYPE DEFINITIONS - TypeScript-friendly JSDoc types for IDE support\n// ============================================================================\n\n/**\n * @typedef {Record<string, unknown>} TemplateData\n * Data context for template interpolation\n */\n\n/**\n * @typedef {string} TemplateString\n * A string containing {{ expression }} interpolation markers\n */\n\n/**\n * @typedef {string} Expression\n * A JavaScript expression to be evaluated in the data context\n */\n\n/**\n * @typedef {unknown} EvaluationResult\n * The result of evaluating an expression (string, number, boolean, object, etc.)\n */\n\n/**\n * @class 🔒 TemplateEngine\n * @classdesc A secure template engine that handles interpolation and dynamic attribute parsing.\n * Provides a way to evaluate expressions in templates.\n * All methods are static and can be called directly on the class.\n *\n * Template Syntax:\n * - `{{ expression }}` - Interpolate any JavaScript expression\n * - `{{ variable }}` - Access data properties directly\n * - `{{ object.property }}` - Access nested properties\n * - `{{ condition ? a : b }}` - Ternary expressions\n * - `{{ func(arg) }}` - Call functions from data context\n *\n * @example\n * // Basic interpolation\n * const template = \"Hello, {{name}}!\";\n * const data = { name: \"World\" };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Hello, World!\"\n *\n * @example\n * // Nested properties\n * const template = \"Welcome, {{user.name}}!\";\n * const data = { user: { name: \"John\" } };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Welcome, John!\"\n *\n * @example\n * // Expressions\n * const template = \"Status: {{active ? 'Online' : 'Offline'}}\";\n * const data = { active: true };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Status: Online\"\n *\n * @example\n * // With Signal values\n * const template = \"Count: {{count.value}}\";\n * const data = { count: { value: 42 } };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Count: 42\"\n */\nexport class TemplateEngine {\n /**\n * Regular expression for matching template expressions in the format {{ expression }}\n * Matches: {{ anything }} with optional whitespace inside braces\n *\n * @static\n * @private\n * @type {RegExp}\n */\n static expressionPattern = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\n /**\n * Cache for compiled expression functions.\n * Stores compiled Function objects keyed by expression string for O(1) lookup.\n *\n * @static\n * @private\n * @type {Map<string, Function>}\n */\n static _functionCache = new Map();\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 {TemplateString|unknown} template - The template string to parse.\n * @param {TemplateData} data - The data context for evaluating expressions.\n * @returns {string} The parsed template with expressions replaced by their values.\n *\n * @example\n * // Simple variables\n * TemplateEngine.parse(\"Hello, {{name}}!\", { name: \"World\" });\n * // Result: \"Hello, World!\"\n *\n * @example\n * // Nested properties\n * TemplateEngine.parse(\"{{user.name}} is {{user.age}} years old\", {\n * user: { name: \"John\", age: 30 }\n * });\n * // Result: \"John is 30 years old\"\n *\n * @example\n * // Multiple expressions\n * TemplateEngine.parse(\"{{greeting}}, {{name}}! You have {{count}} messages.\", {\n * greeting: \"Hello\",\n * name: \"User\",\n * count: 5\n * });\n * // Result: \"Hello, User! You have 5 messages.\"\n *\n * @example\n * // With conditionals\n * TemplateEngine.parse(\"Status: {{online ? 'Active' : 'Inactive'}}\", {\n * online: true\n * });\n * // Result: \"Status: Active\"\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 *\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 * Only use with trusted templates. User input should never be directly interpolated.\n *\n * @public\n * @static\n * @param {Expression|unknown} expression - The expression to evaluate.\n * @param {TemplateData} data - The data context for evaluation.\n * @returns {EvaluationResult} The result of the evaluation, or empty string if evaluation fails.\n *\n * @example\n * // Property access\n * TemplateEngine.evaluate(\"user.name\", { user: { name: \"John\" } });\n * // Result: \"John\"\n *\n * @example\n * // Numeric values\n * TemplateEngine.evaluate(\"user.age\", { user: { age: 30 } });\n * // Result: 30\n *\n * @example\n * // Expressions\n * TemplateEngine.evaluate(\"items.length > 0\", { items: [1, 2, 3] });\n * // Result: true\n *\n * @example\n * // Function calls\n * TemplateEngine.evaluate(\"formatDate(date)\", {\n * date: new Date(),\n * formatDate: (d) => d.toISOString()\n * });\n * // Result: \"2024-01-01T00:00:00.000Z\"\n *\n * @example\n * // Failed evaluation returns empty string\n * TemplateEngine.evaluate(\"nonexistent.property\", {});\n * // Result: \"\"\n */\n static evaluate(expression, data) {\n if (typeof expression !== \"string\") return expression;\n let fn = this._functionCache.get(expression);\n if (!fn) {\n try {\n fn = new Function(\"data\", `with(data) { return ${expression}; }`);\n this._functionCache.set(expression, fn);\n } catch {\n return \"\";\n }\n }\n try {\n return fn(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.12\",\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 // Create a batched render function for this child instance\n // This ensures multiple signal changes result in a single render\n let renderScheduled = false;\n const childComponent =\n eleva._components.get(component) || component;\n\n const scheduleChildRender = () => {\n if (renderScheduled) return;\n renderScheduled = true;\n queueMicrotask(() => {\n renderScheduled = false;\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 // 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 // Use batched render instead of direct patchDOM\n signal.watch(scheduleChildRender);\n }\n });\n\n // Initial render to show the correct signal values\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\n// Short name export for convenience\nexport { PropsPlugin as Props };\n"],"names":["TemplateEngine","parse","template","data","replace","expressionPattern","_","expression","evaluate","fn","_functionCache","get","Function","set","Map","PropsPlugin","name","version","description","install","eleva","options","enableAutoParsing","enableReactivity","onError","detectType","value","undefined","Date","Set","Array","isArray","parsePropValue","startsWith","JSON","e","Error","isNaN","parseFloat","Number","match","date","getTime","error","extractProps","element","props","attrs","attributes","i","length","attr","propName","slice","parsedValue","removeAttribute","createReactiveProps","reactiveProps","Object","entries","forEach","key","signal","_extractProps","originalMount","mount","container","compName","enhancedProps","call","originalMountComponents","_mountComponents","parentContextCache","WeakMap","pendingSignalLinks","children","childInstances","selector","component","el","querySelectorAll","HTMLElement","extractedProps","parentContext","currentElement","_eleva_instance","parentElement","signalProps","keys","finalProps","nonSignalProps","reactiveNonSignalProps","instance","includes","push","add","size","pending","assign","renderScheduled","childComponent","_components","scheduleChildRender","queueMicrotask","templateResult","newHtml","renderer","patchDOM","watch","delete","_originalExtractProps","_originalMount","_originalMountComponents","uninstall"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- var t,e;t=this,e=function(t){"use strict";class e{static parse(t,e){return"string"!=typeof t?t:t.replace(this.expressionPattern,(t,n)=>this.evaluate(n,e))}static evaluate(t,e){if("string"!=typeof t)return t;let n=this._functionCache.get(t);if(!n)try{n=Function("data",`with(data) { return ${t}; }`),this._functionCache.set(t,n)}catch{return""}try{return n(e)}catch{return""}}}e.expressionPattern=/\{\{\s*(.*?)\s*\}\}/g,e._functionCache=new Map;let n={name:"props",version:"1.0.0-rc.12",description:"Advanced props data handling for complex data structures with automatic type detection and reactivity",install(t,n={}){let{enableAutoParsing:a=!0,enableReactivity:r=!0,onError:i=null}=n,o=t=>{try{if("string"!=typeof t)return t;if("true"===t)return!0;if("false"===t)return!1;if("null"===t)return null;if("undefined"===t)return;if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){throw Error(`Invalid JSON: ${t}`)}if("1"===t)return!0;if("0"===t)return!1;if(""===t)return!0;if(!isNaN(t)&&""!==t&&!isNaN(parseFloat(t)))return Number(t);if(t.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)){let e=new Date(t);if(!isNaN(e.getTime()))return e}return t}catch(e){return i&&i(e,t),t}},l=e=>{let n={};return Object.entries(e).forEach(([e,a])=>{a&&"object"==typeof a&&"value"in a&&"watch"in a?n[e]=a:n[e]=new t.signal(a)}),n};t._extractProps=t=>{let e={},n=t.attributes;for(let r=n.length-1;r>=0;r--){let i=n[r];if(i.name.startsWith(":")){let n=i.name.slice(1),r=a?o(i.value):i.value;e[n]=r,t.removeAttribute(i.name)}}return e};let s=t.mount;t.mount=async(e,n,a={})=>{let i=r?l(a):a;return await s.call(t,e,n,i)};let c=t._mountComponents,u=new WeakMap,f=new Set;t._mountComponents=async(n,a,i)=>{for(let[e,o]of Object.entries(a))if(e)for(let a of n.querySelectorAll(e)){if(!(a instanceof HTMLElement))continue;let e=t._extractProps(a),s=e,c=u.get(n);if(!c){let t=n;for(;t&&!c;){if(t._eleva_instance&&t._eleva_instance.data){c=t._eleva_instance.data,u.set(n,c);break}t=t.parentElement}}if(r&&c){let n={};Object.keys(e).forEach(e=>{c[e]&&c[e]instanceof t.signal&&(n[e]=c[e])}),s={...e,...n}}let p=s;if(r){let t={};Object.entries(s).forEach(([e,n])=>{n&&"object"==typeof n&&"value"in n&&"watch"in n||(t[e]=n)}),p={...l(t),...s}}let d=await t.mount(a,o,p);d&&!i.includes(d)&&(i.push(d),r&&Object.keys(e).length>0&&!c&&f.add({instance:d,extractedProps:e,container:n,component:o}))}if(r&&f.size>0)for(let n of f){let{instance:a,extractedProps:r,container:i,component:o}=n,l=u.get(i);if(!l){let t=i;for(;t&&!l;){if(t._eleva_instance&&t._eleva_instance.data){l=t._eleva_instance.data,u.set(i,l);break}t=t.parentElement}}if(l){let i={};if(Object.keys(r).forEach(e=>{l[e]&&l[e]instanceof t.signal&&(i[e]=l[e])}),Object.keys(i).length>0){Object.assign(a.data,i);let n=!1,r=t._components.get(o)||o,l=()=>{n||(n=!0,queueMicrotask(()=>{if(n=!1,r&&r.template){let n="function"==typeof r.template?r.template(a.data):r.template,i=e.parse(n,a.data);t.renderer.patchDOM(a.container,i)}}))};if(Object.keys(i).forEach(t=>{let e=i[t];e&&"function"==typeof e.watch&&e.watch(l)}),r&&r.template){let n="function"==typeof r.template?r.template(a.data):r.template,i=e.parse(n,a.data);t.renderer.patchDOM(a.container,i)}}f.delete(n)}}},t.props={parse:t=>a?o(t):t,detectType:t=>null===t?"null":void 0===t?"undefined":"boolean"==typeof t?"boolean":"number"==typeof t?"number":"string"==typeof t?"string":"function"==typeof t?"function":t instanceof Date?"date":t instanceof Map?"map":t instanceof Set?"set":Array.isArray(t)?"array":"object"==typeof t?"object":"unknown"},t._originalExtractProps=t._extractProps,t._originalMount=s,t._originalMountComponents=c},uninstall(t){t._originalExtractProps&&(t._extractProps=t._originalExtractProps,delete t._originalExtractProps),t._originalMount&&(t.mount=t._originalMount,delete t._originalMount),t._originalMountComponents&&(t._mountComponents=t._originalMountComponents,delete t._originalMountComponents),t.props&&delete t.props}};t.Props=n,t.PropsPlugin=n},"object"==typeof exports&&"u">typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="u">typeof globalThis?globalThis:t||self).ElevaPropsPlugin={});
2
- //# sourceMappingURL=props.umd.min.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"props.umd.min.js","sources":["../../src/modules/TemplateEngine.js","../../src/plugins/Props.js"],"sourcesContent":["\"use strict\";\n\n// ============================================================================\n// TYPE DEFINITIONS - TypeScript-friendly JSDoc types for IDE support\n// ============================================================================\n\n/**\n * @typedef {Record<string, unknown>} TemplateData\n * Data context for template interpolation\n */\n\n/**\n * @typedef {string} TemplateString\n * A string containing {{ expression }} interpolation markers\n */\n\n/**\n * @typedef {string} Expression\n * A JavaScript expression to be evaluated in the data context\n */\n\n/**\n * @typedef {unknown} EvaluationResult\n * The result of evaluating an expression (string, number, boolean, object, etc.)\n */\n\n/**\n * @class 🔒 TemplateEngine\n * @classdesc A secure template engine that handles interpolation and dynamic attribute parsing.\n * Provides a way to evaluate expressions in templates.\n * All methods are static and can be called directly on the class.\n *\n * Template Syntax:\n * - `{{ expression }}` - Interpolate any JavaScript expression\n * - `{{ variable }}` - Access data properties directly\n * - `{{ object.property }}` - Access nested properties\n * - `{{ condition ? a : b }}` - Ternary expressions\n * - `{{ func(arg) }}` - Call functions from data context\n *\n * @example\n * // Basic interpolation\n * const template = \"Hello, {{name}}!\";\n * const data = { name: \"World\" };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Hello, World!\"\n *\n * @example\n * // Nested properties\n * const template = \"Welcome, {{user.name}}!\";\n * const data = { user: { name: \"John\" } };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Welcome, John!\"\n *\n * @example\n * // Expressions\n * const template = \"Status: {{active ? 'Online' : 'Offline'}}\";\n * const data = { active: true };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Status: Online\"\n *\n * @example\n * // With Signal values\n * const template = \"Count: {{count.value}}\";\n * const data = { count: { value: 42 } };\n * const result = TemplateEngine.parse(template, data);\n * // Result: \"Count: 42\"\n */\nexport class TemplateEngine {\n /**\n * Regular expression for matching template expressions in the format {{ expression }}\n * Matches: {{ anything }} with optional whitespace inside braces\n *\n * @static\n * @private\n * @type {RegExp}\n */\n static expressionPattern = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\n /**\n * Cache for compiled expression functions.\n * Stores compiled Function objects keyed by expression string for O(1) lookup.\n *\n * @static\n * @private\n * @type {Map<string, Function>}\n */\n static _functionCache = new Map();\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 {TemplateString|unknown} template - The template string to parse.\n * @param {TemplateData} data - The data context for evaluating expressions.\n * @returns {string} The parsed template with expressions replaced by their values.\n *\n * @example\n * // Simple variables\n * TemplateEngine.parse(\"Hello, {{name}}!\", { name: \"World\" });\n * // Result: \"Hello, World!\"\n *\n * @example\n * // Nested properties\n * TemplateEngine.parse(\"{{user.name}} is {{user.age}} years old\", {\n * user: { name: \"John\", age: 30 }\n * });\n * // Result: \"John is 30 years old\"\n *\n * @example\n * // Multiple expressions\n * TemplateEngine.parse(\"{{greeting}}, {{name}}! You have {{count}} messages.\", {\n * greeting: \"Hello\",\n * name: \"User\",\n * count: 5\n * });\n * // Result: \"Hello, User! You have 5 messages.\"\n *\n * @example\n * // With conditionals\n * TemplateEngine.parse(\"Status: {{online ? 'Active' : 'Inactive'}}\", {\n * online: true\n * });\n * // Result: \"Status: Active\"\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 *\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 * Only use with trusted templates. User input should never be directly interpolated.\n *\n * @public\n * @static\n * @param {Expression|unknown} expression - The expression to evaluate.\n * @param {TemplateData} data - The data context for evaluation.\n * @returns {EvaluationResult} The result of the evaluation, or empty string if evaluation fails.\n *\n * @example\n * // Property access\n * TemplateEngine.evaluate(\"user.name\", { user: { name: \"John\" } });\n * // Result: \"John\"\n *\n * @example\n * // Numeric values\n * TemplateEngine.evaluate(\"user.age\", { user: { age: 30 } });\n * // Result: 30\n *\n * @example\n * // Expressions\n * TemplateEngine.evaluate(\"items.length > 0\", { items: [1, 2, 3] });\n * // Result: true\n *\n * @example\n * // Function calls\n * TemplateEngine.evaluate(\"formatDate(date)\", {\n * date: new Date(),\n * formatDate: (d) => d.toISOString()\n * });\n * // Result: \"2024-01-01T00:00:00.000Z\"\n *\n * @example\n * // Failed evaluation returns empty string\n * TemplateEngine.evaluate(\"nonexistent.property\", {});\n * // Result: \"\"\n */\n static evaluate(expression, data) {\n if (typeof expression !== \"string\") return expression;\n let fn = this._functionCache.get(expression);\n if (!fn) {\n try {\n fn = new Function(\"data\", `with(data) { return ${expression}; }`);\n this._functionCache.set(expression, fn);\n } catch {\n return \"\";\n }\n }\n try {\n return fn(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.12\",\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 // Create a batched render function for this child instance\n // This ensures multiple signal changes result in a single render\n let renderScheduled = false;\n const childComponent =\n eleva._components.get(component) || component;\n\n const scheduleChildRender = () => {\n if (renderScheduled) return;\n renderScheduled = true;\n queueMicrotask(() => {\n renderScheduled = false;\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 // 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 // Use batched render instead of direct patchDOM\n signal.watch(scheduleChildRender);\n }\n });\n\n // Initial render to show the correct signal values\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\n// Short name export for convenience\nexport { PropsPlugin as Props };\n"],"names":["TemplateEngine","parse","template","data","replace","expressionPattern","_","expression","evaluate","fn","_functionCache","get","Function","set","Map","PropsPlugin","name","version","description","install","eleva","options","enableAutoParsing","enableReactivity","onError","parsePropValue","value","startsWith","JSON","e","Error","isNaN","parseFloat","Number","match","date","Date","getTime","error","createReactiveProps","props","reactiveProps","Object","entries","forEach","key","signal","_extractProps","element","attrs","attributes","i","length","attr","propName","slice","parsedValue","removeAttribute","originalMount","mount","container","compName","enhancedProps","call","originalMountComponents","_mountComponents","parentContextCache","WeakMap","pendingSignalLinks","Set","children","childInstances","selector","component","el","querySelectorAll","HTMLElement","extractedProps","parentContext","currentElement","_eleva_instance","parentElement","signalProps","keys","finalProps","nonSignalProps","instance","includes","push","add","size","pending","assign","renderScheduled","childComponent","_components","scheduleChildRender","queueMicrotask","templateResult","newHtml","renderer","patchDOM","watch","delete","detectType","undefined","Array","isArray","_originalExtractProps","_originalMount","_originalMountComponents","uninstall"],"mappings":"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"}