chispa 0.2.5 → 0.2.6

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.
@@ -170,7 +170,7 @@ var HtmlCompiler = class _HtmlCompiler {
170
170
  return htmlNodeCode.trim();
171
171
  }
172
172
  static getPropsTypename(cbid) {
173
- return "T" + cbid.charAt(0).toUpperCase() + cbid.slice(1) + "Props";
173
+ return "Chispa" + cbid.charAt(0).toUpperCase() + cbid.slice(1) + "Props";
174
174
  }
175
175
  wrapFnComponent(cbid, jsx) {
176
176
  const typename = _HtmlCompiler.getPropsTypename(cbid);
@@ -198,7 +198,7 @@ var HtmlCompiler = class _HtmlCompiler {
198
198
  let itemsType = "{\n";
199
199
  items.forEach((itemCbid) => {
200
200
  const itemTypename = _HtmlCompiler.getPropsTypename(itemCbid);
201
- itemsType += `${itemCbid}?: ${itemTypename} | TContent;
201
+ itemsType += `${itemCbid}?: ${itemTypename} | ChispaContent;
202
202
  `;
203
203
  });
204
204
  itemsType += "}\n";
@@ -208,9 +208,9 @@ var HtmlCompiler = class _HtmlCompiler {
208
208
  } else {
209
209
  const tagname = this.componentsTags[cbid];
210
210
  if (this.isSvg[cbid]) {
211
- return `type ${typename} = TItemBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;
211
+ return `type ${typename} = ChispaNodeBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;
212
212
  } else {
213
- return `type ${typename} = TItemBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;
213
+ return `type ${typename} = ChispaNodeBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;
214
214
  }
215
215
  }
216
216
  }
@@ -224,8 +224,9 @@ var HtmlCompiler = class _HtmlCompiler {
224
224
  `;
225
225
  }
226
226
  const jsOutput = `
227
- import { appendChild, getItem, getValidProps, buildClass, setAttributes, setProps, TContent, TItemBuilderProps } from 'chispa';
228
-
227
+ import { appendChild, getItem, getValidProps, buildClass, setAttributes, setProps } from 'chispa';
228
+ import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';
229
+
229
230
  const SVG_NS = 'http://www.w3.org/2000/svg';
230
231
 
231
232
  const Components = {
@@ -235,7 +236,7 @@ var HtmlCompiler = class _HtmlCompiler {
235
236
  export default Components;
236
237
  `;
237
238
  const dtsOutput = `
238
- import { TContent, TItemBuilderProps } from 'chispa';
239
+ import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';
239
240
 
240
241
  ${typedefs}
241
242
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/html-compiler/generator.ts","../../src/html-compiler/html-compiler.ts","../../src/html-compiler/cli.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = 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 function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfiles.forEach((file) => {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) return;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(fullPath, content, rootDir);\n\t\t}\n\t});\n}\n","import { JSDOM } from 'jsdom';\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\tif (isComponent) {\n\t\t\tfinalClass = `buildClass('${finalClass}', props.addClass, props.classes)`;\n\t\t\treturn ` 'class': ${finalClass}, `;\n\t\t} else {\n\t\t\treturn ` 'class': \"${finalClass}\", `;\n\t\t}\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\tattrValue = attrValue.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"');\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}': \"${attrValue}\", `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': \"${attrValue}\", `;\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\n\t\t\t\tif (!this.componentsItems[currComp]) {\n\t\t\t\t\tthis.componentsItems[currComp] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.componentsItems[currComp].push(cbid);\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(Components, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(Components, 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, getValidProps(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 'T' + 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} | TContent;\\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} = TItemBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = TItemBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic compile(): { js: 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, getValidProps, buildClass, setAttributes, setProps, TContent, TItemBuilderProps } from 'chispa';\n\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const Components = {\n ${componentsClasses}\n };\n \n export default Components;\n `;\n\n\t\tconst dtsOutput = `\n import { TContent, TItemBuilderProps } from 'chispa';\n \n ${typedefs}\n \n declare const Components: {\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 Components;\n `;\n\n\t\treturn { js: jsOutput, dts: dtsOutput };\n\t}\n}\n","#!/usr/bin/env node\nimport { findAndCompileHtmlFiles } from './generator';\n\nconst args = process.argv.slice(2);\n\nif (args.includes('--compile-html')) {\n\tconst rootDir = process.cwd();\n\tconsole.log('Scanning for HTML files...');\n\tfindAndCompileHtmlFiles(rootDir, rootDir);\n\tconsole.log('HTML compilation completed.');\n} else {\n\tconsole.log('Usage: chispa-cli --compile-html');\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/html-compiler/generator.ts","../../src/html-compiler/html-compiler.ts","../../src/html-compiler/cli.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = 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 function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfiles.forEach((file) => {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) return;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(fullPath, content, rootDir);\n\t\t}\n\t});\n}\n","import { JSDOM } from 'jsdom';\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\tif (isComponent) {\n\t\t\tfinalClass = `buildClass('${finalClass}', props.addClass, props.classes)`;\n\t\t\treturn ` 'class': ${finalClass}, `;\n\t\t} else {\n\t\t\treturn ` 'class': \"${finalClass}\", `;\n\t\t}\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\tattrValue = attrValue.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"');\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}': \"${attrValue}\", `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': \"${attrValue}\", `;\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\n\t\t\t\tif (!this.componentsItems[currComp]) {\n\t\t\t\t\tthis.componentsItems[currComp] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.componentsItems[currComp].push(cbid);\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(Components, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(Components, 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, getValidProps(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 'Chispa' + 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} | ChispaContent;\\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} = ChispaNodeBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic compile(): { js: 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, getValidProps, buildClass, setAttributes, setProps } from 'chispa';\n import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';\n\t\t\t\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const Components = {\n ${componentsClasses}\n };\n \n export default Components;\n `;\n\n\t\tconst dtsOutput = `\n import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';\n \n ${typedefs}\n \n declare const Components: {\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 Components;\n `;\n\n\t\treturn { js: jsOutput, dts: dtsOutput };\n\t}\n}\n","#!/usr/bin/env node\nimport { findAndCompileHtmlFiles } from './generator';\n\nconst args = process.argv.slice(2);\n\nif (args.includes('--compile-html')) {\n\tconst rootDir = process.cwd();\n\tconsole.log('Scanning for HTML files...');\n\tfindAndCompileHtmlFiles(rootDir, rootDir);\n\tconsole.log('HTML compilation completed.');\n} else {\n\tconsole.log('Usage: chispa-cli --compile-html');\n}\n"],"mappings":"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","names":[]}
@@ -164,7 +164,7 @@ var HtmlCompiler = class _HtmlCompiler {
164
164
  return htmlNodeCode.trim();
165
165
  }
166
166
  static getPropsTypename(cbid) {
167
- return "T" + cbid.charAt(0).toUpperCase() + cbid.slice(1) + "Props";
167
+ return "Chispa" + cbid.charAt(0).toUpperCase() + cbid.slice(1) + "Props";
168
168
  }
169
169
  wrapFnComponent(cbid, jsx) {
170
170
  const typename = _HtmlCompiler.getPropsTypename(cbid);
@@ -192,7 +192,7 @@ var HtmlCompiler = class _HtmlCompiler {
192
192
  let itemsType = "{\n";
193
193
  items.forEach((itemCbid) => {
194
194
  const itemTypename = _HtmlCompiler.getPropsTypename(itemCbid);
195
- itemsType += `${itemCbid}?: ${itemTypename} | TContent;
195
+ itemsType += `${itemCbid}?: ${itemTypename} | ChispaContent;
196
196
  `;
197
197
  });
198
198
  itemsType += "}\n";
@@ -202,9 +202,9 @@ var HtmlCompiler = class _HtmlCompiler {
202
202
  } else {
203
203
  const tagname = this.componentsTags[cbid];
204
204
  if (this.isSvg[cbid]) {
205
- return `type ${typename} = TItemBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;
205
+ return `type ${typename} = ChispaNodeBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;
206
206
  } else {
207
- return `type ${typename} = TItemBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;
207
+ return `type ${typename} = ChispaNodeBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;
208
208
  }
209
209
  }
210
210
  }
@@ -218,8 +218,9 @@ var HtmlCompiler = class _HtmlCompiler {
218
218
  `;
219
219
  }
220
220
  const jsOutput = `
221
- import { appendChild, getItem, getValidProps, buildClass, setAttributes, setProps, TContent, TItemBuilderProps } from 'chispa';
222
-
221
+ import { appendChild, getItem, getValidProps, buildClass, setAttributes, setProps } from 'chispa';
222
+ import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';
223
+
223
224
  const SVG_NS = 'http://www.w3.org/2000/svg';
224
225
 
225
226
  const Components = {
@@ -229,7 +230,7 @@ var HtmlCompiler = class _HtmlCompiler {
229
230
  export default Components;
230
231
  `;
231
232
  const dtsOutput = `
232
- import { TContent, TItemBuilderProps } from 'chispa';
233
+ import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';
233
234
 
234
235
  ${typedefs}
235
236
 
@@ -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';\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\tif (isComponent) {\n\t\t\tfinalClass = `buildClass('${finalClass}', props.addClass, props.classes)`;\n\t\t\treturn ` 'class': ${finalClass}, `;\n\t\t} else {\n\t\t\treturn ` 'class': \"${finalClass}\", `;\n\t\t}\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\tattrValue = attrValue.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"');\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}': \"${attrValue}\", `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': \"${attrValue}\", `;\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\n\t\t\t\tif (!this.componentsItems[currComp]) {\n\t\t\t\t\tthis.componentsItems[currComp] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.componentsItems[currComp].push(cbid);\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(Components, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(Components, 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, getValidProps(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 'T' + 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} | TContent;\\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} = TItemBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = TItemBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic compile(): { js: 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, getValidProps, buildClass, setAttributes, setProps, TContent, TItemBuilderProps } from 'chispa';\n\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const Components = {\n ${componentsClasses}\n };\n \n export default Components;\n `;\n\n\t\tconst dtsOutput = `\n import { TContent, TItemBuilderProps } from 'chispa';\n \n ${typedefs}\n \n declare const Components: {\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 Components;\n `;\n\n\t\treturn { js: jsOutput, dts: dtsOutput };\n\t}\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = 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 function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfiles.forEach((file) => {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) return;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(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\tbuildStart() {\n\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(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 { js } = compiler.compile();\n\t\t\t\t\tgenerateTypes(realId, content, rootDir);\n\n\t\t\t\t\tconst result = await transformWithEsbuild(js, 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';\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\tif (isComponent) {\n\t\t\tfinalClass = `buildClass('${finalClass}', props.addClass, props.classes)`;\n\t\t\treturn ` 'class': ${finalClass}, `;\n\t\t} else {\n\t\t\treturn ` 'class': \"${finalClass}\", `;\n\t\t}\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\tattrValue = attrValue.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"');\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}': \"${attrValue}\", `;\n\t\t\t} else {\n\t\t\t\tattrsHtml += ` '${attrName}': \"${attrValue}\", `;\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\n\t\t\t\tif (!this.componentsItems[currComp]) {\n\t\t\t\t\tthis.componentsItems[currComp] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.componentsItems[currComp].push(cbid);\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(Components, props, '${cbid}')`;\n\t\t\t\t} else {\n\t\t\t\t\thtmlNodeCode += `getItem(Components, 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, getValidProps(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 'Chispa' + 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} | ChispaContent;\\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} = ChispaNodeBuilderProps<SVGElementTagNameMap['${tagname}'], ${itemsType}>;`;\n\t\t\t} else {\n\t\t\t\treturn `type ${typename} = ChispaNodeBuilderProps<HTMLElementTagNameMap['${tagname.toLowerCase()}'], ${itemsType}>;`;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic compile(): { js: 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, getValidProps, buildClass, setAttributes, setProps } from 'chispa';\n import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';\n\t\t\t\n const SVG_NS = 'http://www.w3.org/2000/svg';\n \n const Components = {\n ${componentsClasses}\n };\n \n export default Components;\n `;\n\n\t\tconst dtsOutput = `\n import type { ChispaContent, ChispaNodeBuilderProps } from 'chispa';\n \n ${typedefs}\n \n declare const Components: {\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 Components;\n `;\n\n\t\treturn { js: jsOutput, dts: dtsOutput };\n\t}\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { HtmlCompiler } from './html-compiler';\n\nexport function generateTypes(filePath: string, content: string, rootDir: string) {\n\ttry {\n\t\tconst compiler = new HtmlCompiler(content);\n\t\tconst { dts } = 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 function findAndCompileHtmlFiles(dir: string, rootDir: string) {\n\tif (!fs.existsSync(dir)) return;\n\tconst files = fs.readdirSync(dir);\n\tfiles.forEach((file) => {\n\t\tconst fullPath = path.join(dir, file);\n\t\tif (fullPath === path.join(rootDir, 'index.html')) return;\n\t\tif (fs.statSync(fullPath).isDirectory()) {\n\t\t\tif (file !== 'node_modules' && file !== '.git' && file !== 'dist' && file !== '.chispa') {\n\t\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(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\tbuildStart() {\n\t\t\tfindAndCompileHtmlFiles(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\tgenerateTypes(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 { js } = compiler.compile();\n\t\t\t\t\tgenerateTypes(realId, content, rootDir);\n\n\t\t\t\t\tconst result = await transformWithEsbuild(js, 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":";AAAA,SAAS,aAAa;AAEtB,IAAM,gBAAgB,CAAC,QAAQ,QAAQ,MAAM,MAAM,OAAO,SAAS,QAAQ,QAAQ,SAAS,UAAU,QAAQ;AAE9G,IAAM,gBAAgB;AAEf,IAAM,eAAN,MAAM,cAAa;AAAA,EASzB,YAAY,aAAqB;AARjC,SAAQ,aAAqC,CAAC;AAC9C,SAAQ,QAAkB,CAAC,UAAU;AACrC,SAAQ,kBAA4C,CAAC;AACrD,SAAQ,iBAAyC,CAAC;AAClD,SAAQ,QAAiC,CAAC;AAC1C,SAAQ,eAAe;AAItB,UAAM,MAAM,IAAI,MAAM,WAAW;AACjC,SAAK,eAAe,IAAI,OAAO;AAAA,EAChC;AAAA,EAEA,OAAe,SAAS,KAAqB;AAC5C,QAAI,IAAI,WAAW,IAAI,GAAG;AACzB,aAAO;AAAA,IACR;AACA,UAAM,MAAM,IAAI,MAAM,GAAG;AACzB,QAAI,YAAY;AAChB,QAAI,QAAQ,CAAC,GAAG,MAAM;AACrB,mBAAa,MAAM,IAAI,IAAI,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC;AAAA,IACjE,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,OAAe,WAAW,SAAyB;AAClD,QAAI,MAAM;AACV,UAAM,SAAS,QAAQ,MAAM,GAAG;AAChC,WAAO,QAAQ,CAAC,SAAS;AACxB,YAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,UAAI,MAAM,WAAW,EAAG;AACxB,YAAM,OAAO,cAAa,SAAS,MAAM,CAAC,EAAE,KAAK,CAAC;AAClD,aAAO,IAAI,IAAI,MAAM,MAAM,CAAC,EAAE,KAAK,CAAC;AAAA,IACrC,CAAC;AACD,WAAO;AACP,WAAO;AAAA,EACR;AAAA,EAEQ,cAAc,WAA0B,aAA8B;AAC7E,UAAM,cAAc,aAAa,IAAI,MAAM,GAAG;AAC9C,QAAI,aAAa;AAEjB,eAAW,QAAQ,CAAC,aAAa;AAChC,UAAI,CAAC,SAAS,WAAW,QAAQ,GAAG;AACnC,sBAAc,WAAW;AAAA,MAC1B;AAAA,IACD,CAAC;AAED,iBAAa,WAAW,KAAK;AAE7B,QAAI,aAAa;AAChB,mBAAa,eAAe,UAAU;AACtC,aAAO,aAAa,UAAU;AAAA,IAC/B,OAAO;AACN,aAAO,cAAc,UAAU;AAAA,IAChC;AAAA,EACD;AAAA,EAEQ,iBAAiB,SAAkB,aAA8B;AACxE,QAAI,YAAY;AAChB,iBAAa,KAAK,cAAc,QAAQ,aAAa,OAAO,GAAG,WAAW;AAE1E,UAAM,KAAK,QAAQ,UAAU,EAAE,QAAQ,CAAC,SAAS;AAChD,YAAM,WAAW,KAAK;AACtB,UAAI,YAAY,KAAK;AAErB,UAAI,aAAa,UAAW;AAC5B,UAAI,aAAa,QAAS;AAE1B,kBAAY,UAAU,QAAQ,OAAO,GAAG,EAAE,QAAQ,MAAM,KAAK;AAQ7D,UAAI,aAAa,SAAS;AAYzB,qBAAa,KAAK,QAAQ,OAAO,SAAS;AAAA,MAC3C,OAAO;AACN,qBAAa,KAAK,QAAQ,OAAO,SAAS;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,iBAAa;AACb,WAAO;AAAA,EACR;AAAA,EAEQ,eAAe,SAAe,cAAc,OAAe;AAClE,QAAI,eAAe;AAEnB,QAAI,QAAQ,aAAa,GAAG;AAE3B,YAAM,UAAU;AAChB,UAAI,UAAU,QAAQ;AAEtB,UAAI,YAAY,OAAO;AACtB,aAAK;AAAA,MACN;AAEA,UAAI,OAAO,QAAQ,aAAa,SAAS;AAEzC,UAAI,MAAM;AACT,cAAM,WAAW,KAAK,MAAM,CAAC;AAC7B,gBAAQ,gBAAgB,SAAS;AACjC,eAAO,cAAa,SAAS,IAAI;AAEjC,YAAI,CAAC,KAAK,gBAAgB,QAAQ,GAAG;AACpC,eAAK,gBAAgB,QAAQ,IAAI,CAAC;AAAA,QACnC;AAEA,aAAK,gBAAgB,QAAQ,EAAE,KAAK,IAAI;AACxC,aAAK,MAAM,QAAQ,IAAI;AACvB,aAAK,WAAW,IAAI,IAAI,KAAK,eAAe,SAAS,IAAI;AACzD,aAAK,eAAe,IAAI,IAAI,QAAQ;AACpC,aAAK,MAAM,IAAI,IAAI,KAAK,eAAe;AACvC,aAAK,MAAM,MAAM;AAEjB,YAAI,aAAa,YAAY;AAC5B,0BAAgB,+BAA+B,IAAI;AAAA,QACpD,OAAO;AACN,0BAAgB,qCAAqC,IAAI;AAAA,QAC1D;AAAA,MACD,OAAO;AACN,cAAM,QAAQ,KAAK,iBAAiB,SAAS,WAAW;AAExD,YAAI,CAAC,KAAK,cAAc;AACvB,oBAAU,QAAQ,YAAY;AAC9B,0BAAgB,iDAAiD,OAAO;AAAA;AAAA,QACzE,OAAO;AACN,0BAAgB,mDAAmD,aAAa,OAAO,OAAO;AAAA;AAAA,QAC/F;AAEA,wBAAgB,uBAAuB,KAAK;AAAA;AAC5C,YAAI,aAAa;AAChB,0BAAgB;AAAA;AAAA,QACjB;AAEA,YAAI,QAAQ;AACZ,gBAAQ,WAAW,QAAQ,CAAC,UAAU;AACrC,gBAAM,SAAS,KAAK,eAAe,KAAK;AACxC,cAAI,QAAQ;AACX,qBAAS,qBAAqB,MAAM;AAAA;AAAA,UACrC;AAAA,QACD,CAAC;AAED,YAAI,CAAC,cAAc,SAAS,QAAQ,YAAY,CAAC,GAAG;AACnD,cAAI,aAAa;AAChB,4BAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAOQ,KAAK;AAAA;AAAA;AAAA,UAG9B,OAAO;AACN,4BAAgB;AAAA,UACjB;AAAA,QACD;AAEA,YAAI,aAAa;AAChB,0BAAgB;AAAA;AAAA,QACjB;AAEA,wBAAgB;AAEhB,YAAI,YAAY,OAAO;AACtB,eAAK;AAAA,QACN;AAAA,MACD;AAAA,IACD,WAAW,QAAQ,aAAa,GAAG;AAElC,YAAM,WAAW;AACjB,YAAM,SAAS,SAAS;AACxB,YAAM,YAAY,SAAS,OAAO,QAAQ,YAAY,IAAI;AAE1D,YAAM,WAAW,CAAC,SAAS,SAAS,SAAS,SAAS,IAAI,EAAE,SAAS,SAAS;AAE9E,UAAI,CAAC,YAAY,SAAS,aAAa;AACtC,YAAI,SAAS,YAAY,KAAK,MAAM,IAAI;AACvC,cAAI,SAAS,YAAY,SAAS,GAAG;AACpC,4BAAgB;AAAA,UACjB;AAAA,QACD,OAAO;AACN,yBAAe,2BAA2B,KAAK,UAAU,SAAS,WAAW,CAAC;AAAA,QAC/E;AAAA,MACD;AAAA,IACD;AAEA,WAAO,aAAa,KAAK;AAAA,EAC1B;AAAA,EAEA,OAAe,iBAAiB,MAAsB;AACrD,WAAO,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,IAAI;AAAA,EAClE;AAAA,EAEQ,gBAAgB,MAAc,KAAqB;AAC1D,UAAM,WAAW,cAAa,iBAAiB,IAAI;AACnD,WAAO,WAAW,QAAQ;AAAA,UAAoB,GAAG;AAAA;AAAA,EAClD;AAAA,EAEQ,sBAAsB;AAC7B,UAAM,OAAO,KAAK,aAAa,cAAc,MAAM;AACnD,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,gBAAgB;AAE3C,QAAI,cAAc;AAElB,SAAK,WAAW,QAAQ,CAAC,UAAU;AAClC,YAAM,SAAS,KAAK,eAAe,KAAK;AACxC,UAAI,QAAQ;AACX,uBAAe,yBAAyB,MAAM;AAAA;AAAA,MAC/C;AAAA,IACD,CAAC;AAED,mBAAe;AACf,mBAAe;AAEf,SAAK,WAAW,UAAU,IAAI;AAAA,EAC/B;AAAA,EAEQ,WAAW,MAAsB;AACxC,UAAM,QAAQ,KAAK,gBAAgB,IAAI,KAAK,CAAC;AAC7C,QAAI,YAAY;AAChB,UAAM,QAAQ,CAAC,aAAa;AAC3B,YAAM,eAAe,cAAa,iBAAiB,QAAQ;AAC3D,mBAAa,GAAG,QAAQ,MAAM,YAAY;AAAA;AAAA,IAC3C,CAAC;AACD,iBAAa;AAEb,UAAM,WAAW,cAAa,iBAAiB,IAAI;AAEnD,QAAI,SAAS,YAAY;AACxB,aAAO,aAAa,QAAQ,IAAI,SAAS;AAAA,IAC1C,OAAO;AACN,YAAM,UAAU,KAAK,eAAe,IAAI;AACxC,UAAI,KAAK,MAAM,IAAI,GAAG;AACrB,eAAO,QAAQ,QAAQ,mDAAmD,OAAO,OAAO,SAAS;AAAA,MAClG,OAAO;AACN,eAAO,QAAQ,QAAQ,oDAAoD,QAAQ,YAAY,CAAC,OAAO,SAAS;AAAA,MACjH;AAAA,IACD;AAAA,EACD;AAAA,EAEO,UAAuC;AAC7C,SAAK,oBAAoB;AAEzB,QAAI,oBAAoB;AACxB,QAAI,WAAW;AAEf,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,UAAU,GAAG;AAC9D,kBAAY,KAAK,WAAW,IAAI,IAAI;AACpC,2BAAqB,GAAG,IAAI,KAAK,KAAK,gBAAgB,MAAM,OAAO,CAAC;AAAA;AAAA,IACrE;AAEA,UAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAOD,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAMjC,UAAM,YAAY;AAAA;AAAA;AAAA,cAGN,QAAQ;AAAA;AAAA;AAAA,kBAGJ,OAAO,KAAK,KAAK,UAAU,EACvC,IAAI,CAAC,SAAS;AACd,YAAM,WAAW,cAAa,iBAAiB,IAAI;AACnD,aAAO,GAAG,IAAI,aAAa,QAAQ;AAAA,IACpC,CAAC,EACA,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAMd,WAAO,EAAE,IAAI,UAAU,KAAK,UAAU;AAAA,EACvC;AACD;;;ACnTA,YAAY,QAAQ;AACpB,YAAY,UAAU;AAGf,SAAS,cAAc,UAAkB,SAAiB,SAAiB;AACjF,MAAI;AACH,UAAM,WAAW,IAAI,aAAa,OAAO;AACzC,UAAM,EAAE,IAAI,IAAI,SAAS,QAAQ;AAEjC,UAAM,SAAc,UAAK,SAAS,eAAe;AACjD,UAAM,eAAoB,cAAS,SAAS,QAAQ;AACpD,UAAM,aAAkB,UAAK,QAAQ,eAAe,OAAO;AAC3D,UAAM,YAAiB,aAAQ,UAAU;AAEzC,QAAI,CAAI,cAAW,SAAS,GAAG;AAC9B,MAAG,aAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC5C;AACA,IAAG,iBAAc,YAAY,GAAG;AAAA,EACjC,SAAS,GAAG;AACX,YAAQ,MAAM,uCAAuC,QAAQ,IAAI,CAAC;AAAA,EACnE;AACD;AAEO,SAAS,wBAAwB,KAAa,SAAiB;AACrE,MAAI,CAAI,cAAW,GAAG,EAAG;AACzB,QAAM,QAAW,eAAY,GAAG;AAChC,QAAM,QAAQ,CAAC,SAAS;AACvB,UAAM,WAAgB,UAAK,KAAK,IAAI;AACpC,QAAI,aAAkB,UAAK,SAAS,YAAY,EAAG;AACnD,QAAO,YAAS,QAAQ,EAAE,YAAY,GAAG;AACxC,UAAI,SAAS,kBAAkB,SAAS,UAAU,SAAS,UAAU,SAAS,WAAW;AACxF,gCAAwB,UAAU,OAAO;AAAA,MAC1C;AAAA,IACD,WAAW,KAAK,SAAS,OAAO,GAAG;AAClC,cAAQ,IAAI,wBAAwB,QAAQ;AAC5C,YAAM,UAAa,gBAAa,UAAU,OAAO;AACjD,oBAAc,UAAU,SAAS,OAAO;AAAA,IACzC;AAAA,EACD,CAAC;AACF;;;ACrCA,SAAsB,4BAA4B;AAClD,YAAYA,SAAQ;AAOpB,IAAM,cAAc,CAAC,OAAe,OAAO,KAAK;AAMhD,IAAM,gBAAgB,CAAC,OAAe,GAAG,QAAQ,OAAO,EAAE,EAAE,QAAQ,cAAc,EAAE;AAE7E,SAAS,mBAA2B;AAC1C,MAAI,UAAU,QAAQ,IAAI;AAE1B,SAAO;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe,QAAQ;AACtB,gBAAU,OAAO;AAAA,IAClB;AAAA,IACA,aAAa;AACZ,8BAAwB,SAAS,OAAO;AAAA,IACzC;AAAA,IACA,MAAM,gBAAgB,KAAK;AAC1B,UAAI,IAAI,KAAK,SAAS,OAAO,GAAG;AAC/B,cAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,sBAAc,IAAI,MAAM,SAAS,OAAO;AAGxC,cAAM,SAAS,IAAI,OAAO,YAAY,cAAc,YAAY,IAAI,IAAI,CAAC;AACzE,YAAI,QAAQ;AACX,iBAAO,CAAC,MAAM;AAAA,QACf;AAAA,MACD;AAAA,IACD;AAAA,IACA,MAAM,UAAU,QAAQ,UAAU,SAAS;AAC1C,UAAI,OAAO,SAAS,iBAAiB,GAAG;AACvC,eAAO;AAAA,MACR;AACA,UAAI,OAAO,SAAS,OAAO,KAAK,UAAU;AACzC,cAAM,aAAa,MAAM,KAAK,QAAQ,QAAQ,UAAU,EAAE,UAAU,MAAM,GAAG,QAAQ,CAAC;AACtF,YAAI,cAAc,CAAC,WAAW,UAAU;AACvC,iBAAO,YAAY,WAAW,EAAE;AAAA,QACjC;AAAA,MACD;AACA,aAAO;AAAA,IACR;AAAA,IACA,MAAM,KAAK,IAAI;AACd,UAAI,GAAG,SAAS,iBAAiB,GAAG;AACnC,cAAM,SAAS,cAAc,EAAE;AAC/B,YAAI;AACH,gBAAM,UAAa,iBAAa,QAAQ,OAAO;AAC/C,cAAI,QAAQ,SAAS,iBAAiB,KAAK,QAAQ,SAAS,OAAO,GAAG;AACrE,mBAAO;AAAA,UACR;AAEA,gBAAM,WAAW,IAAI,aAAa,OAAO;AACzC,gBAAM,EAAE,GAAG,IAAI,SAAS,QAAQ;AAChC,wBAAc,QAAQ,SAAS,OAAO;AAEtC,gBAAM,SAAS,MAAM,qBAAqB,IAAI,QAAQ;AAAA,YACrD,QAAQ;AAAA,UACT,CAAC;AACD,iBAAO,OAAO;AAAA,QACf,SAAS,GAAG;AACX,kBAAQ,MAAM,0BAA0B,EAAE,KAAK,CAAC;AAChD,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;","names":["fs"]}
package/dist/index.d.ts CHANGED
@@ -124,24 +124,24 @@ type ChispaClasses = Record<string, boolean>;
124
124
  type ChispaNode = string | number | Node | null;
125
125
  type ChispaContent = ChispaNode | ChispaNode[] | Component | ComponentList;
126
126
  type ChispaCSSPropertiesStrings = {
127
- [K in keyof CSSStyleDeclaration]?: string | Signal<string>;
127
+ [K in keyof CSSStyleDeclaration]?: string | Signal<string> | (() => string);
128
128
  };
129
129
  type AllowSignals<T> = {
130
130
  [K in keyof T]: T[K] | Signal<T[K]>;
131
131
  };
132
132
  type ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<Partial<T>, 'style' | 'dataset'>>;
133
- interface IItemBuilderAdditionalProps<T, TNodes> {
133
+ interface INodeBuilderAdditionalProps<T, TNodes> {
134
134
  addClass?: string;
135
135
  classes?: ChispaClasses;
136
136
  nodes?: TNodes;
137
- inner?: ChispaContent | Signal<ChispaContent>;
137
+ inner?: ChispaContent | Signal<ChispaContent> | (() => ChispaContent);
138
138
  style?: ChispaCSSPropertiesStrings;
139
139
  dataset?: Record<string, string>;
140
140
  _ref?: (node: T) => void | {
141
141
  current: T | null;
142
142
  };
143
143
  }
144
- type ChispaItemBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & IItemBuilderAdditionalProps<T, TNodes>;
144
+ type ChispaNodeBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & INodeBuilderAdditionalProps<T, TNodes>;
145
145
  declare function buildClass(literalValue: string, additionalValue?: string, classes?: ChispaClasses): string;
146
146
  declare function getValidProps(props: any): any;
147
147
  declare function getItem<T>(Components: T, items: any, itemName: keyof T): any;
@@ -163,4 +163,4 @@ interface ControlledInputOptions {
163
163
  }
164
164
  declare function bindControlledInput(element: HTMLInputElement | HTMLTextAreaElement, signal: WritableSignal<string>, options?: ControlledInputOptions): () => void;
165
165
 
166
- export { type ChispaContent, type ChispaItemBuilderProps, Signal, WritableSignal, appendChild, bindControlledInput, buildClass, component, componentList, computed, getItem, getValidProps, globalContext, isSignal, setAttributes, setProps, signal };
166
+ export { type ChispaContent, type ChispaNodeBuilderProps, Signal, WritableSignal, appendChild, bindControlledInput, buildClass, component, componentList, computed, getItem, getValidProps, globalContext, isSignal, setAttributes, setProps, signal };
package/dist/index.js CHANGED
@@ -443,7 +443,11 @@ function setProps(node, props) {
443
443
  if (props.style !== void 0) {
444
444
  const style = props.style;
445
445
  for (const styleKey in style) {
446
- if (isSignal(style[styleKey])) {
446
+ if (typeof style[styleKey] === "function") {
447
+ globalContext.addReactivity(() => {
448
+ node.style[styleKey] = style[styleKey]();
449
+ });
450
+ } else if (isSignal(style[styleKey])) {
447
451
  globalContext.addReactivity(() => {
448
452
  node.style[styleKey] = style[styleKey].get();
449
453
  });
@@ -482,6 +486,10 @@ function setProps(node, props) {
482
486
  }
483
487
  function appendChild(node, child) {
484
488
  if (child === null) return;
489
+ if (typeof child === "function") {
490
+ processSignalChild(node, computed(child));
491
+ return;
492
+ }
485
493
  if (isSignal(child)) {
486
494
  processSignalChild(node, child);
487
495
  return;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts"],"sourcesContent":["import { Component, ComponentList } from './components';\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\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\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.disposables.push(this);\n\t\t} else {\n\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\t// Mark the context as dirty (needing re-render)\n\t\t//console.log('marking context as dirty');\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 { WithSignals } from './components';\nimport { globalContext, Reactivity } from './context';\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]);\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\tconsole.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 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 type { Signal, WritableSignal };\n","import { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n//export type TComponentFactory<T extends TDict> = ((props: WithSignals<T>) => Node) | (() => Node);\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => Node;\n\nexport class Component<TProps = any> {\n\tpublic onUnmount: (() => void) | null = null;\n\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tpublic disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\t//constructor(private readonly factoryFn: TComponentFactory<T>, public readonly key: any = null, public readonly props: WithSignals<T> = null) {}\n\tconstructor(private readonly factoryFn: ComponentFactory<TProps>, public readonly key: any = null, public readonly props: TProps = null) {}\n\n\tmount(container: Node, anchor: Node) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\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\t\tif (!this.container || !this.nodes) return;\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\t// Insertar en la nueva posición\n\t\tthis.nodes.forEach((node) => {\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\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\t\tif (this.onUnmount) {\n\t\t\tthis.onUnmount();\n\t\t\tthis.onUnmount = null;\n\t\t}\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\t//return (props?: WithSignals<T>) => {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: WritableSignal<T[]>, props: TProps) => Node;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node;\n\tprivate anchor: Node; // 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: WritableSignal<TItem[]>,\n\t\tprivate readonly props: TProps = 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\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\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) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\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\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: WritableSignal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: WritableSignal<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: WritableSignal<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 { isSignal, Signal } from './signals';\n\nexport type ChispaClasses = Record<string, boolean>;\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | ChispaNode[] | Component | ComponentList; // | Signal<ChispaNode | ChispaNode[] | Component | ComponentList>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: string | Signal<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 IItemBuilderAdditionalProps<T, TNodes> {\n\taddClass?: string;\n\tclasses?: ChispaClasses;\n\tnodes?: TNodes;\n\tinner?: ChispaContent | Signal<ChispaContent>;\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, string>;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaItemBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & IItemBuilderAdditionalProps<T, TNodes>;\n\nfunction makeclass(classes: ChispaClasses) {\n\tlet finalClasses = [];\n\n\tfor (const className in classes) {\n\t\tif (classes[className]) {\n\t\t\tfinalClasses.push(className);\n\t\t}\n\t}\n\n\treturn finalClasses.join(' ').trim();\n}\n\nexport function buildClass(literalValue: string, additionalValue?: string, classes?: ChispaClasses) {\n\tconst parts = [];\n\tif (literalValue) parts.push(literalValue);\n\tif (additionalValue) parts.push(additionalValue);\n\tparts.push(makeclass(classes ?? {}));\n\treturn parts.join(' ').trim();\n}\n\nconst forbiddenProps = ['addClass', 'classes', 'nodes', 'inner', '_ref'];\n\nexport function getValidProps(props: 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];\n\t\t}\n\t}\n\n\tif (props._ref !== undefined) {\n\t\t//finalProps.ref = props._ref;\n\t}\n\n\treturn finalProps;\n}\n\nexport function getItem<T>(Components: T, items: any, itemName: keyof T) {\n\tif (!items || !items[itemName]) {\n\t\treturn null;\n\t}\n\n\tconst item = items[itemName];\n\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = Components[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\treturn Comp(itemProps);\n\t} else {\n\t\treturn item;\n\t}\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr].trim();\n\t\tif (!attrValue) continue;\n\t\t//console.log('setting attr', attr, attrValue )\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nexport function setProps<T extends Element>(node: T, props: any) {\n\tif (node instanceof HTMLElement) {\n\t\tif (props.style !== undefined) {\n\t\t\tconst style = props.style;\n\t\t\tfor (const styleKey in style) {\n\t\t\t\tif (isSignal(style[styleKey])) {\n\t\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\t\tnode.style[styleKey as any] = style[styleKey].get();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tnode.style[styleKey as any] = style[styleKey];\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete props.style;\n\t\t}\n\t\tif (props.dataset !== undefined) {\n\t\t\tconst dataset = props.dataset;\n\t\t\tfor (const datasetKey in dataset) {\n\t\t\t\tif (isSignal(dataset[datasetKey])) {\n\t\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\t\tnode.dataset[datasetKey] = dataset[datasetKey].get();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tnode.dataset[datasetKey] = dataset[datasetKey];\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete props.dataset;\n\t\t}\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = 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\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContent | Signal<ChispaContent>) {\n\tif (child === null) return;\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 processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaNode | Component<any> | ComponentList<any> | ChispaNode[]>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList = 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 (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 {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tfrag.append(...n.map((c) => toNode(c)));\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 { WritableSignal } from './signals';\n\nexport interface ControlledInputOptions {\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: string) => string;\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: string) => boolean;\n}\n\nexport function bindControlledInput(element: HTMLInputElement | HTMLTextAreaElement, signal: WritableSignal<string>, options: ControlledInputOptions = {}) {\n\tconst { transform, validate } = options;\n\n\t// Initialize value\n\telement.value = 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 = 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\tif (target.value !== newValue) {\n\t\t\tconst lengthDiff = target.value.length - newValue.length;\n\t\t\ttarget.value = newValue;\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 newValue = signal.get();\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n"],"mappings":"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","names":["component","signal","component","index","component","signal"]}
1
+ {"version":3,"sources":["../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts"],"sourcesContent":["import { Component, ComponentList } from './components';\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\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\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.disposables.push(this);\n\t\t} else {\n\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\t// Mark the context as dirty (needing re-render)\n\t\t//console.log('marking context as dirty');\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 { WithSignals } from './components';\nimport { globalContext, Reactivity } from './context';\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]);\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\tconsole.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 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 type { Signal, WritableSignal };\n","import { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n//export type TComponentFactory<T extends TDict> = ((props: WithSignals<T>) => Node) | (() => Node);\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => Node;\n\nexport class Component<TProps = any> {\n\tpublic onUnmount: (() => void) | null = null;\n\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tpublic disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\t//constructor(private readonly factoryFn: TComponentFactory<T>, public readonly key: any = null, public readonly props: WithSignals<T> = null) {}\n\tconstructor(private readonly factoryFn: ComponentFactory<TProps>, public readonly key: any = null, public readonly props: TProps = null) {}\n\n\tmount(container: Node, anchor: Node) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\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\t\tif (!this.container || !this.nodes) return;\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\t// Insertar en la nueva posición\n\t\tthis.nodes.forEach((node) => {\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\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\t\tif (this.onUnmount) {\n\t\t\tthis.onUnmount();\n\t\t\tthis.onUnmount = null;\n\t\t}\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\t//return (props?: WithSignals<T>) => {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: WritableSignal<T[]>, props: TProps) => Node;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node;\n\tprivate anchor: Node; // 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: WritableSignal<TItem[]>,\n\t\tprivate readonly props: TProps = 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\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\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) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\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\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: WritableSignal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: WritableSignal<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: WritableSignal<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 ChispaClasses = Record<string, boolean>;\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | ChispaNode[] | Component | ComponentList; // | Signal<ChispaNode | ChispaNode[] | Component | ComponentList>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: string | Signal<string> | (() => 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 INodeBuilderAdditionalProps<T, TNodes> {\n\taddClass?: string;\n\tclasses?: ChispaClasses;\n\tnodes?: TNodes;\n\tinner?: ChispaContent | Signal<ChispaContent> | (() => ChispaContent);\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, string>;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaNodeBuilderProps<T, TNodes> = ChispaNodeBuilderBaseProps<T> & INodeBuilderAdditionalProps<T, TNodes>;\n\nfunction makeclass(classes: ChispaClasses) {\n\tlet finalClasses = [];\n\n\tfor (const className in classes) {\n\t\tif (classes[className]) {\n\t\t\tfinalClasses.push(className);\n\t\t}\n\t}\n\n\treturn finalClasses.join(' ').trim();\n}\n\nexport function buildClass(literalValue: string, additionalValue?: string, classes?: ChispaClasses) {\n\tconst parts = [];\n\tif (literalValue) parts.push(literalValue);\n\tif (additionalValue) parts.push(additionalValue);\n\tparts.push(makeclass(classes ?? {}));\n\treturn parts.join(' ').trim();\n}\n\nconst forbiddenProps = ['addClass', 'classes', 'nodes', 'inner', '_ref'];\n\nexport function getValidProps(props: 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];\n\t\t}\n\t}\n\n\tif (props._ref !== undefined) {\n\t\t//finalProps.ref = props._ref;\n\t}\n\n\treturn finalProps;\n}\n\nexport function getItem<T>(Components: T, items: any, itemName: keyof T) {\n\tif (!items || !items[itemName]) {\n\t\treturn null;\n\t}\n\n\tconst item = items[itemName];\n\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = Components[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\treturn Comp(itemProps);\n\t} else {\n\t\treturn item;\n\t}\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr].trim();\n\t\tif (!attrValue) continue;\n\t\t//console.log('setting attr', attr, attrValue )\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nexport function setProps<T extends Element>(node: T, props: any) {\n\tif (node instanceof HTMLElement) {\n\t\tif (props.style !== undefined) {\n\t\t\tconst style = props.style;\n\t\t\tfor (const styleKey in style) {\n\t\t\t\tif (typeof style[styleKey] === 'function') {\n\t\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\t\tnode.style[styleKey as any] = style[styleKey]();\n\t\t\t\t\t});\n\t\t\t\t} else if (isSignal(style[styleKey])) {\n\t\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\t\tnode.style[styleKey as any] = style[styleKey].get();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tnode.style[styleKey as any] = style[styleKey];\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete props.style;\n\t\t}\n\t\tif (props.dataset !== undefined) {\n\t\t\tconst dataset = props.dataset;\n\t\t\tfor (const datasetKey in dataset) {\n\t\t\t\tif (isSignal(dataset[datasetKey])) {\n\t\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\t\tnode.dataset[datasetKey] = dataset[datasetKey].get();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tnode.dataset[datasetKey] = dataset[datasetKey];\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete props.dataset;\n\t\t}\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = 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\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContent | Signal<ChispaContent>) {\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 processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaNode | Component<any> | ComponentList<any> | ChispaNode[]>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList = 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 (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 {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tfrag.append(...n.map((c) => toNode(c)));\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 { WritableSignal } from './signals';\n\nexport interface ControlledInputOptions {\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: string) => string;\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: string) => boolean;\n}\n\nexport function bindControlledInput(element: HTMLInputElement | HTMLTextAreaElement, signal: WritableSignal<string>, options: ControlledInputOptions = {}) {\n\tconst { transform, validate } = options;\n\n\t// Initialize value\n\telement.value = 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 = 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\tif (target.value !== newValue) {\n\t\t\tconst lengthDiff = target.value.length - newValue.length;\n\t\t\ttarget.value = newValue;\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 newValue = signal.get();\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n"],"mappings":"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","names":["component","signal","component","index","component","signal"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chispa",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "A fully declarative UI reactive framework for building web applications.",
5
5
  "author": "José Carlos HR <joecarlhr@gmail.com>",
6
6
  "license": "MIT",