ladrillosjs 2.0.0-beta.2.2 → 2.0.0-beta.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webcomponent-DrCSyWrI.mjs","sources":["../src/core/css/cssParser.ts","../src/core/html/htmlparser.ts","../src/cache/functionCache.ts","../src/core/html/htmlRenderer.ts","../src/core/js/scriptParser.ts","../src/core/webcomponent.ts"],"sourcesContent":["type StyleTarget = HTMLElement | ShadowRoot;\r\n\r\nexport const loadStyles = (\r\n target: StyleTarget,\r\n cssText: string | undefined,\r\n useShadowDOM: boolean\r\n): void => {\r\n if (!cssText) return;\r\n\r\n const styleEl = document.createElement(\"style\");\r\n styleEl.textContent = cssText;\r\n\r\n if (useShadowDOM) {\r\n target.appendChild(styleEl);\r\n } else {\r\n document.head.appendChild(styleEl);\r\n }\r\n};\r\n","import {\r\n BindingDescriptor,\r\n TwoWayBindingDescriptor,\r\n ConditionalDescriptor,\r\n LoopDescriptor,\r\n} from \"../../types/LadrilloTypes\";\r\nimport { REGEX_PATTERNS } from \"../../utils/regex\";\r\nimport { logParseError } from \"../../utils/devErrors\";\r\n\r\n/**\r\n * Injects the template HTML into the host element and scans for data bindings.\r\n * Returns a list of all bindings found in text nodes and attributes.\r\n */\r\nexport const loadTemplate = (\r\n host: HTMLElement | ShadowRoot,\r\n template: string\r\n): {\r\n bindings: BindingDescriptor[];\r\n twoWayBindings: TwoWayBindingDescriptor[];\r\n conditionals: ConditionalDescriptor[][];\r\n loops: LoopDescriptor[];\r\n} => {\r\n host.innerHTML = template;\r\n\r\n const bindings = scanBindings(host);\r\n const twoWayBindings = scanTwoWayBindings(host);\r\n const conditionals = scanConditionals(host);\r\n const loops = scanLoops(host);\r\n\r\n return { bindings, twoWayBindings, conditionals, loops };\r\n};\r\n\r\n/**\r\n * Extracts variable names from function arguments.\r\n * e.g., \"formatPrice(price)\" → [\"price\"]\r\n * e.g., \"add(x, y)\" → [\"x\", \"y\"]\r\n * e.g., \"format(user.name)\" → [\"user\"]\r\n */\r\nconst extractFunctionArguments = (functionCall: string): string[] => {\r\n const variables: string[] = [];\r\n\r\n // Extract the part between parentheses\r\n const argsMatch = functionCall.match(/\\((.*)\\)/);\r\n if (!argsMatch) return variables;\r\n\r\n const argsString = argsMatch[1].trim();\r\n if (!argsString) return variables;\r\n\r\n // Split by commas, but respect nested function calls\r\n const args = argsString.split(\",\").map((arg) => arg.trim());\r\n\r\n args.forEach((arg) => {\r\n // Remove string literals (both single and double quotes)\r\n if (/^['\"]/.test(arg)) return;\r\n\r\n // Remove numeric literals\r\n if (/^\\d+/.test(arg)) return;\r\n\r\n // Extract variable name (handle dot notation, just get root)\r\n const identifierMatch = arg.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)/);\r\n if (identifierMatch) {\r\n variables.push(identifierMatch[1]);\r\n }\r\n });\r\n\r\n return variables;\r\n};\r\n\r\n/**\r\n * Traverses the DOM tree and collects all data binding expressions.\r\n * Looks for {property} placeholders in both text content and element attributes.\r\n */\r\nconst scanBindings = (host: HTMLElement | ShadowRoot): BindingDescriptor[] => {\r\n // TreeWalker efficiently traverses only text nodes\r\n const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT, null);\r\n const bindings: BindingDescriptor[] = [];\r\n let node: Text | null;\r\n\r\n // Helper function to check if a node is inside a $for loop element\r\n const isInsideLoopElement = (node: Node): boolean => {\r\n let current = node.parentElement;\r\n while (current) {\r\n if (current.hasAttribute && current.hasAttribute(\"$for\")) {\r\n return true;\r\n }\r\n current = current.parentElement;\r\n }\r\n return false;\r\n };\r\n\r\n // Scan for text nodes with bindings\r\n // e.g. <p>{name}</p> or <span>{user.firstName}</span>\r\n while ((node = walker.nextNode() as Text | null)) {\r\n // Skip bindings inside $for loop elements - they'll be handled by processClonedElement\r\n if (isInsideLoopElement(node)) {\r\n continue;\r\n }\r\n\r\n const matches = [...node.textContent.matchAll(REGEX_PATTERNS.bindings)];\r\n\r\n if (matches.length > 0) {\r\n // Store the original template text before any replacements\r\n const original = node.textContent;\r\n\r\n // Create one binding descriptor per node with all its placeholders\r\n const nodeBindings = matches.map((match) => {\r\n const raw = match[1].trim();\r\n const isFunction = raw.includes(\"(\") && raw.includes(\")\"); // Detect function calls like MyName(\"Peter\")\r\n\r\n // Detect if this is a JavaScript expression (contains operators, method calls, etc.)\r\n // Note: We need to be careful with hyphens - they could be part of property names (data-note)\r\n // or subtraction operators. We check if hyphen is surrounded by word characters.\r\n const hasOperator =\r\n /[+*/%<>=!&|]/.test(raw) || // Math or logical operators (excluding hyphen)\r\n /\\s-\\s/.test(raw); // Hyphen with spaces around it (likely subtraction)\r\n\r\n // Check if starts with an operator (like !variable or typeof variable)\r\n const startsWithOperator = /^(!|typeof\\s|void\\s|delete\\s)/.test(raw);\r\n\r\n const isExpression =\r\n hasOperator ||\r\n startsWithOperator || // Expressions starting with operators\r\n /\\.(?![\\s}])[a-zA-Z_$][\\w]*\\(/.test(raw) || // Method calls like name.toLowerCase()\r\n /\\bnew\\s+/.test(raw) || // Object instantiation like new Date()\r\n /\\b(typeof|instanceof|void|delete)\\b/.test(raw); // Other JS operators\r\n\r\n // For functions, extract the function name as the path\r\n // For properties, split by dot notation\r\n const path = isFunction\r\n ? [raw.split(\"(\")[0].trim()] // Extract function name before (\r\n : raw.split(\".\").map((p) => p.trim());\r\n\r\n // Extract variables from function arguments\r\n const functionArgs = isFunction ? extractFunctionArguments(raw) : [];\r\n\r\n return { raw, path, isFunction, isExpression, functionArgs };\r\n });\r\n\r\n bindings.push({ node, bindings: nodeBindings, original });\r\n }\r\n } // Scan for attributes with bindings\r\n // e.g. <img src=\"{imageUrl}\"> or <input value=\"{user.email}\">\r\n const elements = host.querySelectorAll(\"*\");\r\n elements.forEach((el) => {\r\n // Skip bindings on $for loop elements - they'll be handled by processClonedElement\r\n if (el.hasAttribute(\"$for\") || isInsideLoopElement(el)) {\r\n return;\r\n }\r\n\r\n for (const attr of el.attributes) {\r\n // Skip conditional and special directive attributes\r\n if (\r\n attr.name === \"$if\" ||\r\n attr.name === \"$else-if\" ||\r\n attr.name === \"$else\" ||\r\n attr.name === \"$bind\"\r\n ) {\r\n continue;\r\n }\r\n\r\n const matches = [...attr.value.matchAll(REGEX_PATTERNS.bindings)];\r\n if (matches.length > 0) {\r\n // Store the original attribute value\r\n const original = attr.value;\r\n\r\n // Create one binding descriptor per attribute with all its placeholders\r\n const attrBindings = matches.map((match) => {\r\n const raw = match[1].trim();\r\n const isFunction = raw.includes(\"(\") && raw.includes(\")\");\r\n\r\n // Detect if this is a JavaScript expression\r\n // Note: We need to be careful with hyphens - they could be part of property names\r\n const hasOperator =\r\n /[+*/%<>=!&|]/.test(raw) || // Math or logical operators (excluding hyphen)\r\n /\\s-\\s/.test(raw); // Hyphen with spaces around it (likely subtraction)\r\n\r\n // Check if starts with an operator (like !variable or typeof variable)\r\n const startsWithOperator = /^(!|typeof\\s|void\\s|delete\\s)/.test(raw);\r\n\r\n const isExpression =\r\n hasOperator ||\r\n startsWithOperator || // Expressions starting with operators\r\n /\\.(?![\\s}])[a-zA-Z_$][\\w]*\\(/.test(raw) || // Method calls like name.toLowerCase()\r\n /\\bnew\\s+/.test(raw) || // Object instantiation like new Date()\r\n /\\b(typeof|instanceof|void|delete)\\b/.test(raw); // Other JS operators\r\n\r\n const path = isFunction\r\n ? [raw.split(\"(\")[0].trim()]\r\n : raw.split(\".\").map((p) => p.trim());\r\n\r\n // Extract variables from function arguments\r\n const functionArgs = isFunction ? extractFunctionArguments(raw) : [];\r\n\r\n return { raw, path, isFunction, isExpression, functionArgs };\r\n });\r\n\r\n bindings.push({\r\n node: el as unknown as Text,\r\n bindings: attrBindings,\r\n original,\r\n isAttribute: true,\r\n attributeName: attr.name,\r\n });\r\n }\r\n }\r\n });\r\n\r\n return bindings;\r\n};\r\n\r\n/**\r\n * Scans for elements with $bind attribute for two-way data binding.\r\n * e.g. <input $bind=\"inputText\"> or <input $bind=\"person.name\">\r\n * Now also supports contenteditable elements: <div contenteditable $bind=\"text\">\r\n */\r\nconst scanTwoWayBindings = (\r\n host: HTMLElement | ShadowRoot\r\n): TwoWayBindingDescriptor[] => {\r\n const twoWayBindings: TwoWayBindingDescriptor[] = [];\r\n const elements = host.querySelectorAll(\"[\\\\$bind]\");\r\n\r\n elements.forEach((el) => {\r\n const bindValue = el.getAttribute(\"$bind\");\r\n if (!bindValue) return;\r\n\r\n const raw = bindValue.trim();\r\n const path = raw.split(\".\").map((p) => p.trim());\r\n\r\n // Support form inputs (input, textarea, select)\r\n if (\r\n el instanceof HTMLInputElement ||\r\n el instanceof HTMLTextAreaElement ||\r\n el instanceof HTMLSelectElement\r\n ) {\r\n twoWayBindings.push({\r\n element: el,\r\n path,\r\n raw,\r\n isContentEditable: false,\r\n initialValue: el.value || \"\",\r\n });\r\n el.removeAttribute(\"$bind\");\r\n }\r\n // Support contenteditable elements (including those with contenteditable=\"false\" initially)\r\n else if (el instanceof HTMLElement && el.hasAttribute(\"contenteditable\")) {\r\n twoWayBindings.push({\r\n element: el,\r\n path,\r\n raw,\r\n isContentEditable: true,\r\n initialValue: el.textContent?.trim() || \"\",\r\n });\r\n el.removeAttribute(\"$bind\");\r\n }\r\n });\r\n\r\n return twoWayBindings;\r\n};\r\n\r\n/**\r\n * Scans for elements with $if, $else-if, and $else attributes for conditional rendering.\r\n * Groups related conditionals together (if → else-if → else chains).\r\n * e.g. <div $if=\"isVisible\">...</div> or <div $else-if=\"count > 5\">...</div>\r\n */\r\nconst scanConditionals = (\r\n host: HTMLElement | ShadowRoot\r\n): ConditionalDescriptor[][] => {\r\n const allConditionals: ConditionalDescriptor[][] = [];\r\n const processedElements = new Set<Element>();\r\n\r\n // Find all $if elements (start of conditional chains)\r\n const ifElements = host.querySelectorAll(\"[\\\\$if]\");\r\n\r\n ifElements.forEach((element) => {\r\n if (processedElements.has(element)) return;\r\n\r\n const group: ConditionalDescriptor[] = [];\r\n let currentElement: Element | null = element;\r\n\r\n // Process the $if and all following $else-if and $else siblings\r\n while (currentElement) {\r\n const hasIf = currentElement.hasAttribute(\"$if\");\r\n const hasElseIf = currentElement.hasAttribute(\"$else-if\");\r\n const hasElse = currentElement.hasAttribute(\"$else\");\r\n\r\n if (!hasIf && !hasElseIf && !hasElse) break;\r\n\r\n processedElements.add(currentElement);\r\n\r\n let type: \"if\" | \"else-if\" | \"else\";\r\n let condition = \"\";\r\n\r\n if (hasIf) {\r\n type = \"if\";\r\n condition = currentElement.getAttribute(\"$if\") || \"\";\r\n currentElement.removeAttribute(\"$if\");\r\n } else if (hasElseIf) {\r\n type = \"else-if\";\r\n condition = currentElement.getAttribute(\"$else-if\") || \"\";\r\n currentElement.removeAttribute(\"$else-if\");\r\n } else {\r\n type = \"else\";\r\n currentElement.removeAttribute(\"$else\");\r\n }\r\n\r\n // Create a comment placeholder to mark the position\r\n const placeholder = document.createComment(\r\n `conditional:${type}:${condition}`\r\n );\r\n\r\n const parent = currentElement.parentElement || host;\r\n const nextSibling = currentElement.nextSibling;\r\n\r\n // Insert placeholder before the element\r\n parent.insertBefore(placeholder, currentElement);\r\n\r\n const descriptor: ConditionalDescriptor = {\r\n element: currentElement as Element,\r\n condition: condition.trim(),\r\n type,\r\n placeholder,\r\n group: [], // Will be set after the group is complete\r\n originalParent: parent as Element | ShadowRoot,\r\n nextSibling,\r\n };\r\n\r\n group.push(descriptor);\r\n\r\n // Move to the next sibling to check for $else-if or $else\r\n const next: Element | null = currentElement.nextElementSibling;\r\n\r\n // Remove element from DOM initially\r\n currentElement.remove();\r\n\r\n currentElement = next;\r\n\r\n // If next element isn't $else-if or $else, stop the chain\r\n if (\r\n next &&\r\n !next.hasAttribute(\"$else-if\") &&\r\n !next.hasAttribute(\"$else\")\r\n ) {\r\n break;\r\n }\r\n }\r\n\r\n // Set the group reference for all descriptors in this chain\r\n group.forEach((desc) => {\r\n desc.group = group;\r\n });\r\n\r\n allConditionals.push(group);\r\n });\r\n\r\n return allConditionals;\r\n};\r\n\r\n/**\r\n * Extracts variable names from conditional expressions.\r\n * Removes curly braces and extracts identifiers.\r\n * e.g., \"{sending}\" → [\"sending\"], \"{count > 5}\" → [\"count\"]\r\n */\r\nexport const extractConditionalVariables = (\r\n conditionalGroups: ConditionalDescriptor[][]\r\n): Set<string> => {\r\n const variables = new Set<string>();\r\n\r\n conditionalGroups.forEach((group) => {\r\n group.forEach((descriptor) => {\r\n let condition = descriptor.condition;\r\n\r\n // Remove curly braces: {sending} → sending\r\n condition = condition.replace(/\\{([^}]+)\\}/g, \"$1\");\r\n\r\n // Extract variable names (identifiers)\r\n // Match JavaScript identifiers but exclude keywords and literals\r\n const identifierRegex =\r\n /\\b([a-zA-Z_$][a-zA-Z0-9_$]*(?:\\.[a-zA-Z_$][a-zA-Z0-9_$]*)*)\\b/g;\r\n const keywords = new Set([\r\n \"true\",\r\n \"false\",\r\n \"null\",\r\n \"undefined\",\r\n \"typeof\",\r\n \"instanceof\",\r\n \"new\",\r\n \"return\",\r\n \"if\",\r\n \"else\",\r\n \"for\",\r\n \"while\",\r\n \"do\",\r\n \"switch\",\r\n \"case\",\r\n \"break\",\r\n \"continue\",\r\n ]);\r\n\r\n let match;\r\n while ((match = identifierRegex.exec(condition)) !== null) {\r\n const identifier = match[1];\r\n const rootVar = identifier.split(\".\")[0]; // Get root variable name\r\n\r\n // Skip keywords and literals\r\n if (!keywords.has(rootVar)) {\r\n variables.add(rootVar);\r\n }\r\n }\r\n });\r\n });\r\n\r\n return variables;\r\n};\r\n\r\n/**\r\n * Scans for elements with $for attribute for list rendering.\r\n * Supports syntax: \"item in items\" or \"(item, index) in items\"\r\n * e.g. <li $for=\"item in items\">{item}</li>\r\n * e.g. <div $for=\"(user, index) in users\">{index}: {user.name}</div>\r\n */\r\nconst scanLoops = (host: HTMLElement | ShadowRoot): LoopDescriptor[] => {\r\n const loops: LoopDescriptor[] = [];\r\n const loopElements = host.querySelectorAll(\"[\\\\$for]\");\r\n\r\n loopElements.forEach((element) => {\r\n const forExpression = element.getAttribute(\"$for\");\r\n if (!forExpression) return;\r\n\r\n const keyAttribute = element.getAttribute(\"$key\") || undefined;\r\n\r\n // Parse the expression: \"item in items\" or \"(item, index) in items\"\r\n const match = forExpression.match(\r\n /^\\s*(?:\\(([^,]+),\\s*([^)]+)\\)|([^\\s]+))\\s+(?:in|of)\\s+(.+)\\s*$/\r\n );\r\n\r\n if (!match) {\r\n logParseError(`Invalid $for expression: \"${forExpression}\"`, {\r\n expression: forExpression,\r\n lineHint: \"$for attribute parsing\",\r\n });\r\n return;\r\n }\r\n\r\n const itemName = (match[1] || match[3]).trim();\r\n const indexName = match[2]?.trim();\r\n const arrayName = match[4].trim();\r\n\r\n // Create a comment placeholder\r\n const placeholder = document.createComment(`loop:${forExpression}`);\r\n\r\n const parent = element.parentElement || host;\r\n parent.insertBefore(placeholder, element);\r\n\r\n // Remove the $for and $key attributes\r\n element.removeAttribute(\"$for\");\r\n if (keyAttribute) element.removeAttribute(\"$key\");\r\n\r\n // Remove the element from DOM (it will be cloned for each iteration)\r\n element.remove();\r\n\r\n const descriptor: LoopDescriptor = {\r\n template: element as Element,\r\n expression: forExpression,\r\n itemName,\r\n indexName,\r\n arrayName,\r\n keyAttribute,\r\n placeholder,\r\n renderedElements: [],\r\n originalParent: parent as Element | ShadowRoot,\r\n };\r\n\r\n loops.push(descriptor);\r\n });\r\n\r\n return loops;\r\n};\r\n\r\n/**\r\n * Extracts variable names from loop expressions.\r\n * e.g., \"item in items\" → [\"items\"], \"(user, index) in users\" → [\"users\"]\r\n */\r\nexport const extractLoopVariables = (loops: LoopDescriptor[]): Set<string> => {\r\n const variables = new Set<string>();\r\n\r\n loops.forEach((loop) => {\r\n // Add the array name as a variable to watch\r\n const rootVar = loop.arrayName.split(\".\")[0];\r\n variables.add(rootVar);\r\n });\r\n\r\n return variables;\r\n};\r\n","/**\r\n * Cache for compiled function expressions used in template bindings.\r\n * Prevents memory leaks by reusing Function objects for identical expressions.\r\n * Example: {MyName(\"Peter\")} compiles once and is reused on every render.\r\n */\r\nconst functionCache = new Map<string, Function>();\r\nconst maxFunctionCacheSize = 100; // Functions are small, can cache more\r\n\r\n/**\r\n * Gets or creates a cached function for evaluating template expressions.\r\n * Uses LRU pattern to limit cache size and prevent unbounded growth.\r\n * @param expression - The JavaScript expression to compile (e.g., 'MyName(\"Peter\")')\r\n * @returns Compiled Function object that can be executed with a component context\r\n */\r\nexport const getCachedFunction = (expression: string): Function => {\r\n const cached = functionCache.get(expression);\r\n\r\n if (cached) {\r\n // LRU: Move to end (most recently used position)\r\n functionCache.delete(expression);\r\n functionCache.set(expression, cached);\r\n return cached;\r\n }\r\n\r\n // Cache miss: compile new function\r\n // Include common globals in the function scope\r\n const compiledFunc = new Function(\r\n \"component\",\r\n `\r\n const { Date, Array, Math, String, Number, Boolean, Object, JSON, RegExp } = globalThis;\r\n with(component) { \r\n return ${expression}; \r\n }\r\n `\r\n );\r\n\r\n // Check cache size and evict least recently used if needed\r\n if (functionCache.size >= maxFunctionCacheSize) {\r\n const firstKey = functionCache.keys().next().value;\r\n if (firstKey) {\r\n functionCache.delete(firstKey);\r\n }\r\n }\r\n\r\n // Add as most recently used\r\n functionCache.set(expression, compiledFunc);\r\n return compiledFunc;\r\n};\r\n\r\n/**\r\n * Clears the function cache. Useful for testing or memory management.\r\n */\r\nexport const clearFunctionCache = (): void => {\r\n functionCache.clear();\r\n};\r\n\r\n/**\r\n * Gets the current function cache size for debugging/monitoring.\r\n */\r\nexport const getFunctionCacheSize = (): number => {\r\n return functionCache.size;\r\n};\r\n","import {\r\n BindingDescriptor,\r\n ConditionalDescriptor,\r\n LoopDescriptor,\r\n} from \"../../types/LadrilloTypes\";\r\nimport { getCachedFunction } from \"../../cache/functionCache\";\r\nimport {\r\n logBindingError,\r\n logEventHandlerError,\r\n logConditionalError,\r\n logLoopError,\r\n createErrorContext,\r\n} from \"../../utils/devErrors\";\r\n\r\n/**\r\n * Safely retrieves a nested value from an object using a path array.\r\n * Example: getValue({ user: { name: 'John' } }, ['user', 'name']) returns 'John'\r\n */\r\nconst getValue = (ctx: unknown, path: string[]): unknown => {\r\n return path.reduce<unknown>((acc: unknown, segment: string) => {\r\n // Stop traversal if we hit null/undefined or non-object\r\n if (acc == null || typeof acc !== \"object\") return undefined;\r\n return (acc as Record<string, unknown>)[segment];\r\n }, ctx);\r\n};\r\n\r\n/**\r\n * Safely sets a nested value in an object using a path array.\r\n * Example: setValue({ user: {} }, ['user', 'name'], 'John') sets user.name to 'John'\r\n * Creates intermediate objects if they don't exist.\r\n */\r\nexport const setValue = (ctx: any, path: string[], value: unknown): void => {\r\n if (path.length === 0) return;\r\n\r\n // Navigate to the parent object\r\n const lastKey = path[path.length - 1];\r\n const parentPath = path.slice(0, -1);\r\n\r\n let current = ctx;\r\n\r\n // Create intermediate objects if needed\r\n for (const segment of parentPath) {\r\n if (current[segment] === undefined || current[segment] === null) {\r\n current[segment] = {};\r\n }\r\n current = current[segment];\r\n }\r\n\r\n // Set the final value\r\n current[lastKey] = value;\r\n};\r\n\r\n/**\r\n * Updates all DOM bindings with values from the current state context.\r\n * Replaces {property.path} placeholders in text nodes and element attributes.\r\n * Always renders from the original template to support reactive updates.\r\n */\r\nexport const renderBindings = (\r\n bindings: BindingDescriptor[],\r\n context: unknown,\r\n component?: any\r\n): void => {\r\n for (const binding of bindings) {\r\n // Start with the original template\r\n let result = binding.original;\r\n let lastValue: unknown; // Track the last evaluated value for boolean attributes\r\n let hasUndefinedBinding = false; // Track if any binding is undefined\r\n\r\n // Replace all placeholders in this node\r\n for (const { raw, path, isFunction, isExpression } of binding.bindings) {\r\n let value: unknown;\r\n let skipReplacement = false;\r\n\r\n if (isExpression || isFunction) {\r\n // Execute JavaScript expressions like i + 1, name.toLowerCase(), MyName(\"Peter\")\r\n // or !filename (negation), etc.\r\n try {\r\n // Use cached function to prevent memory leaks\r\n const evalFunc = getCachedFunction(raw);\r\n // Pass component directly (don't spread - we need the property descriptors)\r\n // The with(component) scope in getCachedFunction will access properties correctly\r\n value = evalFunc(component || context);\r\n // For expressions/functions, we always replace even if the result is undefined\r\n // because the expression was successfully evaluated\r\n } catch (error) {\r\n logBindingError(raw, error as Error, createErrorContext(component));\r\n value = undefined;\r\n skipReplacement = true;\r\n }\r\n } else {\r\n // Simple property access (e.g., {filename}, {user.name})\r\n value = getValue(context, path);\r\n\r\n // Only skip replacement if it's a simple property and the value is undefined\r\n // This preserves the {placeholder} for missing values\r\n if (value === undefined) {\r\n skipReplacement = true;\r\n }\r\n }\r\n\r\n // If we should skip replacement, mark it and continue\r\n if (skipReplacement) {\r\n hasUndefinedBinding = true;\r\n continue;\r\n }\r\n\r\n const replacement = String(value ?? \"\");\r\n\r\n // Track last value for boolean attribute handling\r\n lastValue = value;\r\n\r\n // Replace this specific placeholder\r\n result = result.replace(`{${raw}}`, replacement);\r\n }\r\n\r\n // If all bindings are undefined, show the original template with placeholders\r\n if (hasUndefinedBinding && result === binding.original) {\r\n // Don't modify - keep the original {placeholder} visible\r\n }\r\n\r\n // Apply the final result to the DOM\r\n if (binding.node.nodeType === Node.TEXT_NODE) {\r\n const textNode = binding.node as Text;\r\n const parentElement = textNode.parentElement;\r\n\r\n // Check if this looks like HTML content\r\n const isHTMLContent =\r\n result.trim().startsWith(\"<\") && result.includes(\">\");\r\n\r\n // If parent element exists and content is HTML, render as HTML\r\n if (parentElement && isHTMLContent) {\r\n parentElement.innerHTML = result;\r\n } else {\r\n // Otherwise, use textContent for security\r\n textNode.textContent = result;\r\n }\r\n } else {\r\n // Handle attribute bindings (e.g., <img src=\"{imageUrl}\">)\r\n const element = binding.node as unknown as Element;\r\n if (binding.isAttribute && binding.attributeName) {\r\n // Handle boolean attributes (disabled, checked, readonly, required, etc.)\r\n const booleanAttributes = [\r\n \"disabled\",\r\n \"checked\",\r\n \"readonly\",\r\n \"required\",\r\n \"selected\",\r\n \"hidden\",\r\n \"open\",\r\n \"autofocus\",\r\n \"autoplay\",\r\n \"controls\",\r\n \"loop\",\r\n \"muted\",\r\n ];\r\n\r\n if (booleanAttributes.includes(binding.attributeName.toLowerCase())) {\r\n // For boolean attributes: use the original value, not the stringified result\r\n const boolValue =\r\n typeof lastValue === \"boolean\"\r\n ? lastValue\r\n : lastValue === \"true\" || lastValue === \"True\";\r\n if (boolValue) {\r\n element.setAttribute(binding.attributeName, \"\");\r\n } else {\r\n element.removeAttribute(binding.attributeName);\r\n }\r\n } else {\r\n // For regular attributes, just set the value\r\n element.setAttribute(binding.attributeName, result);\r\n }\r\n }\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Evaluates a conditional expression in the context of the component.\r\n * Supports both simple boolean checks and complex expressions.\r\n * e.g. \"isVisible\", \"{isVisible}\", \"count > 5\", \"{count} > 5\"\r\n */\r\nconst evaluateCondition = (\r\n condition: string,\r\n context: unknown,\r\n component?: any\r\n): boolean => {\r\n if (!condition) return true; // $else has no condition\r\n\r\n // Remove curly braces if present: {sending} -> sending\r\n let processedCondition = condition.trim();\r\n\r\n // Replace all {variable} with just variable\r\n processedCondition = processedCondition.replace(/\\{([^}]+)\\}/g, \"$1\");\r\n\r\n try {\r\n // Replace variable references in the condition with their values\r\n // This is a simple approach - for production, consider a proper expression parser\r\n const func = new Function(\r\n \"context\",\r\n \"component\",\r\n `\r\n with (context) {\r\n try {\r\n return Boolean(${processedCondition});\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n `\r\n );\r\n\r\n return func(context, component);\r\n } catch (error) {\r\n logConditionalError(\r\n condition,\r\n error as Error,\r\n createErrorContext(component)\r\n );\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Processes event handlers on an element and its descendants.\r\n * Converts inline event attributes to proper event listeners with component scope access.\r\n */\r\nconst processElementEventHandlers = (\r\n element: Element,\r\n component: any\r\n): void => {\r\n const eventTypes = [\r\n \"click\",\r\n \"dblclick\",\r\n \"mousedown\",\r\n \"mouseup\",\r\n \"mouseover\",\r\n \"mouseout\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mouseleave\",\r\n \"keydown\",\r\n \"keyup\",\r\n \"keypress\",\r\n \"focus\",\r\n \"blur\",\r\n \"change\",\r\n \"input\",\r\n \"submit\",\r\n \"reset\",\r\n \"scroll\",\r\n \"resize\",\r\n \"load\",\r\n \"unload\",\r\n \"touchstart\",\r\n \"touchend\",\r\n \"touchmove\",\r\n \"touchcancel\",\r\n \"dragstart\",\r\n \"drag\",\r\n \"dragend\",\r\n \"dragenter\",\r\n \"dragover\",\r\n \"dragleave\",\r\n \"drop\",\r\n ];\r\n\r\n // Process the element itself and all descendants\r\n const elementsToProcess = [element, ...element.querySelectorAll(\"*\")];\r\n\r\n elementsToProcess.forEach((el) => {\r\n eventTypes.forEach((eventType) => {\r\n const attributeName = `on${eventType}`;\r\n const handlerCode = el.getAttribute(attributeName);\r\n\r\n if (handlerCode) {\r\n // Skip if already processed\r\n const key = `__processed_${attributeName}`;\r\n if ((el as any)[key]) return;\r\n\r\n // Remove the attribute\r\n el.removeAttribute(attributeName);\r\n\r\n // Add event listener with component scope\r\n (el as HTMLElement).addEventListener(\r\n eventType,\r\n function (this: HTMLElement, event: Event) {\r\n try {\r\n const func = new Function(\r\n \"event\",\r\n \"component\",\r\n `\r\n with(component) {\r\n ${handlerCode}\r\n }\r\n `\r\n );\r\n func.call(this, event, component);\r\n } catch (error) {\r\n logEventHandlerError(\r\n eventType,\r\n handlerCode,\r\n error as Error,\r\n createErrorContext(component, {\r\n elementTag: el.tagName.toLowerCase(),\r\n })\r\n );\r\n }\r\n }\r\n );\r\n\r\n // Mark as processed\r\n (el as any)[key] = true;\r\n }\r\n });\r\n });\r\n};\r\n\r\n/**\r\n * Updates conditional rendering based on current state.\r\n * Shows/hides elements based on their $if, $else-if, $else conditions.\r\n */\r\nexport const renderConditionals = (\r\n conditionalGroups: ConditionalDescriptor[][],\r\n context: unknown,\r\n component?: any\r\n): void => {\r\n // Process each conditional group (if/else-if/else chain)\r\n for (const group of conditionalGroups) {\r\n let conditionMet = false;\r\n\r\n // Evaluate each condition in the group\r\n for (const descriptor of group) {\r\n const { element, condition, type, placeholder, originalParent } =\r\n descriptor;\r\n\r\n // Check if this condition should be rendered\r\n let shouldRender = false;\r\n\r\n if (type === \"else\") {\r\n // $else renders if no previous condition was met\r\n shouldRender = !conditionMet;\r\n } else if (!conditionMet) {\r\n // $if or $else-if: evaluate condition\r\n shouldRender = evaluateCondition(condition, context, component);\r\n if (shouldRender) conditionMet = true;\r\n }\r\n\r\n // Update DOM based on shouldRender\r\n const isInDOM = element.parentNode !== null;\r\n\r\n if (shouldRender && !isInDOM) {\r\n // Insert element after its placeholder\r\n placeholder.parentNode?.insertBefore(element, placeholder.nextSibling);\r\n\r\n // Process event handlers on newly inserted element\r\n if (component) {\r\n processElementEventHandlers(element, component);\r\n }\r\n } else if (!shouldRender && isInDOM) {\r\n // Remove element from DOM\r\n element.remove();\r\n }\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Renders loop elements based on array data.\r\n * Creates clones of the template for each item in the array.\r\n */\r\nexport const renderLoops = (\r\n loops: LoopDescriptor[],\r\n context: unknown,\r\n component?: any\r\n): void => {\r\n for (const loop of loops) {\r\n const {\r\n template,\r\n itemName,\r\n indexName,\r\n arrayName,\r\n placeholder,\r\n renderedElements,\r\n } = loop;\r\n\r\n // Get the array data from context\r\n const arrayData = getValue(context, arrayName.split(\".\"));\r\n\r\n // Validate array - only warn if the value exists but is not an array\r\n // (undefined values are expected during initial render before scripts execute)\r\n if (arrayData !== undefined && !Array.isArray(arrayData)) {\r\n logLoopError(\r\n `${itemName} in ${arrayName}`,\r\n new Error(`\"${arrayName}\" is not an array, got: ${typeof arrayData}`),\r\n createErrorContext(component, {\r\n lineHint: `$for loop in template`,\r\n })\r\n );\r\n // Clear any existing rendered elements\r\n renderedElements.forEach((el) => el.remove());\r\n renderedElements.length = 0;\r\n return;\r\n }\r\n\r\n // If array doesn't exist yet, don't render anything (wait for state initialization)\r\n if (!arrayData) {\r\n return;\r\n }\r\n\r\n // Remove all currently rendered elements\r\n renderedElements.forEach((el) => el.remove());\r\n renderedElements.length = 0;\r\n\r\n // Render each item\r\n arrayData.forEach((item, index) => {\r\n // Clone the template\r\n const clone = template.cloneNode(true) as Element;\r\n\r\n // Create a scoped context for this iteration\r\n const scopedContext: Record<string, any> = {\r\n ...(context as Record<string, any>),\r\n [itemName]: item,\r\n };\r\n\r\n if (indexName) {\r\n scopedContext[indexName] = index;\r\n }\r\n\r\n // Process bindings in the cloned element\r\n processClonedElement(clone, scopedContext, component);\r\n\r\n // Insert after placeholder (or after the last rendered element)\r\n const insertAfter =\r\n renderedElements.length > 0\r\n ? renderedElements[renderedElements.length - 1]\r\n : placeholder;\r\n\r\n insertAfter.parentNode?.insertBefore(clone, insertAfter.nextSibling);\r\n\r\n // Track rendered element\r\n renderedElements.push(clone);\r\n\r\n // Process event handlers\r\n if (component) {\r\n processElementEventHandlers(clone, component);\r\n }\r\n });\r\n }\r\n};\r\n\r\n/**\r\n * Processes bindings in a cloned element for loop rendering.\r\n * Replaces {variable} placeholders with actual values.\r\n */\r\nconst processClonedElement = (\r\n element: Element,\r\n context: unknown,\r\n component?: any\r\n): void => {\r\n // Process text nodes\r\n const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null);\r\n let node: Text | null;\r\n\r\n while ((node = walker.nextNode() as Text | null)) {\r\n if (node.textContent && node.textContent.includes(\"{\")) {\r\n let result = node.textContent;\r\n const matches = [...node.textContent.matchAll(/\\{([^}]+)\\}/g)];\r\n\r\n matches.forEach((match) => {\r\n const raw = match[1].trim();\r\n\r\n // Detect if this is a JavaScript expression\r\n const isFunction = raw.includes(\"(\") && raw.includes(\")\");\r\n const hasOperator = /[+*/%<>=!&|]/.test(raw) || /\\s-\\s/.test(raw);\r\n const isExpression =\r\n hasOperator ||\r\n /\\.(?![\\s}])[a-zA-Z_$][\\w]*\\(/.test(raw) || // Method calls\r\n /\\bnew\\s+/.test(raw) || // Object instantiation like new Date()\r\n /\\b(typeof|instanceof|void|delete)\\b/.test(raw); // Other JS operators\r\n\r\n let value: unknown;\r\n\r\n if (isExpression || isFunction) {\r\n // Execute JavaScript expressions\r\n try {\r\n const evalFunc = getCachedFunction(raw);\r\n const scope =\r\n typeof context === \"object\" && context !== null\r\n ? { ...context, ...(component || {}) }\r\n : component || {};\r\n value = evalFunc(scope);\r\n } catch (error) {\r\n logBindingError(\r\n raw,\r\n error as Error,\r\n createErrorContext(component, {\r\n lineHint: `$for loop template binding`,\r\n })\r\n );\r\n value = undefined;\r\n }\r\n } else {\r\n // Simple property access\r\n const path = raw.split(\".\").map((p) => p.trim());\r\n value = getValue(context, path);\r\n }\r\n\r\n if (value !== undefined) {\r\n result = result.replace(`{${raw}}`, String(value ?? \"\"));\r\n }\r\n });\r\n\r\n node.textContent = result;\r\n }\r\n }\r\n\r\n // Process attributes (including event handlers with loop variables)\r\n const elementsWithBindings = [element, ...element.querySelectorAll(\"*\")];\r\n elementsWithBindings.forEach((el) => {\r\n Array.from(el.attributes).forEach((attr) => {\r\n if (attr.value.includes(\"{\")) {\r\n let result = attr.value;\r\n const matches = [...attr.value.matchAll(/\\{([^}]+)\\}/g)];\r\n\r\n matches.forEach((match) => {\r\n const raw = match[1].trim();\r\n\r\n // Detect if this is a JavaScript expression\r\n const isFunction = raw.includes(\"(\") && raw.includes(\")\");\r\n const hasOperator = /[+*/%<>=!&|]/.test(raw) || /\\s-\\s/.test(raw);\r\n const isExpression =\r\n hasOperator ||\r\n /\\.(?![\\s}])[a-zA-Z_$][\\w]*\\(/.test(raw) || // Method calls\r\n /\\bnew\\s+/.test(raw) || // Object instantiation like new Date()\r\n /\\b(typeof|instanceof|void|delete)\\b/.test(raw); // Other JS operators\r\n\r\n let value: unknown;\r\n\r\n if (isExpression || isFunction) {\r\n // Execute JavaScript expressions\r\n try {\r\n const evalFunc = getCachedFunction(raw);\r\n const scope =\r\n typeof context === \"object\" && context !== null\r\n ? { ...context, ...(component || {}) }\r\n : component || {};\r\n value = evalFunc(scope);\r\n } catch (error) {\r\n logBindingError(\r\n raw,\r\n error as Error,\r\n createErrorContext(component, {\r\n attributeName: attr.name,\r\n lineHint: `$for loop attribute binding`,\r\n })\r\n );\r\n value = undefined;\r\n }\r\n } else {\r\n // Simple property access\r\n const path = raw.split(\".\").map((p) => p.trim());\r\n value = getValue(context, path);\r\n }\r\n\r\n if (value !== undefined) {\r\n result = result.replace(`{${raw}}`, String(value ?? \"\"));\r\n }\r\n });\r\n\r\n el.setAttribute(attr.name, result);\r\n }\r\n });\r\n });\r\n};\r\n","import {\r\n ScriptElement,\r\n BindingDescriptor,\r\n ExternalScriptElement,\r\n TwoWayBindingDescriptor,\r\n} from \"../../types/LadrilloTypes\";\r\nimport { eventBus } from \"../eventBus\";\r\nimport { logScriptError, createErrorContext } from \"../../utils/devErrors\";\r\n\r\nconst getHostElement = (host: HTMLElement | ShadowRoot): HTMLElement =>\r\n host instanceof ShadowRoot ? (host.host as HTMLElement) : host;\r\n\r\n/**\r\n * Injects $bind variables into the script scope.\r\n * Creates property descriptors that proxy to component.state for reactive access.\r\n */\r\nconst injectBindVariables = (\r\n scriptContent: string,\r\n twoWayBindings: TwoWayBindingDescriptor[]\r\n): {\r\n injectedCode: string;\r\n componentInjections: string;\r\n bindVarNames: Set<string>;\r\n} => {\r\n const bindVarNames = new Set<string>();\r\n\r\n // Extract all $bind variable names (root-level only, e.g., \"person\" from \"person.name\")\r\n twoWayBindings.forEach(({ path }) => {\r\n const rootVar = path[0];\r\n bindVarNames.add(rootVar);\r\n });\r\n\r\n // Create proxy getters/setters for each $bind variable in script scope\r\n const componentInjections: string[] = [];\r\n\r\n bindVarNames.forEach((varName) => {\r\n // Define on component object for event handler access via with(component)\r\n componentInjections.push(`\r\n if (!Object.getOwnPropertyDescriptor(component, '${varName}')) {\r\n Object.defineProperty(component, '${varName}', {\r\n get() { return this.state.${varName}; },\r\n set(val) { this.state.${varName} = val; },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n }\r\n `);\r\n });\r\n\r\n return {\r\n injectedCode: \"\", // No longer needed in script scope\r\n componentInjections: componentInjections.join(\"\\n\"),\r\n bindVarNames,\r\n };\r\n};\r\n\r\n/**\r\n * Extracts variable declarations (const, let, var) from script content\r\n * that match the template bindings or conditionals, and returns code to bind them to state.\r\n * Only binds variables that are actually used in the template or conditionals.\r\n * Also extracts default values for each variable.\r\n */\r\nconst extractStateBindings = (\r\n scriptContent: string,\r\n bindings: BindingDescriptor[],\r\n conditionalVars: Set<string> = new Set()\r\n): {\r\n stateBindings: string[];\r\n boundVarNames: Set<string>;\r\n defaultValues: Map<string, string>;\r\n} => {\r\n const stateBindings: string[] = [];\r\n const defaultValues = new Map<string, string>();\r\n\r\n // Create a Set of all binding names used in the template for fast lookup\r\n const bindingNames = new Set<string>();\r\n bindings.forEach((binding) => {\r\n binding.bindings.forEach((b) => {\r\n // Extract the root property name (e.g., \"user.name\" → \"user\", \"count\" → \"count\")\r\n const rootName = b.path[0];\r\n bindingNames.add(rootName);\r\n\r\n // Also add function arguments (e.g., formatPrice(price) → \"price\")\r\n if (b.isFunction && b.functionArgs) {\r\n b.functionArgs.forEach((arg) => {\r\n bindingNames.add(arg);\r\n });\r\n }\r\n });\r\n });\r\n\r\n // Add conditional variables to binding names\r\n conditionalVars.forEach((varName) => {\r\n bindingNames.add(varName);\r\n });\r\n\r\n // Match: const name = value; | let count = 0; | var items = [];\r\n const variableRegex = /(?:const|let|var)\\s+(\\w+)\\s*=\\s*([^;]+);?/g;\r\n\r\n let match;\r\n while ((match = variableRegex.exec(scriptContent)) !== null) {\r\n const varName = match[1];\r\n const defaultValue = match[2].trim();\r\n\r\n // Only auto-bind if this variable is used in a template binding\r\n if (bindingNames.has(varName)) {\r\n stateBindings.push(`component.state.${varName} = ${varName};`);\r\n defaultValues.set(varName, defaultValue);\r\n }\r\n }\r\n\r\n return { stateBindings, boundVarNames: bindingNames, defaultValues };\r\n};\r\n\r\n/**\r\n * Transforms script content to redirect bound variable assignments to state.\r\n * Handles assignments, increments, decrements, compound assignments, and nested property access.\r\n * Examples:\r\n * - \"name = value\" → \"component.state.name = value\"\r\n * - \"count++\" → \"component.state.count++\"\r\n * - \"count += 5\" → \"component.state.count += 5\"\r\n * - \"user.name = value\" → \"component.state.user.name = value\"\r\n * This makes reactivity transparent - users don't need to know about state.\r\n */\r\nconst transformBoundAssignments = (\r\n scriptContent: string,\r\n boundVarNames: Set<string>\r\n): string => {\r\n if (boundVarNames.size === 0) return scriptContent;\r\n\r\n let transformed = scriptContent;\r\n\r\n boundVarNames.forEach((varName) => {\r\n // 1. Transform array/object index access with assignment: items[0].name = value, items[0]++, etc.\r\n // Match: varName[index].property or varName[index][index2] followed by =, +=, etc.\r\n const arrayIndexWriteRegex = new RegExp(\r\n `\\\\b${varName}((?:\\\\[[^\\\\]]+\\\\])(?:\\\\.[\\\\w]+|\\\\[[^\\\\]]+\\\\])*)\\\\s*([=+\\\\-*/%&|^]|\\\\+\\\\+|\\\\-\\\\-)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n arrayIndexWriteRegex,\r\n `component.state.${varName}$1 $2`\r\n );\r\n\r\n // 2. Transform array/object index access in expressions (reads)\r\n const arrayIndexReadRegex = new RegExp(\r\n `(?<!component\\\\.state\\\\.)\\\\b${varName}((?:\\\\[[^\\\\]]+\\\\])(?:\\\\.[\\\\w]+|\\\\[[^\\\\]]+\\\\])*)(?![=+\\\\-*/%&|^]|\\\\+\\\\+|\\\\-\\\\-)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n arrayIndexReadRegex,\r\n `component.state.${varName}$1`\r\n );\r\n\r\n // 3. Transform property access with assignment/operators: user.name = value, user.count++, etc.\r\n // Match: varName.property followed by =, +=, -=, ++, --, etc.\r\n const propertyWriteRegex = new RegExp(\r\n `\\\\b${varName}\\\\.(\\\\w+(?:\\\\.\\\\w+)*)\\\\s*([=+\\\\-*/%&|^]|\\\\+\\\\+|\\\\-\\\\-)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n propertyWriteRegex,\r\n `component.state.${varName}.$1 $2`\r\n );\r\n\r\n // 4. Transform property access in expressions: user.name (reads)\r\n // But NOT if it's part of an already transformed component.state.varName\r\n // And NOT if it's in a variable declaration\r\n const propertyReadRegex = new RegExp(\r\n `(?<!component\\\\.state\\\\.)(?<!const\\\\s${varName}\\\\s*=\\\\s*{[^}]*)\\\\b${varName}\\\\.(\\\\w+(?:\\\\.\\\\w+)*)(?![=+\\\\-*/%&|^]|\\\\+\\\\+|\\\\-\\\\-)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n propertyReadRegex,\r\n `component.state.${varName}.$1`\r\n );\r\n\r\n // 3. Transform increment/decrement on the variable itself: count++ or ++count\r\n const incrementRegex = new RegExp(\r\n `(?<!\\\\.)\\\\b(\\\\+\\\\+|\\\\-\\\\-)${varName}\\\\b|\\\\b${varName}(\\\\+\\\\+|\\\\-\\\\-)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(incrementRegex, (match) => {\r\n if (match.startsWith(\"++\") || match.startsWith(\"--\")) {\r\n const op = match.substring(0, 2);\r\n return `${op}component.state.${varName}`;\r\n } else {\r\n const op = match.substring(match.length - 2);\r\n return `component.state.${varName}${op}`;\r\n }\r\n });\r\n\r\n // 4. Transform compound assignments on the variable itself: count += 5\r\n const compoundRegex = new RegExp(\r\n `(?<!\\\\.)\\\\b${varName}\\\\s*(\\\\+=|\\\\-=|\\\\*=|\\\\/=|%=|\\\\*\\\\*=|<<=|>>=|>>>=|&=|\\\\|=|\\\\^=)`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n compoundRegex,\r\n `component.state.${varName}$1`\r\n );\r\n\r\n // 5. Transform simple assignments: name = value (but not in declarations)\r\n const assignmentRegex = new RegExp(\r\n `(?<!const\\\\s)(?<!let\\\\s)(?<!var\\\\s)(?<!\\\\.)\\\\b${varName}\\\\s*=\\\\s*([^=])`,\r\n \"g\"\r\n );\r\n transformed = transformed.replace(\r\n assignmentRegex,\r\n `component.state.${varName} = $1`\r\n );\r\n });\r\n\r\n return transformed;\r\n};\r\n\r\n/**\r\n * Processes script content: extracts functions, binds state variables, and transforms assignments.\r\n * This is the core script processing logic that can be reused for both inline and external scripts.\r\n * @param scriptContent - The raw script content to process\r\n * @param bindings - Template bindings to determine which variables should be reactive\r\n * @param twoWayBindings - Two-way bound variables from $bind attributes\r\n * @param host - The host element or shadow root (for querySelector)\r\n * @param componentHost - The component element to execute the script on\r\n * @param conditionalVars - Variables used in conditional expressions ($if, $else-if)\r\n * @returns Map of variable names to their default values\r\n */\r\nconst processScript = (\r\n scriptContent: string,\r\n bindings: BindingDescriptor[],\r\n twoWayBindings: TwoWayBindingDescriptor[],\r\n host: HTMLElement | ShadowRoot,\r\n componentHost: HTMLElement,\r\n conditionalVars: Set<string> = new Set()\r\n): Map<string, string> => {\r\n try {\r\n // Inject $bind variables\r\n const { injectedCode, componentInjections, bindVarNames } =\r\n injectBindVariables(scriptContent, twoWayBindings);\r\n\r\n // Extract function names from the script content\r\n const functionRegex =\r\n /function\\s+(\\w+)|const\\s+(\\w+)\\s*=\\s*(?:\\([^)]*\\)|[\\w\\s]*)\\s*=>/g;\r\n const functionNames: string[] = [];\r\n let match;\r\n\r\n while ((match = functionRegex.exec(scriptContent)) !== null) {\r\n const functionName = match[1] || match[2];\r\n if (functionName) {\r\n functionNames.push(functionName);\r\n }\r\n }\r\n\r\n // Auto-attach detected functions\r\n // Wrap functions to bind them to component and maintain variable access\r\n const attachFunctions = functionNames\r\n .map(\r\n (name) =>\r\n `component.${name} = typeof ${name} !== 'undefined' ? ${name}.bind(component) : undefined;`\r\n )\r\n .join(\"\\n \");\r\n\r\n // Extract and auto-bind variables to state (only those used in template bindings or conditionals)\r\n const { stateBindings, boundVarNames, defaultValues } =\r\n extractStateBindings(scriptContent, bindings, conditionalVars);\r\n\r\n // Merge bindVarNames with boundVarNames for transformation\r\n const allBoundVars = new Set([...boundVarNames, ...bindVarNames]);\r\n\r\n const attachStateBindings = stateBindings.join(\"\\n \");\r\n\r\n // Transform the script to make bound variable assignments reactive\r\n const transformedContent = transformBoundAssignments(\r\n scriptContent,\r\n allBoundVars\r\n );\r\n\r\n // Create a wrapper that captures functions and variables in component scope\r\n const wrappedScript = `\r\n (function() {\r\n // Create component scope with direct access to state\r\n const component = this;\r\n const $state = component.state;\r\n \r\n // Define $bind variables on component object for event handler access\r\n ${componentInjections}\r\n \r\n // Provide framework utilities with $ prefix to avoid naming conflicts\r\n const $setState = (updates) => component.setState(updates);\r\n \r\n // Event bus methods for component communication\r\n const $emit = (eventName, data) => arguments[2].emit(eventName, data);\r\n const $listen = (eventName, callback) => {\r\n const unsubscribe = arguments[2].listen(eventName, callback);\r\n // Store unsubscribe function for cleanup on disconnect\r\n if (!component.__eventUnsubscribers) {\r\n component.__eventUnsubscribers = [];\r\n }\r\n component.__eventUnsubscribers.push(unsubscribe);\r\n return unsubscribe;\r\n };\r\n \r\n // Also attach to component for event handler access\r\n component.$emit = $emit;\r\n component.$listen = $listen;\r\n \r\n // Override querySelector/querySelectorAll to query within the component's host\r\n const host = arguments[1];\r\n const $querySelector = (selector) => host.querySelector(selector);\r\n const $querySelectorAll = (selector) => host.querySelectorAll(selector);\r\n \r\n // Execute script content within component scope so $bind variables are accessible\r\n with(component) {\r\n ${transformedContent}\r\n \r\n // Auto-bind variables to component state (e.g., const name = \"value\" → this.state.name = \"value\")\r\n ${attachStateBindings}\r\n \r\n // Auto-attach all detected functions to component for onclick access\r\n ${attachFunctions}\r\n }\r\n }).call(arguments[0], arguments[0], arguments[1], arguments[2])\r\n `;\r\n\r\n const executor = new Function(wrappedScript);\r\n executor(componentHost, host, eventBus);\r\n\r\n return defaultValues;\r\n } catch (error) {\r\n logScriptError(error as Error, createErrorContext(componentHost));\r\n return new Map();\r\n }\r\n};\r\n\r\n/**\r\n * Processes inline event handlers (onclick, onkeyup, oninput, etc.) to bind them to the component context.\r\n * Removes inline event attributes and converts them to proper event listeners\r\n * that have access to the component scope.\r\n * @param host - The host element or shadow root\r\n * @param componentHost - The component element\r\n */\r\nconst processEventHandlers = (\r\n host: HTMLElement | ShadowRoot,\r\n componentHost: HTMLElement\r\n): void => {\r\n // All standard DOM events that can be handled as attributes\r\n const eventTypes = [\r\n \"click\",\r\n \"dblclick\",\r\n \"mousedown\",\r\n \"mouseup\",\r\n \"mouseover\",\r\n \"mouseout\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mouseleave\",\r\n \"keydown\",\r\n \"keyup\",\r\n \"keypress\",\r\n \"focus\",\r\n \"blur\",\r\n \"change\",\r\n \"input\",\r\n \"submit\",\r\n \"reset\",\r\n \"scroll\",\r\n \"resize\",\r\n \"load\",\r\n \"unload\",\r\n \"touchstart\",\r\n \"touchend\",\r\n \"touchmove\",\r\n \"touchcancel\",\r\n \"dragstart\",\r\n \"drag\",\r\n \"dragend\",\r\n \"dragenter\",\r\n \"dragover\",\r\n \"dragleave\",\r\n \"drop\",\r\n ];\r\n\r\n // Add a WeakSet to track processed elements\r\n const processedElements = new WeakSet<Element>();\r\n\r\n eventTypes.forEach((eventType) => {\r\n const attributeName = `on${eventType}`;\r\n const elements =\r\n host instanceof ShadowRoot\r\n ? host.querySelectorAll(`[${attributeName}]`)\r\n : componentHost.querySelectorAll(`[${attributeName}]`);\r\n\r\n elements.forEach((element) => {\r\n // Create a unique key for this element + event combination\r\n const key = `${attributeName}`;\r\n if ((element as any)[`__processed_${key}`]) return; // Skip if already processed\r\n\r\n const handlerCode = element.getAttribute(attributeName);\r\n if (handlerCode) {\r\n element.removeAttribute(attributeName);\r\n (element as HTMLElement).addEventListener(\r\n eventType,\r\n function (this: HTMLElement, event: Event) {\r\n const func = new Function(\r\n \"event\",\r\n \"component\",\r\n `\r\n with(component) {\r\n ${handlerCode}\r\n }\r\n `\r\n );\r\n func.call(this, event, componentHost);\r\n }\r\n );\r\n\r\n // Mark as processed for this specific event\r\n (element as any)[`__processed_${key}`] = true;\r\n }\r\n });\r\n });\r\n};\r\n\r\n/**\r\n * Transforms a module script to make variable bindings reactive.\r\n * Detects variables used in template bindings and wraps assignments to update component state.\r\n * @param scriptContent - The module script content\r\n * @param bindings - Template bindings to determine which variables should be reactive\r\n * @param componentId - The component ID for accessing the context\r\n * @returns Transformed script content\r\n */\r\nconst transformModuleScript = (\r\n scriptContent: string,\r\n bindings: BindingDescriptor[],\r\n componentId: string\r\n): string => {\r\n // Extract variable names used in bindings\r\n const bindingVarNames = new Set<string>();\r\n bindings.forEach((binding) => {\r\n binding.bindings.forEach((b) => {\r\n if (!b.isFunction) {\r\n const rootName = b.path[0];\r\n bindingVarNames.add(rootName);\r\n }\r\n });\r\n });\r\n\r\n if (bindingVarNames.size === 0) {\r\n return scriptContent; // No transformations needed\r\n }\r\n\r\n // Add helper code at the beginning to get component context\r\n const helperCode = `\r\n// Auto-generated: Get component context for reactive bindings\r\nconst __getContext = () => window.__ladrilloContexts?.get('${componentId}');\r\nconst __component = __getContext()?.element;\r\n`;\r\n\r\n let transformed = scriptContent;\r\n\r\n // Transform variable declarations to initialize state\r\n bindingVarNames.forEach((varName) => {\r\n // Match: let varName = value; or const varName = value;\r\n const declRegex = new RegExp(\r\n `(let|const|var)\\\\s+${varName}\\\\s*=\\\\s*([^;]+);`,\r\n \"g\"\r\n );\r\n\r\n transformed = transformed.replace(declRegex, (match, keyword, value) => {\r\n return `${keyword} ${varName} = ${value};\\nif (__component?.setState) __component.setState({ ${varName}: ${varName} });`;\r\n });\r\n\r\n // Transform assignments: varName = value\r\n // Make sure we don't match declarations (let/const/var) or object properties (obj.varName)\r\n const assignRegex = new RegExp(\r\n `(?<!let\\\\s|const\\\\s|var\\\\s|\\\\.)\\\\b${varName}\\\\s*=\\\\s*([^;]+);`,\r\n \"g\"\r\n );\r\n\r\n transformed = transformed.replace(assignRegex, (match, value) => {\r\n return `${varName} = ${value};\\nif (__component?.setState) __component.setState({ ${varName}: ${varName} });`;\r\n });\r\n\r\n // Transform increment/decrement operators\r\n const incDecRegex = new RegExp(`\\\\b${varName}(\\\\+\\\\+|\\\\-\\\\-)`, \"g\");\r\n\r\n transformed = transformed.replace(incDecRegex, (match, op) => {\r\n return `${varName}${op};\\nif (__component?.setState) __component.setState({ ${varName}: ${varName} });`;\r\n });\r\n\r\n // Transform compound assignments\r\n const compoundRegex = new RegExp(\r\n `\\\\b${varName}\\\\s*(\\\\+=|\\\\-=|\\\\*=|\\\\/=)\\\\s*([^;]+);`,\r\n \"g\"\r\n );\r\n\r\n transformed = transformed.replace(compoundRegex, (match, op, value) => {\r\n return `${varName} ${op} ${value};\\nif (__component?.setState) __component.setState({ ${varName}: ${varName} });`;\r\n });\r\n });\r\n\r\n return helperCode + transformed;\r\n};\r\n\r\nexport const loadScripts = async (\r\n host: HTMLElement | ShadowRoot,\r\n scripts: ScriptElement[],\r\n bindings: BindingDescriptor[],\r\n twoWayBindings: TwoWayBindingDescriptor[] = [],\r\n conditionalVars: Set<string> = new Set()\r\n): Promise<Map<string, string>> => {\r\n const allDefaults = new Map<string, string>();\r\n\r\n if (!scripts?.length) return allDefaults;\r\n\r\n const componentHost = getHostElement(host);\r\n\r\n for (const scriptDefinition of scripts) {\r\n if (scriptDefinition.content) {\r\n const defaults = processScript(\r\n scriptDefinition.content,\r\n bindings,\r\n twoWayBindings,\r\n host,\r\n componentHost,\r\n conditionalVars\r\n );\r\n\r\n // Merge defaults from this script\r\n defaults.forEach((value, key) => {\r\n if (!allDefaults.has(key)) {\r\n allDefaults.set(key, value);\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Process all event handlers to bind them to the component\r\n processEventHandlers(host, componentHost);\r\n\r\n return allDefaults;\r\n};\r\n\r\n/**\r\n * Loads a global external script (e.g., from CDN) and returns a promise that resolves when loaded.\r\n * Prevents duplicate script tags by checking if the script is already loaded.\r\n * @param src - The script URL\r\n * @param type - The script type (e.g., 'module', 'text/javascript')\r\n * @returns Promise that resolves when the script is loaded\r\n */\r\nconst loadGlobalScript = (src: string, type: string | null): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n // Check if script is already loaded and ready\r\n const existingScript = document.querySelector(\r\n `script[src=\"${src}\"]`\r\n ) as HTMLScriptElement;\r\n if (existingScript) {\r\n // If script already loaded, check if it's ready\r\n if (existingScript.dataset.loaded === \"true\") {\r\n resolve();\r\n return;\r\n }\r\n\r\n // If it's loading, wait for it\r\n existingScript.addEventListener(\"load\", () => resolve(), { once: true });\r\n existingScript.addEventListener(\r\n \"error\",\r\n () => reject(new Error(`Failed to load external script: ${src}`)),\r\n { once: true }\r\n );\r\n return;\r\n }\r\n\r\n const script = document.createElement(\"script\");\r\n script.src = src;\r\n if (type) {\r\n script.type = type;\r\n }\r\n\r\n script.onload = () => {\r\n script.dataset.loaded = \"true\";\r\n resolve();\r\n };\r\n script.onerror = () =>\r\n reject(new Error(`Failed to load external script: ${src}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n};\r\n\r\nexport const loadExternalScripts = async (\r\n host: HTMLElement | ShadowRoot,\r\n externalScripts: ExternalScriptElement[],\r\n bindings: BindingDescriptor[],\r\n twoWayBindings: TwoWayBindingDescriptor[] = [],\r\n conditionalVars: Set<string> = new Set(),\r\n componentSourcePath?: string\r\n) => {\r\n const componentHost = getHostElement(host);\r\n\r\n for (const s of externalScripts) {\r\n // Resolve script URL relative to the component's HTML file location\r\n // Convert relative path to absolute URL if needed\r\n let baseURL: string;\r\n if (componentSourcePath) {\r\n // If it's already an absolute URL, use it directly\r\n if (\r\n componentSourcePath.startsWith(\"http://\") ||\r\n componentSourcePath.startsWith(\"https://\")\r\n ) {\r\n baseURL = componentSourcePath;\r\n } else {\r\n // Convert relative path to absolute URL using window.location\r\n // Ensure the base URL ends with the component path including filename\r\n // so that relative paths like '../js/app.js' resolve correctly\r\n const fullComponentURL = new URL(\r\n componentSourcePath,\r\n window.location.href\r\n ).href;\r\n baseURL = fullComponentURL;\r\n }\r\n } else {\r\n baseURL = window.location.href;\r\n }\r\n\r\n const scriptURL = new URL(s.src, baseURL).href;\r\n\r\n if (s.external) {\r\n // Inject script tag to document for external CDN scripts (e.g., highlight.js, three.js)\r\n // These scripts load globally and don't need component-specific processing\r\n await loadGlobalScript(scriptURL, s.type);\r\n } else if (s.type === \"module\") {\r\n // For module scripts, load them normally as ES modules\r\n // The bind attribute is a signal that the user wants reactive bindings,\r\n // but ES modules can't be transformed the same way as regular scripts\r\n // So we store the context and let the module use helper functions\r\n const componentId = componentHost.tagName.toLowerCase();\r\n\r\n if (!(window as any).__ladrilloContexts) {\r\n (window as any).__ladrilloContexts = new Map();\r\n }\r\n\r\n // Store the component context so the module can access it\r\n (window as any).__ladrilloContexts.set(componentId, {\r\n host,\r\n shadowRoot: host instanceof ShadowRoot ? host : null,\r\n element: componentHost,\r\n state: (componentHost as any).state,\r\n setState: (componentHost as any).setState?.bind(componentHost),\r\n });\r\n\r\n // Load the module script normally\r\n const script = document.createElement(\"script\");\r\n script.type = \"module\";\r\n script.src = scriptURL;\r\n script.setAttribute(\"data-component\", componentId);\r\n document.head.appendChild(script);\r\n } else {\r\n // Fetch and process local non-module scripts through reactive processing\r\n await fetch(scriptURL)\r\n .then((response) => {\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n const contentType = response.headers.get(\"content-type\");\r\n if (\r\n contentType &&\r\n !contentType.includes(\"javascript\") &&\r\n !contentType.includes(\"text/plain\")\r\n ) {\r\n throw new Error(`Expected JavaScript but got ${contentType}`);\r\n }\r\n return response.text();\r\n })\r\n .then((scriptContent) => {\r\n // Reuse the same processing logic as inline scripts\r\n processScript(\r\n scriptContent,\r\n bindings,\r\n twoWayBindings,\r\n host,\r\n componentHost,\r\n conditionalVars\r\n );\r\n })\r\n .catch((error) => {\r\n console.error(`Failed to load external script: ${s.src}`, error);\r\n });\r\n }\r\n }\r\n\r\n // Process all event handlers to bind them to the component\r\n processEventHandlers(host, componentHost);\r\n};\r\n","import {\r\n BindingDescriptor,\r\n LadrillosComponent,\r\n TwoWayBindingDescriptor,\r\n ConditionalDescriptor,\r\n LoopDescriptor,\r\n} from \"../types/LadrilloTypes\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { logTwoWayBindingError, createErrorContext } from \"../utils/devErrors\";\r\nimport { loadStyles } from \"./css/cssParser\";\r\n\r\nimport {\r\n loadTemplate,\r\n extractConditionalVariables,\r\n extractLoopVariables,\r\n} from \"./html/htmlparser\";\r\nimport {\r\n renderBindings,\r\n setValue,\r\n renderConditionals,\r\n renderLoops,\r\n} from \"./html/htmlRenderer\";\r\nimport { loadExternalScripts, loadScripts } from \"./js/scriptParser\";\r\n\r\nexport const defineWebComponent = (\r\n component: LadrillosComponent,\r\n useShadowDOM: boolean\r\n) => {\r\n const { tagName, template, scripts, externalScripts, styles, sourcePath } =\r\n component;\r\n\r\n class ComponentElement extends HTMLElement {\r\n state: any;\r\n #bindings: BindingDescriptor[] = [];\r\n #twoWayBindings: TwoWayBindingDescriptor[] = [];\r\n #conditionals: ConditionalDescriptor[][] = [];\r\n #loops: LoopDescriptor[] = [];\r\n #twoWayBindingCleanups: Array<() => void> = [];\r\n #sourcePath: string | undefined = sourcePath;\r\n #proxyCache: WeakMap<object, any> = new WeakMap();\r\n\r\n /**\r\n * Creates a deep reactive proxy that tracks nested object/array mutations\r\n * @param target - The object or array to make reactive\r\n * @param callback - Function to call when any nested property changes\r\n */\r\n #createDeepProxy(target: any, callback: () => void): any {\r\n // Don't proxy primitives or null\r\n if (target === null || typeof target !== \"object\") {\r\n return target;\r\n }\r\n\r\n // Don't proxy DOM elements or other complex objects\r\n if (target instanceof HTMLElement || target instanceof Node) {\r\n return target;\r\n }\r\n\r\n // Check if we already have a proxy for this object\r\n if (this.#proxyCache.has(target)) {\r\n return this.#proxyCache.get(target);\r\n }\r\n\r\n const proxy = new Proxy(target, {\r\n get: (obj, prop) => {\r\n const value = obj[prop];\r\n\r\n // For array mutation methods, bind them to trigger callback after execution\r\n if (Array.isArray(obj) && typeof value === \"function\") {\r\n const arrayMutationMethods = [\r\n \"push\",\r\n \"pop\",\r\n \"shift\",\r\n \"unshift\",\r\n \"splice\",\r\n \"sort\",\r\n \"reverse\",\r\n ];\r\n if (arrayMutationMethods.includes(prop as string)) {\r\n return (...args: any[]) => {\r\n const result = (value as Function).apply(obj, args);\r\n callback(); // Trigger re-render after mutation\r\n return result;\r\n };\r\n }\r\n }\r\n\r\n // Recursively proxy nested objects/arrays\r\n if (value !== null && typeof value === \"object\") {\r\n return this.#createDeepProxy(value, callback);\r\n }\r\n return value;\r\n },\r\n set: (obj, prop, value) => {\r\n const prev = obj[prop];\r\n // Skip if value hasn't changed\r\n if (Object.is(prev, value)) return true;\r\n\r\n obj[prop] = value;\r\n callback(); // Trigger re-render\r\n return true;\r\n },\r\n });\r\n\r\n // Cache the proxy\r\n this.#proxyCache.set(target, proxy);\r\n return proxy;\r\n }\r\n\r\n constructor() {\r\n super();\r\n if (useShadowDOM) this.attachShadow({ mode: \"open\" });\r\n\r\n const internalState: any = {};\r\n\r\n // Callback for triggering re-renders\r\n const triggerUpdate = () => {\r\n renderBindings(this.#bindings, this.state, this);\r\n renderConditionals(this.#conditionals, this.state, this);\r\n renderLoops(this.#loops, this.state, this);\r\n this.#updateTwoWayBindings();\r\n };\r\n\r\n // Wrap state in a deep reactive Proxy to detect all nested changes\r\n this.state = new Proxy(internalState, {\r\n get: (target, prop) => {\r\n return target[prop as keyof typeof target];\r\n },\r\n set: (target, prop, value) => {\r\n const prev = target[prop as keyof typeof target];\r\n const propertyExists = prop in target;\r\n\r\n // Skip update if property exists AND value hasn't changed (avoids unnecessary re-renders)\r\n // But always proceed if property doesn't exist yet (need to create descriptor)\r\n if (propertyExists && Object.is(prev, value)) return true;\r\n\r\n // Wrap objects/arrays in deep proxies for nested reactivity\r\n if (value !== null && typeof value === \"object\") {\r\n target[prop as keyof typeof target] = this.#createDeepProxy(\r\n value,\r\n triggerUpdate\r\n );\r\n } else {\r\n target[prop as keyof typeof target] = value;\r\n }\r\n\r\n // Auto-create property descriptor on component for direct access in with() scope\r\n if (!Object.getOwnPropertyDescriptor(this, prop)) {\r\n Object.defineProperty(this, prop, {\r\n get() {\r\n return this.state[prop];\r\n },\r\n set(val) {\r\n this.state[prop] = val;\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n });\r\n }\r\n\r\n // Re-render all bindings with the updated state\r\n triggerUpdate();\r\n return true;\r\n },\r\n });\r\n }\r\n /**\r\n * Updates component state with one or more key-value pairs\r\n * @param updates - Object containing state updates\r\n * @example\r\n * component.setState({ count: 5, name: 'John' })\r\n */\r\n setState(updates: Record<string, any>): void {\r\n Object.assign(this.state, updates);\r\n }\r\n\r\n static #parseAttributeValue(raw: string | null) {\r\n if (raw === null || raw === \"\") return null;\r\n if (raw === \"undefined\") return undefined;\r\n try {\r\n return JSON.parse(raw);\r\n } catch {\r\n return raw;\r\n }\r\n }\r\n\r\n // Invoked when element is added to the DOM\r\n async connectedCallback() {\r\n const host = useShadowDOM ? this.shadowRoot! : this;\r\n\r\n // Parse template and collect all data binding locations\r\n const { bindings, twoWayBindings, conditionals, loops } = loadTemplate(\r\n host,\r\n template\r\n );\r\n this.#bindings = bindings;\r\n this.#twoWayBindings = twoWayBindings;\r\n this.#conditionals = conditionals;\r\n this.#loops = loops;\r\n\r\n // Extract variables used in conditional expressions and loops\r\n const conditionalVars = extractConditionalVariables(conditionals);\r\n const loopVars = extractLoopVariables(loops);\r\n\r\n // Inject component styles\r\n loadStyles(host, styles, useShadowDOM);\r\n\r\n // Load external scripts first (e.g., CDN libraries like highlight.js)\r\n // so they're available when inline scripts execute\r\n await loadExternalScripts(\r\n host,\r\n externalScripts,\r\n this.#bindings,\r\n this.#twoWayBindings,\r\n new Set([...conditionalVars, ...loopVars]),\r\n this.#sourcePath\r\n );\r\n\r\n // Execute component scripts (event handlers, methods, etc.)\r\n // Pass conditional variables and loop variables so they get mapped to state\r\n // Get default values from script declarations\r\n const scriptDefaults = await loadScripts(\r\n host,\r\n scripts,\r\n this.#bindings,\r\n this.#twoWayBindings,\r\n new Set([...conditionalVars, ...loopVars])\r\n );\r\n\r\n // Initialize state with script defaults first (before attributes override them)\r\n scriptDefaults.forEach((defaultValue, varName) => {\r\n // Only set if the state doesn't already have a value\r\n if (this.state[varName] === undefined) {\r\n try {\r\n // Evaluate the default value\r\n const evalFunc = new Function(`return ${defaultValue}`);\r\n this.state[varName] = evalFunc();\r\n } catch (error) {\r\n // If evaluation fails, use the raw value\r\n this.state[varName] = defaultValue;\r\n }\r\n }\r\n });\r\n\r\n // Sync initial state from HTML attributes (e.g., <my-component name=\"value\">)\r\n // This will override script defaults if attributes are present\r\n this._initializeStateFromAttributes();\r\n\r\n // Setup two-way bindings\r\n this._setupTwoWayBindings();\r\n\r\n // Perform initial render with current state values (after scripts are ready)\r\n renderBindings(this.#bindings, this.state, this);\r\n renderConditionals(this.#conditionals, this.state, this);\r\n renderLoops(this.#loops, this.state, this);\r\n\r\n // Set up MutationObserver to watch for attribute changes\r\n this._setupAttributeObserver();\r\n }\r\n\r\n // Invoked when element is removed from the DOM\r\n disconnectedCallback() {\r\n // Clean up MutationObserver\r\n if ((this as any).__attributeObserver) {\r\n (this as any).__attributeObserver.disconnect();\r\n (this as any).__attributeObserver = null;\r\n }\r\n\r\n // Clean up two-way binding event listeners\r\n this.#twoWayBindingCleanups.forEach((cleanup) => {\r\n try {\r\n cleanup();\r\n } catch (error) {\r\n logTwoWayBindingError(\r\n \"cleanup\",\r\n error as Error,\r\n createErrorContext(this, {\r\n lineHint: \"disconnectedCallback cleanup\",\r\n })\r\n );\r\n }\r\n });\r\n this.#twoWayBindingCleanups = [];\r\n\r\n // Clean up EventBus subscriptions\r\n const unsubscribers = (this as any).__eventUnsubscribers;\r\n if (unsubscribers && Array.isArray(unsubscribers)) {\r\n unsubscribers.forEach((unsub: () => void) => {\r\n try {\r\n unsub();\r\n } catch (error) {\r\n logger.error(\r\n `⚠️ Event Bus Error: Failed to unsubscribe from event`,\r\n createErrorContext(this)\r\n );\r\n logger.error(` Error details: ${(error as Error).message}`);\r\n }\r\n });\r\n (this as any).__eventUnsubscribers = [];\r\n }\r\n }\r\n\r\n // Set up observer to watch for attribute changes\r\n _setupAttributeObserver() {\r\n const observer = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === \"attributes\" && mutation.attributeName) {\r\n const newValue = this.getAttribute(mutation.attributeName);\r\n this._handleAttributeChange(mutation.attributeName, newValue);\r\n }\r\n });\r\n });\r\n\r\n observer.observe(this, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n });\r\n\r\n (this as any).__attributeObserver = observer;\r\n }\r\n\r\n // initializes the state from the attributes\r\n _initializeStateFromAttributes() {\r\n this.getAttributeNames().forEach((name) => {\r\n const raw = this.getAttribute(name);\r\n this._handleAttributeChange(name, raw);\r\n });\r\n }\r\n\r\n // Invoked when attributes are changed.\r\n _handleAttributeChange(name: string, raw: string | null) {\r\n if (name) {\r\n // remove \"this.state.\" prefix if it exists\r\n const STATE_PREFIX = \"this.state.\";\r\n if (name.startsWith(STATE_PREFIX)) {\r\n name = name.slice(STATE_PREFIX.length);\r\n }\r\n }\r\n const value = ComponentElement.#parseAttributeValue(raw);\r\n this.state[name] = value;\r\n }\r\n\r\n // Setup two-way data bindings for input elements with $bind\r\n _setupTwoWayBindings() {\r\n this.#twoWayBindings.forEach(\r\n ({ element, path, raw, isContentEditable, initialValue }) => {\r\n // Initialize state property if it doesn't exist, using stored initial content\r\n const currentValue = this._getNestedValue(path);\r\n\r\n if (currentValue === undefined) {\r\n const content = initialValue || \"\";\r\n setValue(this.state, path, content);\r\n }\r\n\r\n if (isContentEditable) {\r\n // Handle contenteditable elements\r\n const contentEditableEl = element as HTMLElement;\r\n\r\n // Initial sync from state to element\r\n contentEditableEl.textContent = this._getNestedValue(path) ?? \"\";\r\n\r\n // Listen for input changes and update state\r\n const handleInput = (e: Event) => {\r\n const target = e.target as HTMLElement;\r\n const newValue = target.textContent || \"\";\r\n\r\n // Update state using setValue to handle nested paths\r\n setValue(this.state, path, newValue);\r\n };\r\n\r\n contentEditableEl.addEventListener(\"input\", handleInput);\r\n\r\n // Store cleanup function\r\n const cleanup = () => {\r\n contentEditableEl.removeEventListener(\"input\", handleInput);\r\n };\r\n this.#twoWayBindingCleanups.push(cleanup);\r\n } else {\r\n // Handle form input elements\r\n const inputEl = element as\r\n | HTMLInputElement\r\n | HTMLTextAreaElement\r\n | HTMLSelectElement;\r\n\r\n // Check if this is a checkbox or radio button\r\n const isCheckbox =\r\n inputEl instanceof HTMLInputElement &&\r\n inputEl.type === \"checkbox\";\r\n const isRadio =\r\n inputEl instanceof HTMLInputElement && inputEl.type === \"radio\";\r\n\r\n // Initial sync from state to element\r\n if (isCheckbox) {\r\n // For checkboxes, use 'checked' property\r\n inputEl.checked = Boolean(this._getNestedValue(path));\r\n } else {\r\n // For other inputs, use 'value' property\r\n inputEl.value = this._getNestedValue(path) ?? \"\";\r\n }\r\n\r\n // Listen for input changes and update state\r\n const handleInput = (e: Event) => {\r\n const target = e.target as\r\n | HTMLInputElement\r\n | HTMLTextAreaElement\r\n | HTMLSelectElement;\r\n\r\n let newValue: any;\r\n\r\n if (\r\n target instanceof HTMLInputElement &&\r\n target.type === \"checkbox\"\r\n ) {\r\n // For checkboxes, get the 'checked' property\r\n newValue = target.checked;\r\n } else if (\r\n target instanceof HTMLInputElement &&\r\n target.type === \"radio\"\r\n ) {\r\n // For radio buttons, get the 'value' property\r\n newValue = target.value;\r\n } else {\r\n // For other inputs, get the 'value' property\r\n newValue = target.value;\r\n }\r\n\r\n // Update state using setValue to handle nested paths\r\n setValue(this.state, path, newValue);\r\n };\r\n\r\n inputEl.addEventListener(\"input\", handleInput);\r\n\r\n // Store cleanup function for 'input' listener\r\n const cleanupInput = () => {\r\n inputEl.removeEventListener(\"input\", handleInput);\r\n };\r\n this.#twoWayBindingCleanups.push(cleanupInput);\r\n\r\n // For select and certain input types, also listen to 'change'\r\n if (\r\n inputEl instanceof HTMLSelectElement ||\r\n (inputEl instanceof HTMLInputElement &&\r\n [\"checkbox\", \"radio\", \"file\"].includes(inputEl.type))\r\n ) {\r\n inputEl.addEventListener(\"change\", handleInput);\r\n\r\n // Store cleanup function for 'change' listener\r\n const cleanupChange = () => {\r\n inputEl.removeEventListener(\"change\", handleInput);\r\n };\r\n this.#twoWayBindingCleanups.push(cleanupChange);\r\n }\r\n }\r\n }\r\n );\r\n }\r\n\r\n // Update two-way bound elements when state changes\r\n #updateTwoWayBindings() {\r\n this.#twoWayBindings.forEach(({ element, path, isContentEditable }) => {\r\n const value = this._getNestedValue(path);\r\n\r\n if (isContentEditable) {\r\n const contentEditableEl = element as HTMLElement;\r\n if (contentEditableEl.textContent !== value) {\r\n contentEditableEl.textContent = value ?? \"\";\r\n }\r\n } else {\r\n const inputEl = element as\r\n | HTMLInputElement\r\n | HTMLTextAreaElement\r\n | HTMLSelectElement;\r\n\r\n // Handle checkboxes differently\r\n if (\r\n inputEl instanceof HTMLInputElement &&\r\n inputEl.type === \"checkbox\"\r\n ) {\r\n const boolValue = Boolean(value);\r\n if (inputEl.checked !== boolValue) {\r\n inputEl.checked = boolValue;\r\n }\r\n } else {\r\n // For other inputs, use value property\r\n if (inputEl.value !== value) {\r\n inputEl.value = value ?? \"\";\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Helper to get nested value from state\r\n _getNestedValue(path: string[]): any {\r\n return path.reduce((acc, key) => {\r\n return acc?.[key];\r\n }, this.state);\r\n }\r\n }\r\n\r\n // Only define if not already defined\r\n if (!customElements.get(tagName)) {\r\n customElements.define(tagName, ComponentElement);\r\n logger.log(`Web component defined: <${tagName}></${tagName}>`);\r\n }\r\n};\r\n"],"names":["loadStyles","target","cssText","useShadowDOM","styleEl","loadTemplate","host","template","bindings","scanBindings","twoWayBindings","scanTwoWayBindings","conditionals","scanConditionals","loops","scanLoops","extractFunctionArguments","functionCall","variables","argsMatch","argsString","arg","identifierMatch","walker","node","isInsideLoopElement","current","matches","REGEX_PATTERNS","original","nodeBindings","match","raw","isFunction","hasOperator","startsWithOperator","isExpression","path","p","functionArgs","el","attr","attrBindings","bindValue","_a","allConditionals","processedElements","element","group","currentElement","hasIf","hasElseIf","hasElse","type","condition","placeholder","parent","nextSibling","descriptor","next","desc","extractConditionalVariables","conditionalGroups","identifierRegex","keywords","rootVar","forExpression","keyAttribute","logParseError","itemName","indexName","arrayName","extractLoopVariables","loop","functionCache","maxFunctionCacheSize","getCachedFunction","expression","cached","compiledFunc","firstKey","getValue","ctx","acc","segment","setValue","value","lastKey","parentPath","renderBindings","context","component","binding","result","lastValue","hasUndefinedBinding","skipReplacement","error","logBindingError","createErrorContext","replacement","textNode","parentElement","isHTMLContent","evaluateCondition","processedCondition","logConditionalError","processElementEventHandlers","eventTypes","eventType","attributeName","handlerCode","key","event","logEventHandlerError","renderConditionals","conditionMet","originalParent","shouldRender","isInDOM","renderLoops","renderedElements","arrayData","logLoopError","item","index","clone","scopedContext","__spreadProps","__spreadValues","processClonedElement","insertAfter","evalFunc","scope","getHostElement","injectBindVariables","scriptContent","bindVarNames","componentInjections","varName","extractStateBindings","conditionalVars","stateBindings","defaultValues","bindingNames","b","rootName","variableRegex","defaultValue","transformBoundAssignments","boundVarNames","transformed","arrayIndexWriteRegex","arrayIndexReadRegex","propertyWriteRegex","propertyReadRegex","incrementRegex","op","compoundRegex","assignmentRegex","processScript","componentHost","injectedCode","functionRegex","functionNames","functionName","attachFunctions","name","allBoundVars","attachStateBindings","transformedContent","wrappedScript","eventBus","logScriptError","processEventHandlers","loadScripts","_0","_1","_2","_3","__async","scripts","allDefaults","scriptDefinition","loadGlobalScript","src","resolve","reject","existingScript","script","loadExternalScripts","externalScripts","componentSourcePath","s","baseURL","scriptURL","componentId","response","contentType","defineWebComponent","tagName","styles","sourcePath","_ComponentElement","__privateAdd","_ComponentElement_instances","_bindings","_twoWayBindings","_conditionals","_loops","_twoWayBindingCleanups","_sourcePath","_proxyCache","internalState","triggerUpdate","__privateGet","__privateMethod","updateTwoWayBindings_fn","prop","prev","createDeepProxy_fn","val","updates","__privateSet","loopVars","cleanup","logTwoWayBindingError","unsubscribers","unsub","logger","observer","mutations","mutation","newValue","STATE_PREFIX","_ComponentElement_static","parseAttributeValue_fn","isContentEditable","initialValue","content","contentEditableEl","handleInput","e","inputEl","isCheckbox","_b","cleanupInput","cleanupChange","callback","proxy","obj","args","boolValue","ComponentElement"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ladrillosjs",
3
- "version": "2.0.0-beta.2.2",
3
+ "version": "2.0.0-beta.3",
4
4
  "description": "A lightweight, zero-dependency web component framework for building modular web applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,8 +0,0 @@
1
- "use strict";var y=t=>{throw TypeError(t)};var R=(t,e,r)=>e.has(t)||y("Cannot "+r);var S=(t,e,r)=>e.has(t)?y("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r);var C=(t,e,r)=>(R(t,e,"access private method"),r);var a=(t,e,r)=>new Promise((s,o)=>{var n=u=>{try{i(r.next(u))}catch(h){o(h)}},c=u=>{try{i(r.throw(u))}catch(h){o(h)}},i=u=>u.done?s(u.value):Promise.resolve(u.value).then(n,c);i((r=r.apply(t,e)).next())});const $=()=>{try{return!1}catch(t){return process.env.NODE_ENV==="development"}},m={log(t,...e){$()&&console.log(t,...e)},error(t,...e){console.error(t,...e)},warn(t,...e){$()&&console.warn(t,...e)}},l=new Map,M=25,z=t=>{const e=l.get(t);return e&&(l.delete(t),l.set(t,e)),e},F=(t,e)=>{if(l.has(t))l.delete(t);else if(l.size>=M){const r=l.keys().next().value;r&&l.delete(r)}l.set(t,e)},L=t=>a(null,null,function*(){if(!t)throw new Error("Path cannot be null or empty");const e=z(t);if(e)return e;try{const r=yield fetch(t);if(!r.ok)throw new Error(`Failed to fetch component from ${t}: ${r.statusText}`);const s=yield r.text();return F(t,s),s}catch(r){m.error(`Error fetching component from ${t}: ${r.message}`)}}),j=t=>a(null,null,function*(){try{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);return yield e.text()}catch(e){return m.error(`Failed to fetch resource at ${t}:`,e),""}}),d={bindings:/{([^}]+)}/g,comments:{js:/\/\*[\s\S]*?\*\/|\/\/.*$/gm,css:/\/\*[\s\S]*?\*\//g,html:/<!--[\s\S]*?-->/g}},D=new DOMParser,N=(t,e)=>a(null,null,function*(){const r=B(t),{scripts:s,externalScripts:o}=G(r),n=yield O(r),c=r.body.innerHTML.trim();return{tagName:e,template:c,scripts:s,externalScripts:o,styles:n}}),B=t=>D.parseFromString(t.replace(d.comments.html,""),"text/html"),H=t=>["/@vite/","/__vite","/webpack-dev-server","/hot-update","/__webpack_hmr","/browser-sync/","/livereload.js"].some(r=>t.includes(r)),G=t=>{var s,o;const e=[],r=[];for(const n of t.querySelectorAll("script")){if(n.src){if(H(n.src)){n.remove();continue}const c=n.hasAttribute("external");r.push({src:n.getAttribute("src")||n.src,type:(s=n.type)!=null?s:null,external:c})}else if(n.textContent){let c=n.textContent.trim();c=c.replace(d.comments.js,"").trim(),e.push({content:c,type:(o=n.type)!=null?o:null})}n.remove()}return{scripts:e,externalScripts:r}},K=t=>{const e=t.match(/const __vite__css = "((?:[^"\\]|\\.)*)"/);if(e&&e[1])return e[1].replace(/\\r\\n/g,`
2
- `).replace(/\\n/g,`
3
- `).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const r=t.match(/export\s+default\s+"((?:[^"\\]|\\.)*)"/);return r&&r[1]?r[1].replace(/\\r\\n/g,`
4
- `).replace(/\\n/g,`
5
- `).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):t.includes("import")||t.includes("export")?(m.warn("CSS file returned JavaScript module format. CSS may not load correctly."),""):t},O=t=>a(null,null,function*(){let e="";const r=t.querySelectorAll("style, link[rel='stylesheet']");for(const s of r){if(s.tagName==="LINK"){const n=yield j(s.href),c=K(n);c&&(e+=`
6
- `+c)}else if(s.tagName==="STYLE"){const o=s;if(o.textContent){let n=o.textContent.trim();n=n.replace(d.comments.css,"").trim(),e+=`
7
- `+n}}s.remove()}return e.trim()});var p,x;class W{constructor(){S(this,p);this.components={}}registerComponent(e,r,s=!0){return a(this,null,function*(){if(this.components[e]){m.warn(`Component with name "${e}" is already registered.`);return}try{const o=yield L(r),n=yield N(o,e);this.components[e]={tagName:e,template:n.template,scripts:n.scripts,externalScripts:n.externalScripts,styles:n.styles,sourcePath:r},m.log(`Component ${e} registered successfully`),yield C(this,p,x).call(this,e,s)}catch(o){m.error(`Failed to register component "${e}": ${o.message}`);return}})}}p=new WeakSet,x=function(e,r){return a(this,null,function*(){const{defineWebComponent:s}=yield Promise.resolve().then(()=>require("./webcomponent-BJpmLRdd.js"));this.components[e]&&s(this.components[e],r)})};const v=new W;class X{constructor(){this.listeners=new Map}emit(e,r){const s=new CustomEvent(e,{detail:r,bubbles:!0,composed:!0});document.dispatchEvent(s);const o=this.listeners.get(e);if(!o||o.size===0)return Promise.resolve();const n=[];return o.forEach(c=>{try{const i=c(r);i instanceof Promise&&n.push(i)}catch(i){console.error(`Error in event listener for "${e}":`,i),n.push(Promise.reject(i))}}),n.length>0?Promise.all(n).then(()=>{}):Promise.resolve()}listen(e,r){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(r),()=>{this.off(e,r)}}off(e,r){const s=this.listeners.get(e);s&&(s.delete(r),s.size===0&&this.listeners.delete(e))}clear(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var r,s;return(s=(r=this.listeners.get(e))==null?void 0:r.size)!=null?s:0}}const g=new X,E=(t,e,r)=>v.registerComponent(t,e,r),_=t=>a(null,null,function*(){yield Promise.all(t.map(({name:e,path:r,useShadowDOM:s})=>v.registerComponent(e,r,s)))}),q=(t,e)=>g.listen(t,e),P=(t,e)=>{g.emit(t,e)},I=(t,e)=>{if(e){const r=e.tagName.toLowerCase();window.__ladrilloContexts||(window.__ladrilloContexts=new Map),window.__ladrilloContexts.set(r,{shadowRoot:t,element:e})}},w=()=>{const t=window.__ladrilloContexts;if(t&&t.size>0){const e=Array.from(t.values());return e[e.length-1]}return null},b=()=>{const t=w();return t&&t.element?t.element.state||{}:{}},f=t=>{const e=w();e&&e.setState&&e.setState(t)},A=(t,e)=>(f({[t]:e}),r=>{f({[t]:r})}),T=(t,e)=>{if(e)return e.querySelector(t);const r=w();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelector(t);if(o)return o}}return document.querySelector(t)},k=(t,e)=>{if(e)return e.querySelectorAll(t);const r=w();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelectorAll(t);if(o.length>0)return o}}return document.querySelectorAll(t)};typeof window!="undefined"&&(window.ladrillosjs={registerComponent:E,registerComponents:_},window.$listen=q,window.$emit=P,window.$querySelector=T,window.$querySelectorAll=k,window.$reactive=A,window.$setState=f,window.$getState=b);exports.$emit=P;exports.$getState=b;exports.$listen=q;exports.$querySelector=T;exports.$querySelectorAll=k;exports.$reactive=A;exports.$setState=f;exports.REGEX_PATTERNS=d;exports.__setComponentContext=I;exports.eventBus=g;exports.logger=m;exports.registerComponent=E;exports.registerComponents=_;
8
- //# sourceMappingURL=index-CMmTngHq.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CMmTngHq.js","sources":["../src/utils/logger.ts","../src/cache/index.ts","../src/core/componentSource.ts","../src/utils/regex.ts","../src/core/componentParser.ts","../src/core/main.ts","../src/core/eventBus.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Utility for conditional logging based on environment\r\n */\r\n\r\n// Type guard for Vite environment\r\nconst isDevelopment = (): boolean => {\r\n try {\r\n return (import.meta as any).env?.DEV === true;\r\n } catch {\r\n return process.env.NODE_ENV === 'development';\r\n }\r\n};\r\n\r\nexport const logger = {\r\n /**\r\n * Log a message only in development mode\r\n * @param message - The message to log\r\n * @param args - Additional arguments to log\r\n */\r\n log(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.log(message, ...args);\r\n }\r\n },\r\n\r\n /**\r\n * Log an error (always logs in both dev and production)\r\n * @param message - The error message\r\n * @param args - Additional arguments to log\r\n */\r\n error(message: string, ...args: any[]): void {\r\n console.error(message, ...args);\r\n },\r\n\r\n /**\r\n * Log a warning only in development mode\r\n * @param message - The warning message\r\n * @param args - Additional arguments to log\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.warn(message, ...args);\r\n }\r\n },\r\n};\r\n","const cache = new Map<string, string>();\r\nconst maxCacheSize = 25; // TODO: make configurable for developer to set\r\n\r\n/**\r\n * LRU Cache: Gets cached content and marks it as recently used\r\n * Moves the accessed item to the end of the Map (most recently used position)\r\n * This ensures frequently accessed components stay in cache longer\r\n * @param path - The file path to retrieve from cache\r\n * @returns The cached content or undefined if not found\r\n */\r\nexport const getCached = (path: string): string | undefined => {\r\n const cached = cache.get(path);\r\n if (cached) {\r\n // LRU: Move to end (most recently used position)\r\n cache.delete(path);\r\n cache.set(path, cached);\r\n }\r\n return cached;\r\n};\r\n\r\n/**\r\n * LRU Cache: Stores content with automatic eviction of least recently used items\r\n * Maintains cache size limit by removing oldest items when full\r\n * Updates existing items without affecting cache size\r\n * @param path - The file path to cache\r\n * @param content - The content to store\r\n */\r\nexport const setCache = (path: string, content: string): void => {\r\n if (cache.has(path)) {\r\n // Update existing: remove and re-add to mark as most recent\r\n cache.delete(path);\r\n } else if (cache.size >= maxCacheSize) {\r\n // Cache full: remove least recently used (first item in Map)\r\n const firstKey = cache.keys().next().value;\r\n if (firstKey) {\r\n cache.delete(firstKey);\r\n }\r\n }\r\n // Add/update as most recently used (end of Map)\r\n cache.set(path, content);\r\n};\r\n","import { getCached, setCache } from \"../cache\";\r\nimport { logger } from \"../utils/logger\";\r\n\r\n/**\r\n * Fetches component source with caching support\r\n * @param path - The file path to fetch\r\n * @returns The component source content\r\n */\r\nexport const fetchComponentSource = async (\r\n path: string\r\n): Promise<string | undefined> => {\r\n if (!path) {\r\n throw new Error(\"Path cannot be null or empty\");\r\n }\r\n\r\n const cached = getCached(path);\r\n if (cached) return cached;\r\n\r\n // fetch and cache\r\n try {\r\n const response = await fetch(path);\r\n\r\n if (!response.ok) {\r\n throw new Error(\r\n `Failed to fetch component from ${path}: ${response.statusText}`\r\n );\r\n }\r\n\r\n const text = await response.text();\r\n setCache(path, text);\r\n\r\n return text;\r\n } catch (error) {\r\n logger.error(\r\n `Error fetching component from ${path}: ${(error as Error).message}`\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * Safe fetch helper that returns empty string on error\r\n * @param url - The URL to fetch\r\n * @returns The fetched content or empty string\r\n */\r\nexport const safeFetch = async (url: string): Promise<string> => {\r\n try {\r\n const res = await fetch(url);\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n return await res.text();\r\n } catch (err) {\r\n logger.error(`Failed to fetch resource at ${url}:`, err);\r\n return \"\";\r\n }\r\n};\r\n","import { RegexPatterns } from \"../types/LadrilloTypes\";\r\n\r\nexport const REGEX_PATTERNS: RegexPatterns = {\r\n bindings: /{([^}]+)}/g,\r\n comments: {\r\n js: /\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*$/gm,\r\n css: /\\/\\*[\\s\\S]*?\\*\\//g,\r\n html: /<!--[\\s\\S]*?-->/g,\r\n },\r\n};\r\n","import {\r\n ExternalScriptElement,\r\n LadrillosComponent,\r\n ScriptElement,\r\n} from \"../types/LadrilloTypes\";\r\nimport { REGEX_PATTERNS } from \"../utils/regex\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { safeFetch } from \"./componentSource\";\r\n\r\nconst parser = new DOMParser();\r\n\r\n/**\r\n * Parses component HTML and extracts scripts and styles\r\n * @param source - The HTML source of the component\r\n * @param name - The name of the component\r\n * @returns Parsed component object\r\n */\r\nexport const parseComponent = async (\r\n source: string,\r\n name: string\r\n): Promise<LadrillosComponent> => {\r\n const doc = parseComponentHTML(source);\r\n const { scripts, externalScripts } = extractScripts(doc);\r\n const styles = await extractStyles(doc);\r\n const template = doc.body.innerHTML.trim();\r\n\r\n return {\r\n tagName: name,\r\n template,\r\n scripts,\r\n externalScripts,\r\n styles,\r\n };\r\n};\r\n\r\n/**\r\n * Parses HTML content and removes comments\r\n * @param source - The HTML source to parse\r\n * @returns Parsed DOM document\r\n */\r\nexport const parseComponentHTML = (source: string): Document => {\r\n return parser.parseFromString(\r\n source.replace(REGEX_PATTERNS.comments.html, \"\"),\r\n \"text/html\"\r\n );\r\n};\r\n\r\n/**\r\n * Checks if a script URL is a development server script that should be ignored.\r\n * Dev server scripts (Vite, Webpack HMR, etc.) are injected by the dev environment\r\n * and should not be processed as part of the component.\r\n */\r\nconst isDevServerScript = (src: string): boolean => {\r\n const devPatterns = [\r\n \"/@vite/\", // Vite dev client\r\n \"/__vite\", // Vite internal\r\n \"/webpack-dev-server\", // Webpack dev server\r\n \"/hot-update\", // Webpack HMR\r\n \"/__webpack_hmr\", // Webpack HMR\r\n \"/browser-sync/\", // Browser Sync\r\n \"/livereload.js\", // LiveReload\r\n ];\r\n\r\n return devPatterns.some((pattern) => src.includes(pattern));\r\n};\r\n\r\n/**\r\n * Extracts and processes script elements from the document\r\n * @param doc - The parsed document\r\n * @returns Object containing scripts and external scripts\r\n */\r\nexport const extractScripts = (\r\n doc: Document\r\n): {\r\n scripts: ScriptElement[];\r\n externalScripts: ExternalScriptElement[];\r\n} => {\r\n const scripts: ScriptElement[] = [];\r\n const externalScripts: ExternalScriptElement[] = [];\r\n\r\n for (const el of doc.querySelectorAll(\"script\")) {\r\n if (el.src) {\r\n // Skip dev server scripts (Vite, Webpack, etc.)\r\n if (isDevServerScript(el.src)) {\r\n el.remove();\r\n continue;\r\n }\r\n\r\n // Only mark as external if the 'external' attribute is explicitly present\r\n const isExternal = el.hasAttribute(\"external\");\r\n\r\n externalScripts.push({\r\n src: el.getAttribute(\"src\") || el.src, // Use getAttribute to preserve relative paths\r\n type: el.type ?? null,\r\n external: isExternal,\r\n });\r\n } else if (el.textContent) {\r\n let content = el.textContent.trim();\r\n // strip JavaScript comments (single‑line and block)\r\n content = content.replace(REGEX_PATTERNS.comments.js, \"\").trim();\r\n scripts.push({\r\n content,\r\n type: el.type ?? null,\r\n });\r\n }\r\n el.remove();\r\n }\r\n\r\n return { scripts, externalScripts };\r\n};\r\n\r\n/**\r\n * Extracts CSS content from various response formats\r\n * Handles:\r\n * - Vite dev server (wrapped in __vite__css variable)\r\n * - Plain CSS files (production/CDN)\r\n * - Other build tool formats\r\n */\r\nconst extractCSSFromResponse = (response: string): string => {\r\n // Check if this is a Vite HMR response (contains __vite__css)\r\n // Use a regex that properly handles escaped quotes within the string\r\n const viteMatch = response.match(/const __vite__css = \"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (viteMatch && viteMatch[1]) {\r\n // Unescape the CSS string\r\n return viteMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // Check for other module formats (e.g., \"export default ...\")\r\n const exportMatch = response.match(/export\\s+default\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (exportMatch && exportMatch[1]) {\r\n return exportMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // If it looks like JavaScript (not CSS), warn and return empty\r\n if (response.includes(\"import\") || response.includes(\"export\")) {\r\n logger.warn(\r\n \"CSS file returned JavaScript module format. CSS may not load correctly.\"\r\n );\r\n return \"\";\r\n }\r\n\r\n // If not a module format, assume it's plain CSS (production or direct file)\r\n return response;\r\n};\r\n\r\n/**\r\n * Extracts and processes style elements from the document\r\n * @param doc - The parsed document\r\n * @returns Concatenated CSS content\r\n */\r\nexport const extractStyles = async (doc: Document): Promise<string> => {\r\n let style = \"\";\r\n\r\n // Process styles in document order (inline styles and external stylesheets)\r\n const styleElements = doc.querySelectorAll(\"style, link[rel='stylesheet']\");\r\n\r\n for (const element of styleElements) {\r\n if (element.tagName === \"LINK\") {\r\n const linkElement = element as HTMLLinkElement;\r\n const response = await safeFetch(linkElement.href);\r\n const cssContent = extractCSSFromResponse(response);\r\n if (cssContent) {\r\n style += \"\\n\" + cssContent;\r\n }\r\n } else if (element.tagName === \"STYLE\") {\r\n const styleEl = element as HTMLStyleElement;\r\n if (styleEl.textContent) {\r\n let css = styleEl.textContent.trim();\r\n // strip CSS comments\r\n css = css.replace(REGEX_PATTERNS.comments.css, \"\").trim();\r\n style += \"\\n\" + css;\r\n }\r\n }\r\n element.remove();\r\n }\r\n\r\n return style.trim();\r\n};\r\n","import { LadrillosComponent } from \"../types/LadrilloTypes\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { fetchComponentSource } from \"./componentSource\";\r\nimport { parseComponent } from \"./componentParser\";\r\n\r\nclass Ladrillos {\r\n // properties\r\n components: Record<string, LadrillosComponent>;\r\n\r\n constructor() {\r\n // Initialize the Ladrillos instance\r\n this.components = {};\r\n }\r\n\r\n async registerComponent(\r\n name: string,\r\n path: string,\r\n useShadowDOM: boolean = true\r\n ): Promise<void> {\r\n if (this.components[name]) {\r\n logger.warn(`Component with name \"${name}\" is already registered.`);\r\n return;\r\n }\r\n\r\n try {\r\n const source = await fetchComponentSource(path);\r\n const component = await parseComponent(source!, name);\r\n\r\n this.components[name] = {\r\n tagName: name,\r\n template: component.template,\r\n scripts: component.scripts,\r\n externalScripts: component.externalScripts,\r\n styles: component.styles,\r\n sourcePath: path,\r\n };\r\n\r\n // Define the web component\r\n logger.log(`Component ${name} registered successfully`);\r\n await this.#defineWebComponent(name, useShadowDOM);\r\n } catch (error) {\r\n logger.error(\r\n `Failed to register component \"${name}\": ${(error as Error).message}`\r\n );\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Defines the web component using the webcomponent module\r\n * @param name - Component name\r\n * @param useShadowDOM - Whether to use Shadow DOM\r\n */\r\n async #defineWebComponent(\r\n name: string,\r\n useShadowDOM: boolean\r\n ): Promise<void> {\r\n const { defineWebComponent } = await import(\"./webcomponent\");\r\n\r\n // safety check\r\n if (this.components[name]) {\r\n defineWebComponent(this.components[name], useShadowDOM);\r\n }\r\n }\r\n}\r\n\r\nexport const ladrillos = new Ladrillos();\r\n","/**\r\n * Global Event Bus for component-to-component communication\r\n * Allows components to emit events and listen to events from other components\r\n */\r\n\r\ntype EventCallback = (data?: any) => void | Promise<void>;\r\ntype EventListeners = Map<string, Set<EventCallback>>;\r\n\r\nclass EventBus {\r\n private listeners: EventListeners = new Map();\r\n\r\n /**\r\n * Emit an event with optional data\r\n * @param eventName - The name of the event to emit\r\n * @param data - Optional data to pass to listeners\r\n * @returns Promise that resolves when all listeners have been called\r\n */\r\n emit(eventName: string, data?: any): Promise<void> {\r\n // Also dispatch as a native DOM CustomEvent so document.addEventListener works\r\n const customEvent = new CustomEvent(eventName, {\r\n detail: data,\r\n bubbles: true,\r\n composed: true,\r\n });\r\n document.dispatchEvent(customEvent);\r\n\r\n const callbacks = this.listeners.get(eventName);\r\n\r\n if (!callbacks || callbacks.size === 0) {\r\n // No listeners, resolve immediately\r\n return Promise.resolve();\r\n }\r\n\r\n // Execute all callbacks and collect promises\r\n const promises: Promise<void>[] = [];\r\n\r\n callbacks.forEach((callback) => {\r\n try {\r\n const result = callback(data);\r\n // If callback returns a promise, add it to promises array\r\n if (result instanceof Promise) {\r\n promises.push(result);\r\n }\r\n } catch (error) {\r\n console.error(`Error in event listener for \"${eventName}\":`, error);\r\n promises.push(Promise.reject(error));\r\n }\r\n });\r\n\r\n // If any callbacks returned promises, wait for all of them\r\n if (promises.length > 0) {\r\n return Promise.all(promises).then(() => undefined);\r\n }\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * Listen to an event\r\n * @param eventName - The name of the event to listen for\r\n * @param callback - Function to call when event is emitted\r\n * @returns Function to remove the listener\r\n */\r\n listen(eventName: string, callback: EventCallback): () => void {\r\n if (!this.listeners.has(eventName)) {\r\n this.listeners.set(eventName, new Set());\r\n }\r\n\r\n this.listeners.get(eventName)!.add(callback);\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n this.off(eventName, callback);\r\n };\r\n }\r\n\r\n /**\r\n * Remove a specific event listener\r\n * @param eventName - The name of the event\r\n * @param callback - The callback to remove\r\n */\r\n off(eventName: string, callback: EventCallback): void {\r\n const callbacks = this.listeners.get(eventName);\r\n if (callbacks) {\r\n callbacks.delete(callback);\r\n // Clean up empty sets\r\n if (callbacks.size === 0) {\r\n this.listeners.delete(eventName);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event, or all listeners if no event specified\r\n * @param eventName - Optional event name to clear listeners for\r\n */\r\n clear(eventName?: string): void {\r\n if (eventName) {\r\n this.listeners.delete(eventName);\r\n } else {\r\n this.listeners.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Get count of listeners for an event\r\n * @param eventName - The event name\r\n * @returns Number of listeners\r\n */\r\n listenerCount(eventName: string): number {\r\n return this.listeners.get(eventName)?.size ?? 0;\r\n }\r\n}\r\n\r\n// Export singleton instance\r\nexport const eventBus = new EventBus();\r\n","import { ladrillos } from \"./core/main.js\";\r\nimport { eventBus } from \"./core/eventBus.js\";\r\n\r\ndeclare global {\r\n interface Window {\r\n ladrillosjs: {\r\n registerComponent: typeof registerComponent;\r\n registerComponents: typeof registerComponents;\r\n };\r\n $listen: typeof $listen;\r\n $emit: typeof $emit;\r\n $querySelector: typeof $querySelector;\r\n $querySelectorAll: typeof $querySelectorAll;\r\n $reactive: typeof $reactive;\r\n $setState: typeof $setState;\r\n $getState: typeof $getState;\r\n }\r\n}\r\n\r\nexport const registerComponent = (\r\n name: string,\r\n path: string,\r\n useShadowDOM?: boolean\r\n) => ladrillos.registerComponent(name, path, useShadowDOM);\r\n\r\nexport const registerComponents = async (\r\n components: Array<{ name: string; path: string; useShadowDOM?: boolean }>\r\n): Promise<void> => {\r\n await Promise.all(\r\n components.map(({ name, path, useShadowDOM }) =>\r\n ladrillos.registerComponent(name, path, useShadowDOM)\r\n )\r\n );\r\n};\r\n\r\n// Event bus helper functions\r\nexport const $listen = (event: string, callback: (data?: any) => void) => {\r\n return eventBus.listen(event, callback);\r\n};\r\n\r\nexport const $emit = (event: string, data?: any) => {\r\n eventBus.emit(event, data);\r\n};\r\n\r\n// Component context management\r\n// Maps script URLs to their component contexts for persistent association\r\nconst scriptContextMap = new Map<\r\n string,\r\n { shadowRoot?: ShadowRoot; element?: HTMLElement }\r\n>();\r\nconst activeContext: { shadowRoot?: ShadowRoot; element?: HTMLElement } | null =\r\n null;\r\n\r\n/**\r\n * Internal: Set component context for a script\r\n * Called by the framework when loading scripts from components\r\n */\r\nexport const __setComponentContext = (\r\n shadowRoot?: ShadowRoot,\r\n element?: HTMLElement\r\n) => {\r\n // Store in the global registry by component tag name\r\n if (element) {\r\n const tagName = element.tagName.toLowerCase();\r\n if (!(window as any).__ladrilloContexts) {\r\n (window as any).__ladrilloContexts = new Map();\r\n }\r\n (window as any).__ladrilloContexts.set(tagName, { shadowRoot, element });\r\n }\r\n};\r\n\r\n/**\r\n * Internal: Get component context for the current script\r\n */\r\nconst getComponentContext = () => {\r\n const registry = (window as any).__ladrilloContexts as Map<string, any>;\r\n if (registry && registry.size > 0) {\r\n // For now, return the last registered context\r\n // TODO: In the future, we could track which script belongs to which component\r\n const contexts = Array.from(registry.values());\r\n return contexts[contexts.length - 1];\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Get the component's reactive state\r\n * Returns a Proxy that allows direct property access to component.state\r\n * @returns Proxy to component state or empty object if no component context\r\n */\r\nexport const $getState = (): any => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.element) {\r\n return (ctx.element as any).state || {};\r\n }\r\n return {};\r\n};\r\n\r\n/**\r\n * Set component state\r\n * @param updates - Object with state updates\r\n */\r\nexport const $setState = (updates: any) => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.setState) {\r\n ctx.setState(updates);\r\n }\r\n};\r\n\r\n/**\r\n * Creates a reactive variable that automatically updates the component when changed.\r\n * For use in ES module scripts with the bind attribute.\r\n * @param name - The variable name (must match the binding in the template)\r\n * @param initialValue - The initial value\r\n * @returns A setter function to update the value\r\n *\r\n * @example\r\n * ```javascript\r\n * import { $reactive } from 'ladrillosjs';\r\n *\r\n * // In your module script:\r\n * const setBeers = $reactive('beers', 'loading...');\r\n *\r\n * // Later, update it:\r\n * setBeers('<card>...</card>');\r\n * ```\r\n */\r\nexport const $reactive = <T = any>(\r\n name: string,\r\n initialValue: T\r\n): ((value: T) => void) => {\r\n // Initialize the state\r\n $setState({ [name]: initialValue });\r\n\r\n // Return a setter function\r\n return (value: T) => {\r\n $setState({ [name]: value });\r\n };\r\n};\r\n\r\n// DOM query helpers with smart component context detection\r\n// Automatically searches within component context when appropriate\r\nexport const $querySelector = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): Element | null => {\r\n if (root) {\r\n return root.querySelector(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelector(selector);\r\n if (result) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelector(selector);\r\n};\r\n\r\nexport const $querySelectorAll = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): NodeListOf<Element> => {\r\n if (root) {\r\n return root.querySelectorAll(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelectorAll(selector);\r\n if (result.length > 0) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelectorAll(selector);\r\n};\r\n\r\n// for a browser‑global via <script src=\"…ladrillosjs.js\"></script>\r\nif (typeof window !== \"undefined\") {\r\n window.ladrillosjs = {\r\n registerComponent,\r\n registerComponents,\r\n };\r\n\r\n // Expose helper functions globally for non-module scripts\r\n window.$listen = $listen;\r\n window.$emit = $emit;\r\n window.$querySelector = $querySelector;\r\n window.$querySelectorAll = $querySelectorAll;\r\n window.$reactive = $reactive;\r\n window.$setState = $setState;\r\n window.$getState = $getState;\r\n}\r\n"],"names":["isDevelopment","e","logger","message","args","cache","maxCacheSize","getCached","path","cached","setCache","content","firstKey","fetchComponentSource","__async","response","text","error","safeFetch","url","res","err","REGEX_PATTERNS","parser","parseComponent","source","name","doc","parseComponentHTML","scripts","externalScripts","extractScripts","styles","extractStyles","template","isDevServerScript","src","pattern","el","isExternal","_a","_b","extractCSSFromResponse","viteMatch","exportMatch","style","styleElements","element","cssContent","styleEl","css","Ladrillos","__privateAdd","_Ladrillos_instances","useShadowDOM","component","__privateMethod","defineWebComponent_fn","defineWebComponent","ladrillos","EventBus","eventName","data","customEvent","callbacks","promises","callback","result","eventBus","registerComponent","registerComponents","components","$listen","event","$emit","__setComponentContext","shadowRoot","tagName","getComponentContext","registry","contexts","$getState","ctx","$setState","updates","$reactive","initialValue","value","$querySelector","selector","root","searchRoot","$querySelectorAll"],"mappings":"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"}