coralite 0.38.2 → 0.38.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.
@@ -1 +1 @@
1
- {"version":3,"file":"coralite-element.d.ts","sourceRoot":"","sources":["../../lib/coralite-element.js"],"names":[],"mappings":"AAuCA;;;;;;GAMG;AACH,8BAJW,GAAG,QACH,WAAS,MAAM,GACb,GAAG,CAmBf;AAmmBD;;;;;;;;;;GAUG;AACH,6CARW,wBAAwB,kBACxB,WAAS,IAAI,UAErB;IAAyE,uBAAuB,GAAxF,KAAK,CAAC,iDAAiD,CAAC;IACQ,sBAAsB,GAAtF,KAAK,CAAC,gDAAgD,CAAC;IACC,cAAc,GAAtE,KAAK,CAAC,wCAAwC,CAAC;CACvD,GAAU,OAAO,eAAe,CA8BlC;AAxoBD;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH;IAOI;;;;OAIG;IACH,4BAHU,eAAe,GAAC,IAAI,CAGF;IAE5B;;;;OAIG;IACH,uBAHU,MAAM,GAAC,IAAI,CAGE;IAEvB;;;;OAIG;IACH,kBAHU,MAAO,IAAI,CAGH;IAElB;;;;OAIG;IACH,qBAHU,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAG1D;IAEnB;;;;OAIG;IACH,4BAHU,OAAO,CAGY;IAE7B;;;;OAIG;IACH,iCAHU,MAAM,GAAC,IAAI,CAGY;IAEjC;;;OAGG;IACH,qBAHU,gBAAgB,GAAC,IAAI,CAGV;IAErB;;;;OAIG;IACH,gCAHU,WAAS,IAAI,CAGS;IAEhC;;;;OAIG;IACH,mCAHU;YAAQ,MAAM,GAAE,eAAe;KAAC,GAAC,IAAI,CAGZ;IAEnC;;;;;;;;OAQG;IACH,kBAPU;QACL,uBAAuB,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAClF,sBAAsB,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChF,cAAc,EAAE,KAAK,CAAC,wCAAwC,CAAC,CAAA;KAChE,CAOH;IAED;;;OAGG;IACH,kBAFU,wBAAwB,GAAC,IAAI,CAEX;IAG9B;;;;OAIG;IACH,0BAsDC;IAED;;;;;OAKG;IACH,sCAkBC;IAED;;;;;;;OAOG;IACH,+BAJW,MAAM,UACN,MAAM,GAAC,IAAI,UACX,MAAM,GAAC,IAAI,QAWrB;IAED;;;;;;OAMG;IACH,oBAmFC;IAED;;;;;;OAMG;IACH,6BAYC;IAED;;;;;OAKG;IACH,oBAHW,MAAM,EAAE,GACN,IAAI,GAAC,IAAI,CAYrB;IAED;;;;OAIG;IACH,uBAiCC;IAED;;;;OAIG;IACH,wBASC;IAED;;;;;;;OAOG;IACH,mBA2GC;IAED;;;;OAIG;IACH,sBAqCC;IAED;;;;;;OAMG;IACH,cAqCC;CACF;;;;;iBA7lBa,MAAM;;;;mBACN,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEA/DV,oBAAoB;sEAApB,oBAAoB;8DAApB,oBAAoB"}
1
+ {"version":3,"file":"coralite-element.d.ts","sourceRoot":"","sources":["../../lib/coralite-element.js"],"names":[],"mappings":"AAwCA;;;;;;GAMG;AACH,8BAJW,GAAG,QACH,WAAS,MAAM,GACb,GAAG,CAmBf;AAkmBD;;;;;;;;;;GAUG;AACH,6CARW,wBAAwB,kBACxB,WAAS,IAAI,UAErB;IAAyE,uBAAuB,GAAxF,KAAK,CAAC,iDAAiD,CAAC;IACQ,sBAAsB,GAAtF,KAAK,CAAC,gDAAgD,CAAC;IACC,cAAc,GAAtE,KAAK,CAAC,wCAAwC,CAAC;CACvD,GAAU,OAAO,eAAe,CA8BlC;AAvoBD;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH;IAOI;;;;OAIG;IACH,4BAHU,eAAe,GAAC,IAAI,CAGF;IAE5B;;;;OAIG;IACH,uBAHU,MAAM,GAAC,IAAI,CAGE;IAEvB;;;;OAIG;IACH,kBAHU,MAAO,IAAI,CAGH;IAElB;;;;OAIG;IACH,qBAHU,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAG1D;IAEnB;;;;OAIG;IACH,4BAHU,OAAO,CAGY;IAE7B;;;;OAIG;IACH,iCAHU,MAAM,GAAC,IAAI,CAGY;IAEjC;;;OAGG;IACH,qBAHU,gBAAgB,GAAC,IAAI,CAGV;IAErB;;;;OAIG;IACH,gCAHU,WAAS,IAAI,CAGS;IAEhC;;;;OAIG;IACH,mCAHU;YAAQ,MAAM,GAAE,eAAe;KAAC,GAAC,IAAI,CAGZ;IAEnC;;;;;;;;OAQG;IACH,kBAPU;QACL,uBAAuB,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAClF,sBAAsB,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChF,cAAc,EAAE,KAAK,CAAC,wCAAwC,CAAC,CAAA;KAChE,CAOH;IAED;;;OAGG;IACH,kBAFU,wBAAwB,GAAC,IAAI,CAEX;IAG9B;;;;OAIG;IACH,0BAsDC;IAED;;;;;OAKG;IACH,sCAkBC;IAED;;;;;;;OAOG;IACH,+BAJW,MAAM,UACN,MAAM,GAAC,IAAI,UACX,MAAM,GAAC,IAAI,QAWrB;IAED;;;;;;OAMG;IACH,oBAkFC;IAED;;;;;;OAMG;IACH,6BAYC;IAED;;;;;OAKG;IACH,oBAHW,MAAM,EAAE,GACN,IAAI,GAAC,IAAI,CAYrB;IAED;;;;OAIG;IACH,uBAiCC;IAED;;;;OAIG;IACH,wBASC;IAED;;;;;;;OAOG;IACH,mBA2GC;IAED;;;;OAIG;IACH,sBAqCC;IAED;;;;;;OAMG;IACH,cAqCC;CACF;;;;;iBA5lBa,MAAM;;;;mBACN,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAhEV,oBAAoB;sEAApB,oBAAoB;8DAApB,oBAAoB"}
@@ -54,6 +54,14 @@ function createReadOnlyProxy(target, proxies = /* @__PURE__ */ new WeakMap()) {
54
54
  return proxy;
55
55
  }
56
56
 
57
+ // lib/utils/client/inject.js
58
+ function processHTML(html) {
59
+ if (typeof window !== "undefined" && window.processHTML) {
60
+ return window.processHTML(html);
61
+ }
62
+ return html;
63
+ }
64
+
57
65
  // lib/coralite-element.js
58
66
  var BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
59
67
  "allowfullscreen",
@@ -137,7 +145,7 @@ var CoraliteElement = class extends HTMLElement {
137
145
  const isImperative = !this.hasAttribute("data-cid");
138
146
  if (isImperative && this.componentOptions.templateHTML) {
139
147
  const originalLightDOM = Array.from(this.childNodes);
140
- this.innerHTML = this.componentOptions.templateHTML;
148
+ this.innerHTML = processHTML(this.componentOptions.templateHTML);
141
149
  if (originalLightDOM.length > 0) {
142
150
  const slots = this.querySelectorAll("slot");
143
151
  slots.forEach((slot) => {
@@ -236,6 +244,16 @@ var CoraliteElement = class extends HTMLElement {
236
244
  }
237
245
  }
238
246
  }
247
+ for (const hook of this._hooks.onBeforeComponentRender) {
248
+ hook({
249
+ state: target,
250
+ instanceId: this._instanceId,
251
+ componentId: this.componentOptions.componentId,
252
+ refs,
253
+ element: this,
254
+ options: this.componentOptions
255
+ });
256
+ }
239
257
  for (const attr of this.attributes) {
240
258
  if (attr.name === "data-cid") {
241
259
  continue;
@@ -255,16 +273,6 @@ var CoraliteElement = class extends HTMLElement {
255
273
  console.error("Coralite Element hydration failed:", this._instanceId);
256
274
  }
257
275
  }
258
- for (const hook of this._hooks.onBeforeComponentRender) {
259
- hook({
260
- state: target,
261
- instanceId: this._instanceId,
262
- componentId: this.componentOptions.componentId,
263
- refs,
264
- element: this,
265
- options: this.componentOptions
266
- });
267
- }
268
276
  this._getterAbortControllers = {};
269
277
  for (const [key, getter] of Object.entries(options.getters || {})) {
270
278
  Object.defineProperty(target, key, {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../lib/utils/errors.js", "../../lib/utils/core.js", "../../lib/coralite-element.js"],
4
- "sourcesContent": ["\n/**\n * @import { CoraliteErrorData } from '../../types/index.js'\n */\n\n/**\n * Base error class for all Coralite-related errors.\n */\nexport class CoraliteError extends Error {\n /**\n * @param {string} message - The error message.\n * @param {Object} [options] - Additional options for the error.\n * @param {string} [options.componentId] - The ID of the component where the error occurred.\n * @param {string} [options.filePath] - The path to the file where the error occurred.\n * @param {string} [options.instanceId] - The unique ID of the component instance.\n * @param {string} [options.pagePath] - The path to the page being rendered.\n * @param {number} [options.line] - The line number where the error occurred.\n * @param {number} [options.column] - The column number where the error occurred.\n * @param {string} [options.stackFile] - The file name from the stack trace.\n * @param {Error} [options.cause] - The original error that caused this error.\n */\n constructor (message, options = {}) {\n super(message, options)\n this.name = 'CoraliteError'\n this.isCoraliteError = true\n this.componentId = options.componentId\n this.filePath = options.filePath\n this.instanceId = options.instanceId\n this.pagePath = options.pagePath\n this.line = options.line\n this.column = options.column\n this.stackFile = options.stackFile\n\n // Polyfill cause if necessary (node version differences)\n if (options.cause && !this.cause) {\n this.cause = options.cause\n }\n }\n}\n\n/**\n * Default error handler.\n * @param {CoraliteErrorData} data - The data object containing error details.\n */\nexport function defaultOnError ({ level, message, error }) {\n if (level === 'ERR') {\n if (error) {\n throw error\n }\n throw new CoraliteError(message)\n } else if (level === 'WARN') {\n console.warn(message)\n } else {\n console.log(message)\n }\n}\n\n/**\n * Handles errors using an optional callback or the default handler.\n * @param {Object} options - The options for handling the error.\n * @param {Function} [options.onErrorCallback] - The optional custom error callback function.\n * @param {CoraliteErrorData} options.data - The error data to be handled.\n */\nexport function handleError ({ onErrorCallback, data }) {\n const error = data.error\n if (error && 'isCoraliteError' in error && error.isCoraliteError) {\n const coraliteError = error\n // @ts-ignore\n data.componentId = data.componentId || coraliteError.componentId\n // @ts-ignore\n data.filePath = data.filePath || coraliteError.filePath\n // @ts-ignore\n data.instanceId = data.instanceId || coraliteError.instanceId\n // @ts-ignore\n data.pagePath = data.pagePath || coraliteError.pagePath\n // @ts-ignore\n data.line = data.line || coraliteError.line\n // @ts-ignore\n data.column = data.column || coraliteError.column\n // @ts-ignore\n data.stackFile = data.stackFile || coraliteError.stackFile\n }\n\n if (onErrorCallback) {\n onErrorCallback(data)\n } else {\n defaultOnError(data)\n }\n}\n", "import { CoraliteError } from './errors.js'\n\n/**\n * @import {\n * CoraliteModule,\n * CoraliteComponent,\n * CoraliteComponentResult,\n * } from '../../types/index.js'\n */\n\nconst KEBAB_REGEX = /[-|:]([a-z])/g\n\n/**\n * Converts a kebab-case string to camelCase\n * @param {string} str - The kebab-case string to convert\n * @returns {string} - The camelCase version of the string\n */\nexport function kebabToCamel (str) {\n // replace each dash followed by a letter with the uppercase version of the letter\n return str.replace(KEBAB_REGEX, function (match, letter) {\n return letter.toUpperCase()\n })\n}\n\n/**\n * Converts all keys in an object from kebab-case to camelCase\n * @template T\n * @param {Record<string, T>} object - The object with kebab-case keys\n * @returns {Record<string, T>} - A new object with camelCase keys\n */\nexport function cleanKeys (object) {\n /** @type {Record<string, T>} */\n const result = {}\n\n for (const [key, value] of Object.entries(object)) {\n result[key] = value\n\n const camelKey = kebabToCamel(key)\n if (camelKey !== key) {\n result[camelKey] = value\n }\n }\n\n return result\n}\n\n/**\n * Recursively clones an object or array and normalizes any function state\n * it finds into a string representation that preserves standard function syntax,\n * bypassing ES6 shorthand method serialization issues.\n * @param {any} target - The object or array to normalize.\n * @param {Function} [transform] - Optional transform function for each node.\n * @param {WeakMap} [seen=new WeakMap()] - Map of seen objects to handle circular references.\n * @returns {any} A deeply cloned object with normalized functions.\n */\nexport function normalizeObjectFunctions (target, transform = null, seen = new WeakMap()) {\n if (typeof transform === 'function') {\n const transformed = transform(target)\n if (transformed !== target) {\n return transformed\n }\n }\n\n if (typeof target !== 'object' || target === null) {\n return target\n }\n\n if (seen.has(target)) {\n return seen.get(target)\n }\n\n if (Array.isArray(target)) {\n const arr = []\n seen.set(target, arr)\n for (let i = 0; i < target.length; i++) {\n arr.push(normalizeObjectFunctions(target[i], transform, seen))\n }\n return arr\n }\n\n const obj = {}\n seen.set(target, obj)\n for (const key in target) {\n if (Object.hasOwn(target, key)) {\n if (typeof target[key] === 'function') {\n const normalizedString = normalizeFunction(target[key])\n const originalFunction = target[key]\n\n const wrapper = function () {\n return originalFunction.apply(this, arguments)\n }\n wrapper.toString = () => normalizedString\n obj[key] = wrapper\n } else {\n obj[key] = normalizeObjectFunctions(target[key], transform, seen)\n }\n }\n }\n\n return obj\n}\n\n/**\n * Checks whether the given object is an object and has at least one own key.\n * @param {any} obj - The object to check.\n * @returns {boolean} True if the object is truthy and has keys, otherwise false.\n */\nexport function hasObjectKeys (obj) {\n return obj && typeof obj === 'object' && Object.keys(obj).length > 0\n}\n\n/**\n * Merges two arrays, returning a new array with unique items.\n * Uses JSON.stringify for deep comparison of object elements, preserving object uniqueness correctly.\n * @param {Array<any>} [arr1] - The first array.\n * @param {Array<any>} [arr2] - The second array.\n * @returns {Array<any>} A new array with unique values from both input arrays.\n */\nexport function mergeUniqueObjects (arr1, arr2) {\n const all = [...(arr1 || []), ...(arr2 || [])]\n const seen = new Set()\n return all.filter(item => {\n const key = typeof item === 'object' ? JSON.stringify(item) : item\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n\n/**\n * Normalizes function declarations to ensure consistent formatting.\n * Converts shorthand method syntax to full function declarations where needed,\n * while preserving arrow functions and existing full declarations.\n *\n * @param {Function} func - The function to normalize\n * @returns {string} The normalized function string representation\n */\nexport function normalizeFunction (func) {\n const original = func.toString().trim()\n\n const firstBrace = original.indexOf('{')\n const firstArrow = original.indexOf('=>')\n\n const isArrow = firstArrow !== -1 && (firstBrace === -1 || firstArrow < firstBrace)\n\n if (isArrow) {\n return original\n }\n\n // For non-arrows, extract header to check for shorthand\n const header = firstBrace !== -1 ? original.slice(0, firstBrace).trim() : original\n\n const isStandard = header.startsWith('function') || header.startsWith('async function')\n\n if (isStandard) {\n return original\n }\n\n // Handle Method Shorthand\n if (header.startsWith('async ')) {\n if (header.startsWith('async get ') || header.startsWith('async set ')) {\n return original\n }\n\n return original.replace(/^async\\s+([$\\w]+)\\s*\\(/, 'async function(')\n } else {\n if (header.startsWith('get ') || header.startsWith('set ')) {\n return original\n }\n\n return original.replace(/^([$\\w]+)\\s*\\(/, 'function(')\n }\n}\n\n\n/**\n * Recursively clones an AST node and its children, ensuring that\n * inner references (like parents and slots) point to the newly cloned nodes.\n *\n * @param {Map<Object, Object>} nodeMap - A map tracking original nodes to their newly cloned counterparts.\n * @param {Object} node - The current AST node being cloned.\n * @param {Object} [parent] - The parent node reference to assign to the clone.\n * @returns {Object} The newly cloned node.\n */\nexport function cloneNode (nodeMap, node, parent) {\n const newNode = Object.create(Object.getPrototypeOf(node))\n\n // Copy all own enumerable properties\n Object.assign(newNode, node)\n\n if (parent) {\n newNode.parent = parent\n }\n\n if (newNode.attribs) {\n newNode.attribs = { ...newNode.attribs }\n }\n\n // Register in map\n nodeMap.set(node, newNode)\n\n // Recursively clone children\n if (node.children) {\n const children = node.children\n const length = children.length\n const clonedChildren = new Array(length)\n newNode.children = clonedChildren\n\n for (let i = 0; i < length; i++) {\n const clonedChild = cloneNode(nodeMap, children[i], newNode)\n clonedChildren[i] = clonedChild\n if (i > 0) {\n clonedChild.prev = clonedChildren[i - 1]\n clonedChildren[i - 1].next = clonedChild\n }\n }\n }\n\n // Update slot references to point to new cloned nodes\n if (node.slots) {\n const slots = node.slots\n const length = slots.length\n const clonedSlots = new Array(length)\n for (let i = 0; i < length; i++) {\n const slot = slots[i]\n const clonedSlot = { ...slot }\n if (slot.node) {\n const clonedNode = nodeMap.get(slot.node)\n if (clonedNode) {\n clonedSlot.node = clonedNode\n }\n }\n clonedSlots[i] = clonedSlot\n }\n newNode.slots = clonedSlots\n }\n\n // Preserve the enhanced flag without re-running enhanceNode\n Object.defineProperty(newNode, '__coralite_enhanced__', {\n value: true,\n enumerable: false,\n configurable: true\n })\n\n return newNode\n}\n\n/**\n * Creates a shallow copy of a CoraliteModule with a deep clone of its DOM tree (template) and re-linked internal references to enable safe independent mutation.\n *\n * Top-level non-DOM state (id, path, script, isTemplate, lineOffset) are shallow copied. Nested objects within these state (e.g., path) remain shared references. Only DOM-related structures undergo deep cloning and reference re-linking to isolate mutations from the original module.\n *\n * @param {CoraliteModule} originalModule - Module to clone.\n * @returns {CoraliteModule}\n */\nexport function cloneModuleInstance (originalModule) {\n const nodeMap = new Map()\n\n // Clone the main template tree\n const newTemplate = cloneNode(nodeMap, originalModule.template, null)\n\n // Reconstruct the 'values' object\n const newValues = {\n attributes: originalModule.values.attributes.map(item => ({\n ...item,\n element: nodeMap.get(item.element)\n })),\n textNodes: originalModule.values.textNodes.map(item => ({\n ...item,\n textNode: nodeMap.get(item.textNode)\n })),\n refs: originalModule.values.refs.map(item => ({\n ...item,\n element: nodeMap.get(item.element)\n }))\n }\n\n // Reconstruct customElements list\n const newCustomElements = originalModule.customElements.map(el => nodeMap.get(el))\n\n // Reconstruct slotElements\n const newSlotElements = {}\n if (originalModule.slotElements) {\n for (const modId in originalModule.slotElements) {\n newSlotElements[modId] = {}\n const slotGroup = originalModule.slotElements[modId]\n\n for (const slotName in slotGroup) {\n const slotItem = slotGroup[slotName]\n newSlotElements[modId][slotName] = {\n ...slotItem,\n element: nodeMap.get(slotItem.element)\n }\n }\n }\n }\n\n // Return the new module structure\n return {\n ...originalModule,\n template: newTemplate,\n values: newValues,\n customElements: newCustomElements,\n // @ts-ignore\n slotElements: newSlotElements\n }\n}\n\n/**\n * Creates a deep copy of a CoraliteComponent with re-linked internal references to enable safe independent mutation.\n *\n * @param {CoraliteComponent & CoraliteComponentResult} originalDocument - Document to clone.\n * @returns {CoraliteComponent & CoraliteComponentResult}\n */\nexport function cloneComponentInstance (originalDocument) {\n const nodeMap = new Map()\n const newRoot = cloneNode(nodeMap, originalDocument.root, null)\n\n const newCustomElements = originalDocument.customElements.map(el => nodeMap.get(el))\n const newTempElements = originalDocument.tempElements ? originalDocument.tempElements.map(el => nodeMap.get(el)) : []\n const newSkipRenderElements = originalDocument.skipRenderElements ? originalDocument.skipRenderElements.map(el => nodeMap.get(el)) : []\n\n return {\n ...originalDocument,\n state: { ...originalDocument.state },\n root: newRoot,\n customElements: newCustomElements,\n tempElements: newTempElements,\n skipRenderElements: newSkipRenderElements\n }\n}\n\n/**\n * Calculates the DOM path from a node to the root.\n * @param {Object} node - The node to calculate the path for.\n * @param {Object} root - The root node.\n * @returns {Array<number>} An array of indices representing the path.\n */\nexport function getNodePath (node, root) {\n const path = []\n let current = node\n while (current && current !== root) {\n const parent = current.parent\n if (!parent) {\n break\n }\n const index = parent.children.indexOf(current)\n if (index === -1) {\n break\n }\n path.unshift(index)\n current = parent\n }\n return path\n}\n\n/**\n * Generates a hydration map for the client.\n * @param {Array<Object>} templateNodes - The component's template nodes.\n * @param {Object} templateValues - The component's template values.\n * @returns {Object} The hydration map.\n */\nexport function generateHydrationMap (templateNodes, templateValues) {\n const map = {\n texts: [],\n attributes: [],\n refs: []\n }\n\n if (!templateNodes || !templateValues) {\n return map\n }\n\n const root = templateNodes.length > 0 ? templateNodes[0].parent : { children: templateNodes }\n\n if (templateValues.textNodes) {\n for (const item of templateValues.textNodes) {\n if (item.textNode) {\n const isHtml = item.type === 'html'\n const targetNode = isHtml ? item.textNode.parent : item.textNode\n\n map.texts.push({\n path: getNodePath(targetNode, root),\n template: item.textNode.data,\n type: isHtml ? 'html' : 'text'\n })\n }\n }\n }\n\n if (templateValues.attributes) {\n for (const item of templateValues.attributes) {\n if (item.element && item.element.attribs) {\n const originalValue = item.element.attribs[item.name]\n map.attributes.push({\n path: getNodePath(item.element, root),\n name: item.name,\n template: originalValue\n })\n }\n }\n }\n\n if (templateValues.refs) {\n for (const item of templateValues.refs) {\n if (item.element) {\n map.refs.push({\n path: getNodePath(item.element, root),\n name: item.name\n })\n }\n }\n }\n\n return map\n}\n\n/**\n * Recursively adds a component and its dependencies to a tracking object.\n *\n * @param {string} componentId - The ID of the component to add.\n * @param {Object.<string, boolean>} processed - The object tracking processed components.\n * @param {Object.<string, any>} sharedFunctions - The map of shared component functions.\n */\nexport function addComponentAndDependencies (componentId, processed, sharedFunctions) {\n if (!processed[componentId] && sharedFunctions[componentId]) {\n processed[componentId] = true\n\n // Add all dependencies of this component\n const dependencies = sharedFunctions[componentId].components || []\n for (const depId of dependencies) {\n addComponentAndDependencies(depId, processed, sharedFunctions)\n }\n }\n}\n\n/**\n * Recursively clones an AST node and its children, stripping circular references\n * and assigning unique IDs for client-side hydration.\n *\n * @param {Array<Object>} nodes - The nodes to clean.\n * @param {WeakMap} nodeMap - Map to track original nodes to their unique IDs.\n * @param {Object} state - Object containing the current node counter.\n * @returns {Array<Object>|null} The cleaned AST nodes.\n */\nexport function cleanAST (nodes, nodeMap, state) {\n if (!nodes) {\n return null\n }\n\n return nodes.map((node) => {\n const cloned = { ...node }\n // Assign unique ID for token mapping\n const id = state.counter++\n nodeMap.set(node, id)\n cloned._id = id\n\n // Remove circular references\n delete cloned.parent\n delete cloned.prev\n delete cloned.next\n delete cloned.slots\n\n if (cloned.children) {\n cloned.children = cleanAST(cloned.children, nodeMap, state)\n }\n return cloned\n })\n}\n\n/**\n * Cleans the template values object, mapping original node references to unique IDs.\n *\n * @param {Object} values - The values object to clean.\n * @param {WeakMap} nodeMap - Map of original nodes to their unique IDs.\n * @returns {Object|null} The cleaned values object.\n */\nexport function cleanValues (values, nodeMap) {\n if (!values) {\n return null\n }\n\n const result = { ...values }\n\n if (result.attributes) {\n result.attributes = result.attributes.map(item => {\n const cloned = { ...item }\n cloned.elementId = nodeMap.get(item.element)\n delete cloned.element\n return cloned\n })\n }\n\n if (result.textNodes) {\n result.textNodes = result.textNodes.map(item => {\n const cloned = { ...item }\n cloned.textNodeId = nodeMap.get(item.textNode)\n delete cloned.textNode\n return cloned\n })\n }\n\n if (result.refs) {\n result.refs = result.refs.map(item => {\n const cloned = { ...item }\n cloned.elementId = nodeMap.get(item.element)\n delete cloned.element\n return cloned\n })\n }\n return result\n}\n\n/**\n * Safely merges partial plugin updates into the main context object.\n * Deeply merges plain objects and overwrites other types (arrays, primitives, etc.).\n *\n * @param {any} current - The current state object.\n * @param {any} patch - The patch object containing updates.\n * @returns {any} The newly merged state object.\n */\nexport function mergePluginState (current, patch) {\n if (!patch || typeof patch !== 'object') {\n return current\n }\n\n const result = { ...current }\n\n for (const key of Object.keys(patch)) {\n const patchValue = patch[key]\n const currentValue = result[key]\n\n // If both are plain objects, merge them deeply\n if (\n patchValue && typeof patchValue === 'object' && !Array.isArray(patchValue) &&\n currentValue && typeof currentValue === 'object' && !Array.isArray(currentValue)\n ) {\n result[key] = mergePluginState(currentValue, patchValue)\n } else {\n // Otherwise, overwrite (Arrays, strings, numbers, etc.)\n result[key] = patchValue\n }\n }\n\n return result\n}\n\n/**\n * Creates a reactive proxy that triggers a callback on changes.\n * Supports deep reactivity via lazy proxying of nested objects.\n *\n * @param {Object} target - The object to proxy.\n * @param {Function} onChange - Callback triggered when a property is set or deleted.\n * @param {WeakMap} [proxies=new WeakMap()] - Cache for existing proxies to handle circular references and identity.\n * @returns {Proxy} The reactive proxy.\n */\nexport function createReactiveProxy (target, onChange, proxies = new WeakMap()) {\n if (proxies.has(target)) {\n return proxies.get(target)\n }\n\n const handler = {\n get (target, property, receiver) {\n const value = Reflect.get(target, property, receiver)\n if (value !== null && typeof value === 'object' && !(typeof Node !== 'undefined' && value instanceof Node)) {\n return createReactiveProxy(value, onChange, proxies)\n }\n return value\n },\n set (target, property, value, receiver) {\n const oldValue = target[property]\n if (oldValue === value && property in target) {\n return true\n }\n\n const result = Reflect.set(target, property, value, receiver)\n if (result) {\n onChange({\n property,\n value,\n oldValue,\n target\n })\n }\n return result\n },\n deleteProperty (target, property) {\n const hadProperty = Object.prototype.hasOwnProperty.call(target, property)\n const oldValue = target[property]\n const result = Reflect.deleteProperty(target, property)\n if (result && hadProperty) {\n onChange({\n property,\n value: undefined,\n oldValue,\n target,\n deleted: true\n })\n }\n return result\n }\n }\n\n const proxy = new Proxy(target, handler)\n proxies.set(target, proxy)\n return proxy\n}\n\n/**\n * Creates a read-only proxy that throws on mutation attempts.\n * @param {Object} target - The object to proxy.\n * @param {WeakMap} [proxies=new WeakMap()] - Cache for existing proxies.\n * @returns {Proxy} The read-only proxy.\n */\nexport function createReadOnlyProxy (target, proxies = new WeakMap()) {\n if (proxies.has(target)) {\n return proxies.get(target)\n }\n\n const handler = {\n get (target, property, receiver) {\n const value = Reflect.get(target, property, receiver)\n if (value !== null && typeof value === 'object' && !(typeof Node !== 'undefined' && value instanceof Node)) {\n return createReadOnlyProxy(value, proxies)\n }\n return value\n },\n set () {\n throw new CoraliteError('Cannot mutate state inside a getter. State is read-only here.')\n },\n deleteProperty () {\n throw new CoraliteError('Cannot delete state inside a getter. State is read-only here.')\n }\n }\n\n const proxy = new Proxy(target, handler)\n\n proxies.set(target, proxy)\n\n return proxy\n}\n\n/**\n * Defines a Coralite component.\n * On the client, this acts as an identity function for type safety and HRM.\n * @param {Object} options - Component options\n * @returns {Object} The component options\n */\nexport function defineComponent (options) {\n return options\n}\n", "/**\n * @import {\n * CoraliteClientPluginDisconnectedCallback,\n * CoraliteClientPluginAfterComponentRenderCallback,\n * CoraliteClientPluginBeforeComponentRenderCallback\n * } from '../types/plugin.js'\n */\n\nimport { createReadOnlyProxy } from './utils/core.js'\n\nconst BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n 'truespeed'\n])\n\n/**\n * Coerces a value to a specified type.\n * Supports Number, Boolean, and String.\n * @param {any} value - The value to coerce.\n * @param {Function|string} type - The target type (Constructor or string name).\n * @returns {any} The coerced value.\n */\nexport function coerce (value, type) {\n if (value === null || value === undefined) {\n return value\n }\n if (type === Number || type === 'Number') {\n return Number(value)\n }\n if (type === Boolean || type === 'Boolean') {\n if (value === '') {\n return true\n }\n return value !== 'false' && value !== null\n }\n if (type === String || type === 'String') {\n return String(value)\n }\n return value\n}\n\n/**\n * @typedef {Object} CoraliteComponentOptions\n * @property {string} componentId - The unique identifier for the component.\n * @property {string} [templateHTML] - The raw HTML string for imperative mounting.\n * @property {Object} [defaultValues] - The initial state values extracted from the server data block.\n * @property {Object} [attributes] - Schema for coercing HTML attributes into typed primitives.\n * @property {Object.<string, Function>} [getters] - Pure functions for derived state, supporting Promises.\n * @property {Object.<string, Function>} [slots] - Transformation functions for projected Light DOM.\n * @property {Function} [client] - The client-side controller logic.\n * @property {Object} [hydrationMap] - AST mapping for reactive text nodes, attributes, and refs.\n */\n\n/**\n * Base class for all Coralite custom elements.\n *\n * @augments HTMLElement\n */\nexport class CoraliteElement extends HTMLElement {\n /**\n * Initializes a new instance of the CoraliteElement.\n * Sets up internal state trackers, binding collections, and hook registries.\n */\n constructor () {\n super()\n /**\n * Controls native teardown of event listeners and async fetches upon disconnection.\n * @type {AbortController|null}\n * @protected\n */\n this._abortController = null\n\n /**\n * A globally unique, deterministic identifier (e.g., `my-comp-0`).\n * @type {string|null}\n * @protected\n */\n this._instanceId = null\n\n /**\n * The unified, deeply reactive proxy holding attributes, data, and getters.\n * @type {Object|null}\n * @protected\n */\n this._state = null\n\n /**\n * The collection of DOM nodes mapped to template tokens and attributes.\n * @type {Array<{type: string, node: Node, template?: string, name?: string}>}\n * @protected\n */\n this._bindings = []\n\n /**\n * Flag to prevent multiple synchronous state mutations from triggering multiple DOM paints.\n * @type {boolean}\n * @protected\n */\n this._isUpdatePending = false\n\n /**\n * A unique Symbol generated per render cycle to prevent async getter race conditions.\n * @type {symbol|null}\n * @protected\n */\n this._currentRenderVersion = null\n\n /**\n * @type {MutationObserver|null}\n * @protected\n */\n this._observer = null\n\n /**\n * Hook to fetch globally registered Phase-2 plugin contexts.\n * @type {Function|null}\n * @protected\n */\n this._clientContextGetter = null\n\n /**\n * Tracks AbortControllers specifically for cancelling stale async getters.\n * @type {Object.<string, AbortController>|null}\n * @protected\n */\n this._getterAbortControllers = null\n\n /**\n * Internal lifecycle hooks injected by registered Coralite plugins.\n * @type {{\n * onBeforeComponentRender: Array<CoraliteClientPluginBeforeComponentRenderCallback>,\n * onAfterComponentRender: Array<CoraliteClientPluginAfterComponentRenderCallback>,\n * onDisconnected: Array<CoraliteClientPluginDisconnectedCallback>\n * }}\n * @protected\n */\n this._hooks = {\n onBeforeComponentRender: [],\n onAfterComponentRender: [],\n onDisconnected: []\n }\n\n /**\n * The definition and schema of the component generated by the compiler.\n * @type {CoraliteComponentOptions|null}\n */\n this.componentOptions = null\n }\n\n /**\n * Invoked natively when the element is added to the document.\n * Handles the architectural split between Declarative (SSR) and Imperative (JS) components.\n * Orchestrates template injection, instance ID generation, and state/binding setup.\n */\n connectedCallback () {\n this._abortController = new AbortController()\n\n if (!this.componentOptions) {\n return\n }\n\n // Declarative components receive a data-cid from the server.\n // Imperative components (created via document.createElement) do not.\n const isImperative = !this.hasAttribute('data-cid')\n\n // Imperative Flow: Manually stamp the template and project the Light DOM.\n if (isImperative && this.componentOptions.templateHTML) {\n const originalLightDOM = Array.from(this.childNodes)\n this.innerHTML = this.componentOptions.templateHTML\n\n if (originalLightDOM.length > 0) {\n const slots = this.querySelectorAll('slot')\n slots.forEach(slot => {\n const slotName = slot.getAttribute('name') || 'default'\n const matchingNodes = originalLightDOM.filter(node => {\n // @ts-ignore\n const nodeSlot = (node.getAttribute && node.getAttribute('slot')) || 'default'\n return nodeSlot === slotName\n })\n matchingNodes.forEach(n => slot.appendChild(n))\n })\n }\n }\n\n // Establish the Deterministic Instance ID\n if (this.hasAttribute('data-cid')) {\n this._instanceId = this.getAttribute('data-cid')\n } else {\n // Fallback counter for imperatively created components\n // @ts-ignore\n window.__coralite_instanceCounters = window.__coralite_instanceCounters || {}\n const prefix = this.componentOptions.componentId\n // @ts-ignore\n if (window.__coralite_instanceCounters[prefix] === undefined) {\n // @ts-ignore\n window.__coralite_instanceCounters[prefix] = 0\n }\n // @ts-ignore\n this._instanceId = `${prefix}-${window.__coralite_instanceCounters[prefix]++}`\n }\n\n if (isImperative) {\n this.setAttribute('data-cid', this._instanceId)\n }\n\n this._setupState()\n this._setupBindings()\n this._init(isImperative)\n }\n\n /**\n * Invoked natively when the element is removed from the document.\n * Aborts pending requests and triggers `onDisconnected` plugin hooks\n * to ensure external libraries (e.g., Observers) do not cause memory leaks.\n * @this {any}\n */\n disconnectedCallback () {\n if (this._abortController) {\n this._abortController.abort()\n }\n\n if (!this.componentOptions) {\n return\n }\n\n for (const hook of this._hooks.onDisconnected) {\n hook({\n state: this._state,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n element: this,\n options: this.componentOptions\n })\n }\n }\n\n /**\n * Invoked natively when an observed HTML attribute changes.\n * Coerces the raw string value based on the component's attribute schema\n * and synchronizes it into the reactive state proxy.\n * @param {string} name - The kebab-case name of the attribute.\n * @param {string|null} oldVal - The previous value.\n * @param {string|null} newVal - The new value.\n */\n attributeChangedCallback (name, oldVal, newVal) {\n if (!this._state || oldVal === newVal || name === 'data-cid') {\n return\n }\n const camelName = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n const schema = this.componentOptions.attributes?.[camelName] || this.componentOptions.attributes?.[name]\n const value = schema ? coerce(newVal, schema.type) : newVal\n\n this._state[camelName] = value\n }\n\n /**\n * Constructs the unified state object.\n * Merges `defaultValues`, JSON hydration payloads, and DOM attributes.\n * Defines getters (wrapping state in a Read-Only proxy) and applies the final Read/Write Proxy.\n * @this {any}\n * @private\n */\n _setupState () {\n const options = this.componentOptions\n const target = { ...options.defaultValues }\n\n /** @type {Array<{name: string, element: HTMLElement}>} */\n const refs = []\n if (options.hydrationMap && options.hydrationMap.refs) {\n for (const ref of options.hydrationMap.refs) {\n const uniqueRefValue = `${this._instanceId}__${ref.name}`\n\n if (!target[`ref_${ref.name}`]) {\n target[`ref_${ref.name}`] = uniqueRefValue\n }\n\n const node = this.getNodeByPath(ref.path)\n if (node) {\n if (node.setAttribute) {\n node.setAttribute('ref', uniqueRefValue)\n }\n refs.push({\n name: ref.name,\n element: node\n })\n }\n }\n }\n\n // Process initial attributes mapping\n for (const attr of this.attributes) {\n if (attr.name === 'data-cid') {\n continue\n }\n const camelName = attr.name.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n const schema = options.attributes?.[camelName] || options.attributes?.[attr.name]\n target[camelName] = schema ? coerce(attr.value, schema.type) : attr.value\n }\n\n // Hydrate data() block results from the SSR JSON payload\n const hydrationTag = document.getElementById('__CORALITE_HYDRATION__')\n if (hydrationTag) {\n try {\n const allData = JSON.parse(hydrationTag.textContent)\n if (allData[this._instanceId]) {\n Object.assign(target, allData[this._instanceId])\n }\n } catch {\n console.error('Coralite Element hydration failed:', this._instanceId)\n }\n }\n\n // Trigger Before-Render hooks BEFORE state is proxied, allowing plugins to inject reactive data\n for (const hook of this._hooks.onBeforeComponentRender) {\n hook({\n state: target,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n refs,\n element: this,\n options: this.componentOptions\n })\n }\n\n\n // Define derived state getters with isolation controllers\n this._getterAbortControllers = {}\n for (const [key, getter] of Object.entries(options.getters || {})) {\n Object.defineProperty(target, key, {\n get: () => {\n if (this._getterAbortControllers[key]) {\n this._getterAbortControllers[key].abort()\n }\n this._getterAbortControllers[key] = new AbortController()\n\n // Enforce \"Dual-Proxy\" safety: Getters cannot mutate state\n const roState = createReadOnlyProxy(this._state)\n return getter(roState, { signal: this._getterAbortControllers[key].signal })\n },\n enumerable: true,\n configurable: true\n })\n }\n\n this._state = this._createReactiveProxy(target)\n }\n\n /**\n * Wraps the state target in a reactive Proxy.\n * Intercepts property setters to automatically batch and schedule DOM updates.\n * @param {Object} target - The state dictionary.\n * @returns {Proxy} The reactive state proxy.\n * @private\n */\n _createReactiveProxy (target) {\n const self = this\n return new Proxy(target, {\n set (t, p, v) {\n if (t[p] === v) {\n return true\n }\n t[p] = v\n self._scheduleUpdate()\n return true\n }\n })\n }\n\n /**\n * Traverses the DOM tree using an AST-generated path index array.\n * Allows O(1) element lookups without relying on querySelectors or classes.\n * @param {number[]} path - Array of childNode indices (e.g., `[0, 1, 2]`).\n * @returns {Node|null} The physical DOM node, or null if traversal fails.\n */\n getNodeByPath (path) {\n let node = this\n for (const index of path) {\n if (!node) {\n return null\n }\n // @ts-ignore\n node = node.childNodes[index]\n }\n return node\n }\n\n /**\n * Initializes DOM bindings based on the compiler's hydration map.\n * Caches physical DOM references to text nodes and attributes that contain template tokens.\n * @private\n */\n _setupBindings () {\n this._bindings = []\n const map = this.componentOptions.hydrationMap\n if (!map) {\n return\n }\n\n if (map.texts) {\n for (const item of map.texts) {\n const node = this.getNodeByPath(item.path)\n if (node) {\n this._bindings.push({\n type: item.type || 'text',\n node,\n template: item.template\n })\n }\n }\n }\n\n if (map.attributes) {\n for (const item of map.attributes) {\n const node = this.getNodeByPath(item.path)\n if (node) {\n this._bindings.push({\n type: 'attribute',\n node,\n name: item.name,\n template: item.template\n })\n }\n }\n }\n }\n\n /**\n * Schedules a DOM update in the next microtask queue.\n * This guarantees that multiple synchronous state mutations result in only one render pass.\n * @private\n */\n _scheduleUpdate () {\n if (this._isUpdatePending) {\n return\n }\n this._isUpdatePending = true\n queueMicrotask(() => {\n this._updateDOM()\n this._isUpdatePending = false\n })\n }\n\n /**\n * Performs the physical DOM update and resolves template tokens.\n * **Async Safety:** Implements a Symbol-based locking mechanism (`renderVersion`)\n * to guarantee that if state mutates while an async getter is pending, the stale\n * Promise will be discarded, preventing DOM race conditions.\n * @this {any}\n * @private\n */\n _updateDOM () {\n // Create a unique lock for this specific render cycle\n const renderVersion = Symbol()\n this._currentRenderVersion = renderVersion\n\n // Extract unique tokens to prevent double-reading and accidental aborts\n /** @type {Set<string>} */\n const requiredTokens = new Set()\n for (const binding of this._bindings) {\n binding.template.replace(/\\{\\{\\s*(.+?)\\s*\\}\\}/g, (_, key) => {\n requiredTokens.add(key)\n return ''\n })\n }\n\n const evaluatedTokens = {}\n let hasPromise = false\n\n // Evaluate getters exactly once per render cycle\n for (const key of requiredTokens) {\n let val = this._state[key]\n if (typeof val === 'function') {\n val = val(this._state)\n }\n evaluatedTokens[key] = val\n if (val instanceof Promise) {\n hasPromise = true\n }\n }\n\n // The DOM Mutator Function\n const applyBindings = (tokenValues) => {\n // Race Condition Lock: Abort if a newer render cycle has already begun\n if (this._currentRenderVersion !== renderVersion) {\n return\n }\n\n for (const binding of this._bindings) {\n const hydratedValue = binding.template.replace(/\\{\\{\\s*(.+?)\\s*\\}\\}/g, (_, key) => {\n return tokenValues[key] ?? ''\n })\n\n if (binding.type === 'text') {\n if (binding.node.textContent !== hydratedValue) {\n binding.node.textContent = hydratedValue\n }\n } else if (binding.type === 'html') {\n /** @type {HTMLElement} */\n // @ts-ignore\n const element = binding.node\n\n if (element.innerHTML !== hydratedValue) {\n element.innerHTML = hydratedValue\n }\n } else if (binding.type === 'attribute') {\n /** @type {HTMLElement} */\n // @ts-ignore\n const element = binding.node\n\n if (BOOLEAN_ATTRIBUTES.has(binding.name)) {\n const isFalsy = hydratedValue === '' || hydratedValue === 'false' || hydratedValue === 'null' || hydratedValue === '0' || hydratedValue === 'undefined'\n if (isFalsy) {\n element.removeAttribute(binding.name)\n } else {\n element.setAttribute(binding.name, '')\n }\n } else {\n if (element.getAttribute(binding.name) !== hydratedValue) {\n element.setAttribute(binding.name, hydratedValue)\n }\n }\n }\n }\n\n this._processSlots()\n\n // Trigger After-Render hooks ONLY after the physical DOM is stable\n for (const hook of this._hooks.onAfterComponentRender) {\n hook({\n state: this._state,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n element: this,\n options: this.componentOptions\n })\n }\n }\n\n // Await Promises or Apply Synchronously\n if (hasPromise) {\n const keys = Object.keys(evaluatedTokens)\n const promises = keys.map(k => Promise.resolve(evaluatedTokens[k]))\n\n Promise.all(promises).then(resolvedValues => {\n const resolvedMap = {}\n keys.forEach((k, i) => {\n resolvedMap[k] = resolvedValues[i]\n })\n applyBindings(resolvedMap)\n }).catch(e => {\n if (e.name !== 'AbortError') {\n console.error('Coralite Async Getter Error:', e)\n }\n })\n } else {\n applyBindings(evaluatedTokens)\n }\n }\n\n /**\n * Evaluates and projects Light DOM elements into their respective `<slot>` nodes.\n * Invokes component-specific slot transformation functions.\n * @private\n */\n _processSlots () {\n const slots = this.componentOptions.slots\n if (!slots || Object.keys(slots).length === 0) {\n return\n }\n\n const slotElements = this.querySelectorAll('slot')\n slotElements.forEach(slotEl => {\n const slotName = slotEl.getAttribute('name') || 'default'\n const slotFn = slots[slotName]\n\n if (slotFn) {\n // @ts-ignore\n if (!slotEl._originalNodes) {\n // @ts-ignore\n slotEl._originalNodes = Array.from(slotEl.childNodes).map(n => n.cloneNode(true))\n }\n\n // @ts-ignore\n const result = slotFn(slotEl._originalNodes, this._state)\n\n if (result === undefined) {\n return\n }\n\n if (result === null || result === '' || (Array.isArray(result) && result.length === 0)) {\n slotEl.innerHTML = ''\n return\n }\n\n if (typeof result === 'string') {\n slotEl.innerHTML = result\n } else if (Array.isArray(result)) {\n slotEl.replaceChildren(...result)\n }\n }\n })\n }\n\n /**\n * The final initialization pipeline.\n * Injects globally registered client plugins into the local context payload,\n * triggers the initial DOM render, and invokes the user's `script()` logic.\n * @param {boolean} [isImperative=false] - If true, initial render runs synchronously.\n * @private\n */\n async _init (isImperative = false) {\n const self = this\n /**\n * The context payload injected into the user's script block.\n * @type {Object}\n */\n let localContext = {\n instanceId: this._instanceId,\n state: this._state,\n root: this,\n signal: this._abortController.signal,\n refs (id) {\n const refId = self._state[`ref_${id}`]\n if (!refId && typeof refId !== 'string') {\n return null\n }\n return self.querySelector(`[ref=\"${refId}\"]`)\n }\n }\n\n if (typeof this._clientContextGetter === 'function') {\n localContext = await this._clientContextGetter(localContext)\n }\n\n if (isImperative) {\n this._updateDOM()\n } else {\n this._scheduleUpdate()\n }\n\n if (this.componentOptions.client) {\n try {\n this.componentOptions.client(localContext)\n } catch (error) {\n console.error(`Coralite Error: Component \"${this.componentOptions.componentId}\" script failed:`, error)\n }\n }\n }\n}\n\n/**\n * Factory function to create a Coralite element class.\n * It dynamically defines the class, including observed attributes and hook initialization.\n * @param {CoraliteComponentOptions} options - Component options and metadata.\n * @param {Function|null} [contextGetter=null] - Optional function to retrieve client-side plugin context.\n * @param {Object} [hooks={}] - Lifecycle hooks to register.\n * @param {Array<CoraliteClientPluginBeforeComponentRenderCallback>} [hooks.onBeforeComponentRender] - Hooks to run before render.\n * @param {Array<CoraliteClientPluginAfterComponentRenderCallback>} [hooks.onAfterComponentRender] - Hooks to run after render.\n * @param {Array<CoraliteClientPluginDisconnectedCallback>} [hooks.onDisconnected] - Hooks to run after render.\n * @returns {typeof CoraliteElement} A new CoraliteElement subclass.\n */\nexport function createCoraliteClass (options, contextGetter = null, hooks = {}) {\n return class extends CoraliteElement {\n /**\n * The attributes to observe for changes.\n * @returns {string[]} Array of attribute names.\n */\n static get observedAttributes () {\n if (!options.attributes) {\n return []\n }\n return Object.keys(options.attributes).map(key => key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()\n )\n }\n\n /**\n * Initializes the dynamic Coralite element.\n */\n constructor () {\n super()\n this.componentOptions = options\n this._clientContextGetter = contextGetter\n this._hooks = {\n onBeforeComponentRender: hooks.onBeforeComponentRender || [],\n onAfterComponentRender: hooks.onAfterComponentRender || [],\n onDisconnected: hooks.onDisconnected || []\n }\n }\n }\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../lib/utils/errors.js", "../../lib/utils/core.js", "../../lib/utils/client/inject.js", "../../lib/coralite-element.js"],
4
+ "sourcesContent": ["\n/**\n * @import { CoraliteErrorData } from '../../types/index.js'\n */\n\n/**\n * Base error class for all Coralite-related errors.\n */\nexport class CoraliteError extends Error {\n /**\n * @param {string} message - The error message.\n * @param {Object} [options] - Additional options for the error.\n * @param {string} [options.componentId] - The ID of the component where the error occurred.\n * @param {string} [options.filePath] - The path to the file where the error occurred.\n * @param {string} [options.instanceId] - The unique ID of the component instance.\n * @param {string} [options.pagePath] - The path to the page being rendered.\n * @param {number} [options.line] - The line number where the error occurred.\n * @param {number} [options.column] - The column number where the error occurred.\n * @param {string} [options.stackFile] - The file name from the stack trace.\n * @param {Error} [options.cause] - The original error that caused this error.\n */\n constructor (message, options = {}) {\n super(message, options)\n this.name = 'CoraliteError'\n this.isCoraliteError = true\n this.componentId = options.componentId\n this.filePath = options.filePath\n this.instanceId = options.instanceId\n this.pagePath = options.pagePath\n this.line = options.line\n this.column = options.column\n this.stackFile = options.stackFile\n\n // Polyfill cause if necessary (node version differences)\n if (options.cause && !this.cause) {\n this.cause = options.cause\n }\n }\n}\n\n/**\n * Default error handler.\n * @param {CoraliteErrorData} data - The data object containing error details.\n */\nexport function defaultOnError ({ level, message, error }) {\n if (level === 'ERR') {\n if (error) {\n throw error\n }\n throw new CoraliteError(message)\n } else if (level === 'WARN') {\n console.warn(message)\n } else {\n console.log(message)\n }\n}\n\n/**\n * Handles errors using an optional callback or the default handler.\n * @param {Object} options - The options for handling the error.\n * @param {Function} [options.onErrorCallback] - The optional custom error callback function.\n * @param {CoraliteErrorData} options.data - The error data to be handled.\n */\nexport function handleError ({ onErrorCallback, data }) {\n const error = data.error\n if (error && 'isCoraliteError' in error && error.isCoraliteError) {\n const coraliteError = error\n // @ts-ignore\n data.componentId = data.componentId || coraliteError.componentId\n // @ts-ignore\n data.filePath = data.filePath || coraliteError.filePath\n // @ts-ignore\n data.instanceId = data.instanceId || coraliteError.instanceId\n // @ts-ignore\n data.pagePath = data.pagePath || coraliteError.pagePath\n // @ts-ignore\n data.line = data.line || coraliteError.line\n // @ts-ignore\n data.column = data.column || coraliteError.column\n // @ts-ignore\n data.stackFile = data.stackFile || coraliteError.stackFile\n }\n\n if (onErrorCallback) {\n onErrorCallback(data)\n } else {\n defaultOnError(data)\n }\n}\n", "import { CoraliteError } from './errors.js'\n\n/**\n * @import {\n * CoraliteModule,\n * CoraliteComponent,\n * CoraliteComponentResult,\n * } from '../../types/index.js'\n */\n\nconst KEBAB_REGEX = /[-|:]([a-z])/g\n\n/**\n * Converts a kebab-case string to camelCase\n * @param {string} str - The kebab-case string to convert\n * @returns {string} - The camelCase version of the string\n */\nexport function kebabToCamel (str) {\n // replace each dash followed by a letter with the uppercase version of the letter\n return str.replace(KEBAB_REGEX, function (match, letter) {\n return letter.toUpperCase()\n })\n}\n\n/**\n * Converts all keys in an object from kebab-case to camelCase\n * @template T\n * @param {Record<string, T>} object - The object with kebab-case keys\n * @returns {Record<string, T>} - A new object with camelCase keys\n */\nexport function cleanKeys (object) {\n /** @type {Record<string, T>} */\n const result = {}\n\n for (const [key, value] of Object.entries(object)) {\n result[key] = value\n\n const camelKey = kebabToCamel(key)\n if (camelKey !== key) {\n result[camelKey] = value\n }\n }\n\n return result\n}\n\n/**\n * Recursively clones an object or array and normalizes any function state\n * it finds into a string representation that preserves standard function syntax,\n * bypassing ES6 shorthand method serialization issues.\n * @param {any} target - The object or array to normalize.\n * @param {Function} [transform] - Optional transform function for each node.\n * @param {WeakMap} [seen=new WeakMap()] - Map of seen objects to handle circular references.\n * @returns {any} A deeply cloned object with normalized functions.\n */\nexport function normalizeObjectFunctions (target, transform = null, seen = new WeakMap()) {\n if (typeof transform === 'function') {\n const transformed = transform(target)\n if (transformed !== target) {\n return transformed\n }\n }\n\n if (typeof target !== 'object' || target === null) {\n return target\n }\n\n if (seen.has(target)) {\n return seen.get(target)\n }\n\n if (Array.isArray(target)) {\n const arr = []\n seen.set(target, arr)\n for (let i = 0; i < target.length; i++) {\n arr.push(normalizeObjectFunctions(target[i], transform, seen))\n }\n return arr\n }\n\n const obj = {}\n seen.set(target, obj)\n for (const key in target) {\n if (Object.hasOwn(target, key)) {\n if (typeof target[key] === 'function') {\n const normalizedString = normalizeFunction(target[key])\n const originalFunction = target[key]\n\n const wrapper = function () {\n return originalFunction.apply(this, arguments)\n }\n wrapper.toString = () => normalizedString\n obj[key] = wrapper\n } else {\n obj[key] = normalizeObjectFunctions(target[key], transform, seen)\n }\n }\n }\n\n return obj\n}\n\n/**\n * Checks whether the given object is an object and has at least one own key.\n * @param {any} obj - The object to check.\n * @returns {boolean} True if the object is truthy and has keys, otherwise false.\n */\nexport function hasObjectKeys (obj) {\n return obj && typeof obj === 'object' && Object.keys(obj).length > 0\n}\n\n/**\n * Merges two arrays, returning a new array with unique items.\n * Uses JSON.stringify for deep comparison of object elements, preserving object uniqueness correctly.\n * @param {Array<any>} [arr1] - The first array.\n * @param {Array<any>} [arr2] - The second array.\n * @returns {Array<any>} A new array with unique values from both input arrays.\n */\nexport function mergeUniqueObjects (arr1, arr2) {\n const all = [...(arr1 || []), ...(arr2 || [])]\n const seen = new Set()\n return all.filter(item => {\n const key = typeof item === 'object' ? JSON.stringify(item) : item\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n\n/**\n * Normalizes function declarations to ensure consistent formatting.\n * Converts shorthand method syntax to full function declarations where needed,\n * while preserving arrow functions and existing full declarations.\n *\n * @param {Function} func - The function to normalize\n * @returns {string} The normalized function string representation\n */\nexport function normalizeFunction (func) {\n const original = func.toString().trim()\n\n const firstBrace = original.indexOf('{')\n const firstArrow = original.indexOf('=>')\n\n const isArrow = firstArrow !== -1 && (firstBrace === -1 || firstArrow < firstBrace)\n\n if (isArrow) {\n return original\n }\n\n // For non-arrows, extract header to check for shorthand\n const header = firstBrace !== -1 ? original.slice(0, firstBrace).trim() : original\n\n const isStandard = header.startsWith('function') || header.startsWith('async function')\n\n if (isStandard) {\n return original\n }\n\n // Handle Method Shorthand\n if (header.startsWith('async ')) {\n if (header.startsWith('async get ') || header.startsWith('async set ')) {\n return original\n }\n\n return original.replace(/^async\\s+([$\\w]+)\\s*\\(/, 'async function(')\n } else {\n if (header.startsWith('get ') || header.startsWith('set ')) {\n return original\n }\n\n return original.replace(/^([$\\w]+)\\s*\\(/, 'function(')\n }\n}\n\n\n/**\n * Recursively clones an AST node and its children, ensuring that\n * inner references (like parents and slots) point to the newly cloned nodes.\n *\n * @param {Map<Object, Object>} nodeMap - A map tracking original nodes to their newly cloned counterparts.\n * @param {Object} node - The current AST node being cloned.\n * @param {Object} [parent] - The parent node reference to assign to the clone.\n * @returns {Object} The newly cloned node.\n */\nexport function cloneNode (nodeMap, node, parent) {\n const newNode = Object.create(Object.getPrototypeOf(node))\n\n // Copy all own enumerable properties\n Object.assign(newNode, node)\n\n if (parent) {\n newNode.parent = parent\n }\n\n if (newNode.attribs) {\n newNode.attribs = { ...newNode.attribs }\n }\n\n // Register in map\n nodeMap.set(node, newNode)\n\n // Recursively clone children\n if (node.children) {\n const children = node.children\n const length = children.length\n const clonedChildren = new Array(length)\n newNode.children = clonedChildren\n\n for (let i = 0; i < length; i++) {\n const clonedChild = cloneNode(nodeMap, children[i], newNode)\n clonedChildren[i] = clonedChild\n if (i > 0) {\n clonedChild.prev = clonedChildren[i - 1]\n clonedChildren[i - 1].next = clonedChild\n }\n }\n }\n\n // Update slot references to point to new cloned nodes\n if (node.slots) {\n const slots = node.slots\n const length = slots.length\n const clonedSlots = new Array(length)\n for (let i = 0; i < length; i++) {\n const slot = slots[i]\n const clonedSlot = { ...slot }\n if (slot.node) {\n const clonedNode = nodeMap.get(slot.node)\n if (clonedNode) {\n clonedSlot.node = clonedNode\n }\n }\n clonedSlots[i] = clonedSlot\n }\n newNode.slots = clonedSlots\n }\n\n // Preserve the enhanced flag without re-running enhanceNode\n Object.defineProperty(newNode, '__coralite_enhanced__', {\n value: true,\n enumerable: false,\n configurable: true\n })\n\n return newNode\n}\n\n/**\n * Creates a shallow copy of a CoraliteModule with a deep clone of its DOM tree (template) and re-linked internal references to enable safe independent mutation.\n *\n * Top-level non-DOM state (id, path, script, isTemplate, lineOffset) are shallow copied. Nested objects within these state (e.g., path) remain shared references. Only DOM-related structures undergo deep cloning and reference re-linking to isolate mutations from the original module.\n *\n * @param {CoraliteModule} originalModule - Module to clone.\n * @returns {CoraliteModule}\n */\nexport function cloneModuleInstance (originalModule) {\n const nodeMap = new Map()\n\n // Clone the main template tree\n const newTemplate = cloneNode(nodeMap, originalModule.template, null)\n\n // Reconstruct the 'values' object\n const newValues = {\n attributes: originalModule.values.attributes.map(item => ({\n ...item,\n element: nodeMap.get(item.element)\n })),\n textNodes: originalModule.values.textNodes.map(item => ({\n ...item,\n textNode: nodeMap.get(item.textNode)\n })),\n refs: originalModule.values.refs.map(item => ({\n ...item,\n element: nodeMap.get(item.element)\n }))\n }\n\n // Reconstruct customElements list\n const newCustomElements = originalModule.customElements.map(el => nodeMap.get(el))\n\n // Reconstruct slotElements\n const newSlotElements = {}\n if (originalModule.slotElements) {\n for (const modId in originalModule.slotElements) {\n newSlotElements[modId] = {}\n const slotGroup = originalModule.slotElements[modId]\n\n for (const slotName in slotGroup) {\n const slotItem = slotGroup[slotName]\n newSlotElements[modId][slotName] = {\n ...slotItem,\n element: nodeMap.get(slotItem.element)\n }\n }\n }\n }\n\n // Return the new module structure\n return {\n ...originalModule,\n template: newTemplate,\n values: newValues,\n customElements: newCustomElements,\n // @ts-ignore\n slotElements: newSlotElements\n }\n}\n\n/**\n * Creates a deep copy of a CoraliteComponent with re-linked internal references to enable safe independent mutation.\n *\n * @param {CoraliteComponent & CoraliteComponentResult} originalDocument - Document to clone.\n * @returns {CoraliteComponent & CoraliteComponentResult}\n */\nexport function cloneComponentInstance (originalDocument) {\n const nodeMap = new Map()\n const newRoot = cloneNode(nodeMap, originalDocument.root, null)\n\n const newCustomElements = originalDocument.customElements.map(el => nodeMap.get(el))\n const newTempElements = originalDocument.tempElements ? originalDocument.tempElements.map(el => nodeMap.get(el)) : []\n const newSkipRenderElements = originalDocument.skipRenderElements ? originalDocument.skipRenderElements.map(el => nodeMap.get(el)) : []\n\n return {\n ...originalDocument,\n state: { ...originalDocument.state },\n root: newRoot,\n customElements: newCustomElements,\n tempElements: newTempElements,\n skipRenderElements: newSkipRenderElements\n }\n}\n\n/**\n * Calculates the DOM path from a node to the root.\n * @param {Object} node - The node to calculate the path for.\n * @param {Object} root - The root node.\n * @returns {Array<number>} An array of indices representing the path.\n */\nexport function getNodePath (node, root) {\n const path = []\n let current = node\n while (current && current !== root) {\n const parent = current.parent\n if (!parent) {\n break\n }\n const index = parent.children.indexOf(current)\n if (index === -1) {\n break\n }\n path.unshift(index)\n current = parent\n }\n return path\n}\n\n/**\n * Generates a hydration map for the client.\n * @param {Array<Object>} templateNodes - The component's template nodes.\n * @param {Object} templateValues - The component's template values.\n * @returns {Object} The hydration map.\n */\nexport function generateHydrationMap (templateNodes, templateValues) {\n const map = {\n texts: [],\n attributes: [],\n refs: []\n }\n\n if (!templateNodes || !templateValues) {\n return map\n }\n\n const root = templateNodes.length > 0 ? templateNodes[0].parent : { children: templateNodes }\n\n if (templateValues.textNodes) {\n for (const item of templateValues.textNodes) {\n if (item.textNode) {\n const isHtml = item.type === 'html'\n const targetNode = isHtml ? item.textNode.parent : item.textNode\n\n map.texts.push({\n path: getNodePath(targetNode, root),\n template: item.textNode.data,\n type: isHtml ? 'html' : 'text'\n })\n }\n }\n }\n\n if (templateValues.attributes) {\n for (const item of templateValues.attributes) {\n if (item.element && item.element.attribs) {\n const originalValue = item.element.attribs[item.name]\n map.attributes.push({\n path: getNodePath(item.element, root),\n name: item.name,\n template: originalValue\n })\n }\n }\n }\n\n if (templateValues.refs) {\n for (const item of templateValues.refs) {\n if (item.element) {\n map.refs.push({\n path: getNodePath(item.element, root),\n name: item.name\n })\n }\n }\n }\n\n return map\n}\n\n/**\n * Recursively adds a component and its dependencies to a tracking object.\n *\n * @param {string} componentId - The ID of the component to add.\n * @param {Object.<string, boolean>} processed - The object tracking processed components.\n * @param {Object.<string, any>} sharedFunctions - The map of shared component functions.\n */\nexport function addComponentAndDependencies (componentId, processed, sharedFunctions) {\n if (!processed[componentId] && sharedFunctions[componentId]) {\n processed[componentId] = true\n\n // Add all dependencies of this component\n const dependencies = sharedFunctions[componentId].components || []\n for (const depId of dependencies) {\n addComponentAndDependencies(depId, processed, sharedFunctions)\n }\n }\n}\n\n/**\n * Recursively clones an AST node and its children, stripping circular references\n * and assigning unique IDs for client-side hydration.\n *\n * @param {Array<Object>} nodes - The nodes to clean.\n * @param {WeakMap} nodeMap - Map to track original nodes to their unique IDs.\n * @param {Object} state - Object containing the current node counter.\n * @returns {Array<Object>|null} The cleaned AST nodes.\n */\nexport function cleanAST (nodes, nodeMap, state) {\n if (!nodes) {\n return null\n }\n\n return nodes.map((node) => {\n const cloned = { ...node }\n // Assign unique ID for token mapping\n const id = state.counter++\n nodeMap.set(node, id)\n cloned._id = id\n\n // Remove circular references\n delete cloned.parent\n delete cloned.prev\n delete cloned.next\n delete cloned.slots\n\n if (cloned.children) {\n cloned.children = cleanAST(cloned.children, nodeMap, state)\n }\n return cloned\n })\n}\n\n/**\n * Cleans the template values object, mapping original node references to unique IDs.\n *\n * @param {Object} values - The values object to clean.\n * @param {WeakMap} nodeMap - Map of original nodes to their unique IDs.\n * @returns {Object|null} The cleaned values object.\n */\nexport function cleanValues (values, nodeMap) {\n if (!values) {\n return null\n }\n\n const result = { ...values }\n\n if (result.attributes) {\n result.attributes = result.attributes.map(item => {\n const cloned = { ...item }\n cloned.elementId = nodeMap.get(item.element)\n delete cloned.element\n return cloned\n })\n }\n\n if (result.textNodes) {\n result.textNodes = result.textNodes.map(item => {\n const cloned = { ...item }\n cloned.textNodeId = nodeMap.get(item.textNode)\n delete cloned.textNode\n return cloned\n })\n }\n\n if (result.refs) {\n result.refs = result.refs.map(item => {\n const cloned = { ...item }\n cloned.elementId = nodeMap.get(item.element)\n delete cloned.element\n return cloned\n })\n }\n return result\n}\n\n/**\n * Safely merges partial plugin updates into the main context object.\n * Deeply merges plain objects and overwrites other types (arrays, primitives, etc.).\n *\n * @param {any} current - The current state object.\n * @param {any} patch - The patch object containing updates.\n * @returns {any} The newly merged state object.\n */\nexport function mergePluginState (current, patch) {\n if (!patch || typeof patch !== 'object') {\n return current\n }\n\n const result = { ...current }\n\n for (const key of Object.keys(patch)) {\n const patchValue = patch[key]\n const currentValue = result[key]\n\n // If both are plain objects, merge them deeply\n if (\n patchValue && typeof patchValue === 'object' && !Array.isArray(patchValue) &&\n currentValue && typeof currentValue === 'object' && !Array.isArray(currentValue)\n ) {\n result[key] = mergePluginState(currentValue, patchValue)\n } else {\n // Otherwise, overwrite (Arrays, strings, numbers, etc.)\n result[key] = patchValue\n }\n }\n\n return result\n}\n\n/**\n * Creates a reactive proxy that triggers a callback on changes.\n * Supports deep reactivity via lazy proxying of nested objects.\n *\n * @param {Object} target - The object to proxy.\n * @param {Function} onChange - Callback triggered when a property is set or deleted.\n * @param {WeakMap} [proxies=new WeakMap()] - Cache for existing proxies to handle circular references and identity.\n * @returns {Proxy} The reactive proxy.\n */\nexport function createReactiveProxy (target, onChange, proxies = new WeakMap()) {\n if (proxies.has(target)) {\n return proxies.get(target)\n }\n\n const handler = {\n get (target, property, receiver) {\n const value = Reflect.get(target, property, receiver)\n if (value !== null && typeof value === 'object' && !(typeof Node !== 'undefined' && value instanceof Node)) {\n return createReactiveProxy(value, onChange, proxies)\n }\n return value\n },\n set (target, property, value, receiver) {\n const oldValue = target[property]\n if (oldValue === value && property in target) {\n return true\n }\n\n const result = Reflect.set(target, property, value, receiver)\n if (result) {\n onChange({\n property,\n value,\n oldValue,\n target\n })\n }\n return result\n },\n deleteProperty (target, property) {\n const hadProperty = Object.prototype.hasOwnProperty.call(target, property)\n const oldValue = target[property]\n const result = Reflect.deleteProperty(target, property)\n if (result && hadProperty) {\n onChange({\n property,\n value: undefined,\n oldValue,\n target,\n deleted: true\n })\n }\n return result\n }\n }\n\n const proxy = new Proxy(target, handler)\n proxies.set(target, proxy)\n return proxy\n}\n\n/**\n * Creates a read-only proxy that throws on mutation attempts.\n * @param {Object} target - The object to proxy.\n * @param {WeakMap} [proxies=new WeakMap()] - Cache for existing proxies.\n * @returns {Proxy} The read-only proxy.\n */\nexport function createReadOnlyProxy (target, proxies = new WeakMap()) {\n if (proxies.has(target)) {\n return proxies.get(target)\n }\n\n const handler = {\n get (target, property, receiver) {\n const value = Reflect.get(target, property, receiver)\n if (value !== null && typeof value === 'object' && !(typeof Node !== 'undefined' && value instanceof Node)) {\n return createReadOnlyProxy(value, proxies)\n }\n return value\n },\n set () {\n throw new CoraliteError('Cannot mutate state inside a getter. State is read-only here.')\n },\n deleteProperty () {\n throw new CoraliteError('Cannot delete state inside a getter. State is read-only here.')\n }\n }\n\n const proxy = new Proxy(target, handler)\n\n proxies.set(target, proxy)\n\n return proxy\n}\n\n/**\n * Defines a Coralite component.\n * On the client, this acts as an identity function for type safety and HRM.\n * @param {Object} options - Component options\n * @returns {Object} The component options\n */\nexport function defineComponent (options) {\n return options\n}\n", "import { defineComponent } from '../core.js'\nimport { definePlugin } from '../../plugin.js'\n\n/**\n * Creates a Coralite element or a standard HTML element.\n * Proxy to window.createCoraliteElement or document.createElement.\n *\n * @param {string} tag - The tag name.\n * @param {Object} [options] - Optional element options.\n * @returns {HTMLElement} The created element.\n */\nexport function createCoraliteElement (tag, options) {\n // @ts-ignore\n if (typeof window !== 'undefined' && window.createCoraliteElement) {\n // @ts-ignore\n return window.createCoraliteElement(tag, options)\n }\n return document.createElement(tag, options)\n}\n\n/**\n * Processes an HTML string for custom elements.\n * Proxy to window.processHTML if available.\n *\n * @param {string} html - The HTML string.\n * @returns {string} The HTML string.\n */\nexport function processHTML (html) {\n // @ts-ignore\n if (typeof window !== 'undefined' && window.processHTML) {\n // @ts-ignore\n return window.processHTML(html)\n }\n return html\n}\n\nexport { defineComponent, definePlugin }\n", "/**\n * @import {\n * CoraliteClientPluginDisconnectedCallback,\n * CoraliteClientPluginAfterComponentRenderCallback,\n * CoraliteClientPluginBeforeComponentRenderCallback\n * } from '../types/plugin.js'\n */\n\nimport { createReadOnlyProxy } from './utils/core.js'\nimport { processHTML } from './utils/client/inject.js'\n\nconst BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n 'truespeed'\n])\n\n/**\n * Coerces a value to a specified type.\n * Supports Number, Boolean, and String.\n * @param {any} value - The value to coerce.\n * @param {Function|string} type - The target type (Constructor or string name).\n * @returns {any} The coerced value.\n */\nexport function coerce (value, type) {\n if (value === null || value === undefined) {\n return value\n }\n if (type === Number || type === 'Number') {\n return Number(value)\n }\n if (type === Boolean || type === 'Boolean') {\n if (value === '') {\n return true\n }\n return value !== 'false' && value !== null\n }\n if (type === String || type === 'String') {\n return String(value)\n }\n return value\n}\n\n/**\n * @typedef {Object} CoraliteComponentOptions\n * @property {string} componentId - The unique identifier for the component.\n * @property {string} [templateHTML] - The raw HTML string for imperative mounting.\n * @property {Object} [defaultValues] - The initial state values extracted from the server data block.\n * @property {Object} [attributes] - Schema for coercing HTML attributes into typed primitives.\n * @property {Object.<string, Function>} [getters] - Pure functions for derived state, supporting Promises.\n * @property {Object.<string, Function>} [slots] - Transformation functions for projected Light DOM.\n * @property {Function} [client] - The client-side controller logic.\n * @property {Object} [hydrationMap] - AST mapping for reactive text nodes, attributes, and refs.\n */\n\n/**\n * Base class for all Coralite custom elements.\n *\n * @augments HTMLElement\n */\nexport class CoraliteElement extends HTMLElement {\n /**\n * Initializes a new instance of the CoraliteElement.\n * Sets up internal state trackers, binding collections, and hook registries.\n */\n constructor () {\n super()\n /**\n * Controls native teardown of event listeners and async fetches upon disconnection.\n * @type {AbortController|null}\n * @protected\n */\n this._abortController = null\n\n /**\n * A globally unique, deterministic identifier (e.g., `my-comp-0`).\n * @type {string|null}\n * @protected\n */\n this._instanceId = null\n\n /**\n * The unified, deeply reactive proxy holding attributes, data, and getters.\n * @type {Object|null}\n * @protected\n */\n this._state = null\n\n /**\n * The collection of DOM nodes mapped to template tokens and attributes.\n * @type {Array<{type: string, node: Node, template?: string, name?: string}>}\n * @protected\n */\n this._bindings = []\n\n /**\n * Flag to prevent multiple synchronous state mutations from triggering multiple DOM paints.\n * @type {boolean}\n * @protected\n */\n this._isUpdatePending = false\n\n /**\n * A unique Symbol generated per render cycle to prevent async getter race conditions.\n * @type {symbol|null}\n * @protected\n */\n this._currentRenderVersion = null\n\n /**\n * @type {MutationObserver|null}\n * @protected\n */\n this._observer = null\n\n /**\n * Hook to fetch globally registered Phase-2 plugin contexts.\n * @type {Function|null}\n * @protected\n */\n this._clientContextGetter = null\n\n /**\n * Tracks AbortControllers specifically for cancelling stale async getters.\n * @type {Object.<string, AbortController>|null}\n * @protected\n */\n this._getterAbortControllers = null\n\n /**\n * Internal lifecycle hooks injected by registered Coralite plugins.\n * @type {{\n * onBeforeComponentRender: Array<CoraliteClientPluginBeforeComponentRenderCallback>,\n * onAfterComponentRender: Array<CoraliteClientPluginAfterComponentRenderCallback>,\n * onDisconnected: Array<CoraliteClientPluginDisconnectedCallback>\n * }}\n * @protected\n */\n this._hooks = {\n onBeforeComponentRender: [],\n onAfterComponentRender: [],\n onDisconnected: []\n }\n\n /**\n * The definition and schema of the component generated by the compiler.\n * @type {CoraliteComponentOptions|null}\n */\n this.componentOptions = null\n }\n\n /**\n * Invoked natively when the element is added to the document.\n * Handles the architectural split between Declarative (SSR) and Imperative (JS) components.\n * Orchestrates template injection, instance ID generation, and state/binding setup.\n */\n connectedCallback () {\n this._abortController = new AbortController()\n\n if (!this.componentOptions) {\n return\n }\n\n // Declarative components receive a data-cid from the server.\n // Imperative components (created via document.createElement) do not.\n const isImperative = !this.hasAttribute('data-cid')\n\n // Imperative Flow: Manually stamp the template and project the Light DOM.\n if (isImperative && this.componentOptions.templateHTML) {\n const originalLightDOM = Array.from(this.childNodes)\n this.innerHTML = processHTML(this.componentOptions.templateHTML)\n\n if (originalLightDOM.length > 0) {\n const slots = this.querySelectorAll('slot')\n slots.forEach(slot => {\n const slotName = slot.getAttribute('name') || 'default'\n const matchingNodes = originalLightDOM.filter(node => {\n // @ts-ignore\n const nodeSlot = (node.getAttribute && node.getAttribute('slot')) || 'default'\n return nodeSlot === slotName\n })\n matchingNodes.forEach(n => slot.appendChild(n))\n })\n }\n }\n\n // Establish the Deterministic Instance ID\n if (this.hasAttribute('data-cid')) {\n this._instanceId = this.getAttribute('data-cid')\n } else {\n // Fallback counter for imperatively created components\n // @ts-ignore\n window.__coralite_instanceCounters = window.__coralite_instanceCounters || {}\n const prefix = this.componentOptions.componentId\n // @ts-ignore\n if (window.__coralite_instanceCounters[prefix] === undefined) {\n // @ts-ignore\n window.__coralite_instanceCounters[prefix] = 0\n }\n // @ts-ignore\n this._instanceId = `${prefix}-${window.__coralite_instanceCounters[prefix]++}`\n }\n\n if (isImperative) {\n this.setAttribute('data-cid', this._instanceId)\n }\n\n this._setupState()\n this._setupBindings()\n this._init(isImperative)\n }\n\n /**\n * Invoked natively when the element is removed from the document.\n * Aborts pending requests and triggers `onDisconnected` plugin hooks\n * to ensure external libraries (e.g., Observers) do not cause memory leaks.\n * @this {any}\n */\n disconnectedCallback () {\n if (this._abortController) {\n this._abortController.abort()\n }\n\n if (!this.componentOptions) {\n return\n }\n\n for (const hook of this._hooks.onDisconnected) {\n hook({\n state: this._state,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n element: this,\n options: this.componentOptions\n })\n }\n }\n\n /**\n * Invoked natively when an observed HTML attribute changes.\n * Coerces the raw string value based on the component's attribute schema\n * and synchronizes it into the reactive state proxy.\n * @param {string} name - The kebab-case name of the attribute.\n * @param {string|null} oldVal - The previous value.\n * @param {string|null} newVal - The new value.\n */\n attributeChangedCallback (name, oldVal, newVal) {\n if (!this._state || oldVal === newVal || name === 'data-cid') {\n return\n }\n const camelName = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n const schema = this.componentOptions.attributes?.[camelName] || this.componentOptions.attributes?.[name]\n const value = schema ? coerce(newVal, schema.type) : newVal\n\n this._state[camelName] = value\n }\n\n /**\n * Constructs the unified state object.\n * Merges `defaultValues`, JSON hydration payloads, and DOM attributes.\n * Defines getters (wrapping state in a Read-Only proxy) and applies the final Read/Write Proxy.\n * @this {any}\n * @private\n */\n _setupState () {\n const options = this.componentOptions\n const target = { ...options.defaultValues }\n\n /** @type {Array<{name: string, element: HTMLElement}>} */\n const refs = []\n if (options.hydrationMap && options.hydrationMap.refs) {\n for (const ref of options.hydrationMap.refs) {\n const uniqueRefValue = `${this._instanceId}__${ref.name}`\n\n if (!target[`ref_${ref.name}`]) {\n target[`ref_${ref.name}`] = uniqueRefValue\n }\n\n const node = this.getNodeByPath(ref.path)\n if (node) {\n if (node.setAttribute) {\n node.setAttribute('ref', uniqueRefValue)\n }\n refs.push({\n name: ref.name,\n element: node\n })\n }\n }\n }\n\n // Trigger Before-Render hooks BEFORE state is proxied, allowing plugins to inject reactive data\n for (const hook of this._hooks.onBeforeComponentRender) {\n hook({\n state: target,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n refs,\n element: this,\n options: this.componentOptions\n })\n }\n\n // Process initial attributes mapping\n for (const attr of this.attributes) {\n if (attr.name === 'data-cid') {\n continue\n }\n const camelName = attr.name.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n const schema = options.attributes?.[camelName] || options.attributes?.[attr.name]\n target[camelName] = schema ? coerce(attr.value, schema.type) : attr.value\n }\n\n // Hydrate data() block results from the SSR JSON payload\n const hydrationTag = document.getElementById('__CORALITE_HYDRATION__')\n if (hydrationTag) {\n try {\n const allData = JSON.parse(hydrationTag.textContent)\n if (allData[this._instanceId]) {\n Object.assign(target, allData[this._instanceId])\n }\n } catch {\n console.error('Coralite Element hydration failed:', this._instanceId)\n }\n }\n\n // Define derived state getters with isolation controllers\n this._getterAbortControllers = {}\n for (const [key, getter] of Object.entries(options.getters || {})) {\n Object.defineProperty(target, key, {\n get: () => {\n if (this._getterAbortControllers[key]) {\n this._getterAbortControllers[key].abort()\n }\n this._getterAbortControllers[key] = new AbortController()\n\n // Enforce \"Dual-Proxy\" safety: Getters cannot mutate state\n const roState = createReadOnlyProxy(this._state)\n return getter(roState, { signal: this._getterAbortControllers[key].signal })\n },\n enumerable: true,\n configurable: true\n })\n }\n\n this._state = this._createReactiveProxy(target)\n }\n\n /**\n * Wraps the state target in a reactive Proxy.\n * Intercepts property setters to automatically batch and schedule DOM updates.\n * @param {Object} target - The state dictionary.\n * @returns {Proxy} The reactive state proxy.\n * @private\n */\n _createReactiveProxy (target) {\n const self = this\n return new Proxy(target, {\n set (t, p, v) {\n if (t[p] === v) {\n return true\n }\n t[p] = v\n self._scheduleUpdate()\n return true\n }\n })\n }\n\n /**\n * Traverses the DOM tree using an AST-generated path index array.\n * Allows O(1) element lookups without relying on querySelectors or classes.\n * @param {number[]} path - Array of childNode indices (e.g., `[0, 1, 2]`).\n * @returns {Node|null} The physical DOM node, or null if traversal fails.\n */\n getNodeByPath (path) {\n let node = this\n for (const index of path) {\n if (!node) {\n return null\n }\n // @ts-ignore\n node = node.childNodes[index]\n }\n return node\n }\n\n /**\n * Initializes DOM bindings based on the compiler's hydration map.\n * Caches physical DOM references to text nodes and attributes that contain template tokens.\n * @private\n */\n _setupBindings () {\n this._bindings = []\n const map = this.componentOptions.hydrationMap\n if (!map) {\n return\n }\n\n if (map.texts) {\n for (const item of map.texts) {\n const node = this.getNodeByPath(item.path)\n if (node) {\n this._bindings.push({\n type: item.type || 'text',\n node,\n template: item.template\n })\n }\n }\n }\n\n if (map.attributes) {\n for (const item of map.attributes) {\n const node = this.getNodeByPath(item.path)\n if (node) {\n this._bindings.push({\n type: 'attribute',\n node,\n name: item.name,\n template: item.template\n })\n }\n }\n }\n }\n\n /**\n * Schedules a DOM update in the next microtask queue.\n * This guarantees that multiple synchronous state mutations result in only one render pass.\n * @private\n */\n _scheduleUpdate () {\n if (this._isUpdatePending) {\n return\n }\n this._isUpdatePending = true\n queueMicrotask(() => {\n this._updateDOM()\n this._isUpdatePending = false\n })\n }\n\n /**\n * Performs the physical DOM update and resolves template tokens.\n * **Async Safety:** Implements a Symbol-based locking mechanism (`renderVersion`)\n * to guarantee that if state mutates while an async getter is pending, the stale\n * Promise will be discarded, preventing DOM race conditions.\n * @this {any}\n * @private\n */\n _updateDOM () {\n // Create a unique lock for this specific render cycle\n const renderVersion = Symbol()\n this._currentRenderVersion = renderVersion\n\n // Extract unique tokens to prevent double-reading and accidental aborts\n /** @type {Set<string>} */\n const requiredTokens = new Set()\n for (const binding of this._bindings) {\n binding.template.replace(/\\{\\{\\s*(.+?)\\s*\\}\\}/g, (_, key) => {\n requiredTokens.add(key)\n return ''\n })\n }\n\n const evaluatedTokens = {}\n let hasPromise = false\n\n // Evaluate getters exactly once per render cycle\n for (const key of requiredTokens) {\n let val = this._state[key]\n if (typeof val === 'function') {\n val = val(this._state)\n }\n evaluatedTokens[key] = val\n if (val instanceof Promise) {\n hasPromise = true\n }\n }\n\n // The DOM Mutator Function\n const applyBindings = (tokenValues) => {\n // Race Condition Lock: Abort if a newer render cycle has already begun\n if (this._currentRenderVersion !== renderVersion) {\n return\n }\n\n for (const binding of this._bindings) {\n const hydratedValue = binding.template.replace(/\\{\\{\\s*(.+?)\\s*\\}\\}/g, (_, key) => {\n return tokenValues[key] ?? ''\n })\n\n if (binding.type === 'text') {\n if (binding.node.textContent !== hydratedValue) {\n binding.node.textContent = hydratedValue\n }\n } else if (binding.type === 'html') {\n /** @type {HTMLElement} */\n // @ts-ignore\n const element = binding.node\n\n if (element.innerHTML !== hydratedValue) {\n element.innerHTML = hydratedValue\n }\n } else if (binding.type === 'attribute') {\n /** @type {HTMLElement} */\n // @ts-ignore\n const element = binding.node\n\n if (BOOLEAN_ATTRIBUTES.has(binding.name)) {\n const isFalsy = hydratedValue === '' || hydratedValue === 'false' || hydratedValue === 'null' || hydratedValue === '0' || hydratedValue === 'undefined'\n if (isFalsy) {\n element.removeAttribute(binding.name)\n } else {\n element.setAttribute(binding.name, '')\n }\n } else {\n if (element.getAttribute(binding.name) !== hydratedValue) {\n element.setAttribute(binding.name, hydratedValue)\n }\n }\n }\n }\n\n this._processSlots()\n\n // Trigger After-Render hooks ONLY after the physical DOM is stable\n for (const hook of this._hooks.onAfterComponentRender) {\n hook({\n state: this._state,\n instanceId: this._instanceId,\n componentId: this.componentOptions.componentId,\n element: this,\n options: this.componentOptions\n })\n }\n }\n\n // Await Promises or Apply Synchronously\n if (hasPromise) {\n const keys = Object.keys(evaluatedTokens)\n const promises = keys.map(k => Promise.resolve(evaluatedTokens[k]))\n\n Promise.all(promises).then(resolvedValues => {\n const resolvedMap = {}\n keys.forEach((k, i) => {\n resolvedMap[k] = resolvedValues[i]\n })\n applyBindings(resolvedMap)\n }).catch(e => {\n if (e.name !== 'AbortError') {\n console.error('Coralite Async Getter Error:', e)\n }\n })\n } else {\n applyBindings(evaluatedTokens)\n }\n }\n\n /**\n * Evaluates and projects Light DOM elements into their respective `<slot>` nodes.\n * Invokes component-specific slot transformation functions.\n * @private\n */\n _processSlots () {\n const slots = this.componentOptions.slots\n if (!slots || Object.keys(slots).length === 0) {\n return\n }\n\n const slotElements = this.querySelectorAll('slot')\n slotElements.forEach(slotEl => {\n const slotName = slotEl.getAttribute('name') || 'default'\n const slotFn = slots[slotName]\n\n if (slotFn) {\n // @ts-ignore\n if (!slotEl._originalNodes) {\n // @ts-ignore\n slotEl._originalNodes = Array.from(slotEl.childNodes).map(n => n.cloneNode(true))\n }\n\n // @ts-ignore\n const result = slotFn(slotEl._originalNodes, this._state)\n\n if (result === undefined) {\n return\n }\n\n if (result === null || result === '' || (Array.isArray(result) && result.length === 0)) {\n slotEl.innerHTML = ''\n return\n }\n\n if (typeof result === 'string') {\n slotEl.innerHTML = result\n } else if (Array.isArray(result)) {\n slotEl.replaceChildren(...result)\n }\n }\n })\n }\n\n /**\n * The final initialization pipeline.\n * Injects globally registered client plugins into the local context payload,\n * triggers the initial DOM render, and invokes the user's `script()` logic.\n * @param {boolean} [isImperative=false] - If true, initial render runs synchronously.\n * @private\n */\n async _init (isImperative = false) {\n const self = this\n /**\n * The context payload injected into the user's script block.\n * @type {Object}\n */\n let localContext = {\n instanceId: this._instanceId,\n state: this._state,\n root: this,\n signal: this._abortController.signal,\n refs (id) {\n const refId = self._state[`ref_${id}`]\n if (!refId && typeof refId !== 'string') {\n return null\n }\n return self.querySelector(`[ref=\"${refId}\"]`)\n }\n }\n\n if (typeof this._clientContextGetter === 'function') {\n localContext = await this._clientContextGetter(localContext)\n }\n\n if (isImperative) {\n this._updateDOM()\n } else {\n this._scheduleUpdate()\n }\n\n if (this.componentOptions.client) {\n try {\n this.componentOptions.client(localContext)\n } catch (error) {\n console.error(`Coralite Error: Component \"${this.componentOptions.componentId}\" script failed:`, error)\n }\n }\n }\n}\n\n/**\n * Factory function to create a Coralite element class.\n * It dynamically defines the class, including observed attributes and hook initialization.\n * @param {CoraliteComponentOptions} options - Component options and metadata.\n * @param {Function|null} [contextGetter=null] - Optional function to retrieve client-side plugin context.\n * @param {Object} [hooks={}] - Lifecycle hooks to register.\n * @param {Array<CoraliteClientPluginBeforeComponentRenderCallback>} [hooks.onBeforeComponentRender] - Hooks to run before render.\n * @param {Array<CoraliteClientPluginAfterComponentRenderCallback>} [hooks.onAfterComponentRender] - Hooks to run after render.\n * @param {Array<CoraliteClientPluginDisconnectedCallback>} [hooks.onDisconnected] - Hooks to run after render.\n * @returns {typeof CoraliteElement} A new CoraliteElement subclass.\n */\nexport function createCoraliteClass (options, contextGetter = null, hooks = {}) {\n return class extends CoraliteElement {\n /**\n * The attributes to observe for changes.\n * @returns {string[]} Array of attribute names.\n */\n static get observedAttributes () {\n if (!options.attributes) {\n return []\n }\n return Object.keys(options.attributes).map(key => key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()\n )\n }\n\n /**\n * Initializes the dynamic Coralite element.\n */\n constructor () {\n super()\n this.componentOptions = options\n this._clientContextGetter = contextGetter\n this._hooks = {\n onBeforeComponentRender: hooks.onBeforeComponentRender || [],\n onAfterComponentRender: hooks.onAfterComponentRender || [],\n onDisconnected: hooks.onDisconnected || []\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["target"]
7
7
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Creates a Coralite element or a standard HTML element.
3
+ * Proxy to window.createCoraliteElement or document.createElement.
4
+ *
5
+ * @param {string} tag - The tag name.
6
+ * @param {Object} [options] - Optional element options.
7
+ * @returns {HTMLElement} The created element.
8
+ */
9
+ export function createCoraliteElement(tag: string, options?: any): HTMLElement;
10
+ /**
11
+ * Processes an HTML string for custom elements.
12
+ * Proxy to window.processHTML if available.
13
+ *
14
+ * @param {string} html - The HTML string.
15
+ * @returns {string} The HTML string.
16
+ */
17
+ export function processHTML(html: string): string;
18
+ import { defineComponent } from '../core.js';
19
+ import { definePlugin } from '../../plugin.js';
20
+ export { defineComponent, definePlugin };
21
+ //# sourceMappingURL=inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../../../lib/utils/client/inject.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,2CAJW,MAAM,kBAEJ,WAAW,CASvB;AAED;;;;;;GAMG;AACH,kCAHW,MAAM,GACJ,MAAM,CASlB;gCAlC+B,YAAY;6BACf,iBAAiB"}
@@ -65,7 +65,7 @@ export type CoraliteModule = {
65
65
  * Represents a single value that a module can store or process.
66
66
  */
67
67
  export type CoraliteModuleDefinition = string | number | boolean | string[] | (CoraliteDirective | CoraliteAnyNode)[] | {
68
- [x: string]: string;
68
+ [x: string]: any;
69
69
  };
70
70
  /**
71
71
  * A collection of module values associated with a module.
@@ -74,6 +74,7 @@ export type CoraliteModuleDefinitions = {
74
74
  [x: string]: CoraliteModuleDefinition;
75
75
  } & {
76
76
  __script__?: ScriptContent;
77
+ page?: CoralitePage;
77
78
  };
78
79
  /**
79
80
  * Defines a slot element and its configuration within a module.
@@ -102,6 +103,7 @@ import type { CoraliteComponentValues } from './component.js';
102
103
  import type { CoraliteDirective } from './dom.js';
103
104
  import type { CoraliteAnyNode } from './dom.js';
104
105
  import type { ScriptContent } from './script.js';
106
+ import type { CoralitePage } from './core.js';
105
107
  import type { CoraliteScriptContext } from './script.js';
106
108
  import type { CoralitePluginContext } from './plugin.js';
107
109
  //# sourceMappingURL=module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../types/module.js"],"names":[],"mappings":";;;;;;;;;SAYc,MAAM;;;;WACN,gBAAgB;;;;iBAChB,MAAM;;;;eACN,eAAe;;;;aACf,MAAM,GAAC,SAAS;;;;aAChB,MAAM,EAAE;;;;aACR,uBAAuB;;;;qBACvB,eAAe,EAAE;;;;;;;;;;;;gBAEjB,OAAO;;;;kBACP,GAAG,CAAC,MAAM,CAAC;;;;wBACX,GAAG,CAAC,MAAM,CAAC;;;;oBACX,MAAM,EAAE;;;;;uCAKT,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,CAAC,iBAAiB,GAAG,eAAe,CAAC,EAAE,GAAG;QAAQ,MAAM,GAAE,MAAM;CAAC;;;;wCAKxG;QAAQ,MAAM,GAAE,wBAAwB;CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,aAAa,CAAA;CAAE;;;;;;;;UAMzE,MAAM;;;;aACN,eAAe;;6CAKlB,qBAAqB;yDAKrB,qBAAqB,KACnB,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,GAAG,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,CAAC;mDAK/I,qBAAqB,KACnB,MAAS,OAAO,KAAQ;mDAK1B,yBAAyB,YAEjC;IAA8B,MAAM,GAA5B,WAAW;CACnB,KAAU,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;uCAIlB,yBAAyB,GAAG,gCAAgC;qDAK9D,eAAe,EAAE,SACjB,yBAAyB,KACvB,eAAe,EAAE,GAAG,MAAM,GAAG,IAAI;sCA1EW,WAAW;qCADI,UAAU;6CAEzB,gBAAgB;uCAFD,UAAU;qCAAV,UAAU;mCAGzB,aAAa;2CAAb,aAAa;2CAC5B,aAAa"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../types/module.js"],"names":[],"mappings":";;;;;;;;;SAYc,MAAM;;;;WACN,gBAAgB;;;;iBAChB,MAAM;;;;eACN,eAAe;;;;aACf,MAAM,GAAC,SAAS;;;;aAChB,MAAM,EAAE;;;;aACR,uBAAuB;;;;qBACvB,eAAe,EAAE;;;;;;;;;;;;gBAEjB,OAAO;;;;kBACP,GAAG,CAAC,MAAM,CAAC;;;;wBACX,GAAG,CAAC,MAAM,CAAC;;;;oBACX,MAAM,EAAE;;;;;uCAKT,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,CAAC,iBAAiB,GAAG,eAAe,CAAC,EAAE,GAAG;QAAQ,MAAM,GAAE,GAAG;CAAC;;;;wCAKrG;QAAQ,MAAM,GAAE,wBAAwB;CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,aAAa,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,CAAA;CAAE;;;;;;;;UAM9F,MAAM;;;;aACN,eAAe;;6CAKlB,qBAAqB;yDAKrB,qBAAqB,KACnB,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,GAAG,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,CAAC;mDAK/I,qBAAqB,KACnB,MAAS,OAAO,KAAQ;mDAK1B,yBAAyB,YAEjC;IAA8B,MAAM,GAA5B,WAAW;CACnB,KAAU,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;uCAIlB,yBAAyB,GAAG,gCAAgC;qDAK9D,eAAe,EAAE,SACjB,yBAAyB,KACvB,eAAe,EAAE,GAAG,MAAM,GAAG,IAAI;sCA1EyB,WAAW;qCADV,UAAU;6CAEzB,gBAAgB;uCAFD,UAAU;qCAAV,UAAU;mCAGzB,aAAa;kCAFC,WAAW;2CAEzB,aAAa;2CAC5B,aAAa"}
package/llms.txt CHANGED
@@ -12,7 +12,7 @@ When generating code or answering questions about Coralite, you MUST adhere to t
12
12
  **CRITICAL RULE:** You cannot use top-level imports or variables (declared outside `defineComponent`) directly inside the `client` block. The `client` block is serialized and sent to the browser. To bridge server-side data to the client, you must use the `server` block.
13
13
 
14
14
  ## 2. File Structure: Pages vs. Components
15
- * **Pages**: Pages are standard `.html` files (e.g., `index.html`) that serve as route entry points. They act as the **consumers** of components by declaring custom element tags within their HTML body (e.g., `<my-navbar></my-navbar>`).
15
+ * **Pages**: Pages are standard `.html` files (e.g., `index.html`) that serve as route entry points. They act as the **consumers** of components by declaring custom element tags within their HTML body (e.g., `<my-navbar></my-navbar>`). **Pages are strictly consumers; they should never contain logic to manipulate or query component internals.**
16
16
  * **Components**: A Coralite component is strictly an `.html` file. It is not a `.js` or `.jsx` file. A component file consists of up to three top-level root tags:
17
17
  1. `<template id="component-name">` (**Required**): Defines the declarative HTML structure.
18
18
  2. `<style>` (**Optional**): Defines component-specific styles.
@@ -36,6 +36,8 @@ Static components are purely HTML-based elements without scripting logic.
36
36
  Dynamic components are authored by appending a `<script type="module">` below the `<template>`, exporting the core `defineComponent` helper.
37
37
 
38
38
  ### 5.1 Anti-Patterns
39
+
40
+ ### 5.1.1 Vanilla Boilerplate
39
41
  When generating code for Coralite components, **DO NOT** use standard Web Component boilerplate.
40
42
 
41
43
  **❌ BAD (Vanilla Web Component):**
@@ -59,6 +61,18 @@ export default defineComponent({
59
61
  })
60
62
  ```
61
63
 
64
+ ### 5.1.2 Breaking the Component Boundary
65
+ **CRITICAL RULE:** Pages are consumers of components. Any interaction with components from the page (or from other components via the DOM) is an anti-pattern.
66
+
67
+ * **❌ BAD: Querying Component Internals:** Do not use `querySelector` or `getElementById` from a page script to find an element *inside* a component. Component selectors (like classes or internal IDs) are unreliable because Coralite uses `ref` to dynamically create unique, namespaced selectors.
68
+ * **❌ BAD: Page-Level Scripts for Components:** Avoid using `<script>` tags in standard `.html` pages to manipulate components.
69
+ * **❌ BAD: Direct Attribute Manipulation:** Do not attempt to manually update a component's attributes from a page script to trigger changes.
70
+
71
+ **✅ GOOD: Reserved Component Logic:**
72
+ * **Internal Logic:** All logic related to a component's behavior must live inside its own `client` block.
73
+ * **Coordination:** If multiple components need to coordinate, move that logic into a "parent" component that encapsulates them.
74
+ * **Reliable Targeting:** Use the `refs` system inside the `client` block to target elements. This is the only reliable way to select elements within a component.
75
+
62
76
  ### 5.2 Component Structure: Isolated Blocks
63
77
 
64
78
  A component definition consists of four primary blocks:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coralite",
3
- "version": "0.38.2",
3
+ "version": "0.38.3",
4
4
  "description": "HTML modules static site generator",
5
5
  "type": "module",
6
6
  "keywords": [