chispa 0.8.2 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 José Carlos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,36 +1,37 @@
1
- # Chispa
1
+ # Chispa [![npm version](https://img.shields.io/npm/v/chispa.svg?style=flat)](https://www.npmjs.com/package/chispa)
2
2
 
3
- Un motor UI reactivo y extremadamente minimalista.
3
+ Un motor UI reactivo, extremadamente minimalista y sorprendentemente potente.
4
4
 
5
- Chispa no es un framework dogmático: es un motor ligero que expone reactividad mínima sobre DOM real, pensado para integrarse, incrustarse y usarse desde herramientas y entornos donde las capas pesadas sobran.
5
+ Chispa nació de la frustración tras años utilizando los frameworks más populares (como React o Angular) y no encontrar ninguno que me convenciese plenamente en todos los aspectos. Se ha construido destilando lo mejor de cada uno, sumando ideas propias y eliminando sistemáticamente todo lo que sobra.
6
6
 
7
- **Principio**: la función del componente se ejecuta una vez; el resto es flujo de datos (signals DOM).
7
+ El resultado es un motor que pone el foco en la **simpleza absoluta y la limpieza del código**. No es solo un motor para pequeños módulos; tras migrar proyectos complejos a Chispa, la experiencia ha demostrado que el código resultante es mucho más legible, mantenible y libre de la "magia" impredecible de otros frameworks.
8
8
 
9
- **¿Para quién es chispa?**
9
+ **Principio fundamental**: la función del componente se ejecuta una sola vez; el resto es flujo puro de datos (**signals → DOM**).
10
10
 
11
- - Ideal para desarrolladores que necesitan control directo del DOM y baja complejidad mental.
12
- - Perfecto para IDEs, plugins, paneles embebidos, dashboards y UIs que requieren integración con código legado.
11
+ ## ¿Por qué elegir Chispa?
13
12
 
14
- **¿Para qué NO es chispa?**
13
+ - **Baja complejidad mental**: Olvídate de ciclos de vida opacos, re-renders infinitos o hooks con reglas complejas.
14
+ - **Control total**: Tienes acceso directo al DOM real y a las plantillas HTML, sin las abstracciones pesadas de un Virtual DOM.
15
+ - **Código limpio**: Al separar la estructura HTML de la lógica TS y usar señales precisas, el código se vuelve declarativo y extremadamente fácil de seguir.
16
+ - **Rendimiento nativo**: Solo se actualiza el nodo exacto que cambia. Eficiencia máxima por diseño.
17
+ - **HTML real**: Plantillas HTML puras importadas, sin JSX ni transformaciones mágicas.
18
+ - **TS/JS de un solo paso**: Las funciones de componente se ejecutan una vez (setup), eliminando problemas de estado efímero en cada render.
19
+ - **Bindings precisos signal → DOM**: Actualizaciones atómicas sin heurísticas de comparación de árboles.
20
+ - **Motor embebible**: Sin arquitectura impuesta; perfecto tanto para aplicaciones completas como para ser incrustado en sistemas existentes.
21
+ - **Ligero**: Sin dependencias en tiempo de ejecución.
22
+ - **Integración con Vite**: Incluye un plugin de Vite para una experiencia de desarrollo fluida.
15
23
 
16
- - No pretende (de momento) sustituir un framework de aplicación completo (SSR complejo, abstracciones de estado a gran escala).
24
+ ## Crear un nuevo proyecto
17
25
 
18
- ## Diferenciadores
26
+ Puedes crear rápidamente un nuevo proyecto de chispa lanzando el comando:
19
27
 
20
- - **HTML real**: plantillas HTML importadas, sin JSX ni transformaciones mágicas.
21
- - **JS/TS real**: funciones de componente normales (se ejecutan una vez) y señales explícitas.
22
- - **Bindings directos signal → DOM**: actualizaciones precisas sin VDOM ni heurísticas.
23
- - **Motor embebible**: sin lifecycle complejo ni arquitectura impuesta; fácil de integrar y depurar.
24
-
25
- ## Características
28
+ ```bash
29
+ npx create-chispa my-app
30
+ ```
26
31
 
27
- - **Reactividad Fina**: Basado en Signals para actualizaciones precisas y eficientes del DOM.
28
- - 🧩 **Componentes Funcionales**: Crea componentes reutilizables con funciones simples.
29
- - 📄 **Plantillas HTML**: Separa la lógica de la vista importando archivos HTML directamente.
30
- - 🛠️ **Integración con Vite**: Incluye un plugin de Vite para una experiencia de desarrollo fluida.
31
- - 📦 **Ligero**: Sin dependencias pesadas en tiempo de ejecución.
32
+ ## Setup manual
32
33
 
33
- ## Instalación
34
+ ### Instalación
34
35
 
35
36
  Instala `chispa` en tu proyecto:
36
37
 
@@ -38,7 +39,7 @@ Instala `chispa` en tu proyecto:
38
39
  npm install chispa
39
40
  ```
40
41
 
41
- ## Configuración (Vite)
42
+ ### Configuración (Vite)
42
43
 
43
44
  Para usar las plantillas HTML, necesitas configurar el plugin de Chispa en tu `vite.config.ts`:
44
45
 
@@ -94,12 +95,14 @@ export const MyComponent = component(() => {
94
95
 
95
96
  // Retorna el fragmento enlazando los elementos del HTML
96
97
  return tpl.fragment({
97
- // Enlaza el contenido del span con la señal
98
+ // Enlaza el contenido directamente con la señal
98
99
  countDisplay: { inner: count },
99
100
 
100
- // Enlaza el evento click del botón
101
101
  incrementBtn: {
102
+ // Enlaza el evento click del botón
102
103
  onclick: () => count.update((v) => v + 1),
104
+ // Enlaza una propiedad con una función reactiva
105
+ disabled: () => count.get() >= 10,
103
106
  },
104
107
  });
105
108
  });
@@ -118,28 +121,6 @@ import { MyComponent } from './my-component';
118
121
  appendChild(document.body, MyComponent());
119
122
  ```
120
123
 
121
- ## API Principal
122
-
123
- ### Reactividad
124
-
125
- - **`signal(initialValue)`**: Crea una señal reactiva.
126
-
127
- ```typescript
128
- const count = signal(0);
129
- console.log(count.get()); // Leer valor
130
- count.set(5); // Establecer valor
131
- ```
132
-
133
- - **`computed(() => ...)`**: Crea una señal derivada que se actualiza automáticamente cuando sus dependencias cambian.
134
- ```typescript
135
- const double = computed(() => count.get() * 2);
136
- ```
137
-
138
- ### Componentes
139
-
140
- - **`component<Props>((props) => ...)`**: Define un nuevo componente.
141
- - **`appendChild(parent, child)`**: Función auxiliar para montar componentes en el DOM.
142
-
143
124
  ## Licencia
144
125
 
145
126
  MIT
@@ -297,7 +297,8 @@ async function findAndCompileHtmlFiles(dir, rootDir) {
297
297
  import { transformWithEsbuild } from "vite";
298
298
  import * as fs2 from "fs";
299
299
  var toVirtualId = (id) => "\0" + id + ".chispa.ts";
300
- var fromVirtualId = (id) => id.replace(/^\0/, "").replace(".chispa.ts", "");
300
+ var fromVirtualId = (id) => id.replace(/^\0/, "").replace(/\.chispa\.ts$/, "");
301
+ var CHISPA_VIRTUAL_MODULE_SUFFIX = ".html.chispa.ts";
301
302
  function chispaHtmlPlugin() {
302
303
  let rootDir = process.cwd();
303
304
  return {
@@ -320,7 +321,7 @@ function chispaHtmlPlugin() {
320
321
  }
321
322
  },
322
323
  async resolveId(source, importer, options) {
323
- if (source.endsWith(".html.chispa.ts")) {
324
+ if (source.endsWith(CHISPA_VIRTUAL_MODULE_SUFFIX)) {
324
325
  return source;
325
326
  }
326
327
  if (source.endsWith(".html") && importer) {
@@ -332,24 +333,24 @@ function chispaHtmlPlugin() {
332
333
  return null;
333
334
  },
334
335
  async load(id) {
335
- if (id.endsWith(".html.chispa.ts")) {
336
- const realId = fromVirtualId(id);
337
- try {
338
- const content = fs2.readFileSync(realId, "utf-8");
339
- if (content.includes("<!DOCTYPE html>") || content.includes("<html")) {
340
- return "export default {};";
341
- }
342
- const compiler = new HtmlCompiler(content);
343
- const { ts } = await compiler.compile();
344
- generateTypes(realId, content, rootDir);
345
- const result = await transformWithEsbuild(ts, realId, {
346
- loader: "ts"
347
- });
348
- return result.code;
349
- } catch (e) {
350
- console.error(`[chispa] Error loading ${id}:`, e);
351
- throw e;
336
+ if (!id.endsWith(CHISPA_VIRTUAL_MODULE_SUFFIX)) return null;
337
+ const realId = fromVirtualId(id);
338
+ this.addWatchFile(realId);
339
+ try {
340
+ const content = fs2.readFileSync(realId, "utf-8");
341
+ if (content.includes("<!DOCTYPE html>") || content.includes("<html")) {
342
+ return "export default {};";
352
343
  }
344
+ const compiler = new HtmlCompiler(content);
345
+ const { ts } = await compiler.compile();
346
+ generateTypes(realId, content, rootDir);
347
+ const result = await transformWithEsbuild(ts, realId, {
348
+ loader: "ts"
349
+ });
350
+ return result.code;
351
+ } catch (e) {
352
+ console.error(`[chispa] Error loading ${id}:`, e);
353
+ throw e;
353
354
  }
354
355
  }
355
356
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/html-compiler/html-compiler.ts","../../src/html-compiler/generator.ts","../../src/html-compiler/vite-plugin.ts"],"sourcesContent":["import { JSDOM } from 'jsdom';\nimport { format } from 'prettier';\n\nconst VOID_ELEMENTS = ['area', 'base', 'br', 'hr', 'img', 'input', 'link', 'meta', 'param', 'keygen', 'source'];\n\nconst SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\nexport class HtmlCompiler {\n\tprivate components: Record<string, string> = {};\n\tprivate stack: string[] = ['fragment'];\n\tprivate componentsItems: Record<string, string[]> = {};\n\tprivate componentsTags: Record<string, string> = {};\n\tprivate isSvg: Record<string, boolean> = {};\n\tprivate inSvgContext = 0;\n\tprivate htmlDocument: Document;\n\n\tconstructor(htmlContent: string) {\n\t\tconst dom = new JSDOM(htmlContent);\n\t\tthis.htmlDocument = dom.window.document;\n\t}\n\n\tprivate static camelize(str: string): string {\n\t\tif (str.startsWith('--')) {\n\t\t\treturn str;\n\t\t}\n\t\tconst arr = str.split('-');\n\t\tlet camelized = '';\n\t\tarr.forEach((v, i) => {\n\t\t\tcamelized += i === 0 ? v : v.charAt(0).toUpperCase() + v.slice(1);\n\t\t});\n\t\treturn camelized;\n\t}\n\n\tprivate static parseStyle(cssCode: string): string {\n\t\tlet out = '{';\n\t\tconst styles = cssCode.split(';');\n\t\tstyles.forEach((line) => {\n\t\t\tconst parts = line.split(':');\n\t\t\tif (parts.length !== 2) return;\n\t\t\tconst prop = HtmlCompiler.camelize(parts[0].trim());\n\t\t\tout += ` ${prop}: '${parts[1].trim()}',`;\n\t\t});\n\t\tout += '}';\n\t\treturn out;\n\t}\n\n\tprivate makeClassAttr(classAttr: string | null, isComponent: boolean): string {\n\t\tconst tplClasses = (classAttr || '').split(' ');\n\t\tlet finalClass = '';\n\n\t\ttplClasses.forEach((tplClass) => {\n\t\t\tif (!tplClass.startsWith('-tpl--')) {\n\t\t\t\tfinalClass += tplClass + ' ';\n\t\t\t}\n\t\t});\n\n\t\tfinalClass = finalClass.trim();\n\n\t\treturn ` 'class': \"${finalClass}\", `;\n\t}\n\n\tprivate getHtmlNodeAttrs(domNode: Element, isComponent: boolean): string {\n\t\tlet attrsHtml = '{';\n\t\tattrsHtml += this.makeClassAttr(domNode.getAttribute('class'), isComponent);\n\n\t\tArray.from(domNode.attributes).forEach((attr) => {\n\t\t\tconst attrName = attr.name;\n\t\t\tlet attrValue = attr.value;\n\n\t\t\tif (attrName === 'data-cb') return;\n\t\t\tif (attrName === 'class') return;\n\n\t\t\t// Use JSON.stringify to properly escape newlines, quotes and other characters\n\t\t\tconst valueLiteral = JSON.stringify(attrValue);\n\n\t\t\t// Simplified logic compared to PHP which had cbt.prefixize... calls\n\t\t\t// Assuming we just output the value for now as I don't see cbt implementation here\n\t\t\t// The PHP code imported CoreBuilderTools but here we might not have it.\n\t\t\t// The user's example output imports from 'chispa'.\n\t\t\t// I will stick to simple string values for now unless I see cbt in chispa.\n\n\t\t\tif (attrName === 'style') {\n\t\t\t\t// PHP called cbt.prefixizeStyle, but also had parse_style static method.\n\t\t\t\t// Wait, the PHP code used cbt.prefixizeStyle inside get_html_node_attrs.\n\t\t\t\t// But parse_style was defined but not used in the snippet I read?\n\t\t\t\t// Ah, I should check if I should use parseStyle or just output string.\n\t\t\t\t// The PHP code: $attrs_html .= \" '$attr_name': cbt.prefixizeStyle('$attr_value'), \";\n\t\t\t\t// If cbt is a runtime helper, I should output the call.\n\t\t\t\t// But wait, the generated code imports CoreBuilderTools.\n\t\t\t\t// Does 'chispa' export CoreBuilderTools?\n\t\t\t\t// src/index.ts does NOT export CoreBuilderTools.\n\t\t\t\t// It exports appendChild, getItem, etc.\n\t\t\t\t// Maybe I should just output the string for now.\n\t\t\t\tattrsHtml += ` '${attrName}': ${valueLiteral}, `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': ${valueLiteral}, `;\n\t\t\t}\n\t\t});\n\n\t\tattrsHtml += '}';\n\t\treturn attrsHtml;\n\t}\n\n\tprivate buildTsForNode(domNode: Node, isComponent = false): string {\n\t\tlet htmlNodeCode = '';\n\n\t\tif (domNode.nodeType === 1) {\n\t\t\t// Element\n\t\t\tconst element = domNode as Element;\n\t\t\tlet tagName = element.tagName;\n\n\t\t\tif (tagName === 'svg') {\n\t\t\t\tthis.inSvgContext++;\n\t\t\t}\n\n\t\t\tlet cbid = element.getAttribute('data-cb');\n\n\t\t\tif (cbid) {\n\t\t\t\tconst currComp = this.stack[0];\n\t\t\t\telement.removeAttribute('data-cb');\n\t\t\t\tcbid = HtmlCompiler.camelize(cbid);\n\t\t\t\t// Pushear a todos los padres\n\t\t\t\tfor (const comp of this.stack) {\n\t\t\t\t\tif (!this.componentsItems[comp]) {\n\t\t\t\t\t\tthis.componentsItems[comp] = [];\n\t\t\t\t\t}\n\t\t\t\t\tthis.componentsItems[comp].push(cbid);\n\t\t\t\t}\n\n\t\t\t\tthis.stack.unshift(cbid);\n\t\t\t\tthis.components[cbid] = this.buildTsForNode(element, true);\n\t\t\t\tthis.componentsTags[cbid] = element.tagName;\n\t\t\t\tthis.isSvg[cbid] = this.inSvgContext > 0;\n\t\t\t\tthis.stack.shift();\n\n\t\t\t\tif (currComp === 'fragment') {\n\t\t\t\t\thtmlNodeCode += `getItem(template, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(template, props.nodes, '${cbid}')`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst attrs = this.getHtmlNodeAttrs(element, isComponent);\n\n\t\t\t\tif (!this.inSvgContext) {\n\t\t\t\t\ttagName = tagName.toLowerCase();\n\t\t\t\t\thtmlNodeCode += `(() => { const node = document.createElement('${tagName}');\\n`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `(() => { const node = document.createElementNS('${SVG_NAMESPACE}', '${tagName}');\\n`;\n\t\t\t\t}\n\n\t\t\t\thtmlNodeCode += `setAttributes(node, ${attrs});\\n`;\n\t\t\t\tif (isComponent) {\n\t\t\t\t\thtmlNodeCode += `setProps(node, props);\\n`;\n\t\t\t\t}\n\n\t\t\t\tlet subTs = '';\n\t\t\t\telement.childNodes.forEach((child) => {\n\t\t\t\t\tconst chCode = this.buildTsForNode(child);\n\t\t\t\t\tif (chCode) {\n\t\t\t\t\t\tsubTs += `appendChild(node, ${chCode});\\n`;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (!VOID_ELEMENTS.includes(tagName.toLowerCase())) {\n\t\t\t\t\tif (isComponent) {\n\t\t\t\t\t\thtmlNodeCode += `\n if (props.inner === null) {\n node.innerHTML = '';\n } else if (props.inner !== undefined) {\n node.innerHTML = '';\n appendChild(node, props.inner);\n } else {\n ${subTs}\n }\n `;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thtmlNodeCode += subTs;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isComponent) {\n\t\t\t\t\thtmlNodeCode += `if (typeof props._ref === 'function') props._ref(node);\\n`;\n\t\t\t\t}\n\n\t\t\t\thtmlNodeCode += `return node;})()`;\n\n\t\t\t\tif (tagName === 'svg') {\n\t\t\t\t\tthis.inSvgContext--;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (domNode.nodeType === 3) {\n\t\t\t// Text\n\t\t\tconst textNode = domNode as Text;\n\t\t\tconst parent = textNode.parentNode as Element;\n\t\t\tconst parentTag = parent ? parent.tagName.toLowerCase() : '';\n\n\t\t\tconst mustOmit = ['table', 'thead', 'tbody', 'tfoot', 'tr'].includes(parentTag);\n\n\t\t\tif (!mustOmit && textNode.textContent) {\n\t\t\t\tif (textNode.textContent.trim() === '') {\n\t\t\t\t\tif (textNode.textContent.length > 0) {\n\t\t\t\t\t\thtmlNodeCode += `document.createTextNode(' ')`;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode = `document.createTextNode(${JSON.stringify(textNode.textContent)})`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn htmlNodeCode.trim();\n\t}\n\n\tprivate static getPropsTypename(cbid: string): string {\n\t\treturn 'Cb' + cbid.charAt(0).toUpperCase() + cbid.slice(1) + 'Props';\n\t}\n\n\tprivate wrapFnComponent(cbid: string, jsx: string): string {\n\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\t\treturn `(props: ${typename}) => { \\n return(${jsx}); \\n }`;\n\t}\n\n\tprivate createAllComponents() {\n\t\tconst body = this.htmlDocument.querySelector('body');\n\t\tif (!body) throw new Error('Not valid HTML');\n\n\t\tlet rendererJsx = '(() => { const fragment = document.createDocumentFragment();\\n';\n\n\t\tbody.childNodes.forEach((child) => {\n\t\t\tconst chCode = this.buildTsForNode(child);\n\t\t\tif (chCode) {\n\t\t\t\trendererJsx += `appendChild(fragment, ${chCode});\\n`;\n\t\t\t}\n\t\t});\n\n\t\trendererJsx += 'return fragment;\\n';\n\t\trendererJsx += '})()';\n\n\t\tthis.components['fragment'] = rendererJsx;\n\t}\n\n\tprivate getTypedef(cbid: string): string {\n\t\tconst items = this.componentsItems[cbid] || [];\n\t\tlet itemsType = '{\\n';\n\t\titems.forEach((itemCbid) => {\n\t\t\tconst itemTypename = HtmlCompiler.getPropsTypename(itemCbid);\n\t\t\titemsType += `${itemCbid}?: ${itemTypename} | ChispaContentReactive;\\n`;\n\t\t});\n\t\titemsType += '}\\n';\n\n\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\n\t\tif (cbid === 'fragment') {\n\t\t\treturn `interface ${typename} ${itemsType}`;\n\t\t} else {\n\t\t\tconst tagname = this.componentsTags[cbid];\n\t\t\tif (this.isSvg[cbid]) {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderPropsReactive<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderPropsReactive<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async compile(): Promise<{ ts: string; dts: string }> {\n\t\tthis.createAllComponents();\n\n\t\tlet componentsClasses = '';\n\t\tlet typedefs = '';\n\n\t\tfor (const [cbid, compJsx] of Object.entries(this.components)) {\n\t\t\ttypedefs += this.getTypedef(cbid) + '\\n';\n\t\t\tcomponentsClasses += `${cbid}: ${this.wrapFnComponent(cbid, compJsx)},\\n`;\n\t\t}\n\n\t\tconst jsOutput = `\n import { appendChild, getItem, setAttributes, setProps } from 'chispa';\n import type { ChispaContentReactive, ChispaNodeBuilderPropsReactive } from 'chispa';\n\t\t\t\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const template = {\n ${componentsClasses}\n };\n \n export default template;\n `;\n\n\t\tconst dtsOutput = `\n import type { ChispaContentReactive, ChispaNodeBuilderPropsReactive } from 'chispa';\n \n ${typedefs}\n \n declare const template: {\n ${Object.keys(this.components)\n\t\t\t\t\t.map((cbid) => {\n\t\t\t\t\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\t\t\t\t\t\treturn `${cbid}: (props: ${typename}) => Node | DocumentFragment;`;\n\t\t\t\t\t})\n\t\t\t\t\t.join('\\n')}\n };\n \n export default template;\n `;\n\n\t\tconst prettierOptions = {\n\t\t\tparser: 'typescript',\n\t\t\tsemi: true,\n\t\t\tsingleQuote: true,\n\t\t\tuseTabs: true,\n\t\t\tprintWidth: 120,\n\t\t};\n\n\t\treturn {\n\t\t\tts: await format(jsOutput, prettierOptions),\n\t\t\tdts: await format(dtsOutput, prettierOptions),\n\t\t};\n\t}\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport async function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = await compiler.compile();\n\n\t\tconst outDir = path.join(rootDir, '.chispa/types');\n\t\tconst relativePath = path.relative(rootDir, filePath);\n\t\tconst targetPath = path.join(outDir, relativePath + '.d.ts');\n\t\tconst targetDir = path.dirname(targetPath);\n\n\t\tif (!fs.existsSync(targetDir)) {\n\t\t\tfs.mkdirSync(targetDir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(targetPath, dts);\n\t} catch (e) {\n\t\tconsole.error(`[chispa] Error generating types for ${filePath}`, e);\n\t}\n}\n\nexport async function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfor (const file of files) {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) continue;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tawait findAndCompileHtmlFiles(fullPath, rootDir);\n\t\t\t}\n\t\t} else if (file.endsWith('.html')) {\n\t\t\tconsole.log('Generating types for', fullPath);\n\t\t\tconst content = fs.readFileSync(fullPath, 'utf-8');\n\t\t\tawait generateTypes(fullPath, content, rootDir);\n\t\t}\n\t}\n}\n","import { HtmlCompiler } from './html-compiler';\nimport { generateTypes, findAndCompileHtmlFiles } from './generator';\nimport { type Plugin, transformWithEsbuild } from 'vite';\nimport * as fs from 'fs';\n\n/**\n * Convierte una ruta real de archivo en el ID de módulo virtual que usa Vite/Rollup.\n * Añade el prefijo `\\0` para marcar el módulo como virtual y el sufijo\n * `.chispa.ts` para que sea tratado como módulo TypeScript.\n */\nconst toVirtualId = (id: string) => '\\0' + id + '.chispa.ts';\n\n/**\n * Convierte un ID de módulo virtual de vuelta a la ruta real del archivo.\n * Elimina el prefijo `\\0` (si existe) y el sufijo `.chispa.ts`.\n */\nconst fromVirtualId = (id: string) => id.replace(/^\\0/, '').replace('.chispa.ts', '');\n\nexport function chispaHtmlPlugin(): Plugin {\n\tlet rootDir = process.cwd();\n\n\treturn {\n\t\tname: 'chispa-html',\n\t\tenforce: 'pre',\n\t\tconfigResolved(config) {\n\t\t\trootDir = config.root;\n\t\t},\n\t\tasync buildStart() {\n\t\t\tawait findAndCompileHtmlFiles(rootDir, rootDir);\n\t\t},\n\t\tasync handleHotUpdate(ctx) {\n\t\t\tif (ctx.file.endsWith('.html')) {\n\t\t\t\tconst content = await ctx.read();\n\t\t\t\tawait generateTypes(ctx.file, content, rootDir);\n\n\t\t\t\t// Buscamos el módulo virtual asociado al archivo HTML modificado.\n\t\t\t\tconst module = ctx.server.moduleGraph.getModuleById(toVirtualId(ctx.file));\n\t\t\t\tif (module) {\n\t\t\t\t\treturn [module];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync resolveId(source, importer, options) {\n\t\t\tif (source.endsWith('.html.chispa.ts')) {\n\t\t\t\treturn source;\n\t\t\t}\n\t\t\tif (source.endsWith('.html') && importer) {\n\t\t\t\tconst resolution = await this.resolve(source, importer, { skipSelf: true, ...options });\n\t\t\t\tif (resolution && !resolution.external) {\n\t\t\t\t\treturn toVirtualId(resolution.id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tasync load(id) {\n\t\t\tif (id.endsWith('.html.chispa.ts')) {\n\t\t\t\tconst realId = fromVirtualId(id);\n\t\t\t\ttry {\n\t\t\t\t\tconst content = fs.readFileSync(realId, 'utf-8');\n\t\t\t\t\tif (content.includes('<!DOCTYPE html>') || content.includes('<html')) {\n\t\t\t\t\t\treturn 'export default {};';\n\t\t\t\t\t}\n\n\t\t\t\t\tconst compiler = new HtmlCompiler(content);\n\t\t\t\t\tconst { ts } = await compiler.compile();\n\t\t\t\t\tgenerateTypes(realId, content, rootDir);\n\n\t\t\t\t\tconst result = await transformWithEsbuild(ts, realId, {\n\t\t\t\t\t\tloader: 'ts',\n\t\t\t\t\t});\n\t\t\t\t\treturn result.code;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error(`[chispa] Error loading ${id}:`, e);\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["fs"]}
1
+ {"version":3,"sources":["../../src/html-compiler/html-compiler.ts","../../src/html-compiler/generator.ts","../../src/html-compiler/vite-plugin.ts"],"sourcesContent":["import { JSDOM } from 'jsdom';\nimport { format } from 'prettier';\n\nconst VOID_ELEMENTS = ['area', 'base', 'br', 'hr', 'img', 'input', 'link', 'meta', 'param', 'keygen', 'source'];\n\nconst SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\nexport class HtmlCompiler {\n\tprivate components: Record<string, string> = {};\n\tprivate stack: string[] = ['fragment'];\n\tprivate componentsItems: Record<string, string[]> = {};\n\tprivate componentsTags: Record<string, string> = {};\n\tprivate isSvg: Record<string, boolean> = {};\n\tprivate inSvgContext = 0;\n\tprivate htmlDocument: Document;\n\n\tconstructor(htmlContent: string) {\n\t\tconst dom = new JSDOM(htmlContent);\n\t\tthis.htmlDocument = dom.window.document;\n\t}\n\n\tprivate static camelize(str: string): string {\n\t\tif (str.startsWith('--')) {\n\t\t\treturn str;\n\t\t}\n\t\tconst arr = str.split('-');\n\t\tlet camelized = '';\n\t\tarr.forEach((v, i) => {\n\t\t\tcamelized += i === 0 ? v : v.charAt(0).toUpperCase() + v.slice(1);\n\t\t});\n\t\treturn camelized;\n\t}\n\n\tprivate static parseStyle(cssCode: string): string {\n\t\tlet out = '{';\n\t\tconst styles = cssCode.split(';');\n\t\tstyles.forEach((line) => {\n\t\t\tconst parts = line.split(':');\n\t\t\tif (parts.length !== 2) return;\n\t\t\tconst prop = HtmlCompiler.camelize(parts[0].trim());\n\t\t\tout += ` ${prop}: '${parts[1].trim()}',`;\n\t\t});\n\t\tout += '}';\n\t\treturn out;\n\t}\n\n\tprivate makeClassAttr(classAttr: string | null, isComponent: boolean): string {\n\t\tconst tplClasses = (classAttr || '').split(' ');\n\t\tlet finalClass = '';\n\n\t\ttplClasses.forEach((tplClass) => {\n\t\t\tif (!tplClass.startsWith('-tpl--')) {\n\t\t\t\tfinalClass += tplClass + ' ';\n\t\t\t}\n\t\t});\n\n\t\tfinalClass = finalClass.trim();\n\n\t\treturn ` 'class': \"${finalClass}\", `;\n\t}\n\n\tprivate getHtmlNodeAttrs(domNode: Element, isComponent: boolean): string {\n\t\tlet attrsHtml = '{';\n\t\tattrsHtml += this.makeClassAttr(domNode.getAttribute('class'), isComponent);\n\n\t\tArray.from(domNode.attributes).forEach((attr) => {\n\t\t\tconst attrName = attr.name;\n\t\t\tlet attrValue = attr.value;\n\n\t\t\tif (attrName === 'data-cb') return;\n\t\t\tif (attrName === 'class') return;\n\n\t\t\t// Use JSON.stringify to properly escape newlines, quotes and other characters\n\t\t\tconst valueLiteral = JSON.stringify(attrValue);\n\n\t\t\t// Simplified logic compared to PHP which had cbt.prefixize... calls\n\t\t\t// Assuming we just output the value for now as I don't see cbt implementation here\n\t\t\t// The PHP code imported CoreBuilderTools but here we might not have it.\n\t\t\t// The user's example output imports from 'chispa'.\n\t\t\t// I will stick to simple string values for now unless I see cbt in chispa.\n\n\t\t\tif (attrName === 'style') {\n\t\t\t\t// PHP called cbt.prefixizeStyle, but also had parse_style static method.\n\t\t\t\t// Wait, the PHP code used cbt.prefixizeStyle inside get_html_node_attrs.\n\t\t\t\t// But parse_style was defined but not used in the snippet I read?\n\t\t\t\t// Ah, I should check if I should use parseStyle or just output string.\n\t\t\t\t// The PHP code: $attrs_html .= \" '$attr_name': cbt.prefixizeStyle('$attr_value'), \";\n\t\t\t\t// If cbt is a runtime helper, I should output the call.\n\t\t\t\t// But wait, the generated code imports CoreBuilderTools.\n\t\t\t\t// Does 'chispa' export CoreBuilderTools?\n\t\t\t\t// src/index.ts does NOT export CoreBuilderTools.\n\t\t\t\t// It exports appendChild, getItem, etc.\n\t\t\t\t// Maybe I should just output the string for now.\n\t\t\t\tattrsHtml += ` '${attrName}': ${valueLiteral}, `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': ${valueLiteral}, `;\n\t\t\t}\n\t\t});\n\n\t\tattrsHtml += '}';\n\t\treturn attrsHtml;\n\t}\n\n\tprivate buildTsForNode(domNode: Node, isComponent = false): string {\n\t\tlet htmlNodeCode = '';\n\n\t\tif (domNode.nodeType === 1) {\n\t\t\t// Element\n\t\t\tconst element = domNode as Element;\n\t\t\tlet tagName = element.tagName;\n\n\t\t\tif (tagName === 'svg') {\n\t\t\t\tthis.inSvgContext++;\n\t\t\t}\n\n\t\t\tlet cbid = element.getAttribute('data-cb');\n\n\t\t\tif (cbid) {\n\t\t\t\tconst currComp = this.stack[0];\n\t\t\t\telement.removeAttribute('data-cb');\n\t\t\t\tcbid = HtmlCompiler.camelize(cbid);\n\t\t\t\t// Pushear a todos los padres\n\t\t\t\tfor (const comp of this.stack) {\n\t\t\t\t\tif (!this.componentsItems[comp]) {\n\t\t\t\t\t\tthis.componentsItems[comp] = [];\n\t\t\t\t\t}\n\t\t\t\t\tthis.componentsItems[comp].push(cbid);\n\t\t\t\t}\n\n\t\t\t\tthis.stack.unshift(cbid);\n\t\t\t\tthis.components[cbid] = this.buildTsForNode(element, true);\n\t\t\t\tthis.componentsTags[cbid] = element.tagName;\n\t\t\t\tthis.isSvg[cbid] = this.inSvgContext > 0;\n\t\t\t\tthis.stack.shift();\n\n\t\t\t\tif (currComp === 'fragment') {\n\t\t\t\t\thtmlNodeCode += `getItem(template, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(template, props.nodes, '${cbid}')`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst attrs = this.getHtmlNodeAttrs(element, isComponent);\n\n\t\t\t\tif (!this.inSvgContext) {\n\t\t\t\t\ttagName = tagName.toLowerCase();\n\t\t\t\t\thtmlNodeCode += `(() => { const node = document.createElement('${tagName}');\\n`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `(() => { const node = document.createElementNS('${SVG_NAMESPACE}', '${tagName}');\\n`;\n\t\t\t\t}\n\n\t\t\t\thtmlNodeCode += `setAttributes(node, ${attrs});\\n`;\n\t\t\t\tif (isComponent) {\n\t\t\t\t\thtmlNodeCode += `setProps(node, props);\\n`;\n\t\t\t\t}\n\n\t\t\t\tlet subTs = '';\n\t\t\t\telement.childNodes.forEach((child) => {\n\t\t\t\t\tconst chCode = this.buildTsForNode(child);\n\t\t\t\t\tif (chCode) {\n\t\t\t\t\t\tsubTs += `appendChild(node, ${chCode});\\n`;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (!VOID_ELEMENTS.includes(tagName.toLowerCase())) {\n\t\t\t\t\tif (isComponent) {\n\t\t\t\t\t\thtmlNodeCode += `\n if (props.inner === null) {\n node.innerHTML = '';\n } else if (props.inner !== undefined) {\n node.innerHTML = '';\n appendChild(node, props.inner);\n } else {\n ${subTs}\n }\n `;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thtmlNodeCode += subTs;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isComponent) {\n\t\t\t\t\thtmlNodeCode += `if (typeof props._ref === 'function') props._ref(node);\\n`;\n\t\t\t\t}\n\n\t\t\t\thtmlNodeCode += `return node;})()`;\n\n\t\t\t\tif (tagName === 'svg') {\n\t\t\t\t\tthis.inSvgContext--;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (domNode.nodeType === 3) {\n\t\t\t// Text\n\t\t\tconst textNode = domNode as Text;\n\t\t\tconst parent = textNode.parentNode as Element;\n\t\t\tconst parentTag = parent ? parent.tagName.toLowerCase() : '';\n\n\t\t\tconst mustOmit = ['table', 'thead', 'tbody', 'tfoot', 'tr'].includes(parentTag);\n\n\t\t\tif (!mustOmit && textNode.textContent) {\n\t\t\t\tif (textNode.textContent.trim() === '') {\n\t\t\t\t\tif (textNode.textContent.length > 0) {\n\t\t\t\t\t\thtmlNodeCode += `document.createTextNode(' ')`;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode = `document.createTextNode(${JSON.stringify(textNode.textContent)})`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn htmlNodeCode.trim();\n\t}\n\n\tprivate static getPropsTypename(cbid: string): string {\n\t\treturn 'Cb' + cbid.charAt(0).toUpperCase() + cbid.slice(1) + 'Props';\n\t}\n\n\tprivate wrapFnComponent(cbid: string, jsx: string): string {\n\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\t\treturn `(props: ${typename}) => { \\n return(${jsx}); \\n }`;\n\t}\n\n\tprivate createAllComponents() {\n\t\tconst body = this.htmlDocument.querySelector('body');\n\t\tif (!body) throw new Error('Not valid HTML');\n\n\t\tlet rendererJsx = '(() => { const fragment = document.createDocumentFragment();\\n';\n\n\t\tbody.childNodes.forEach((child) => {\n\t\t\tconst chCode = this.buildTsForNode(child);\n\t\t\tif (chCode) {\n\t\t\t\trendererJsx += `appendChild(fragment, ${chCode});\\n`;\n\t\t\t}\n\t\t});\n\n\t\trendererJsx += 'return fragment;\\n';\n\t\trendererJsx += '})()';\n\n\t\tthis.components['fragment'] = rendererJsx;\n\t}\n\n\tprivate getTypedef(cbid: string): string {\n\t\tconst items = this.componentsItems[cbid] || [];\n\t\tlet itemsType = '{\\n';\n\t\titems.forEach((itemCbid) => {\n\t\t\tconst itemTypename = HtmlCompiler.getPropsTypename(itemCbid);\n\t\t\titemsType += `${itemCbid}?: ${itemTypename} | ChispaContentReactive;\\n`;\n\t\t});\n\t\titemsType += '}\\n';\n\n\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\n\t\tif (cbid === 'fragment') {\n\t\t\treturn `interface ${typename} ${itemsType}`;\n\t\t} else {\n\t\t\tconst tagname = this.componentsTags[cbid];\n\t\t\tif (this.isSvg[cbid]) {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderPropsReactive<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderPropsReactive<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async compile(): Promise<{ ts: string; dts: string }> {\n\t\tthis.createAllComponents();\n\n\t\tlet componentsClasses = '';\n\t\tlet typedefs = '';\n\n\t\tfor (const [cbid, compJsx] of Object.entries(this.components)) {\n\t\t\ttypedefs += this.getTypedef(cbid) + '\\n';\n\t\t\tcomponentsClasses += `${cbid}: ${this.wrapFnComponent(cbid, compJsx)},\\n`;\n\t\t}\n\n\t\tconst jsOutput = `\n import { appendChild, getItem, setAttributes, setProps } from 'chispa';\n import type { ChispaContentReactive, ChispaNodeBuilderPropsReactive } from 'chispa';\n\t\t\t\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const template = {\n ${componentsClasses}\n };\n \n export default template;\n `;\n\n\t\tconst dtsOutput = `\n import type { ChispaContentReactive, ChispaNodeBuilderPropsReactive } from 'chispa';\n \n ${typedefs}\n \n declare const template: {\n ${Object.keys(this.components)\n\t\t\t\t\t.map((cbid) => {\n\t\t\t\t\t\tconst typename = HtmlCompiler.getPropsTypename(cbid);\n\t\t\t\t\t\treturn `${cbid}: (props: ${typename}) => Node | DocumentFragment;`;\n\t\t\t\t\t})\n\t\t\t\t\t.join('\\n')}\n };\n \n export default template;\n `;\n\n\t\tconst prettierOptions = {\n\t\t\tparser: 'typescript',\n\t\t\tsemi: true,\n\t\t\tsingleQuote: true,\n\t\t\tuseTabs: true,\n\t\t\tprintWidth: 120,\n\t\t};\n\n\t\treturn {\n\t\t\tts: await format(jsOutput, prettierOptions),\n\t\t\tdts: await format(dtsOutput, prettierOptions),\n\t\t};\n\t}\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport async function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = await compiler.compile();\n\n\t\tconst outDir = path.join(rootDir, '.chispa/types');\n\t\tconst relativePath = path.relative(rootDir, filePath);\n\t\tconst targetPath = path.join(outDir, relativePath + '.d.ts');\n\t\tconst targetDir = path.dirname(targetPath);\n\n\t\tif (!fs.existsSync(targetDir)) {\n\t\t\tfs.mkdirSync(targetDir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(targetPath, dts);\n\t} catch (e) {\n\t\tconsole.error(`[chispa] Error generating types for ${filePath}`, e);\n\t}\n}\n\nexport async function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfor (const file of files) {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) continue;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tawait findAndCompileHtmlFiles(fullPath, rootDir);\n\t\t\t}\n\t\t} else if (file.endsWith('.html')) {\n\t\t\tconsole.log('Generating types for', fullPath);\n\t\t\tconst content = fs.readFileSync(fullPath, 'utf-8');\n\t\t\tawait generateTypes(fullPath, content, rootDir);\n\t\t}\n\t}\n}\n","import { HtmlCompiler } from './html-compiler';\nimport { generateTypes, findAndCompileHtmlFiles } from './generator';\nimport { type Plugin, transformWithEsbuild } from 'vite';\nimport * as fs from 'fs';\n\n/**\n * Convierte una ruta real de archivo en el ID de módulo virtual que usa Vite/Rollup.\n * Añade el prefijo `\\0` para marcar el módulo como virtual y el sufijo\n * `.chispa.ts` para que sea tratado como módulo TypeScript.\n */\nconst toVirtualId = (id: string) => '\\0' + id + '.chispa.ts';\n\n/**\n * Convierte un ID de módulo virtual de vuelta a la ruta real del archivo.\n * Elimina el prefijo `\\0` (si existe) y el sufijo `.chispa.ts`.\n */\nconst fromVirtualId = (id: string) => id.replace(/^\\0/, '').replace(/\\.chispa\\.ts$/, '');\n\nconst CHISPA_VIRTUAL_MODULE_SUFFIX = '.html.chispa.ts';\n\nexport function chispaHtmlPlugin(): Plugin {\n\tlet rootDir = process.cwd();\n\n\treturn {\n\t\tname: 'chispa-html',\n\t\tenforce: 'pre',\n\t\tconfigResolved(config) {\n\t\t\trootDir = config.root;\n\t\t},\n\t\tasync buildStart() {\n\t\t\tawait findAndCompileHtmlFiles(rootDir, rootDir);\n\t\t},\n\t\tasync handleHotUpdate(ctx) {\n\t\t\tif (ctx.file.endsWith('.html')) {\n\t\t\t\tconst content = await ctx.read();\n\t\t\t\tawait generateTypes(ctx.file, content, rootDir);\n\n\t\t\t\t// Buscamos el módulo virtual asociado al archivo HTML modificado.\n\t\t\t\tconst module = ctx.server.moduleGraph.getModuleById(toVirtualId(ctx.file));\n\t\t\t\tif (module) {\n\t\t\t\t\treturn [module];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync resolveId(source, importer, options) {\n\t\t\tif (source.endsWith(CHISPA_VIRTUAL_MODULE_SUFFIX)) {\n\t\t\t\treturn source;\n\t\t\t}\n\t\t\tif (source.endsWith('.html') && importer) {\n\t\t\t\tconst resolution = await this.resolve(source, importer, { skipSelf: true, ...options });\n\t\t\t\tif (resolution && !resolution.external) {\n\t\t\t\t\treturn toVirtualId(resolution.id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tasync load(id) {\n\t\t\tif (!id.endsWith(CHISPA_VIRTUAL_MODULE_SUFFIX)) return null;\n\n\t\t\tconst realId = fromVirtualId(id);\n\t\t\tthis.addWatchFile(realId); // To ensure changes in the HTML file trigger a rebuild in watch mode.\n\t\t\ttry {\n\t\t\t\tconst content = fs.readFileSync(realId, 'utf-8');\n\t\t\t\tif (content.includes('<!DOCTYPE html>') || content.includes('<html')) {\n\t\t\t\t\treturn 'export default {};';\n\t\t\t\t}\n\n\t\t\t\tconst compiler = new HtmlCompiler(content);\n\t\t\t\tconst { ts } = await compiler.compile();\n\t\t\t\tgenerateTypes(realId, content, rootDir);\n\n\t\t\t\tconst result = await transformWithEsbuild(ts, realId, {\n\t\t\t\t\tloader: 'ts',\n\t\t\t\t});\n\t\t\t\treturn result.code;\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(`[chispa] Error loading ${id}:`, e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["fs"]}
package/dist/index.d.ts CHANGED
@@ -6,10 +6,11 @@ type ChispaClasses = Record<string, ChispaReactive<boolean>>;
6
6
  type ChispaCSSPropertiesStrings = {
7
7
  [K in keyof CSSStyleDeclaration]?: ChispaReactive<string>;
8
8
  };
9
+ type EventPropKeys<T> = Extract<keyof T, `on${string}`>;
9
10
  type AllowSignals<T> = {
10
- [K in keyof T]: T[K] | Signal<T[K]>;
11
+ [K in keyof T]: ChispaReactive<T[K]>;
11
12
  };
12
- type ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<Partial<T>, 'style' | 'dataset'>>;
13
+ type ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<T, 'style' | 'dataset' | EventPropKeys<T>>> & Pick<T, EventPropKeys<T>>;
13
14
  interface INodeBuilderSpecialProps {
14
15
  addClass?: ChispaReactive<string | string[]>;
15
16
  classes?: ChispaClasses;
@@ -23,7 +24,7 @@ interface INodeBuilderAdditionalProps<T, TNodes> {
23
24
  current: T | null;
24
25
  };
25
26
  }
26
- type ChispaNodeBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;
27
+ type ChispaNodeBuilderProps<T, TNodes> = Partial<ChispaNodeBuilderBaseProps<T>> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;
27
28
  type ChispaNodeBuilderPropsReactive<T, TNodes> = ChispaReactive<ChispaNodeBuilderProps<T, TNodes>>;
28
29
  declare function getValidProps<T>(props: ChispaNodeBuilderProps<T, any>): ChispaNodeBuilderProps<T, any>;
29
30
  declare function getItem<T>(template: T, items: any, itemName: keyof T): any;
@@ -176,9 +177,9 @@ interface SelectOption {
176
177
  disabled?: boolean;
177
178
  }
178
179
  type InputValueType = string | number;
179
- declare function bindControlledInput<T extends InputValueType>(element: HTMLInputElement | HTMLTextAreaElement, signal: WritableSignal<T>, options?: ControlledInputOptions<T>): () => void;
180
- declare function bindControlledCheckbox(element: HTMLInputElement, signal: WritableSignal<boolean>, indeterminate?: Signal<boolean>): () => void;
181
- declare function bindControlledSelect(element: HTMLSelectElement, signal: WritableSignal<string>, optionsSignal?: Signal<SelectOption[]>): () => void;
180
+ declare function bindControlledInput<T extends InputValueType>(element: HTMLInputElement | HTMLTextAreaElement, valueSignal: WritableSignal<T>, options?: ControlledInputOptions<T>): () => void;
181
+ declare function bindControlledCheckbox(element: HTMLInputElement, valueSignal: WritableSignal<boolean>, indeterminate?: Signal<boolean>): () => void;
182
+ declare function bindControlledSelect(element: HTMLSelectElement, valueSignal: WritableSignal<string>, optionList?: Signal<SelectOption[]> | SelectOption[]): () => void;
182
183
 
183
184
  interface Route {
184
185
  path: string;
package/dist/index.js CHANGED
@@ -455,12 +455,10 @@ var forbiddenProps = ["nodes", "inner", "_ref"];
455
455
  function getValidProps(props) {
456
456
  const finalProps = {};
457
457
  for (const propName in props) {
458
- if (forbiddenProps.indexOf(propName) === -1) {
458
+ if (!forbiddenProps.includes(propName)) {
459
459
  finalProps[propName] = props[propName];
460
460
  }
461
461
  }
462
- if (props._ref !== void 0) {
463
- }
464
462
  return finalProps;
465
463
  }
466
464
  var itemsStack = [];
@@ -500,6 +498,16 @@ function setAttributes(node, attributes) {
500
498
  node.setAttribute(attr, attrValue);
501
499
  }
502
500
  }
501
+ function isEventProp(prop) {
502
+ return prop.startsWith("on");
503
+ }
504
+ function getPropValue(props, prop) {
505
+ const propValue = props[prop];
506
+ if (typeof propValue === "function" && !isEventProp(prop)) {
507
+ return computed(propValue);
508
+ }
509
+ return propValue;
510
+ }
503
511
  function setProps(node, props) {
504
512
  let _props = props;
505
513
  if (typeof _props === "function") {
@@ -516,7 +524,7 @@ function setProps(node, props) {
516
524
  setSpecialProps(node, props);
517
525
  }
518
526
  for (const prop in props) {
519
- const propValue = props[prop];
527
+ const propValue = getPropValue(props, prop);
520
528
  if (isSignal(propValue)) {
521
529
  globalContext.addReactivity(() => {
522
530
  node[prop] = propValue.get();
@@ -707,14 +715,14 @@ function getTypeConverter(exampleValue) {
707
715
  };
708
716
  }
709
717
  }
710
- function bindControlledInput(element, signal2, options = {}) {
718
+ function bindControlledInput(element, valueSignal, options = {}) {
711
719
  const { transform, validate } = options;
712
- const { toTargetType, fromTargetType } = getTypeConverter(signal2.initialValue);
713
- element.value = fromTargetType(signal2.initialValue);
720
+ const { toTargetType, fromTargetType } = getTypeConverter(valueSignal.initialValue);
721
+ element.value = fromTargetType(valueSignal.initialValue);
714
722
  const handleInput = (e) => {
715
723
  const target = e.target;
716
724
  let newValue = toTargetType(target.value);
717
- const originalValue = signal2.get();
725
+ const originalValue = valueSignal.get();
718
726
  const selectionStart = target.selectionStart;
719
727
  const selectionEnd = target.selectionEnd;
720
728
  if (transform) {
@@ -724,7 +732,7 @@ function bindControlledInput(element, signal2, options = {}) {
724
732
  newValue = originalValue;
725
733
  }
726
734
  if (newValue !== originalValue) {
727
- signal2.set(newValue);
735
+ valueSignal.set(newValue);
728
736
  }
729
737
  const newValueStr = fromTargetType(newValue);
730
738
  if (target.value !== newValueStr) {
@@ -739,7 +747,7 @@ function bindControlledInput(element, signal2, options = {}) {
739
747
  };
740
748
  element.addEventListener("input", handleInput);
741
749
  globalContext.addReactivity(() => {
742
- const newValueStr = fromTargetType(signal2.get());
750
+ const newValueStr = fromTargetType(valueSignal.get());
743
751
  if (element.value !== newValueStr) {
744
752
  element.value = newValueStr;
745
753
  }
@@ -748,14 +756,14 @@ function bindControlledInput(element, signal2, options = {}) {
748
756
  element.removeEventListener("input", handleInput);
749
757
  };
750
758
  }
751
- function bindControlledCheckbox(element, signal2, indeterminate) {
752
- element.checked = signal2.initialValue;
759
+ function bindControlledCheckbox(element, valueSignal, indeterminate) {
760
+ element.checked = valueSignal.initialValue;
753
761
  const handleChange = (e) => {
754
762
  const target = e.target;
755
763
  let newChecked = target.checked;
756
- const originalValue = signal2.get();
764
+ const originalValue = valueSignal.get();
757
765
  if (newChecked !== originalValue) {
758
- signal2.set(newChecked);
766
+ valueSignal.set(newChecked);
759
767
  }
760
768
  if (target.checked !== newChecked) {
761
769
  target.checked = newChecked;
@@ -763,7 +771,7 @@ function bindControlledCheckbox(element, signal2, indeterminate) {
763
771
  };
764
772
  element.addEventListener("change", handleChange);
765
773
  globalContext.addReactivity(() => {
766
- const newValue = signal2.get();
774
+ const newValue = valueSignal.get();
767
775
  if (element.checked !== newValue) {
768
776
  element.checked = newValue;
769
777
  }
@@ -777,38 +785,45 @@ function bindControlledCheckbox(element, signal2, indeterminate) {
777
785
  element.removeEventListener("change", handleChange);
778
786
  };
779
787
  }
780
- function bindControlledSelect(element, signal2, optionsSignal) {
781
- const updateOptions = (options) => {
782
- element.innerHTML = "";
783
- options.forEach((option) => {
788
+ function bindControlledSelect(element, valueSignal, optionList) {
789
+ const Options = componentList(
790
+ (option) => {
784
791
  const optElement = document.createElement("option");
785
- optElement.value = option.value;
786
- optElement.textContent = option.label;
787
- if (option.disabled) {
788
- optElement.disabled = true;
789
- }
790
- element.appendChild(optElement);
791
- });
792
- element.value = signal2.get();
793
- };
792
+ setProps(optElement, {
793
+ value: () => option.get().value ?? "",
794
+ textContent: () => option.get().label ?? "",
795
+ disabled: () => option.get().disabled ?? false
796
+ });
797
+ return optElement;
798
+ },
799
+ (o) => o.value
800
+ );
794
801
  const handleChange = (e) => {
795
802
  const target = e.target;
796
803
  let newValue = target.value;
797
- const originalValue = signal2.get();
804
+ const originalValue = valueSignal.get();
798
805
  if (newValue !== originalValue) {
799
- signal2.set(newValue);
806
+ valueSignal.set(newValue);
800
807
  }
801
808
  if (target.value !== newValue) {
802
809
  target.value = newValue;
803
810
  }
804
811
  };
805
- if (optionsSignal) {
812
+ if (optionList) {
813
+ const optionsSignal = isSignal(optionList) ? optionList : computed(() => optionList || []);
814
+ element.innerHTML = "";
815
+ appendChild(element, Options(optionsSignal));
806
816
  globalContext.addReactivity(() => {
807
- updateOptions(optionsSignal.get());
817
+ const currValue = valueSignal.get();
818
+ if (!optionsSignal.get().some((opt) => opt.value === currValue)) {
819
+ element.value = "";
820
+ } else if (element.value !== currValue) {
821
+ element.value = currValue;
822
+ }
808
823
  });
809
824
  }
810
825
  globalContext.addReactivity(() => {
811
- const newValue = signal2.get();
826
+ const newValue = valueSignal.get();
812
827
  if (element.value !== newValue) {
813
828
  element.value = newValue;
814
829
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts","../src/router.ts"],"sourcesContent":["export const ChispaDebugConfig = {\n\tenableReactivityWarnings: false,\n};\n","import { Component, ComponentList } from './components';\nimport { ChispaDebugConfig } from './config';\nimport { Signal } from './signals';\n\ntype ExecutionKind = 'createComponent' | 'computed' | 'addReactivity';\n\nexport interface IDisposable {\n\tdispose: () => void;\n}\n\nclass AppContext {\n\tprivate reactivityContextStack: Reactivity[] = [];\n\n\tprivate refreshTimeout: any = 0;\n\n\t//private contexts = new Set<RenderContext>();\n\n\tprivate dirtyReactivities = new Set<Reactivity>();\n\n\tprivate executionStack: ExecutionKind[] = [];\n\n\tprivate componentStack: (Component | ComponentList)[] = [];\n\n\tpushComponentStack(cmp: Component | ComponentList) {\n\t\tthis.componentStack.push(cmp);\n\t}\n\n\tpopComponentStack() {\n\t\tthis.componentStack.pop();\n\t}\n\n\tgetCurrentComponent() {\n\t\tif (this.componentStack.length === 0) {\n\t\t\t//console.warn('No current component');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.componentStack[this.componentStack.length - 1];\n\t}\n\n\tsetCurrentReactivityContext(context: Reactivity) {\n\t\tthis.reactivityContextStack.push(context);\n\t\t//this.contexts.add(context);\n\t}\n\n\trestorePreviousReactivityContext() {\n\t\tthis.reactivityContextStack.pop();\n\t}\n\n\tgetCurrentRenderContext() {\n\t\tif (this.reactivityContextStack.length === 0) {\n\t\t\t//console.warn('No current render context');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.reactivityContextStack[this.reactivityContextStack.length - 1];\n\t}\n\n\t// Maximum number of iterations to process during a scheduled refresh. Prevents\n\t// unbounded loops in case of uncontrolled reactivity cascades. Use the\n\t// `globalContext.maxScheduleIterations` field to override in tests or\n\t// special cases.\n\tpublic maxScheduleIterations = 100;\n\n\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tlet iteration = 0;\n\t\t\t// Process dirty contexts until none remain, or until the iteration limit\n\t\t\t// is reached (this avoids infinite loops when reactivities keep\n\t\t\t// re-adding themselves or each other).\n\t\t\twhile (this.dirtyReactivities.size > 0 && iteration < this.maxScheduleIterations) {\n\t\t\t\titeration++;\n\t\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\n\t\t\t}\n\n\t\t\tif (this.dirtyReactivities.size > 0) {\n\t\t\t\t// Warn once if we stopped early due to the iteration limit. We also\n\t\t\t\t// clear the set to avoid repeated warnings and to avoid leaving the\n\t\t\t\t// system in a permanently spinning state.\n\t\t\t\tconsole.warn(`[AppContext.scheduleRefresh] possible uncontrolled reactivity cascade: processed ${iteration} iterations — aborting.`);\n\t\t\t\tthis.dirtyReactivities.clear();\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\taddReactivity(executor: () => void) {\n\t\tconst ctx = new Reactivity(executor);\n\t\tglobalContext.pushExecutionStack('addReactivity');\n\t\tctx.exec();\n\t\tglobalContext.popExecutionStack();\n\t\treturn ctx;\n\t}\n\n\tcreateRoot(component: () => Component, mountPoint: HTMLElement) {\n\t\tthis.dirtyReactivities.clear();\n\t\tmountPoint.innerHTML = '';\n\t\tconst cmp = component();\n\t\tcmp.mount(mountPoint, null);\n\t}\n\n\tcanReadSignal() {\n\t\tconst length = this.executionStack.length;\n\t\tif (length === 0) return true;\n\t\tconst current = this.executionStack[length - 1];\n\t\treturn current !== 'createComponent';\n\t}\n\n\tpushExecutionStack(type: ExecutionKind) {\n\t\tthis.executionStack.push(type);\n\t}\n\n\tpopExecutionStack() {\n\t\tthis.executionStack.pop();\n\t}\n\n\taddDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.add(ctx);\n\t}\n\n\tremoveDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.delete(ctx);\n\t}\n}\n\nexport class Reactivity implements IDisposable {\n\tprivate dirty: boolean = false;\n\n\tprivate signals = new Set<Signal<any>>();\n\n\tconstructor(private readonly action: () => void) {\n\t\tconst currentComponent = globalContext.getCurrentComponent();\n\t\tif (currentComponent) {\n\t\t\tcurrentComponent.addDisposable(this);\n\t\t} else {\n\t\t\tif (ChispaDebugConfig.enableReactivityWarnings) {\n\t\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t\t}\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\tthis.dirty = true;\n\t\tglobalContext.addDirtyContext(this);\n\t\tglobalContext.scheduleRefresh();\n\t}\n\n\taddSignal(signal: Signal<any>) {\n\t\tthis.signals.add(signal);\n\t}\n\n\tremoveSignal(signal: Signal<any>) {\n\t\tthis.signals.delete(signal);\n\t}\n\n\tprocess() {\n\t\tif (!this.dirty) return;\n\t\tthis.exec();\n\t\t//console.log('re-render cycle completed');\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n\n\texec() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tglobalContext.setCurrentReactivityContext(this);\n\t\tthis.action();\n\t\tglobalContext.restorePreviousReactivityContext();\n\t}\n\n\tdispose() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n}\n\nexport const globalContext = new AppContext();\n","import { globalContext, Reactivity } from './context';\n\ntype WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n\nabstract class Signal<T> {\n\tprotected abstract value: T;\n\n\tprotected contexts: Set<Reactivity> = new Set();\n\n\tconstructor() {}\n\n\tget() {\n\t\tif (!globalContext.canReadSignal()) {\n\t\t\tthrow new Error('Cannot read a signal value during component creation. Did you mean to use a computed signal instead?');\n\t\t}\n\t\t//context.current.register(this);\n\t\tconst ctx = globalContext.getCurrentRenderContext();\n\t\tif (ctx) {\n\t\t\tthis.contexts.add(ctx);\n\t\t\tctx.addSignal(this);\n\t\t}\n\t\treturn this.value;\n\t}\n\n\tpublic readonly computed = new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget: (_, prop) => {\n\t\t\t\treturn computed(() => this.get()[prop as keyof T]);\n\t\t\t},\n\t\t}\n\t) as WithSignals<T>;\n\n\tremoveContext(ctx: Reactivity) {\n\t\tthis.contexts.delete(ctx);\n\t}\n\n\tdispose() {\n\t\t//console.log('disposing signal', this);\n\t\tthis.contexts.forEach((ctx) => {\n\t\t\tctx.removeSignal(this);\n\t\t});\n\t\tthis.contexts.clear();\n\t}\n}\n\nclass WritableSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tpublic readonly initialValue: T;\n\n\tconstructor(initialValue: T) {\n\t\tsuper();\n\t\tthis.initialValue = initialValue;\n\t\tthis.value = initialValue;\n\t}\n\n\tset(newValue: T) {\n\t\tthis.value = newValue;\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n\n\tupdate(updater: (value: T) => T) {\n\t\tthis.value = updater(this.value);\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n}\n\nclass ComputedSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tprivate computeFn: () => T;\n\n\tconstructor(computeFn: () => T) {\n\t\tsuper();\n\t\tglobalContext.pushExecutionStack('computed');\n\t\tthis.value = computeFn();\n\t\tglobalContext.popExecutionStack();\n\t\tthis.computeFn = computeFn;\n\t}\n\n\trecompute() {\n\t\tconst newValue = this.computeFn();\n\t\tif (newValue !== this.value) {\n\t\t\tthis.value = newValue;\n\t\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t\t}\n\t}\n}\n\nexport function isSignal(value: any): value is Signal<any> {\n\treturn value instanceof Signal;\n}\n\nexport function isWriteableSignal<T>(value: Signal<T>): value is WritableSignal<T> {\n\treturn value instanceof WritableSignal;\n}\n\nexport function signal<T>(initialValue: T) {\n\tconst sig = new WritableSignal(initialValue);\n\n\t// // Creamos una función que se usará como callable\n\t// const fn = (() => sig.get()) as any;\n\n\t// // Copiamos todas las propiedades y métodos de la instancia a la función\n\t// Object.setPrototypeOf(fn, sig.constructor.prototype);\n\n\t// // Copiamos las propiedades de instancia\n\t// Object.assign(fn, this);\n\n\t// // Retornamos la función como si fuera la instancia\n\t// return fn as WritableSignal<T> & (() => T);\n\n\treturn sig;\n}\n\nexport function computed<T>(fn: () => T) {\n\tlet sig: ComputedSignal<T>;\n\tconst ctx = new Reactivity(() => {\n\t\tsig.recompute();\n\t});\n\tglobalContext.setCurrentReactivityContext(ctx);\n\tsig = new ComputedSignal(fn);\n\tglobalContext.restorePreviousReactivityContext();\n\n\treturn sig as Signal<T>;\n}\n\nexport function effect(fn: () => void) {\n\tglobalContext.addReactivity(fn);\n}\n\nexport type { Signal, WritableSignal };\n","import { ChispaContent } from './builder';\nimport { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => ChispaContent;\n\nexport class Component<TProps extends Dict = any> {\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tprivate disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\tconstructor(\n\t\tprivate readonly factoryFn: ComponentFactory<TProps>,\n\t\tpublic readonly key: any = null,\n\t\tpublic readonly props: TProps | null = null\n\t) {}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushExecutionStack('createComponent');\n\t\tglobalContext.pushComponentStack(this);\n\t\tconst node = this.factoryFn ? (this.factoryFn as any)(this.props) : null;\n\t\tglobalContext.popComponentStack();\n\t\tglobalContext.popExecutionStack();\n\t\t// if node is fragment, convert to array of nodes\n\t\tif (node) {\n\t\t\tif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n\t\t\t\tthis.nodes = Array.from(node.childNodes);\n\t\t\t} else {\n\t\t\t\tthis.nodes = [node];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.nodes = null;\n\t\t}\n\t\tthis.insertNodes();\n\t}\n\n\treanchor(anchor: Node | null) {\n\t\tthis.anchor = anchor;\n\n\t\t//console.log('reanchoring', this.nodes, ' before anchor', this.anchor);\n\t\tthis.insertNodes();\n\t}\n\n\tprivate insertNodes() {\n\t\tif (!this.container || !this.nodes) return;\n\t\t// Insertar en la nueva posición\n\t\tfor (const node of this.nodes) {\n\t\t\tif (this.anchor) {\n\t\t\t\tthis.container.insertBefore(node, this.anchor);\n\t\t\t} else {\n\t\t\t\tthis.container.appendChild(node);\n\t\t\t}\n\t\t}\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\n\t\tif (this.nodes) {\n\t\t\tthis.nodes.forEach((node) => {\n\t\t\t\tif (node && node.parentNode) {\n\t\t\t\t\tnode.parentNode.removeChild(node);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t\tthis.disposables = [];\n\t\tthis.nodes = null;\n\t\tthis.container = null;\n\t\tthis.anchor = null;\n\t}\n}\n\n// Definimos overloads para component\nexport function component(factory: ComponentFactory<any>): (props?: any) => Component;\nexport function component<TProps extends Dict>(factory: ComponentFactory<TProps>): (props: TProps) => Component<TProps>;\n\nexport function component<TProps extends Dict = any>(factory: ComponentFactory<TProps>) {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\nexport function onUnmount(unmountFn: () => void) {\n\tconst currentComponent = globalContext.getCurrentComponent();\n\tif (currentComponent) {\n\t\tcurrentComponent.addDisposable({\n\t\t\tdispose: unmountFn,\n\t\t});\n\t} else {\n\t\tthrow new Error('onUnmount must be called within a component context');\n\t}\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props?: TProps) => ChispaContent;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps extends Dict = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node | null = null; // Contenedor donde se montan los nodos\n\tprivate anchor: Node | null = null; // Nodes must be inserted before this node\n\tprivate currentKeys: any[] = [];\n\tpublic disposables: any[] = [];\n\n\tconstructor(\n\t\tprivate readonly itemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\t\tprivate readonly keyFn: KeyFn<TItem>,\n\t\tprivate readonly itemsSignal: Signal<TItem[]>,\n\t\tprivate readonly props: TProps | null = null\n\t) {\n\t\tthis.components = new Map();\n\t}\n\n\t/**\n\t * Obtiene todos los componentes\n\t */\n\tprivate getAllComponents(): Component[] {\n\t\treturn Array.from(this.components.values());\n\t}\n\n\t/**\n\t * Limpia todos los componentes\n\t */\n\tprivate clear(): void {\n\t\tArray.from(this.components.values()).forEach((component) => {\n\t\t\tthis.removeComponent(component);\n\t\t});\n\t}\n\n\t/**\n\t * Elimina un componente completo\n\t */\n\tprivate removeComponent(component: Component) {\n\t\tcomponent.unmount();\n\t\tif (component.key) {\n\t\t\tthis.components.delete(component.key);\n\t\t}\n\t}\n\n\t/**\n\t * Crea un nuevo componente\n\t */\n\tprivate createNewComponent(key: any): Component {\n\t\tconst factory = (props?: TProps) => {\n\t\t\tconst item = computed(() => this.itemsSignal.get().find((v, index) => this.keyFn(v, index) === key)!);\n\t\t\tconst index = computed(() => this.itemsSignal.get().findIndex((v, index) => this.keyFn(v, index) === key));\n\t\t\treturn this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props) : null;\n\t\t};\n\n\t\tconst component = new Component(factory, key, this.props);\n\t\tthis.components.set(key, component);\n\n\t\treturn component;\n\t}\n\n\tprivate getTargetAnchor(items: TItem[], index: number): Node | null {\n\t\tconst nextItem = index + 1 < items.length ? items[index + 1] : null;\n\t\tconst nextComp = nextItem ? this.components.get(this.keyFn(nextItem, index + 1)) : null;\n\t\tif (nextComp && nextComp.nodes) {\n\t\t\treturn nextComp.nodes[0];\n\t\t} else {\n\t\t\t// Es el último componente, debería insertarse antes del anchor original\n\t\t\treturn this.anchor;\n\t\t}\n\t}\n\n\t/**\n\t * Función principal que sincroniza los componentes DOM con un array de keys\n\t */\n\tprivate synchronizeComponents(): void {\n\t\tconst existingComponents = this.getAllComponents();\n\n\t\t// Identificar qué componentes eliminar (los que no están en keys)\n\t\tconst items = this.itemsSignal.get();\n\t\tconst keys = items.map((item, index) => this.keyFn(item, index));\n\t\tconst componentsToRemove = existingComponents.filter((component) => component.key && !keys.includes(component.key));\n\t\tcomponentsToRemove.forEach((component) => this.removeComponent(component));\n\n\t\tthis.currentKeys = this.currentKeys.filter((key) => keys.includes(key));\n\t\t//console.log('Current keys:', this.currentKeys, 'Target keys:', keys);\n\n\t\tif (!this.container) {\n\t\t\tconsole.warn('Container is null in synchronizeComponents');\n\t\t\treturn;\n\t\t}\n\t\t// Procesar cada key en el orden deseado\n\t\tconst container = this.container;\n\n\t\titems.forEach((item, index) => {\n\t\t\tconst targetKey = this.keyFn(item, index);\n\t\t\tconst currentKey = this.currentKeys[index];\n\t\t\tif (targetKey === currentKey) {\n\t\t\t\t// La key no ha cambiado de posición, no hacer nada\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst existingComponent = this.components.get(targetKey);\n\n\t\t\tif (existingComponent) {\n\t\t\t\tconst prevComp = this.components.get(currentKey);\n\t\t\t\tif (!prevComp || !prevComp.nodes) {\n\t\t\t\t\tconsole.warn('Previous component or its nodes not found for key', currentKey);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texistingComponent.reanchor(prevComp.nodes[0]);\n\t\t\t\t// Reordenar el array de keys actuales\n\t\t\t\tthis.currentKeys = this.currentKeys.filter((k) => k !== targetKey);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t} else {\n\t\t\t\t// El componente no existe, crearlo\n\t\t\t\tconst targetAnchor = this.getTargetAnchor(items, index);\n\t\t\t\tconst newComponent = this.createNewComponent(targetKey);\n\t\t\t\tnewComponent.mount(container, targetAnchor);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t}\n\t\t});\n\t}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushComponentStack(this);\n\t\tglobalContext.addReactivity(() => {\n\t\t\tthis.synchronizeComponents();\n\t\t});\n\t\tglobalContext.popComponentStack();\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\t//console.log('Unmounting ComponentList');\n\t\tthis.clear();\n\t\tthis.container = null!;\n\t\tthis.anchor = null!;\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t}\n}\n\n// Definimos overloads para componentList\nexport function componentList<TItem>(\n\titemFactoryFn: ItemFactoryFn<TItem, any>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props: TProps) => ComponentList<TItem, TProps>;\n\nexport function componentList<TItem, TProps extends Dict = any>(itemFactoryFn: ItemFactoryFn<TItem, TProps>, keyFn: KeyFn<TItem>) {\n\treturn (listSignal: Signal<TItem[]>, props?: TProps) => {\n\t\tconst list = new ComponentList(itemFactoryFn, keyFn, listSignal, props);\n\t\treturn list;\n\t};\n}\n","import { createLogger } from 'vite';\nimport { Component, ComponentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, type Signal } from './signals';\n\nexport type ChispaReactive<T> = T | Signal<T> | (() => T);\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | Component | (ChispaNode | Component)[] | ComponentList;\nexport type ChispaContentReactive = ChispaReactive<ChispaContent>;\nexport type ChispaClasses = Record<string, ChispaReactive<boolean>>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: ChispaReactive<string>;\n};\n\ntype AllowSignals<T> = { [K in keyof T]: T[K] | Signal<T[K]> };\n\ntype ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<Partial<T>, 'style' | 'dataset'>>;\ninterface INodeBuilderSpecialProps {\n\taddClass?: ChispaReactive<string | string[]>;\n\tclasses?: ChispaClasses;\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, ChispaReactive<string>>;\n}\ninterface INodeBuilderAdditionalProps<T, TNodes> {\n\tnodes?: TNodes;\n\tinner?: ChispaContentReactive;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaNodeBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;\nexport type ChispaNodeBuilderPropsReactive<T, TNodes> = ChispaReactive<ChispaNodeBuilderProps<T, TNodes>>;\n\nconst forbiddenProps = ['nodes', 'inner', '_ref'];\n\nexport function getValidProps<T>(props: ChispaNodeBuilderProps<T, any>) {\n\tconst finalProps: any = {};\n\n\tfor (const propName in props) {\n\t\tif (forbiddenProps.indexOf(propName) === -1) {\n\t\t\tfinalProps[propName] = props[propName as keyof typeof props];\n\t\t}\n\t}\n\n\tif (props._ref !== undefined) {\n\t\t//finalProps.ref = props._ref;\n\t}\n\n\treturn finalProps as ChispaNodeBuilderProps<T, any>;\n}\n\nconst itemsStack: any[] = [];\nfunction findItemInStack(itemName: string): any {\n\tfor (const itemsDefs of itemsStack) {\n\t\tif (itemsDefs && itemsDefs[itemName]) {\n\t\t\treturn itemsDefs[itemName];\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function getItem<T>(template: T, items: any, itemName: keyof T) {\n\titemsStack.unshift(items);\n\tconst item: any = findItemInStack(itemName as string);\n\n\tif (!item) {\n\t\titemsStack.shift();\n\t\treturn null;\n\t}\n\n\tlet res;\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = template[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\tres = Comp(itemProps);\n\t} else {\n\t\tres = item;\n\t}\n\titemsStack.shift();\n\treturn res;\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr];\n\t\tif (attrValue === undefined || attrValue === null) {\n\t\t\tnode.removeAttribute(attr);\n\t\t\tcontinue;\n\t\t}\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nexport function setProps<T extends Element>(node: T, props: ChispaNodeBuilderPropsReactive<T, any>) {\n\tlet _props = props;\n\tif (typeof _props === 'function') {\n\t\t_props = computed(_props);\n\t}\n\tif (isSignal(_props)) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\tsetProps(node, _props.get());\n\t\t});\n\t\treturn;\n\t}\n\n\tprops = getValidProps(_props);\n\n\tif (node instanceof HTMLElement) {\n\t\tsetSpecialProps(node, props);\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = (props as any)[prop];\n\t\t//console.log('setting prop', prop, propValue )\n\t\tif (isSignal(propValue)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t(node as any)[prop] = propValue.get();\n\t\t\t});\n\t\t} else if (propValue === undefined) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t(node as any)[prop] = propValue;\n\t\t}\n\t}\n}\n\nfunction parseAddClassProp(value: string | string[]): string[] {\n\tconst arr = typeof value === 'string' ? value.split(' ') : value;\n\treturn arr.filter((c) => c.trim() !== '');\n}\n\nfunction setSpecialProps<T extends HTMLElement>(node: T, props: INodeBuilderSpecialProps) {\n\tif (props.style !== undefined) {\n\t\tconst style = props.style;\n\t\tfor (const styleKey in style) {\n\t\t\tlet styleValue = style[styleKey]!;\n\t\t\tif (typeof styleValue === 'function') {\n\t\t\t\tstyleValue = computed(styleValue);\n\t\t\t}\n\t\t\tif (isSignal(styleValue)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.style[styleKey] = styleValue.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.style[styleKey] = styleValue;\n\t\t\t}\n\t\t}\n\t\tdelete props.style;\n\t}\n\n\tif (props.addClass !== undefined) {\n\t\tlet addClass = props.addClass;\n\t\tlet prevClass: string[] | null = null;\n\n\t\tif (typeof addClass === 'function') {\n\t\t\taddClass = computed(addClass);\n\t\t}\n\n\t\tif (isSignal(addClass)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\tconst classes = parseAddClassProp(addClass.get());\n\t\t\t\tconst classesToRemove = prevClass ? prevClass.filter((c) => !classes.includes(c)) : [];\n\t\t\t\tnode.classList.remove(...classesToRemove);\n\t\t\t\tnode.classList.add(...classes);\n\t\t\t\tprevClass = classes;\n\t\t\t});\n\t\t} else {\n\t\t\tconst toAdd = parseAddClassProp(addClass);\n\t\t\tnode.classList.add(...toAdd);\n\t\t}\n\t\tdelete props.addClass;\n\t}\n\n\tif (props.classes !== undefined) {\n\t\tconst classes = props.classes;\n\t\tfor (const className in classes) {\n\t\t\tlet apply = classes[className];\n\t\t\tif (typeof apply === 'function') {\n\t\t\t\tapply = computed(apply);\n\t\t\t}\n\t\t\tif (isSignal(apply)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tif (apply.get()) {\n\t\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (classes[className]) {\n\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t} else {\n\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdelete props.classes;\n\t}\n\n\tif (props.dataset !== undefined) {\n\t\tconst dataset = props.dataset;\n\t\tfor (const datasetKey in dataset) {\n\t\t\tlet ds = dataset[datasetKey];\n\t\t\tif (typeof ds === 'function') {\n\t\t\t\tds = computed(ds);\n\t\t\t}\n\t\t\tif (isSignal(ds)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.dataset[datasetKey] = ds.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.dataset[datasetKey] = ds;\n\t\t\t}\n\t\t}\n\t\tdelete props.dataset;\n\t}\n}\n\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContentReactive) {\n\tif (child === null) return;\n\tif (typeof child === 'function') {\n\t\tprocessSignalChild(node, computed(child));\n\t\treturn;\n\t}\n\tif (isSignal(child)) {\n\t\tprocessSignalChild(node, child);\n\t\treturn;\n\t}\n\tif (child instanceof Component || child instanceof ComponentList) {\n\t\tchild.mount(node, null);\n\t\treturn;\n\t}\n\tif (Array.isArray(child)) {\n\t\tchild.forEach((ch) => {\n\t\t\tappendChild(node, ch);\n\t\t});\n\t\treturn;\n\t}\n\tnode.appendChild(child instanceof Node ? child : document.createTextNode(child.toString()));\n}\n\nfunction isStaticArrayWithComponents(arr: ChispaContent): arr is (Component | ChispaNode)[] {\n\tif (!Array.isArray(arr)) return false;\n\tfor (const item of arr) {\n\t\tif (item instanceof Component) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaContent>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList | null = null;\n\n\tglobalContext.addReactivity(() => {\n\t\t//console.log('Signal child changed', child);\n\t\tconst ch = child.get();\n\t\tif (prevValue) {\n\t\t\tprevValue.unmount();\n\t\t}\n\t\tif (ch === null) {\n\t\t\tprevValue = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component | ComponentList;\n\t\tif (isStaticArrayWithComponents(ch)) {\n\t\t\tcomponent = new Component(() => {\n\t\t\t\tconst frag = document.createDocumentFragment();\n\t\t\t\tfor (const c of ch) {\n\t\t\t\t\tappendChild(frag, c);\n\t\t\t\t}\n\t\t\t\treturn frag;\n\t\t\t});\n\t\t\tcomponent.mount(node, anchor);\n\t\t} else if (ch instanceof Component || ch instanceof ComponentList) {\n\t\t\tch.mount(node, anchor);\n\t\t\tcomponent = ch;\n\t\t} else {\n\t\t\tconst wrCmp = new Component(() => toNode(ch));\n\t\t\t//wrCmp.silent = true;\n\t\t\twrCmp.mount(node, anchor);\n\t\t\tcomponent = wrCmp;\n\t\t}\n\t\tprevValue = component;\n\t});\n}\n\nfunction toNode(n: ChispaNode | ChispaNode[]): Node | null {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tconst nodes = n.map((c) => toNode(c)).filter((n) => n !== null);\n\t\tfrag.append(...nodes);\n\t\treturn frag;\n\t} else if (n instanceof Node) {\n\t\treturn n;\n\t} else if (typeof n === 'string' || typeof n === 'number') {\n\t\treturn document.createTextNode(n.toString());\n\t} else {\n\t\treturn null;\n\t\t//throw new Error('Invalid node type');\n\t}\n}\n","import { globalContext } from './context';\nimport { Signal, WritableSignal } from './signals';\n\nexport interface ControlledInputOptions<T> {\n\t/**\n\t * Optional function to transform the value before setting it to the signal.\n\t * Useful for enforcing uppercase, removing invalid characters, etc.\n\t */\n\ttransform?: (value: T) => T;\n\n\t/**\n\t * Optional function to validate the value.\n\t * If it returns false, the change is rejected and the previous value is restored.\n\t */\n\tvalidate?: (value: T) => boolean;\n}\n\nexport interface SelectOption {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n}\n\ntype InputValueType = string | number;\n\ninterface TypeConverter<T extends InputValueType> {\n\ttoTargetType: (val: string) => T;\n\tfromTargetType: (val: T) => string;\n}\n\nfunction getTypeConverter<T extends InputValueType>(exampleValue: T): TypeConverter<T> {\n\t// TODO: Extend for other types if needed. Also support partial parsing/formatting with invalid intermediate states (e.g. for dates or decimals)\n\tif (typeof exampleValue === 'number') {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => Number(val) as T,\n\t\t\tfromTargetType: (val: T) => val.toString(),\n\t\t} as const;\n\t} else {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => val as T,\n\t\t\tfromTargetType: (val: T) => val as string,\n\t\t} as const;\n\t}\n}\n\nexport function bindControlledInput<T extends InputValueType>(\n\telement: HTMLInputElement | HTMLTextAreaElement,\n\tsignal: WritableSignal<T>,\n\toptions: ControlledInputOptions<T> = {}\n) {\n\tconst { transform, validate } = options;\n\n\t// Get type converters based on the initial value type\n\tconst { toTargetType, fromTargetType } = getTypeConverter(signal.initialValue);\n\n\t// Initialize value\n\telement.value = fromTargetType(signal.initialValue);\n\n\t// Handle input events\n\tconst handleInput = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newValue = toTargetType(target.value);\n\t\tconst originalValue = signal.get();\n\n\t\t// Save cursor position\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\n\t\t// Apply transformation if provided\n\t\tif (transform) {\n\t\t\tnewValue = transform(newValue);\n\t\t}\n\n\t\t// Apply validation if provided\n\t\tif (validate && !validate(newValue)) {\n\t\t\t// If invalid, revert to original value\n\t\t\tnewValue = originalValue;\n\t\t}\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tsignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tconst newValueStr = fromTargetType(newValue);\n\t\tif (target.value !== newValueStr) {\n\t\t\tconst lengthDiff = target.value.length - newValueStr.length;\n\t\t\ttarget.value = newValueStr;\n\n\t\t\t// Restore cursor\n\t\t\tif (selectionStart !== null && selectionEnd !== null) {\n\t\t\t\t// Restore to the saved position.\n\t\t\t\t// Adjust for length difference to keep cursor relative to the content\n\t\t\t\tconst newStart = Math.max(0, selectionStart - lengthDiff);\n\t\t\t\tconst newEnd = Math.max(0, selectionEnd - lengthDiff);\n\t\t\t\ttarget.setSelectionRange(newStart, newEnd);\n\t\t\t}\n\t\t}\n\t};\n\n\telement.addEventListener('input', handleInput);\n\n\t// Subscribe to signal changes to update the input if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValueStr = fromTargetType(signal.get());\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValueStr) {\n\t\t\telement.value = newValueStr;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n\nexport function bindControlledCheckbox(element: HTMLInputElement, signal: WritableSignal<boolean>, indeterminate?: Signal<boolean>) {\n\t// Initialize checked state\n\telement.checked = signal.initialValue;\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newChecked = target.checked;\n\t\tconst originalValue = signal.get();\n\n\t\t// Update signal\n\t\tif (newChecked !== originalValue) {\n\t\t\tsignal.set(newChecked);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value\n\t\tif (target.checked !== newChecked) {\n\t\t\ttarget.checked = newChecked;\n\t\t}\n\t};\n\n\telement.addEventListener('change', handleChange);\n\n\t// Subscribe to signal changes to update the checkbox if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = signal.get();\n\t\tif (element.checked !== newValue) {\n\t\t\telement.checked = newValue;\n\t\t}\n\t});\n\n\t// Subscribe to indeterminate signal if provided as a Signal\n\tif (indeterminate) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\telement.indeterminate = indeterminate.get();\n\t\t});\n\t}\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n\nexport function bindControlledSelect(element: HTMLSelectElement, signal: WritableSignal<string>, optionsSignal?: Signal<SelectOption[]>) {\n\t// Function to update options\n\tconst updateOptions = (options: SelectOption[]) => {\n\t\t// Clear existing options\n\t\telement.innerHTML = '';\n\t\t// Add new options\n\t\toptions.forEach((option) => {\n\t\t\tconst optElement = document.createElement('option');\n\t\t\toptElement.value = option.value;\n\t\t\toptElement.textContent = option.label;\n\t\t\tif (option.disabled) {\n\t\t\t\toptElement.disabled = true;\n\t\t\t}\n\t\t\telement.appendChild(optElement);\n\t\t});\n\t\t// Ensure the current value is set\n\t\telement.value = signal.get();\n\t};\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLSelectElement;\n\t\tlet newValue = target.value;\n\t\tconst originalValue = signal.get();\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tsignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tif (target.value !== newValue) {\n\t\t\ttarget.value = newValue;\n\t\t}\n\t};\n\n\t// Subscribe to options signal changes if provided\n\tif (optionsSignal) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\tupdateOptions(optionsSignal.get());\n\t\t});\n\t}\n\n\t// Subscribe to signal changes to update the select if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = signal.get();\n\t\t// Only update if the value is actually different\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\telement.addEventListener('change', handleChange);\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n","import { signal, computed, Signal } from './signals';\nimport { component, Component, Dict } from './components';\nimport { appendChild, ChispaNodeBuilderProps, setProps } from './builder';\n\nexport interface Route {\n\tpath: string;\n\tcomponent: (props?: any) => Component<any>;\n}\n\nconst currentPath = signal(typeof window !== 'undefined' ? window.location.pathname : '/');\n\nif (typeof window !== 'undefined') {\n\twindow.addEventListener('popstate', () => {\n\t\tcurrentPath.set(window.location.pathname);\n\t});\n}\n\nexport function navigate(to: string, replace = false) {\n\tif (typeof window === 'undefined') {\n\t\tcurrentPath.set(to);\n\t\treturn;\n\t}\n\tif (replace) {\n\t\twindow.history.replaceState({}, '', to);\n\t} else {\n\t\twindow.history.pushState({}, '', to);\n\t}\n\tcurrentPath.set(to);\n}\n\nexport function pathMatches(path: string): Signal<boolean> {\n\treturn computed(() => {\n\t\tconst current = currentPath.get();\n\t\treturn match(path, current) !== null;\n\t});\n}\n\nfunction match(routePath: string, currentPath: string): Dict | null {\n\tif (routePath === '*') return {};\n\tconst routeParts = routePath.split('/').filter(Boolean);\n\tconst currentParts = currentPath.split('/').filter(Boolean);\n\tif (routeParts.length !== currentParts.length) return null;\n\tconst params: Dict = {};\n\tfor (let i = 0; i < routeParts.length; i++) {\n\t\tif (routeParts[i].startsWith(':')) {\n\t\t\tparams[routeParts[i].substring(1)] = currentParts[i];\n\t\t} else if (routeParts[i] !== currentParts[i]) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn params;\n}\n\nexport const Router = component<{ routes: Route[] }>((props) => {\n\tconst container = document.createElement('div');\n\tcontainer.style.display = 'contents';\n\tconst activeRoute = computed(() => {\n\t\tconst path = currentPath.get();\n\t\tfor (const route of props.routes) {\n\t\t\tconst params = match(route.path, path);\n\t\t\tif (params) {\n\t\t\t\treturn route.component(params);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t});\n\tappendChild(container, activeRoute);\n\treturn container;\n});\n\nexport interface LinkProps extends ChispaNodeBuilderProps<HTMLAnchorElement, {}> {\n\tto: string;\n}\n\nexport const Link = component<LinkProps>((props) => {\n\tconst { to, inner, ...rest } = props;\n\tconst a = document.createElement('a');\n\ta.href = to;\n\n\ta.addEventListener('click', (e) => {\n\t\tif (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented || e.button !== 0) {\n\t\t\treturn;\n\t\t}\n\t\te.preventDefault();\n\t\tnavigate(to);\n\t});\n\n\tif (inner) {\n\t\tappendChild(a, inner);\n\t}\n\n\tsetProps(a, rest);\n\n\treturn a;\n});\n"],"mappings":"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","names":["component","signal","component","index","component","n","signal","currentPath"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts","../src/router.ts"],"sourcesContent":["export const ChispaDebugConfig = {\n\tenableReactivityWarnings: false,\n};\n","import { Component, ComponentList } from './components';\nimport { ChispaDebugConfig } from './config';\nimport { Signal } from './signals';\n\ntype ExecutionKind = 'createComponent' | 'computed' | 'addReactivity';\n\nexport interface IDisposable {\n\tdispose: () => void;\n}\n\nclass AppContext {\n\tprivate reactivityContextStack: Reactivity[] = [];\n\n\tprivate refreshTimeout: any = 0;\n\n\t//private contexts = new Set<RenderContext>();\n\n\tprivate dirtyReactivities = new Set<Reactivity>();\n\n\tprivate executionStack: ExecutionKind[] = [];\n\n\tprivate componentStack: (Component | ComponentList)[] = [];\n\n\tpushComponentStack(cmp: Component | ComponentList) {\n\t\tthis.componentStack.push(cmp);\n\t}\n\n\tpopComponentStack() {\n\t\tthis.componentStack.pop();\n\t}\n\n\tgetCurrentComponent() {\n\t\tif (this.componentStack.length === 0) {\n\t\t\t//console.warn('No current component');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.componentStack[this.componentStack.length - 1];\n\t}\n\n\tsetCurrentReactivityContext(context: Reactivity) {\n\t\tthis.reactivityContextStack.push(context);\n\t\t//this.contexts.add(context);\n\t}\n\n\trestorePreviousReactivityContext() {\n\t\tthis.reactivityContextStack.pop();\n\t}\n\n\tgetCurrentRenderContext() {\n\t\tif (this.reactivityContextStack.length === 0) {\n\t\t\t//console.warn('No current render context');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.reactivityContextStack[this.reactivityContextStack.length - 1];\n\t}\n\n\t// Maximum number of iterations to process during a scheduled refresh. Prevents\n\t// unbounded loops in case of uncontrolled reactivity cascades. Use the\n\t// `globalContext.maxScheduleIterations` field to override in tests or\n\t// special cases.\n\tpublic maxScheduleIterations = 100;\n\n\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tlet iteration = 0;\n\t\t\t// Process dirty contexts until none remain, or until the iteration limit\n\t\t\t// is reached (this avoids infinite loops when reactivities keep\n\t\t\t// re-adding themselves or each other).\n\t\t\twhile (this.dirtyReactivities.size > 0 && iteration < this.maxScheduleIterations) {\n\t\t\t\titeration++;\n\t\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\n\t\t\t}\n\n\t\t\tif (this.dirtyReactivities.size > 0) {\n\t\t\t\t// Warn once if we stopped early due to the iteration limit. We also\n\t\t\t\t// clear the set to avoid repeated warnings and to avoid leaving the\n\t\t\t\t// system in a permanently spinning state.\n\t\t\t\tconsole.warn(`[AppContext.scheduleRefresh] possible uncontrolled reactivity cascade: processed ${iteration} iterations — aborting.`);\n\t\t\t\tthis.dirtyReactivities.clear();\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\taddReactivity(executor: () => void) {\n\t\tconst ctx = new Reactivity(executor);\n\t\tglobalContext.pushExecutionStack('addReactivity');\n\t\tctx.exec();\n\t\tglobalContext.popExecutionStack();\n\t\treturn ctx;\n\t}\n\n\tcreateRoot(component: () => Component, mountPoint: HTMLElement) {\n\t\tthis.dirtyReactivities.clear();\n\t\tmountPoint.innerHTML = '';\n\t\tconst cmp = component();\n\t\tcmp.mount(mountPoint, null);\n\t}\n\n\tcanReadSignal() {\n\t\tconst length = this.executionStack.length;\n\t\tif (length === 0) return true;\n\t\tconst current = this.executionStack[length - 1];\n\t\treturn current !== 'createComponent';\n\t}\n\n\tpushExecutionStack(type: ExecutionKind) {\n\t\tthis.executionStack.push(type);\n\t}\n\n\tpopExecutionStack() {\n\t\tthis.executionStack.pop();\n\t}\n\n\taddDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.add(ctx);\n\t}\n\n\tremoveDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.delete(ctx);\n\t}\n}\n\nexport class Reactivity implements IDisposable {\n\tprivate dirty: boolean = false;\n\n\tprivate signals = new Set<Signal<any>>();\n\n\tconstructor(private readonly action: () => void) {\n\t\tconst currentComponent = globalContext.getCurrentComponent();\n\t\tif (currentComponent) {\n\t\t\tcurrentComponent.addDisposable(this);\n\t\t} else {\n\t\t\tif (ChispaDebugConfig.enableReactivityWarnings) {\n\t\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t\t}\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\tthis.dirty = true;\n\t\tglobalContext.addDirtyContext(this);\n\t\tglobalContext.scheduleRefresh();\n\t}\n\n\taddSignal(signal: Signal<any>) {\n\t\tthis.signals.add(signal);\n\t}\n\n\tremoveSignal(signal: Signal<any>) {\n\t\tthis.signals.delete(signal);\n\t}\n\n\tprocess() {\n\t\tif (!this.dirty) return;\n\t\tthis.exec();\n\t\t//console.log('re-render cycle completed');\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n\n\texec() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tglobalContext.setCurrentReactivityContext(this);\n\t\tthis.action();\n\t\tglobalContext.restorePreviousReactivityContext();\n\t}\n\n\tdispose() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n}\n\nexport const globalContext = new AppContext();\n","import { globalContext, Reactivity } from './context';\n\ntype WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n\nabstract class Signal<T> {\n\tprotected abstract value: T;\n\n\tprotected contexts: Set<Reactivity> = new Set();\n\n\tconstructor() {}\n\n\tget() {\n\t\tif (!globalContext.canReadSignal()) {\n\t\t\tthrow new Error('Cannot read a signal value during component creation. Did you mean to use a computed signal instead?');\n\t\t}\n\t\t//context.current.register(this);\n\t\tconst ctx = globalContext.getCurrentRenderContext();\n\t\tif (ctx) {\n\t\t\tthis.contexts.add(ctx);\n\t\t\tctx.addSignal(this);\n\t\t}\n\t\treturn this.value;\n\t}\n\n\tpublic readonly computed = new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget: (_, prop) => {\n\t\t\t\treturn computed(() => this.get()[prop as keyof T]);\n\t\t\t},\n\t\t}\n\t) as WithSignals<T>;\n\n\tremoveContext(ctx: Reactivity) {\n\t\tthis.contexts.delete(ctx);\n\t}\n\n\tdispose() {\n\t\t//console.log('disposing signal', this);\n\t\tthis.contexts.forEach((ctx) => {\n\t\t\tctx.removeSignal(this);\n\t\t});\n\t\tthis.contexts.clear();\n\t}\n}\n\nclass WritableSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tpublic readonly initialValue: T;\n\n\tconstructor(initialValue: T) {\n\t\tsuper();\n\t\tthis.initialValue = initialValue;\n\t\tthis.value = initialValue;\n\t}\n\n\tset(newValue: T) {\n\t\tthis.value = newValue;\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n\n\tupdate(updater: (value: T) => T) {\n\t\tthis.value = updater(this.value);\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n}\n\nclass ComputedSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tprivate computeFn: () => T;\n\n\tconstructor(computeFn: () => T) {\n\t\tsuper();\n\t\tglobalContext.pushExecutionStack('computed');\n\t\tthis.value = computeFn();\n\t\tglobalContext.popExecutionStack();\n\t\tthis.computeFn = computeFn;\n\t}\n\n\trecompute() {\n\t\tconst newValue = this.computeFn();\n\t\tif (newValue !== this.value) {\n\t\t\tthis.value = newValue;\n\t\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t\t}\n\t}\n}\n\nexport function isSignal(value: any): value is Signal<any> {\n\treturn value instanceof Signal;\n}\n\nexport function isWriteableSignal<T>(value: Signal<T>): value is WritableSignal<T> {\n\treturn value instanceof WritableSignal;\n}\n\nexport function signal<T>(initialValue: T) {\n\tconst sig = new WritableSignal(initialValue);\n\n\t// // Creamos una función que se usará como callable\n\t// const fn = (() => sig.get()) as any;\n\n\t// // Copiamos todas las propiedades y métodos de la instancia a la función\n\t// Object.setPrototypeOf(fn, sig.constructor.prototype);\n\n\t// // Copiamos las propiedades de instancia\n\t// Object.assign(fn, this);\n\n\t// // Retornamos la función como si fuera la instancia\n\t// return fn as WritableSignal<T> & (() => T);\n\n\treturn sig;\n}\n\nexport function computed<T>(fn: () => T) {\n\tlet sig: ComputedSignal<T>;\n\tconst ctx = new Reactivity(() => {\n\t\tsig.recompute();\n\t});\n\tglobalContext.setCurrentReactivityContext(ctx);\n\tsig = new ComputedSignal(fn);\n\tglobalContext.restorePreviousReactivityContext();\n\n\treturn sig as Signal<T>;\n}\n\nexport function effect(fn: () => void) {\n\tglobalContext.addReactivity(fn);\n}\n\nexport type { Signal, WritableSignal };\n","import { ChispaContent } from './builder';\nimport { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => ChispaContent;\n\nexport class Component<TProps extends Dict = any> {\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tprivate disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\tconstructor(\n\t\tprivate readonly factoryFn: ComponentFactory<TProps>,\n\t\tpublic readonly key: any = null,\n\t\tpublic readonly props: TProps | null = null\n\t) {}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushExecutionStack('createComponent');\n\t\tglobalContext.pushComponentStack(this);\n\t\tconst node = this.factoryFn ? (this.factoryFn as any)(this.props) : null;\n\t\tglobalContext.popComponentStack();\n\t\tglobalContext.popExecutionStack();\n\t\t// if node is fragment, convert to array of nodes\n\t\tif (node) {\n\t\t\tif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n\t\t\t\tthis.nodes = Array.from(node.childNodes);\n\t\t\t} else {\n\t\t\t\tthis.nodes = [node];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.nodes = null;\n\t\t}\n\t\tthis.insertNodes();\n\t}\n\n\treanchor(anchor: Node | null) {\n\t\tthis.anchor = anchor;\n\n\t\t//console.log('reanchoring', this.nodes, ' before anchor', this.anchor);\n\t\tthis.insertNodes();\n\t}\n\n\tprivate insertNodes() {\n\t\tif (!this.container || !this.nodes) return;\n\t\t// Insertar en la nueva posición\n\t\tfor (const node of this.nodes) {\n\t\t\tif (this.anchor) {\n\t\t\t\tthis.container.insertBefore(node, this.anchor);\n\t\t\t} else {\n\t\t\t\tthis.container.appendChild(node);\n\t\t\t}\n\t\t}\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\n\t\tif (this.nodes) {\n\t\t\tthis.nodes.forEach((node) => {\n\t\t\t\tif (node && node.parentNode) {\n\t\t\t\t\tnode.parentNode.removeChild(node);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t\tthis.disposables = [];\n\t\tthis.nodes = null;\n\t\tthis.container = null;\n\t\tthis.anchor = null;\n\t}\n}\n\n// Definimos overloads para component\nexport function component(factory: ComponentFactory<any>): (props?: any) => Component;\nexport function component<TProps extends Dict>(factory: ComponentFactory<TProps>): (props: TProps) => Component<TProps>;\n\nexport function component<TProps extends Dict = any>(factory: ComponentFactory<TProps>) {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\nexport function onUnmount(unmountFn: () => void) {\n\tconst currentComponent = globalContext.getCurrentComponent();\n\tif (currentComponent) {\n\t\tcurrentComponent.addDisposable({\n\t\t\tdispose: unmountFn,\n\t\t});\n\t} else {\n\t\tthrow new Error('onUnmount must be called within a component context');\n\t}\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props?: TProps) => ChispaContent;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps extends Dict = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node | null = null; // Contenedor donde se montan los nodos\n\tprivate anchor: Node | null = null; // Nodes must be inserted before this node\n\tprivate currentKeys: any[] = [];\n\tpublic disposables: any[] = [];\n\n\tconstructor(\n\t\tprivate readonly itemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\t\tprivate readonly keyFn: KeyFn<TItem>,\n\t\tprivate readonly itemsSignal: Signal<TItem[]>,\n\t\tprivate readonly props: TProps | null = null\n\t) {\n\t\tthis.components = new Map();\n\t}\n\n\t/**\n\t * Obtiene todos los componentes\n\t */\n\tprivate getAllComponents(): Component[] {\n\t\treturn Array.from(this.components.values());\n\t}\n\n\t/**\n\t * Limpia todos los componentes\n\t */\n\tprivate clear(): void {\n\t\tArray.from(this.components.values()).forEach((component) => {\n\t\t\tthis.removeComponent(component);\n\t\t});\n\t}\n\n\t/**\n\t * Elimina un componente completo\n\t */\n\tprivate removeComponent(component: Component) {\n\t\tcomponent.unmount();\n\t\tif (component.key) {\n\t\t\tthis.components.delete(component.key);\n\t\t}\n\t}\n\n\t/**\n\t * Crea un nuevo componente\n\t */\n\tprivate createNewComponent(key: any): Component {\n\t\tconst factory = (props?: TProps) => {\n\t\t\tconst item = computed(() => this.itemsSignal.get().find((v, index) => this.keyFn(v, index) === key)!);\n\t\t\tconst index = computed(() => this.itemsSignal.get().findIndex((v, index) => this.keyFn(v, index) === key));\n\t\t\treturn this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props) : null;\n\t\t};\n\n\t\tconst component = new Component(factory, key, this.props);\n\t\tthis.components.set(key, component);\n\n\t\treturn component;\n\t}\n\n\tprivate getTargetAnchor(items: TItem[], index: number): Node | null {\n\t\tconst nextItem = index + 1 < items.length ? items[index + 1] : null;\n\t\tconst nextComp = nextItem ? this.components.get(this.keyFn(nextItem, index + 1)) : null;\n\t\tif (nextComp && nextComp.nodes) {\n\t\t\treturn nextComp.nodes[0];\n\t\t} else {\n\t\t\t// Es el último componente, debería insertarse antes del anchor original\n\t\t\treturn this.anchor;\n\t\t}\n\t}\n\n\t/**\n\t * Función principal que sincroniza los componentes DOM con un array de keys\n\t */\n\tprivate synchronizeComponents(): void {\n\t\tconst existingComponents = this.getAllComponents();\n\n\t\t// Identificar qué componentes eliminar (los que no están en keys)\n\t\tconst items = this.itemsSignal.get();\n\t\tconst keys = items.map((item, index) => this.keyFn(item, index));\n\t\tconst componentsToRemove = existingComponents.filter((component) => component.key && !keys.includes(component.key));\n\t\tcomponentsToRemove.forEach((component) => this.removeComponent(component));\n\n\t\tthis.currentKeys = this.currentKeys.filter((key) => keys.includes(key));\n\t\t//console.log('Current keys:', this.currentKeys, 'Target keys:', keys);\n\n\t\tif (!this.container) {\n\t\t\tconsole.warn('Container is null in synchronizeComponents');\n\t\t\treturn;\n\t\t}\n\t\t// Procesar cada key en el orden deseado\n\t\tconst container = this.container;\n\n\t\titems.forEach((item, index) => {\n\t\t\tconst targetKey = this.keyFn(item, index);\n\t\t\tconst currentKey = this.currentKeys[index];\n\t\t\tif (targetKey === currentKey) {\n\t\t\t\t// La key no ha cambiado de posición, no hacer nada\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst existingComponent = this.components.get(targetKey);\n\n\t\t\tif (existingComponent) {\n\t\t\t\tconst prevComp = this.components.get(currentKey);\n\t\t\t\tif (!prevComp || !prevComp.nodes) {\n\t\t\t\t\tconsole.warn('Previous component or its nodes not found for key', currentKey);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texistingComponent.reanchor(prevComp.nodes[0]);\n\t\t\t\t// Reordenar el array de keys actuales\n\t\t\t\tthis.currentKeys = this.currentKeys.filter((k) => k !== targetKey);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t} else {\n\t\t\t\t// El componente no existe, crearlo\n\t\t\t\tconst targetAnchor = this.getTargetAnchor(items, index);\n\t\t\t\tconst newComponent = this.createNewComponent(targetKey);\n\t\t\t\tnewComponent.mount(container, targetAnchor);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t}\n\t\t});\n\t}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushComponentStack(this);\n\t\tglobalContext.addReactivity(() => {\n\t\t\tthis.synchronizeComponents();\n\t\t});\n\t\tglobalContext.popComponentStack();\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\t//console.log('Unmounting ComponentList');\n\t\tthis.clear();\n\t\tthis.container = null!;\n\t\tthis.anchor = null!;\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t}\n}\n\n// Definimos overloads para componentList\nexport function componentList<TItem>(\n\titemFactoryFn: ItemFactoryFn<TItem, any>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props: TProps) => ComponentList<TItem, TProps>;\n\nexport function componentList<TItem, TProps extends Dict = any>(itemFactoryFn: ItemFactoryFn<TItem, TProps>, keyFn: KeyFn<TItem>) {\n\treturn (listSignal: Signal<TItem[]>, props?: TProps) => {\n\t\tconst list = new ComponentList(itemFactoryFn, keyFn, listSignal, props);\n\t\treturn list;\n\t};\n}\n","import { Component, ComponentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, type Signal } from './signals';\n\nexport type ChispaReactive<T> = T | Signal<T> | (() => T);\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | Component | (ChispaNode | Component)[] | ComponentList;\nexport type ChispaContentReactive = ChispaReactive<ChispaContent>;\nexport type ChispaClasses = Record<string, ChispaReactive<boolean>>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: ChispaReactive<string>;\n};\n\ntype EventPropKeys<T> = Extract<keyof T, `on${string}`>;\ntype AllowSignals<T> = { [K in keyof T]: ChispaReactive<T[K]> };\n\ntype ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<T, 'style' | 'dataset' | EventPropKeys<T>>> & Pick<T, EventPropKeys<T>>;\ninterface INodeBuilderSpecialProps {\n\taddClass?: ChispaReactive<string | string[]>;\n\tclasses?: ChispaClasses;\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, ChispaReactive<string>>;\n}\ninterface INodeBuilderAdditionalProps<T, TNodes> {\n\tnodes?: TNodes;\n\tinner?: ChispaContentReactive;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaNodeBuilderProps<T, TNodes> = Partial<ChispaNodeBuilderBaseProps<T>> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;\nexport type ChispaNodeBuilderPropsReactive<T, TNodes> = ChispaReactive<ChispaNodeBuilderProps<T, TNodes>>;\n\nconst forbiddenProps = ['nodes', 'inner', '_ref'];\n\nexport function getValidProps<T>(props: ChispaNodeBuilderProps<T, any>) {\n\tconst finalProps: any = {};\n\n\tfor (const propName in props) {\n\t\tif (!forbiddenProps.includes(propName)) {\n\t\t\tfinalProps[propName] = props[propName as keyof typeof props];\n\t\t}\n\t}\n\n\treturn finalProps as ChispaNodeBuilderProps<T, any>;\n}\n\nconst itemsStack: any[] = [];\nfunction findItemInStack(itemName: string): any {\n\tfor (const itemsDefs of itemsStack) {\n\t\tif (itemsDefs && itemsDefs[itemName]) {\n\t\t\treturn itemsDefs[itemName];\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function getItem<T>(template: T, items: any, itemName: keyof T) {\n\titemsStack.unshift(items);\n\tconst item: any = findItemInStack(itemName as string);\n\n\tif (!item) {\n\t\titemsStack.shift();\n\t\treturn null;\n\t}\n\n\tlet res;\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = template[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\tres = Comp(itemProps);\n\t} else {\n\t\tres = item;\n\t}\n\titemsStack.shift();\n\treturn res;\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr];\n\t\tif (attrValue === undefined || attrValue === null) {\n\t\t\tnode.removeAttribute(attr);\n\t\t\tcontinue;\n\t\t}\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nfunction isEventProp(prop: string) {\n\treturn prop.startsWith('on');\n}\n\nfunction getPropValue(props: any, prop: string) {\n\tconst propValue = props[prop];\n\tif (typeof propValue === 'function' && !isEventProp(prop)) {\n\t\treturn computed(propValue);\n\t}\n\treturn propValue;\n}\n\nexport function setProps<T extends Element>(node: T, props: ChispaNodeBuilderPropsReactive<T, any>) {\n\tlet _props = props;\n\tif (typeof _props === 'function') {\n\t\t_props = computed(_props);\n\t}\n\tif (isSignal(_props)) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\tsetProps(node, _props.get());\n\t\t});\n\t\treturn;\n\t}\n\n\tprops = getValidProps(_props);\n\n\tif (node instanceof HTMLElement) {\n\t\tsetSpecialProps(node, props);\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = getPropValue(props, prop);\n\t\t//console.log('setting prop', prop, propValue )\n\t\tif (isSignal(propValue)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t(node as any)[prop] = propValue.get();\n\t\t\t});\n\t\t} else if (propValue === undefined) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t(node as any)[prop] = propValue;\n\t\t}\n\t}\n}\n\nfunction parseAddClassProp(value: string | string[]): string[] {\n\tconst arr = typeof value === 'string' ? value.split(' ') : value;\n\treturn arr.filter((c) => c.trim() !== '');\n}\n\nfunction setSpecialProps<T extends HTMLElement>(node: T, props: INodeBuilderSpecialProps) {\n\tif (props.style !== undefined) {\n\t\tconst style = props.style;\n\t\tfor (const styleKey in style) {\n\t\t\tlet styleValue = style[styleKey]!;\n\t\t\tif (typeof styleValue === 'function') {\n\t\t\t\tstyleValue = computed(styleValue);\n\t\t\t}\n\t\t\tif (isSignal(styleValue)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.style[styleKey] = styleValue.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.style[styleKey] = styleValue;\n\t\t\t}\n\t\t}\n\t\tdelete props.style;\n\t}\n\n\tif (props.addClass !== undefined) {\n\t\tlet addClass = props.addClass;\n\t\tlet prevClass: string[] | null = null;\n\n\t\tif (typeof addClass === 'function') {\n\t\t\taddClass = computed(addClass);\n\t\t}\n\n\t\tif (isSignal(addClass)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\tconst classes = parseAddClassProp(addClass.get());\n\t\t\t\tconst classesToRemove = prevClass ? prevClass.filter((c) => !classes.includes(c)) : [];\n\t\t\t\tnode.classList.remove(...classesToRemove);\n\t\t\t\tnode.classList.add(...classes);\n\t\t\t\tprevClass = classes;\n\t\t\t});\n\t\t} else {\n\t\t\tconst toAdd = parseAddClassProp(addClass);\n\t\t\tnode.classList.add(...toAdd);\n\t\t}\n\t\tdelete props.addClass;\n\t}\n\n\tif (props.classes !== undefined) {\n\t\tconst classes = props.classes;\n\t\tfor (const className in classes) {\n\t\t\tlet apply = classes[className];\n\t\t\tif (typeof apply === 'function') {\n\t\t\t\tapply = computed(apply);\n\t\t\t}\n\t\t\tif (isSignal(apply)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tif (apply.get()) {\n\t\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (classes[className]) {\n\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t} else {\n\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdelete props.classes;\n\t}\n\n\tif (props.dataset !== undefined) {\n\t\tconst dataset = props.dataset;\n\t\tfor (const datasetKey in dataset) {\n\t\t\tlet ds = dataset[datasetKey];\n\t\t\tif (typeof ds === 'function') {\n\t\t\t\tds = computed(ds);\n\t\t\t}\n\t\t\tif (isSignal(ds)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.dataset[datasetKey] = ds.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.dataset[datasetKey] = ds;\n\t\t\t}\n\t\t}\n\t\tdelete props.dataset;\n\t}\n}\n\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContentReactive) {\n\tif (child === null) return;\n\tif (typeof child === 'function') {\n\t\tprocessSignalChild(node, computed(child));\n\t\treturn;\n\t}\n\tif (isSignal(child)) {\n\t\tprocessSignalChild(node, child);\n\t\treturn;\n\t}\n\tif (child instanceof Component || child instanceof ComponentList) {\n\t\tchild.mount(node, null);\n\t\treturn;\n\t}\n\tif (Array.isArray(child)) {\n\t\tchild.forEach((ch) => {\n\t\t\tappendChild(node, ch);\n\t\t});\n\t\treturn;\n\t}\n\tnode.appendChild(child instanceof Node ? child : document.createTextNode(child.toString()));\n}\n\nfunction isStaticArrayWithComponents(arr: ChispaContent): arr is (Component | ChispaNode)[] {\n\tif (!Array.isArray(arr)) return false;\n\tfor (const item of arr) {\n\t\tif (item instanceof Component) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaContent>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList | null = null;\n\n\tglobalContext.addReactivity(() => {\n\t\t//console.log('Signal child changed', child);\n\t\tconst ch = child.get();\n\t\tif (prevValue) {\n\t\t\tprevValue.unmount();\n\t\t}\n\t\tif (ch === null) {\n\t\t\tprevValue = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component | ComponentList;\n\t\tif (isStaticArrayWithComponents(ch)) {\n\t\t\tcomponent = new Component(() => {\n\t\t\t\tconst frag = document.createDocumentFragment();\n\t\t\t\tfor (const c of ch) {\n\t\t\t\t\tappendChild(frag, c);\n\t\t\t\t}\n\t\t\t\treturn frag;\n\t\t\t});\n\t\t\tcomponent.mount(node, anchor);\n\t\t} else if (ch instanceof Component || ch instanceof ComponentList) {\n\t\t\tch.mount(node, anchor);\n\t\t\tcomponent = ch;\n\t\t} else {\n\t\t\tconst wrCmp = new Component(() => toNode(ch));\n\t\t\t//wrCmp.silent = true;\n\t\t\twrCmp.mount(node, anchor);\n\t\t\tcomponent = wrCmp;\n\t\t}\n\t\tprevValue = component;\n\t});\n}\n\nfunction toNode(n: ChispaNode | ChispaNode[]): Node | null {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tconst nodes = n.map((c) => toNode(c)).filter((n) => n !== null);\n\t\tfrag.append(...nodes);\n\t\treturn frag;\n\t} else if (n instanceof Node) {\n\t\treturn n;\n\t} else if (typeof n === 'string' || typeof n === 'number') {\n\t\treturn document.createTextNode(n.toString());\n\t} else {\n\t\treturn null;\n\t\t//throw new Error('Invalid node type');\n\t}\n}\n","import { appendChild, setProps } from './builder';\nimport { componentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, Signal, WritableSignal } from './signals';\n\nexport interface ControlledInputOptions<T> {\n\t/**\n\t * Optional function to transform the value before setting it to the signal.\n\t * Useful for enforcing uppercase, removing invalid characters, etc.\n\t */\n\ttransform?: (value: T) => T;\n\n\t/**\n\t * Optional function to validate the value.\n\t * If it returns false, the change is rejected and the previous value is restored.\n\t */\n\tvalidate?: (value: T) => boolean;\n}\n\nexport interface SelectOption {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n}\n\ntype InputValueType = string | number;\n\ninterface TypeConverter<T extends InputValueType> {\n\ttoTargetType: (val: string) => T;\n\tfromTargetType: (val: T) => string;\n}\n\nfunction getTypeConverter<T extends InputValueType>(exampleValue: T): TypeConverter<T> {\n\t// TODO: Extend for other types if needed. Also support partial parsing/formatting with invalid intermediate states (e.g. for dates or decimals)\n\tif (typeof exampleValue === 'number') {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => Number(val) as T,\n\t\t\tfromTargetType: (val: T) => val.toString(),\n\t\t} as const;\n\t} else {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => val as T,\n\t\t\tfromTargetType: (val: T) => val as string,\n\t\t} as const;\n\t}\n}\n\nexport function bindControlledInput<T extends InputValueType>(\n\telement: HTMLInputElement | HTMLTextAreaElement,\n\tvalueSignal: WritableSignal<T>,\n\toptions: ControlledInputOptions<T> = {}\n) {\n\tconst { transform, validate } = options;\n\n\t// Get type converters based on the initial value type\n\tconst { toTargetType, fromTargetType } = getTypeConverter(valueSignal.initialValue);\n\n\t// Initialize value\n\telement.value = fromTargetType(valueSignal.initialValue);\n\n\t// Handle input events\n\tconst handleInput = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newValue = toTargetType(target.value);\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Save cursor position\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\n\t\t// Apply transformation if provided\n\t\tif (transform) {\n\t\t\tnewValue = transform(newValue);\n\t\t}\n\n\t\t// Apply validation if provided\n\t\tif (validate && !validate(newValue)) {\n\t\t\t// If invalid, revert to original value\n\t\t\tnewValue = originalValue;\n\t\t}\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tconst newValueStr = fromTargetType(newValue);\n\t\tif (target.value !== newValueStr) {\n\t\t\tconst lengthDiff = target.value.length - newValueStr.length;\n\t\t\ttarget.value = newValueStr;\n\n\t\t\t// Restore cursor\n\t\t\tif (selectionStart !== null && selectionEnd !== null) {\n\t\t\t\t// Restore to the saved position.\n\t\t\t\t// Adjust for length difference to keep cursor relative to the content\n\t\t\t\tconst newStart = Math.max(0, selectionStart - lengthDiff);\n\t\t\t\tconst newEnd = Math.max(0, selectionEnd - lengthDiff);\n\t\t\t\ttarget.setSelectionRange(newStart, newEnd);\n\t\t\t}\n\t\t}\n\t};\n\n\telement.addEventListener('input', handleInput);\n\n\t// Subscribe to signal changes to update the input if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValueStr = fromTargetType(valueSignal.get());\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValueStr) {\n\t\t\telement.value = newValueStr;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n\nexport function bindControlledCheckbox(element: HTMLInputElement, valueSignal: WritableSignal<boolean>, indeterminate?: Signal<boolean>) {\n\t// Initialize checked state\n\telement.checked = valueSignal.initialValue;\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newChecked = target.checked;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newChecked !== originalValue) {\n\t\t\tvalueSignal.set(newChecked);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value\n\t\tif (target.checked !== newChecked) {\n\t\t\ttarget.checked = newChecked;\n\t\t}\n\t};\n\n\telement.addEventListener('change', handleChange);\n\n\t// Subscribe to signal changes to update the checkbox if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\tif (element.checked !== newValue) {\n\t\t\telement.checked = newValue;\n\t\t}\n\t});\n\n\t// Subscribe to indeterminate signal if provided as a Signal\n\tif (indeterminate) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\telement.indeterminate = indeterminate.get();\n\t\t});\n\t}\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n\nexport function bindControlledSelect(element: HTMLSelectElement, valueSignal: WritableSignal<string>, optionList?: Signal<SelectOption[]> | SelectOption[]) {\n\tconst Options = componentList<SelectOption>(\n\t\t(option) => {\n\t\t\tconst optElement = document.createElement('option');\n\t\t\tsetProps(optElement, {\n\t\t\t\tvalue: () => option.get().value ?? '',\n\t\t\t\ttextContent: () => option.get().label ?? '',\n\t\t\t\tdisabled: () => option.get().disabled ?? false,\n\t\t\t});\n\t\t\treturn optElement;\n\t\t},\n\t\t(o) => o.value\n\t);\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLSelectElement;\n\t\tlet newValue = target.value;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tif (target.value !== newValue) {\n\t\t\ttarget.value = newValue;\n\t\t}\n\t};\n\n\t// Subscribe to options signal changes if provided\n\tif (optionList) {\n\t\tconst optionsSignal = isSignal(optionList) ? optionList : computed(() => optionList || []);\n\n\t\telement.innerHTML = '';\n\t\tappendChild(element, Options(optionsSignal));\n\t\tglobalContext.addReactivity(() => {\n\t\t\tconst currValue = valueSignal.get();\n\t\t\t// If the current value is not in the new options, reset it\n\t\t\tif (!optionsSignal.get().some((opt) => opt.value === currValue)) {\n\t\t\t\telement.value = '';\n\t\t\t} else if (element.value !== currValue) {\n\t\t\t\telement.value = currValue;\n\t\t\t}\n\t\t});\n\t}\n\n\t// Subscribe to signal changes to update the select if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\t// Only update if the value is actually different\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\telement.addEventListener('change', handleChange);\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n","import { signal, computed, Signal } from './signals';\nimport { component, Component, Dict } from './components';\nimport { appendChild, ChispaNodeBuilderProps, setProps } from './builder';\n\nexport interface Route {\n\tpath: string;\n\tcomponent: (props?: any) => Component<any>;\n}\n\nconst currentPath = signal(typeof window !== 'undefined' ? window.location.pathname : '/');\n\nif (typeof window !== 'undefined') {\n\twindow.addEventListener('popstate', () => {\n\t\tcurrentPath.set(window.location.pathname);\n\t});\n}\n\nexport function navigate(to: string, replace = false) {\n\tif (typeof window === 'undefined') {\n\t\tcurrentPath.set(to);\n\t\treturn;\n\t}\n\tif (replace) {\n\t\twindow.history.replaceState({}, '', to);\n\t} else {\n\t\twindow.history.pushState({}, '', to);\n\t}\n\tcurrentPath.set(to);\n}\n\nexport function pathMatches(path: string): Signal<boolean> {\n\treturn computed(() => {\n\t\tconst current = currentPath.get();\n\t\treturn match(path, current) !== null;\n\t});\n}\n\nfunction match(routePath: string, currentPath: string): Dict | null {\n\tif (routePath === '*') return {};\n\tconst routeParts = routePath.split('/').filter(Boolean);\n\tconst currentParts = currentPath.split('/').filter(Boolean);\n\tif (routeParts.length !== currentParts.length) return null;\n\tconst params: Dict = {};\n\tfor (let i = 0; i < routeParts.length; i++) {\n\t\tif (routeParts[i].startsWith(':')) {\n\t\t\tparams[routeParts[i].substring(1)] = currentParts[i];\n\t\t} else if (routeParts[i] !== currentParts[i]) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn params;\n}\n\nexport const Router = component<{ routes: Route[] }>((props) => {\n\tconst container = document.createElement('div');\n\tcontainer.style.display = 'contents';\n\tconst activeRoute = computed(() => {\n\t\tconst path = currentPath.get();\n\t\tfor (const route of props.routes) {\n\t\t\tconst params = match(route.path, path);\n\t\t\tif (params) {\n\t\t\t\treturn route.component(params);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t});\n\tappendChild(container, activeRoute);\n\treturn container;\n});\n\nexport interface LinkProps extends ChispaNodeBuilderProps<HTMLAnchorElement, {}> {\n\tto: string;\n}\n\nexport const Link = component<LinkProps>((props) => {\n\tconst { to, inner, ...rest } = props;\n\tconst a = document.createElement('a');\n\ta.href = to;\n\n\ta.addEventListener('click', (e) => {\n\t\tif (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented || e.button !== 0) {\n\t\t\treturn;\n\t\t}\n\t\te.preventDefault();\n\t\tnavigate(to);\n\t});\n\n\tif (inner) {\n\t\tappendChild(a, inner);\n\t}\n\n\tsetProps(a, rest);\n\n\treturn a;\n});\n"],"mappings":"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","names":["component","signal","component","index","component","n","currentPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chispa",
3
- "version": "0.8.2",
3
+ "version": "0.9.1",
4
4
  "description": "A fully declarative UI reactive engine for building web applications.",
5
5
  "author": "José Carlos HR <joecarlhr@gmail.com>",
6
6
  "license": "MIT",