nuclo 0.1.108 → 0.1.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/core/attributeManager.d.ts +1 -1
  2. package/dist/core/attributeManager.d.ts.map +1 -1
  3. package/dist/core/classNameMerger.d.ts.map +1 -1
  4. package/dist/core/conditionalUpdater.d.ts.map +1 -1
  5. package/dist/core/elementFactory.d.ts.map +1 -1
  6. package/dist/core/reactiveAttributes.d.ts +1 -2
  7. package/dist/core/reactiveAttributes.d.ts.map +1 -1
  8. package/dist/core/reactiveCleanup.d.ts +7 -8
  9. package/dist/core/reactiveCleanup.d.ts.map +1 -1
  10. package/dist/core/reactiveText.d.ts +1 -2
  11. package/dist/core/reactiveText.d.ts.map +1 -1
  12. package/dist/core/updateController.d.ts.map +1 -1
  13. package/dist/internal/applyModifiers.d.ts +21 -1
  14. package/dist/internal/applyModifiers.d.ts.map +1 -1
  15. package/dist/list/runtime.d.ts +1 -1
  16. package/dist/list/runtime.d.ts.map +1 -1
  17. package/dist/nuclo.cjs +1 -1
  18. package/dist/nuclo.cjs.map +1 -1
  19. package/dist/nuclo.mjs +1 -1
  20. package/dist/nuclo.mjs.map +1 -1
  21. package/dist/nuclo.umd.js +1 -1
  22. package/dist/nuclo.umd.js.map +1 -1
  23. package/dist/polyfill/Document.d.ts.map +1 -1
  24. package/dist/polyfill/Element.d.ts.map +1 -1
  25. package/dist/polyfill/Node.d.ts +1 -1
  26. package/dist/polyfill/Node.d.ts.map +1 -1
  27. package/dist/ssr/nuclo.ssr.cjs +1 -1
  28. package/dist/ssr/nuclo.ssr.cjs.map +1 -1
  29. package/dist/ssr/nuclo.ssr.mjs +1 -1
  30. package/dist/ssr/nuclo.ssr.mjs.map +1 -1
  31. package/dist/ssr/renderToString.d.ts.map +1 -1
  32. package/dist/style/cssGenerator.d.ts.map +1 -1
  33. package/dist/style/cssPropertyTypes.d.ts +96 -96
  34. package/dist/style/cssPropertyTypes.d.ts.map +1 -1
  35. package/dist/style/styleBuilder.d.ts.map +1 -1
  36. package/dist/style/styleCache.d.ts +0 -1
  37. package/dist/style/styleCache.d.ts.map +1 -1
  38. package/dist/style/styleQueries.d.ts.map +1 -1
  39. package/dist/utility/conditionalInfo.d.ts +1 -0
  40. package/dist/utility/conditionalInfo.d.ts.map +1 -1
  41. package/dist/utility/dom.d.ts +2 -11
  42. package/dist/utility/dom.d.ts.map +1 -1
  43. package/dist/utility/errorHandler.d.ts +0 -5
  44. package/dist/utility/errorHandler.d.ts.map +1 -1
  45. package/dist/utility/on.d.ts.map +1 -1
  46. package/dist/utility/scope.d.ts.map +1 -1
  47. package/dist/utility/stringUtils.d.ts +6 -1
  48. package/dist/utility/stringUtils.d.ts.map +1 -1
  49. package/dist/when/builder.d.ts.map +1 -1
  50. package/package.json +1 -1
  51. package/types/features/list.d.ts +7 -1
  52. package/dist/core/reactive.d.ts +0 -4
  53. package/dist/core/reactive.d.ts.map +0 -1
  54. package/dist/utility/arrayUtils.d.ts +0 -2
  55. package/dist/utility/arrayUtils.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Document.d.ts","sourceRoot":"","sources":["../../src/polyfill/Document.ts"],"names":[],"mappings":"AAGA,qBAAa,aAAa;IACxB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,CAAC,UAAU,CAA4G;;IAQ9H,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe;IAInE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe;IAMxF,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAcpC,sBAAsB,IAAI,gBAAgB;IAmE1C,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAe/C,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;IAIxD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAQ1G,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAW9G,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAiBpC,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO;CAG/B;AAED,eAAO,MAAM,QAAQ,UAA6C,CAAC"}
1
+ {"version":3,"file":"Document.d.ts","sourceRoot":"","sources":["../../src/polyfill/Document.ts"],"names":[],"mappings":"AAqEA,qBAAa,aAAa;IACxB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,CAAC,UAAU,CAA4G;;IAQ9H,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe;IAInE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe;IAMxF,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAcpC,sBAAsB,IAAI,gBAAgB;IAI1C,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAe/C,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;IAIxD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAQ1G,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAW9G,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAiBpC,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO;CAG/B;AAED,eAAO,MAAM,QAAQ,UAA6C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Element.d.ts","sourceRoot":"","sources":["../../src/polyfill/Element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAwBnC,qBAAa,YAAa,SAAQ,SAAS;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAM;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,MAAM,CAAM;IACzB,OAAO,CAAC,UAAU,CAAc;IAChC,UAAU,EAAE,OAAO,CAAQ;IAC3B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAM;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,UAAU,CAAkC;IAEpD,IAAI,SAAS,IAAI,MAAM,CAGtB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAE1B;IAED,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,gBAAgB;gBAsCZ,OAAO,EAAE,MAAM;IA6D3B,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAYxC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAS/C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIzC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOnC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,YAAY,CAAC,CAAC,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC;IAqBvE,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAkBxC,YAAY,CAAC,CAAC,SAAS,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAqB5D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAO7D,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOhE,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAkBpC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAe/C,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,kBAAkB;IAmB1B,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;IAiBvD,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;CAa9B"}
1
+ {"version":3,"file":"Element.d.ts","sourceRoot":"","sources":["../../src/polyfill/Element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAqGnC,qBAAa,YAAa,SAAQ,SAAS;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAM;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,MAAM,CAAM;IACzB,OAAO,CAAC,UAAU,CAAc;IAChC,UAAU,EAAE,OAAO,CAAQ;IAC3B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAM;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,UAAU,CAAyC;IAE3D,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAE1B;IAED,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,gBAAgB;gBAsCZ,OAAO,EAAE,MAAM;IAsE3B,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAWxC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAS/C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIzC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOnC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,YAAY,CAAC,CAAC,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC;IAoBvE,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAiBxC,YAAY,CAAC,CAAC,SAAS,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAoB5D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAQ7D,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOhE,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAiBpC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAe/C,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,kBAAkB;IAmB1B,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;IAiBvD,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;CAa9B"}
@@ -6,7 +6,7 @@ export declare class NucloNode {
6
6
  nodeName: string;
7
7
  nodeValue: string | null;
8
8
  parentNode: unknown;
9
- private _childNodes;
9
+ _childNodes: Node[] | null;
10
10
  textContent: string;
11
11
  get childNodes(): NodeListOf<ChildNode>;
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Node.d.ts","sourceRoot":"","sources":["../../src/polyfill/Node.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,SAAS;IACpB,QAAQ,EAAE,MAAM,CAAK;IACrB,QAAQ,EAAE,MAAM,CAAM;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,EAAE,OAAO,CAAQ;IAC3B,OAAO,CAAC,WAAW,CAAc;IACjC,WAAW,EAAE,MAAM,CAAM;IAEzB,IAAI,UAAU,IAAI,UAAU,CAAC,SAAS,CAAC,CAgCtC;CACF"}
1
+ {"version":3,"file":"Node.d.ts","sourceRoot":"","sources":["../../src/polyfill/Node.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,SAAS;IACpB,QAAQ,EAAE,MAAM,CAAK;IACrB,QAAQ,EAAE,MAAM,CAAM;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,EAAE,OAAO,CAAQ;IAC3B,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI,CAAQ;IAClC,WAAW,EAAE,MAAM,CAAM;IAEzB,IAAI,UAAU,IAAI,UAAU,CAAC,SAAS,CAAC,CAgCtC;CACF"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){let t=``;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r>=65&&r<=90?(n>0&&(t+=`-`),t+=String.fromCharCode(r+32)):t+=e[n]}return t}function t(e){let t={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#039;`};return e.replace(/[&<>"']/g,e=>t[e])}function n(e){return globalThis.document?document.createElement(e):null}const r=new Set([`allowfullscreen`,`async`,`autofocus`,`autoplay`,`checked`,`controls`,`default`,`defer`,`disabled`,`formnovalidate`,`hidden`,`ismap`,`loop`,`multiple`,`muted`,`nomodule`,`novalidate`,`open`,`readonly`,`required`,`reversed`,`selected`]);function i(n,i){if(i==null||i===!1)return``;if(i===!0)return` ${n}`;if(r.has(n)){if(i===`false`)return``;if(i===`true`||i===``||i===n)return` ${n}`}if(n===`style`&&typeof i==`object`){let n=Object.entries(i).map(([t,n])=>`${e(t)}:${n}`).join(`;`);return n?` style="${t(n)}"`:``}return` ${n}="${t(String(i))}"`}function a(n){let r=``;if(`attributes`in n&&n.attributes instanceof Map){let a=n;if(a.id&&!n.attributes.has(`id`)&&(r+=i(`id`,a.id)),a.className&&!n.attributes.has(`class`)&&(r+=i(`class`,a.className)),!n.attributes.has(`style`)&&a.style){let n=a.style.cssText||``;if(n){let i=n.split(`;`).map(e=>e.trim()).filter(Boolean).map(t=>{let n=t.indexOf(`:`);if(n===-1)return t;let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();return`${e(r)}:${i}`}).join(`;`);i&&(r+=` style="${t(i)}"`)}}for(let[e,t]of n.attributes)r+=i(e,t);return r}if(n.attributes&&n.attributes.length)for(let e=0;e<n.attributes.length;e++){let t=n.attributes[e];t&&t.name&&(r+=i(t.name,t.value))}return r}const o=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function s(e){if(`tagName`in e&&`children`in e){let t=e.children;if(Array.isArray(t))return t}if(`childNodes`in e){let t=e.childNodes;if(t&&(Array.isArray(t)||t.length!==void 0))return t}return[]}function c(e){if(e.nodeType===3)return t(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let n=e,r=n.tagName.toLowerCase(),i=a(n);if(o.has(r))return`<${r}${i} />`;let l=``,u=s(n);if(u&&u.length>0)for(let e=0;e<u.length;e++){let t=u[e];t&&(l+=c(t))}else{let n=e.textContent;typeof n==`string`&&n&&(l=t(n))}return`<${r}${i}>${l}</${r}>`}if(e.nodeType===11){let t=``,n=s(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&r.nodeType!==8&&(t+=c(r))}return t}return``}function l(e){if(!e)return``;if(typeof e==`function`)try{let t=n(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);let r=e(t,0);return r&&typeof r==`object`&&`nodeType`in r?c(r):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?c(e):``}function u(e){return e.map(e=>l(e))}function d(e,t=`div`,n={}){let r=l(e);return`<${t}${Object.entries(n).map(([e,t])=>i(e,t)).join(``)}>${r}</${t}>`}exports.renderManyToString=u,exports.renderToString=l,exports.renderToStringWithContainer=d;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){let t=``;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r>=65&&r<=90?(n>0&&(t+=`-`),t+=String.fromCharCode(r+32)):t+=e[n]}return t}function t(e){let t={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#039;`};return e.replace(/[&<>"']/g,e=>t[e])}function n(e){return e.replace(/[&<>]/g,e=>e===`&`?`&amp;`:e===`<`?`&lt;`:`&gt;`)}function r(e){return globalThis.document?document.createElement(e):null}const i=new Set(`viewBox.preserveAspectRatio.markerWidth.markerHeight.gradientTransform.patternTransform.clipPathUnits.gradientUnits.patternUnits.pathLength.refX.refY.stdDeviation.baseFrequency.numOctaves.kernelMatrix.tableValues.targetX.targetY.specularExponent.specularConstant.diffuseConstant.surfaceScale.xChannelSelector.yChannelSelector.edgeMode.stitchTiles.spreadMethod.patternContentUnits.markerUnits.startOffset.textLength.lengthAdjust`.split(`.`)),a=new Set([`allowfullscreen`,`async`,`autofocus`,`autoplay`,`checked`,`controls`,`default`,`defer`,`disabled`,`formnovalidate`,`hidden`,`ismap`,`loop`,`multiple`,`muted`,`nomodule`,`novalidate`,`open`,`readonly`,`required`,`reversed`,`selected`]);function o(n,r){if(r==null||r===!1)return``;if(r===!0)return` ${n}`;if(a.has(n)){if(r===`false`)return``;if(r===`true`||r===``||r===n)return` ${n}`}if(n===`style`&&typeof r==`object`){let n=Object.entries(r).filter(([,e])=>e!=null&&e!==``).map(([t,n])=>`${e(t)}: ${n};`).join(` `);return n?` style="${t(n)}"`:``}return` ${n}="${t(String(r))}"`}function s(n){let r=``;if(`attributes`in n&&n.attributes instanceof Map){let a=n;if(a.id&&!n.attributes.has(`id`)&&(r+=o(`id`,a.id)),a.className&&!n.attributes.has(`class`)&&(r+=o(`class`,a.className)),!n.attributes.has(`style`)&&a.style){let n=a.style.cssText||``;if(n){let i=n.split(`;`).map(e=>e.trim()).filter(Boolean).map(t=>{let n=t.indexOf(`:`);if(n===-1)return t;let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();return i?`${e(r)}: ${i};`:``}).filter(Boolean).join(` `);i&&(r+=` style="${t(i)}"`)}}for(let[t,a]of n.attributes){let n=i.has(t)?t:e(t);r+=o(n,a)}return r}if(n.attributes&&n.attributes.length)for(let e=0;e<n.attributes.length;e++){let t=n.attributes[e];t&&t.name&&(r+=o(t.name,t.value))}return r}const c=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function l(e){if(`tagName`in e&&`children`in e){let t=e.children;if(Array.isArray(t))return t}if(`childNodes`in e){let t=e.childNodes;if(t&&(Array.isArray(t)||t.length!==void 0))return t}return[]}function u(e){if(e.nodeType===3)return n(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let t=e,r=t.tagName.toLowerCase(),i=s(t);if(c.has(r))return`<${r}${i} />`;let a=``,o=l(t);if(o&&o.length>0)for(let e=0;e<o.length;e++){let t=o[e];t&&(a+=u(t))}else{let t=e.textContent;typeof t==`string`&&t&&(a=n(t))}return`<${r}${i}>${a}</${r}>`}if(e.nodeType===11){let t=``,n=l(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&(t+=u(r))}return t}return``}function d(e){if(!e)return``;if(typeof e==`function`)try{let t=r(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);let n=e(t,0);return n&&typeof n==`object`&&`nodeType`in n?u(n):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?u(e):``}function f(e){return e.map(e=>d(e))}function p(e,t=`div`,n={}){let r=d(e);return`<${t}${Object.entries(n).map(([e,t])=>o(e,t)).join(``)}>${r}</${t}>`}exports.renderManyToString=f,exports.renderToString=d,exports.renderToStringWithContainer=p;
2
2
  //# sourceMappingURL=nuclo.ssr.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nuclo.ssr.cjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters to prevent XSS\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n","import { isBrowser } from \"./environment\";\nimport { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nfunction createTextNodeSafely(text: string | number | boolean): Text | null {\n if (!globalThis.document) return null;\n try {\n return createTextNode(String(text));\n } catch (error) {\n logError('Failed to create text node', error);\n return null;\n }\n}\n\nfunction createCommentSafely(text: string): Comment | null {\n if (!globalThis.document) return null;\n try {\n return globalThis.document.createComment(text);\n } catch (error) {\n logError('Failed to create comment node', error);\n return null;\n }\n}\n\n/**\n * Creates a comment node safely with error handling.\n * Exported for use across the codebase.\n */\nexport function createComment(text: string): Comment | null {\n return createCommentSafely(text);\n}\n\n/**\n * Creates a conditional comment placeholder node.\n * Uses globalThis.document so it is safe in SSR environments where `document`\n * may not exist as a global binding (avoids bare ReferenceError).\n */\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n\ttry {\n\t\treturn globalThis.document?.createComment(`conditional-${tagName}-${suffix}`) ?? null;\n\t} catch (error) {\n\t\tlogError('Failed to create conditional comment', error);\n\t\treturn null;\n\t}\n}\n\nexport function createMarkerComment(prefix: string): Comment {\n const comment = createCommentSafely(`${prefix}-${Math.random().toString(36).slice(2)}`);\n if (!comment) {\n throw new Error(\"Failed to create comment: document not available\");\n }\n return comment;\n}\n\nexport function createMarkerPair(prefix: string): { start: Comment; end: Comment } {\n const endComment = createCommentSafely(`${prefix}-end`);\n if (!endComment) {\n throw new Error(\"Failed to create comment: document not available\");\n }\n return {\n start: createMarkerComment(`${prefix}-start`),\n end: endComment\n };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNodeSafely(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n\n // Prefer the built-in isConnected property\n if (typeof node.isConnected === \"boolean\") {\n return node.isConnected;\n }\n\n // Fallback for older browsers (only if in browser environment)\n if (isBrowser && typeof document !== 'undefined') {\n return document.contains(node);\n }\n\n // In SSR or when document is not available, assume disconnected\n return false;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n\nimport { escapeHtml, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .map(([key, val]) => {\n const cssKey = camelToKebab(key);\n return `${cssKey}:${val}`;\n })\n .join(';');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n return `${camelToKebab(key)}:${val}`;\n })\n .join(';');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n for (const [name, value] of element.attributes) {\n result += serializeAttribute(name, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeHtml(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeHtml(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n // Skip internal framework comment markers (e.g. \" text-0 \") that are\n // reactive anchors for browser-side updates — they have no meaning in\n // an SSR string and must not appear in the output.\n if (child && child.nodeType !== 8) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) {\n return '';\n }\n\n // If it's a function (NodeModFn), call it to create the element\n if (typeof input === 'function') {\n try {\n // Create a temporary container to render into\n const container = createElement('div');\n if (!container) {\n throw new Error('Document is not available. Make sure polyfills are loaded.');\n }\n\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n // If it's already a Node, serialize it directly\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n"],"mappings":"mEASA,SAAgB,EAAa,EAAqB,CAChD,IAAI,EAAS,GACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,OAAQ,IAAK,CACnC,IAAM,EAAO,EAAI,WAAW,EAAE,CAE1B,GAAQ,IAAM,GAAQ,IACpB,EAAI,IAAG,GAAU,KACrB,GAAU,OAAO,aAAa,EAAO,GAAG,EAExC,GAAU,EAAI,GAGlB,OAAO,EAMT,SAAgB,EAAW,EAAsB,CAC/C,IAAM,EAA8B,CAClC,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,SACN,CACD,OAAO,EAAK,QAAQ,WAAa,GAAS,EAAI,GAAM,CCrBtD,SAAgB,EAAc,EAAyC,CACrE,OAAO,WAAW,SAAW,SAAS,cAAc,EAAQ,CAAsB,KCKpF,MAAM,EAA0B,IAAI,IAAI,CACtC,kBAAmB,QAAS,YAAa,WAAY,UAAW,WAChE,UAAW,QAAS,WAAY,iBAAkB,SAAU,QAAS,OACrE,WAAY,QAAS,WAAY,aAAc,OAAQ,WAAY,WACnE,WAAY,WACb,CAAC,CAKF,SAAS,EAAmB,EAAc,EAAwB,CAChE,GAAI,GAAU,MAA+B,IAAU,GACrD,MAAO,GAGT,GAAI,IAAU,GACZ,MAAO,IAAI,IAIb,GAAI,EAAwB,IAAI,EAAK,CAAE,CACrC,GAAI,IAAU,QAAS,MAAO,GAC9B,GAAI,IAAU,QAAU,IAAU,IAAM,IAAU,EAAM,MAAO,IAAI,IAGrE,GAAI,IAAS,SAAW,OAAO,GAAU,SAAU,CACjD,IAAM,EAAW,OAAO,QAAQ,EAAM,CACnC,KAAK,CAAC,EAAK,KAEH,GADQ,EAAa,EAAI,CACf,GAAG,IACpB,CACD,KAAK,IAAI,CACZ,OAAO,EAAW,WAAW,EAAW,EAAS,CAAC,GAAK,GAGzD,MAAO,IAAI,EAAK,IAAI,EAAW,OAAO,EAAM,CAAC,CAAC,GAMhD,SAAS,EAAoB,EAA0B,CACrD,IAAI,EAAS,GAGb,GAAI,eAAgB,GAAW,EAAQ,sBAAsB,IAAK,CAChE,IAAM,EAAK,EAcX,GAXI,EAAG,IAAM,CAAC,EAAQ,WAAW,IAAI,KAAK,GACxC,GAAU,EAAmB,KAAM,EAAG,GAAG,EAIvC,EAAG,WAAa,CAAC,EAAQ,WAAW,IAAI,QAAQ,GAClD,GAAU,EAAmB,QAAS,EAAG,UAAU,EAKjD,CAAC,EAAQ,WAAW,IAAI,QAAQ,EAAI,EAAG,MAAO,CAChD,IAAM,EAAqB,EAAG,MAAM,SAAW,GAC/C,GAAI,EAAY,CACd,IAAM,EAAa,EAChB,MAAM,IAAI,CACV,IAAK,GAAiB,EAAK,MAAM,CAAC,CAClC,OAAO,QAAQ,CACf,IAAK,GAAiB,CACrB,IAAM,EAAW,EAAK,QAAQ,IAAI,CAClC,GAAI,IAAa,GAAI,OAAO,EAC5B,IAAM,EAAM,EAAK,MAAM,EAAG,EAAS,CAAC,MAAM,CACpC,EAAM,EAAK,MAAM,EAAW,EAAE,CAAC,MAAM,CAC3C,MAAO,GAAG,EAAa,EAAI,CAAC,GAAG,KAC/B,CACD,KAAK,IAAI,CACR,IACF,GAAU,WAAW,EAAW,EAAW,CAAC,KAMlD,IAAK,GAAM,CAAC,EAAM,KAAU,EAAQ,WAClC,GAAU,EAAmB,EAAM,EAAM,CAE3C,OAAO,EAIT,GAAI,EAAQ,YAAc,EAAQ,WAAW,OAC3C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,WAAW,OAAQ,IAAK,CAClD,IAAM,EAAO,EAAQ,WAAW,GAC5B,GAAQ,EAAK,OACf,GAAU,EAAmB,EAAK,KAAM,EAAK,MAAM,EAKzD,OAAO,EAMT,MAAM,EAAgB,IAAI,IAAI,CAC5B,OAAQ,OAAQ,KAAM,MAAO,QAAS,KAAM,MAAO,QACnD,OAAQ,OAAQ,QAAS,SAAU,QAAS,MAC7C,CAAC,CAWF,SAAS,EAAc,EAA6B,CAElD,GAAI,YAAa,GAAQ,aAAc,EAAM,CAC3C,IAAM,EAAY,EAAa,SAC/B,GAAI,MAAM,QAAQ,EAAS,CACzB,OAAO,EAIX,GAAI,eAAgB,EAAM,CACxB,IAAM,EAAc,EAAa,WACjC,GAAI,IAAe,MAAM,QAAQ,EAAW,EAAI,EAAW,SAAW,IAAA,IACpE,OAAO,EAGX,MAAO,EAAE,CAMX,SAAS,EAAc,EAAoB,CAEzC,GAAI,EAAK,WAAa,EACpB,OAAO,EAAW,EAAK,aAAe,GAAG,CAI3C,GAAI,EAAK,WAAa,EACpB,MAAO,OAAO,EAAK,aAAe,GAAG,KAIvC,GAAI,EAAK,WAAa,EAAG,CACvB,IAAM,EAAU,EACV,EAAU,EAAQ,QAAQ,aAAa,CACvC,EAAa,EAAoB,EAAQ,CAG/C,GAAI,EAAc,IAAI,EAAQ,CAC5B,MAAO,IAAI,IAAU,EAAW,KAIlC,IAAI,EAAe,GACb,EAAa,EAAc,EAAQ,CACzC,GAAI,GAAc,EAAW,OAAS,EACpC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAQ,EAAW,GACrB,IACF,GAAgB,EAAc,EAAM,MAGnC,CAEL,IAAM,EAAM,EAAa,YACrB,OAAO,GAAO,UAAY,IAC5B,EAAe,EAAW,EAAG,EAIjC,MAAO,IAAI,IAAU,EAAW,GAAG,EAAa,IAAI,EAAQ,GAI9D,GAAI,EAAK,WAAa,GAAI,CACxB,IAAI,EAAS,GACP,EAAa,EAAc,EAAK,CACtC,GAAI,GAAc,EAAW,OAAS,EACpC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAQ,EAAW,GAIrB,GAAS,EAAM,WAAa,IAC9B,GAAU,EAAc,EAAM,EAIpC,OAAO,EAGT,MAAO,GAoBT,SAAgB,EAAe,EAAgC,CAC7D,GAAI,CAAC,EACH,MAAO,GAIT,GAAI,OAAO,GAAU,WACnB,GAAI,CAEF,IAAM,EAAY,EAAc,MAAM,CACtC,GAAI,CAAC,EACH,MAAU,MAAM,6DAA6D,CAG/E,IAAM,EAAU,EAAM,EAA8C,EAAE,CACtE,OAAO,GAAW,OAAO,GAAY,UAAY,aAAc,EAAU,EAAc,EAAgB,CAAG,SACnG,EAAO,CAEd,OADA,QAAQ,MAAM,uCAAwC,EAAM,CACrD,GASX,MAJI,aAAc,EACT,EAAc,EAAc,CAG9B,GAST,SAAgB,EAAmB,EAAqC,CACtE,OAAO,EAAO,IAAI,GAAS,EAAe,EAAM,CAAC,CAWnD,SAAgB,EACd,EACA,EAAuB,MACvB,EAAyC,EAAE,CACnC,CACR,IAAM,EAAU,EAAe,EAAM,CAKrC,MAAO,IAAI,IAJG,OAAO,QAAQ,EAAe,CACzC,KAAK,CAAC,EAAK,KAAW,EAAmB,EAAK,EAAM,CAAC,CACrD,KAAK,GAAG,CAEqB,GAAG,EAAQ,IAAI,EAAa"}
1
+ {"version":3,"file":"nuclo.ssr.cjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n return text.replace(/[&<>]/g, (char) => (char === '&' ? '&amp;' : char === '<' ? '&lt;' : '&gt;'));\n}\n","import { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n return node.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * SVG attributes that are natively camelCase and must NOT be converted to kebab-case.\n * Most SVG attributes are already kebab-case (stroke-width, fill-rule, etc.), but a\n * handful are defined as camelCase in the SVG spec and must be preserved.\n */\nconst SVG_PRESERVE_CASE_ATTRS = new Set([\n 'viewBox', 'preserveAspectRatio', 'markerWidth', 'markerHeight',\n 'gradientTransform', 'patternTransform', 'clipPathUnits', 'gradientUnits',\n 'patternUnits', 'pathLength', 'refX', 'refY', 'stdDeviation',\n 'baseFrequency', 'numOctaves', 'kernelMatrix', 'tableValues',\n 'targetX', 'targetY', 'specularExponent', 'specularConstant',\n 'diffuseConstant', 'surfaceScale', 'xChannelSelector', 'yChannelSelector',\n 'edgeMode', 'stitchTiles', 'spreadMethod', 'patternContentUnits',\n 'markerUnits', 'startOffset', 'textLength', 'lengthAdjust',\n]);\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .filter(([, val]) => val != null && val !== '')\n .map(([key, val]) => `${camelToKebab(key)}: ${val};`)\n .join(' ');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n // Skip declarations with empty values (e.g. reactive styles that resolved to undefined)\n if (!val) return '';\n return `${camelToKebab(key)}: ${val};`;\n })\n .filter(Boolean)\n .join(' ');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n // Convert camelCase ARIA/HTML attribute names (e.g. ariaLabel → aria-label) that the\n // polyfill stores as-is because NucloElement lacks the browser property mappings.\n // SVG attributes that are natively camelCase (e.g. viewBox, preserveAspectRatio) must\n // NOT be converted — they are stored via setAttribute() as-is.\n for (const [name, value] of element.attributes) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node — only & < > need escaping; quotes are safe in text content\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeText(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeText(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) return '';\n\n if (typeof input === 'function') {\n try {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n"],"mappings":"mEASA,SAAgB,EAAa,EAAqB,CAChD,IAAI,EAAS,GACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,OAAQ,IAAK,CACnC,IAAM,EAAO,EAAI,WAAW,EAAE,CAE1B,GAAQ,IAAM,GAAQ,IACpB,EAAI,IAAG,GAAU,KACrB,GAAU,OAAO,aAAa,EAAO,GAAG,EAExC,GAAU,EAAI,GAGlB,OAAO,EAMT,SAAgB,EAAW,EAAsB,CAC/C,IAAM,EAA8B,CAClC,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,SACN,CACD,OAAO,EAAK,QAAQ,WAAa,GAAS,EAAI,GAAM,CAOtD,SAAgB,EAAW,EAAsB,CAC/C,OAAO,EAAK,QAAQ,SAAW,GAAU,IAAS,IAAM,QAAU,IAAS,IAAM,OAAS,OAAQ,CC5BpG,SAAgB,EAAc,EAAyC,CACrE,OAAO,WAAW,SAAW,SAAS,cAAc,EAAQ,CAAsB,KCIpF,MAAM,EAA0B,IAAI,IAAI,wbASvC,CAAC,CAOI,EAA0B,IAAI,IAAI,CACtC,kBAAmB,QAAS,YAAa,WAAY,UAAW,WAChE,UAAW,QAAS,WAAY,iBAAkB,SAAU,QAAS,OACrE,WAAY,QAAS,WAAY,aAAc,OAAQ,WAAY,WACnE,WAAY,WACb,CAAC,CAKF,SAAS,EAAmB,EAAc,EAAwB,CAChE,GAAI,GAAU,MAA+B,IAAU,GACrD,MAAO,GAGT,GAAI,IAAU,GACZ,MAAO,IAAI,IAIb,GAAI,EAAwB,IAAI,EAAK,CAAE,CACrC,GAAI,IAAU,QAAS,MAAO,GAC9B,GAAI,IAAU,QAAU,IAAU,IAAM,IAAU,EAAM,MAAO,IAAI,IAGrE,GAAI,IAAS,SAAW,OAAO,GAAU,SAAU,CACjD,IAAM,EAAW,OAAO,QAAQ,EAAM,CACnC,QAAQ,EAAG,KAAS,GAAO,MAAQ,IAAQ,GAAG,CAC9C,KAAK,CAAC,EAAK,KAAS,GAAG,EAAa,EAAI,CAAC,IAAI,EAAI,GAAG,CACpD,KAAK,IAAI,CACZ,OAAO,EAAW,WAAW,EAAW,EAAS,CAAC,GAAK,GAGzD,MAAO,IAAI,EAAK,IAAI,EAAW,OAAO,EAAM,CAAC,CAAC,GAMhD,SAAS,EAAoB,EAA0B,CACrD,IAAI,EAAS,GAGb,GAAI,eAAgB,GAAW,EAAQ,sBAAsB,IAAK,CAChE,IAAM,EAAK,EAcX,GAXI,EAAG,IAAM,CAAC,EAAQ,WAAW,IAAI,KAAK,GACxC,GAAU,EAAmB,KAAM,EAAG,GAAG,EAIvC,EAAG,WAAa,CAAC,EAAQ,WAAW,IAAI,QAAQ,GAClD,GAAU,EAAmB,QAAS,EAAG,UAAU,EAKjD,CAAC,EAAQ,WAAW,IAAI,QAAQ,EAAI,EAAG,MAAO,CAChD,IAAM,EAAqB,EAAG,MAAM,SAAW,GAC/C,GAAI,EAAY,CACd,IAAM,EAAa,EAChB,MAAM,IAAI,CACV,IAAK,GAAiB,EAAK,MAAM,CAAC,CAClC,OAAO,QAAQ,CACf,IAAK,GAAiB,CACrB,IAAM,EAAW,EAAK,QAAQ,IAAI,CAClC,GAAI,IAAa,GAAI,OAAO,EAC5B,IAAM,EAAM,EAAK,MAAM,EAAG,EAAS,CAAC,MAAM,CACpC,EAAM,EAAK,MAAM,EAAW,EAAE,CAAC,MAAM,CAG3C,OADK,EACE,GAAG,EAAa,EAAI,CAAC,IAAI,EAAI,GADnB,IAEjB,CACD,OAAO,QAAQ,CACf,KAAK,IAAI,CACR,IACF,GAAU,WAAW,EAAW,EAAW,CAAC,KAUlD,IAAK,GAAM,CAAC,EAAM,KAAU,EAAQ,WAAY,CAC9C,IAAM,EAAW,EAAwB,IAAI,EAAK,CAAG,EAAO,EAAa,EAAK,CAC9E,GAAU,EAAmB,EAAU,EAAM,CAE/C,OAAO,EAIT,GAAI,EAAQ,YAAc,EAAQ,WAAW,OAC3C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,WAAW,OAAQ,IAAK,CAClD,IAAM,EAAO,EAAQ,WAAW,GAC5B,GAAQ,EAAK,OACf,GAAU,EAAmB,EAAK,KAAM,EAAK,MAAM,EAKzD,OAAO,EAMT,MAAM,EAAgB,IAAI,IAAI,CAC5B,OAAQ,OAAQ,KAAM,MAAO,QAAS,KAAM,MAAO,QACnD,OAAQ,OAAQ,QAAS,SAAU,QAAS,MAC7C,CAAC,CAWF,SAAS,EAAc,EAA6B,CAElD,GAAI,YAAa,GAAQ,aAAc,EAAM,CAC3C,IAAM,EAAY,EAAa,SAC/B,GAAI,MAAM,QAAQ,EAAS,CACzB,OAAO,EAIX,GAAI,eAAgB,EAAM,CACxB,IAAM,EAAc,EAAa,WACjC,GAAI,IAAe,MAAM,QAAQ,EAAW,EAAI,EAAW,SAAW,IAAA,IACpE,OAAO,EAGX,MAAO,EAAE,CAMX,SAAS,EAAc,EAAoB,CAEzC,GAAI,EAAK,WAAa,EACpB,OAAO,EAAW,EAAK,aAAe,GAAG,CAI3C,GAAI,EAAK,WAAa,EACpB,MAAO,OAAO,EAAK,aAAe,GAAG,KAIvC,GAAI,EAAK,WAAa,EAAG,CACvB,IAAM,EAAU,EACV,EAAU,EAAQ,QAAQ,aAAa,CACvC,EAAa,EAAoB,EAAQ,CAG/C,GAAI,EAAc,IAAI,EAAQ,CAC5B,MAAO,IAAI,IAAU,EAAW,KAIlC,IAAI,EAAe,GACb,EAAa,EAAc,EAAQ,CACzC,GAAI,GAAc,EAAW,OAAS,EACpC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAQ,EAAW,GACrB,IACF,GAAgB,EAAc,EAAM,MAGnC,CAEL,IAAM,EAAM,EAAa,YACrB,OAAO,GAAO,UAAY,IAC5B,EAAe,EAAW,EAAG,EAIjC,MAAO,IAAI,IAAU,EAAW,GAAG,EAAa,IAAI,EAAQ,GAI9D,GAAI,EAAK,WAAa,GAAI,CACxB,IAAI,EAAS,GACP,EAAa,EAAc,EAAK,CACtC,GAAI,GAAc,EAAW,OAAS,EACpC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAQ,EAAW,GACrB,IACF,GAAU,EAAc,EAAM,EAIpC,OAAO,EAGT,MAAO,GAoBT,SAAgB,EAAe,EAAgC,CAC7D,GAAI,CAAC,EAAO,MAAO,GAEnB,GAAI,OAAO,GAAU,WACnB,GAAI,CACF,IAAM,EAAY,EAAc,MAAM,CACtC,GAAI,CAAC,EAAW,MAAU,MAAM,6DAA6D,CAC7F,IAAM,EAAU,EAAM,EAA8C,EAAE,CACtE,OAAO,GAAW,OAAO,GAAY,UAAY,aAAc,EAAU,EAAc,EAAgB,CAAG,SACnG,EAAO,CAEd,OADA,QAAQ,MAAM,uCAAwC,EAAM,CACrD,GAQX,MAJI,aAAc,EACT,EAAc,EAAc,CAG9B,GAST,SAAgB,EAAmB,EAAqC,CACtE,OAAO,EAAO,IAAI,GAAS,EAAe,EAAM,CAAC,CAWnD,SAAgB,EACd,EACA,EAAuB,MACvB,EAAyC,EAAE,CACnC,CACR,IAAM,EAAU,EAAe,EAAM,CAKrC,MAAO,IAAI,IAJG,OAAO,QAAQ,EAAe,CACzC,KAAK,CAAC,EAAK,KAAW,EAAmB,EAAK,EAAM,CAAC,CACrD,KAAK,GAAG,CAEqB,GAAG,EAAQ,IAAI,EAAa"}
@@ -1,2 +1,2 @@
1
- function e(e){let t=``;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r>=65&&r<=90?(n>0&&(t+=`-`),t+=String.fromCharCode(r+32)):t+=e[n]}return t}function t(e){let t={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#039;`};return e.replace(/[&<>"']/g,e=>t[e])}function n(e){return globalThis.document?document.createElement(e):null}const r=new Set([`allowfullscreen`,`async`,`autofocus`,`autoplay`,`checked`,`controls`,`default`,`defer`,`disabled`,`formnovalidate`,`hidden`,`ismap`,`loop`,`multiple`,`muted`,`nomodule`,`novalidate`,`open`,`readonly`,`required`,`reversed`,`selected`]);function i(n,i){if(i==null||i===!1)return``;if(i===!0)return` ${n}`;if(r.has(n)){if(i===`false`)return``;if(i===`true`||i===``||i===n)return` ${n}`}if(n===`style`&&typeof i==`object`){let n=Object.entries(i).map(([t,n])=>`${e(t)}:${n}`).join(`;`);return n?` style="${t(n)}"`:``}return` ${n}="${t(String(i))}"`}function a(n){let r=``;if(`attributes`in n&&n.attributes instanceof Map){let a=n;if(a.id&&!n.attributes.has(`id`)&&(r+=i(`id`,a.id)),a.className&&!n.attributes.has(`class`)&&(r+=i(`class`,a.className)),!n.attributes.has(`style`)&&a.style){let n=a.style.cssText||``;if(n){let i=n.split(`;`).map(e=>e.trim()).filter(Boolean).map(t=>{let n=t.indexOf(`:`);if(n===-1)return t;let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();return`${e(r)}:${i}`}).join(`;`);i&&(r+=` style="${t(i)}"`)}}for(let[e,t]of n.attributes)r+=i(e,t);return r}if(n.attributes&&n.attributes.length)for(let e=0;e<n.attributes.length;e++){let t=n.attributes[e];t&&t.name&&(r+=i(t.name,t.value))}return r}const o=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function s(e){if(`tagName`in e&&`children`in e){let t=e.children;if(Array.isArray(t))return t}if(`childNodes`in e){let t=e.childNodes;if(t&&(Array.isArray(t)||t.length!==void 0))return t}return[]}function c(e){if(e.nodeType===3)return t(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let n=e,r=n.tagName.toLowerCase(),i=a(n);if(o.has(r))return`<${r}${i} />`;let l=``,u=s(n);if(u&&u.length>0)for(let e=0;e<u.length;e++){let t=u[e];t&&(l+=c(t))}else{let n=e.textContent;typeof n==`string`&&n&&(l=t(n))}return`<${r}${i}>${l}</${r}>`}if(e.nodeType===11){let t=``,n=s(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&r.nodeType!==8&&(t+=c(r))}return t}return``}function l(e){if(!e)return``;if(typeof e==`function`)try{let t=n(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);let r=e(t,0);return r&&typeof r==`object`&&`nodeType`in r?c(r):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?c(e):``}function u(e){return e.map(e=>l(e))}function d(e,t=`div`,n={}){let r=l(e);return`<${t}${Object.entries(n).map(([e,t])=>i(e,t)).join(``)}>${r}</${t}>`}export{u as renderManyToString,l as renderToString,d as renderToStringWithContainer};
1
+ function e(e){let t=``;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r>=65&&r<=90?(n>0&&(t+=`-`),t+=String.fromCharCode(r+32)):t+=e[n]}return t}function t(e){let t={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#039;`};return e.replace(/[&<>"']/g,e=>t[e])}function n(e){return e.replace(/[&<>]/g,e=>e===`&`?`&amp;`:e===`<`?`&lt;`:`&gt;`)}function r(e){return globalThis.document?document.createElement(e):null}const i=new Set(`viewBox.preserveAspectRatio.markerWidth.markerHeight.gradientTransform.patternTransform.clipPathUnits.gradientUnits.patternUnits.pathLength.refX.refY.stdDeviation.baseFrequency.numOctaves.kernelMatrix.tableValues.targetX.targetY.specularExponent.specularConstant.diffuseConstant.surfaceScale.xChannelSelector.yChannelSelector.edgeMode.stitchTiles.spreadMethod.patternContentUnits.markerUnits.startOffset.textLength.lengthAdjust`.split(`.`)),a=new Set([`allowfullscreen`,`async`,`autofocus`,`autoplay`,`checked`,`controls`,`default`,`defer`,`disabled`,`formnovalidate`,`hidden`,`ismap`,`loop`,`multiple`,`muted`,`nomodule`,`novalidate`,`open`,`readonly`,`required`,`reversed`,`selected`]);function o(n,r){if(r==null||r===!1)return``;if(r===!0)return` ${n}`;if(a.has(n)){if(r===`false`)return``;if(r===`true`||r===``||r===n)return` ${n}`}if(n===`style`&&typeof r==`object`){let n=Object.entries(r).filter(([,e])=>e!=null&&e!==``).map(([t,n])=>`${e(t)}: ${n};`).join(` `);return n?` style="${t(n)}"`:``}return` ${n}="${t(String(r))}"`}function s(n){let r=``;if(`attributes`in n&&n.attributes instanceof Map){let a=n;if(a.id&&!n.attributes.has(`id`)&&(r+=o(`id`,a.id)),a.className&&!n.attributes.has(`class`)&&(r+=o(`class`,a.className)),!n.attributes.has(`style`)&&a.style){let n=a.style.cssText||``;if(n){let i=n.split(`;`).map(e=>e.trim()).filter(Boolean).map(t=>{let n=t.indexOf(`:`);if(n===-1)return t;let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();return i?`${e(r)}: ${i};`:``}).filter(Boolean).join(` `);i&&(r+=` style="${t(i)}"`)}}for(let[t,a]of n.attributes){let n=i.has(t)?t:e(t);r+=o(n,a)}return r}if(n.attributes&&n.attributes.length)for(let e=0;e<n.attributes.length;e++){let t=n.attributes[e];t&&t.name&&(r+=o(t.name,t.value))}return r}const c=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function l(e){if(`tagName`in e&&`children`in e){let t=e.children;if(Array.isArray(t))return t}if(`childNodes`in e){let t=e.childNodes;if(t&&(Array.isArray(t)||t.length!==void 0))return t}return[]}function u(e){if(e.nodeType===3)return n(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let t=e,r=t.tagName.toLowerCase(),i=s(t);if(c.has(r))return`<${r}${i} />`;let a=``,o=l(t);if(o&&o.length>0)for(let e=0;e<o.length;e++){let t=o[e];t&&(a+=u(t))}else{let t=e.textContent;typeof t==`string`&&t&&(a=n(t))}return`<${r}${i}>${a}</${r}>`}if(e.nodeType===11){let t=``,n=l(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&(t+=u(r))}return t}return``}function d(e){if(!e)return``;if(typeof e==`function`)try{let t=r(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);let n=e(t,0);return n&&typeof n==`object`&&`nodeType`in n?u(n):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?u(e):``}function f(e){return e.map(e=>d(e))}function p(e,t=`div`,n={}){let r=d(e);return`<${t}${Object.entries(n).map(([e,t])=>o(e,t)).join(``)}>${r}</${t}>`}export{f as renderManyToString,d as renderToString,p as renderToStringWithContainer};
2
2
  //# sourceMappingURL=nuclo.ssr.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nuclo.ssr.mjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters to prevent XSS\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n","import { isBrowser } from \"./environment\";\nimport { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nfunction createTextNodeSafely(text: string | number | boolean): Text | null {\n if (!globalThis.document) return null;\n try {\n return createTextNode(String(text));\n } catch (error) {\n logError('Failed to create text node', error);\n return null;\n }\n}\n\nfunction createCommentSafely(text: string): Comment | null {\n if (!globalThis.document) return null;\n try {\n return globalThis.document.createComment(text);\n } catch (error) {\n logError('Failed to create comment node', error);\n return null;\n }\n}\n\n/**\n * Creates a comment node safely with error handling.\n * Exported for use across the codebase.\n */\nexport function createComment(text: string): Comment | null {\n return createCommentSafely(text);\n}\n\n/**\n * Creates a conditional comment placeholder node.\n * Uses globalThis.document so it is safe in SSR environments where `document`\n * may not exist as a global binding (avoids bare ReferenceError).\n */\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n\ttry {\n\t\treturn globalThis.document?.createComment(`conditional-${tagName}-${suffix}`) ?? null;\n\t} catch (error) {\n\t\tlogError('Failed to create conditional comment', error);\n\t\treturn null;\n\t}\n}\n\nexport function createMarkerComment(prefix: string): Comment {\n const comment = createCommentSafely(`${prefix}-${Math.random().toString(36).slice(2)}`);\n if (!comment) {\n throw new Error(\"Failed to create comment: document not available\");\n }\n return comment;\n}\n\nexport function createMarkerPair(prefix: string): { start: Comment; end: Comment } {\n const endComment = createCommentSafely(`${prefix}-end`);\n if (!endComment) {\n throw new Error(\"Failed to create comment: document not available\");\n }\n return {\n start: createMarkerComment(`${prefix}-start`),\n end: endComment\n };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNodeSafely(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n\n // Prefer the built-in isConnected property\n if (typeof node.isConnected === \"boolean\") {\n return node.isConnected;\n }\n\n // Fallback for older browsers (only if in browser environment)\n if (isBrowser && typeof document !== 'undefined') {\n return document.contains(node);\n }\n\n // In SSR or when document is not available, assume disconnected\n return false;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n\nimport { escapeHtml, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .map(([key, val]) => {\n const cssKey = camelToKebab(key);\n return `${cssKey}:${val}`;\n })\n .join(';');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n return `${camelToKebab(key)}:${val}`;\n })\n .join(';');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n for (const [name, value] of element.attributes) {\n result += serializeAttribute(name, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeHtml(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeHtml(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n // Skip internal framework comment markers (e.g. \" text-0 \") that are\n // reactive anchors for browser-side updates — they have no meaning in\n // an SSR string and must not appear in the output.\n if (child && child.nodeType !== 8) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) {\n return '';\n }\n\n // If it's a function (NodeModFn), call it to create the element\n if (typeof input === 'function') {\n try {\n // Create a temporary container to render into\n const container = createElement('div');\n if (!container) {\n throw new Error('Document is not available. Make sure polyfills are loaded.');\n }\n\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n // If it's already a Node, serialize it directly\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"nuclo.ssr.mjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n return text.replace(/[&<>]/g, (char) => (char === '&' ? '&amp;' : char === '<' ? '&lt;' : '&gt;'));\n}\n","import { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n return node.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * SVG attributes that are natively camelCase and must NOT be converted to kebab-case.\n * Most SVG attributes are already kebab-case (stroke-width, fill-rule, etc.), but a\n * handful are defined as camelCase in the SVG spec and must be preserved.\n */\nconst SVG_PRESERVE_CASE_ATTRS = new Set([\n 'viewBox', 'preserveAspectRatio', 'markerWidth', 'markerHeight',\n 'gradientTransform', 'patternTransform', 'clipPathUnits', 'gradientUnits',\n 'patternUnits', 'pathLength', 'refX', 'refY', 'stdDeviation',\n 'baseFrequency', 'numOctaves', 'kernelMatrix', 'tableValues',\n 'targetX', 'targetY', 'specularExponent', 'specularConstant',\n 'diffuseConstant', 'surfaceScale', 'xChannelSelector', 'yChannelSelector',\n 'edgeMode', 'stitchTiles', 'spreadMethod', 'patternContentUnits',\n 'markerUnits', 'startOffset', 'textLength', 'lengthAdjust',\n]);\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .filter(([, val]) => val != null && val !== '')\n .map(([key, val]) => `${camelToKebab(key)}: ${val};`)\n .join(' ');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n // Skip declarations with empty values (e.g. reactive styles that resolved to undefined)\n if (!val) return '';\n return `${camelToKebab(key)}: ${val};`;\n })\n .filter(Boolean)\n .join(' ');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n // Convert camelCase ARIA/HTML attribute names (e.g. ariaLabel → aria-label) that the\n // polyfill stores as-is because NucloElement lacks the browser property mappings.\n // SVG attributes that are natively camelCase (e.g. viewBox, preserveAspectRatio) must\n // NOT be converted — they are stored via setAttribute() as-is.\n for (const [name, value] of element.attributes) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node — only & < > need escaping; quotes are safe in text content\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeText(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeText(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) return '';\n\n if (typeof input === 'function') {\n try {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderToString.d.ts","sourceRoot":"","sources":["../../src/ssr/renderToString.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,KAAK,eAAe,GAChB,SAAS,CAAC,cAAc,CAAC,GACzB,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,CAAC;AAkNd;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CA4B7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,YAAY,GAAE,MAAc,EAC5B,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAOR"}
1
+ {"version":3,"file":"renderToString.d.ts","sourceRoot":"","sources":["../../src/ssr/renderToString.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,KAAK,eAAe,GAChB,SAAS,CAAC,cAAc,CAAC,GACzB,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,CAAC;AAqOd;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAoB7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,YAAY,GAAE,MAAc,EAC5B,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAOR"}
@@ -1 +1 @@
1
- {"version":3,"file":"cssGenerator.d.ts","sourceRoot":"","sources":["../../src/style/cssGenerator.ts"],"names":[],"mappings":"AAGA,KAAK,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAG1E,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,UAAoB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAoDvI;AAGD,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,GAAE,UAAoB,EAChC,WAAW,CAAC,EAAE,MAAM,GAClB,IAAI,CAyLN;AAGD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEtF"}
1
+ {"version":3,"file":"cssGenerator.d.ts","sourceRoot":"","sources":["../../src/style/cssGenerator.ts"],"names":[],"mappings":"AAGA,KAAK,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AA2D1E,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,UAAoB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAqBvI;AAED,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,GAAE,UAAoB,EAChC,WAAW,CAAC,EAAE,MAAM,GAClB,IAAI,CAkGN;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEtF"}
@@ -1,98 +1,98 @@
1
- export type DisplayValue = "block" | "inline" | "flex" | "grid" | "inline-block" | "inline-flex" | "inline-grid" | "none" | "contents" | "table" | "table-row" | "table-cell" | "list-item" | "run-in" | "flow" | "flow-root" | "ruby" | "ruby-base" | "ruby-text" | "ruby-base-container" | "ruby-text-container" | string;
2
- export type PositionValue = "static" | "relative" | "absolute" | "fixed" | "sticky" | string;
3
- export type TextAlignValue = "left" | "right" | "center" | "justify" | "start" | "end" | "match-parent" | string;
4
- export type FontWeightValue = "normal" | "bold" | "bolder" | "lighter" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | number | string;
5
- export type FontStyleValue = "normal" | "italic" | "oblique" | `oblique ${string}` | string;
6
- export type TextTransformValue = "none" | "capitalize" | "uppercase" | "lowercase" | "full-width" | "full-size-kana" | string;
7
- export type TextDecorationValue = "none" | "underline" | "overline" | "line-through" | "blink" | string;
8
- export type TextDecorationStyleValue = "solid" | "double" | "dotted" | "dashed" | "wavy" | string;
9
- export type TextDecorationLineValue = "none" | "underline" | "overline" | "line-through" | "blink" | string;
10
- export type WhiteSpaceValue = "normal" | "nowrap" | "pre" | "pre-wrap" | "pre-line" | "break-spaces" | string;
11
- export type OverflowValue = "visible" | "hidden" | "clip" | "scroll" | "auto" | string;
12
- export type VisibilityValue = "visible" | "hidden" | "collapse" | string;
13
- export type FlexDirectionValue = "row" | "row-reverse" | "column" | "column-reverse" | string;
14
- export type FlexWrapValue = "nowrap" | "wrap" | "wrap-reverse" | string;
15
- export type AlignItemsValue = "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | string;
16
- export type JustifyContentValue = "normal" | "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | "start" | "end" | "left" | "right" | string;
17
- export type AlignSelfValue = "auto" | "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | string;
18
- export type AlignContentValue = "normal" | "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | "start" | "end" | "baseline" | "first baseline" | "last baseline" | string;
19
- export type JustifySelfValue = "auto" | "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | "left" | "right" | string;
20
- export type JustifyItemsValue = "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | "left" | "right" | "legacy" | string;
21
- export type GridAutoFlowValue = "row" | "column" | "dense" | "row dense" | "column dense" | string;
22
- export type BorderStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | string;
23
- export type OutlineStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | string;
24
- export type BoxSizingValue = "content-box" | "border-box" | string;
25
- export type ObjectFitValue = "fill" | "contain" | "cover" | "none" | "scale-down" | string;
26
- export type VerticalAlignValue = "baseline" | "sub" | "super" | "text-top" | "text-bottom" | "middle" | "top" | "bottom" | string | `${number}%` | `${number}px` | `${number}em` | `${number}rem`;
27
- export type TextAlignLastValue = "auto" | "left" | "right" | "center" | "justify" | "start" | "end" | string;
28
- export type TextJustifyValue = "auto" | "inter-word" | "inter-character" | "none" | string;
29
- export type TextOverflowValue = "clip" | "ellipsis" | string;
30
- export type WordWrapValue = "normal" | "break-word" | "anywhere" | string;
31
- export type OverflowWrapValue = "normal" | "break-word" | "anywhere" | string;
32
- export type BackgroundRepeatValue = "repeat" | "repeat-x" | "repeat-y" | "no-repeat" | "space" | "round" | string;
33
- export type BackgroundAttachmentValue = "scroll" | "fixed" | "local" | string;
34
- export type BackgroundClipValue = "border-box" | "padding-box" | "content-box" | "text" | string;
35
- export type BackgroundOriginValue = "border-box" | "padding-box" | "content-box" | string;
36
- export type TransformStyleValue = "flat" | "preserve-3d" | string;
37
- export type BackfaceVisibilityValue = "visible" | "hidden" | string;
38
- export type AnimationDirectionValue = "normal" | "reverse" | "alternate" | "alternate-reverse" | string;
39
- export type AnimationFillModeValue = "none" | "forwards" | "backwards" | "both" | string;
40
- export type AnimationPlayStateValue = "running" | "paused" | string;
41
- export type ListStyleTypeValue = "none" | "disc" | "circle" | "square" | "decimal" | "decimal-leading-zero" | "lower-roman" | "upper-roman" | "lower-greek" | "lower-latin" | "upper-latin" | "armenian" | "georgian" | "lower-alpha" | "upper-alpha" | string;
42
- export type ListStylePositionValue = "inside" | "outside" | string;
43
- export type BorderCollapseValue = "separate" | "collapse" | string;
44
- export type CaptionSideValue = "top" | "bottom" | "left" | "right" | string;
45
- export type EmptyCellsValue = "show" | "hide" | string;
46
- export type TableLayoutValue = "auto" | "fixed" | string;
47
- export type AppearanceValue = "none" | "auto" | "button" | "textfield" | "menulist-button" | "searchfield" | "textarea" | "push-button" | "slider-horizontal" | "checkbox" | "radio" | "square-button" | "menulist" | "listbox" | "meter" | "progress-bar" | string;
48
- export type UserSelectValue = "none" | "auto" | "text" | "contain" | "all" | string;
49
- export type PointerEventsValue = "auto" | "none" | "visiblePainted" | "visibleFill" | "visibleStroke" | "visible" | "painted" | "fill" | "stroke" | "all" | string;
50
- export type ResizeValue = "none" | "both" | "horizontal" | "vertical" | "block" | "inline" | string;
51
- export type ScrollBehaviorValue = "auto" | "smooth" | string;
52
- export type IsolationValue = "auto" | "isolate" | string;
53
- export type MixBlendModeValue = "normal" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | string;
54
- export type ContainValue = "none" | "strict" | "content" | "size" | "layout" | "style" | "paint" | string;
55
- export type PageBreakValue = "auto" | "always" | "avoid" | "left" | "right" | "recto" | "verso" | string;
56
- export type BreakValue = "auto" | "avoid" | "avoid-page" | "page" | "left" | "right" | "recto" | "verso" | "avoid-column" | "column" | "avoid-region" | "region" | string;
57
- export type ColumnFillValue = "auto" | "balance" | "balance-all" | string;
58
- export type ColumnRuleStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | string;
59
- export type ColumnSpanValue = "none" | "all" | string;
60
- export type CursorValue = "auto" | "default" | "none" | "context-menu" | "help" | "pointer" | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text" | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "e-resize" | "n-resize" | "ne-resize" | "nw-resize" | "s-resize" | "se-resize" | "sw-resize" | "w-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "col-resize" | "row-resize" | "all-scroll" | "zoom-in" | "zoom-out" | "grab" | "grabbing" | string;
61
- export type FloatValue = "none" | "left" | "right" | "inline-start" | "inline-end" | string;
62
- export type ClearValue = "none" | "left" | "right" | "both" | "inline-start" | "inline-end" | string;
63
- export type WritingModeValue = "horizontal-tb" | "vertical-rl" | "vertical-lr" | "sideways-rl" | "sideways-lr" | string;
64
- export type DirectionValue = "ltr" | "rtl" | string;
65
- export type UnicodeBidiValue = "normal" | "embed" | "bidi-override" | "isolate" | "isolate-override" | "plaintext" | string;
66
- export type TextOrientationValue = "mixed" | "upright" | "sideways" | "sideways-right" | "use-glyph-orientation" | string;
67
- export type HyphensValue = "none" | "manual" | "auto" | string;
68
- export type LineBreakValue = "auto" | "loose" | "normal" | "strict" | "anywhere" | string;
69
- export type WordBreakValue = "normal" | "break-all" | "keep-all" | "break-word" | string;
70
- export type TouchActionValue = "auto" | "none" | "pan-x" | "pan-y" | "pan-left" | "pan-right" | "pan-up" | "pan-down" | "pinch-zoom" | "manipulation" | string;
71
- export type OverscrollBehaviorValue = "auto" | "contain" | "none" | string;
72
- export type ImageRenderingValue = "auto" | "smooth" | "crisp-edges" | "pixelated" | string;
73
- export type ColorSchemeValue = "normal" | "light" | "dark" | "light dark" | "only light" | "only dark" | string;
1
+ export type DisplayValue = "block" | "inline" | "flex" | "grid" | "inline-block" | "inline-flex" | "inline-grid" | "none" | "contents" | "table" | "table-row" | "table-cell" | "list-item" | "run-in" | "flow" | "flow-root" | "ruby" | "ruby-base" | "ruby-text" | "ruby-base-container" | "ruby-text-container" | (string & {});
2
+ export type PositionValue = "static" | "relative" | "absolute" | "fixed" | "sticky" | (string & {});
3
+ export type TextAlignValue = "left" | "right" | "center" | "justify" | "start" | "end" | "match-parent" | (string & {});
4
+ export type FontWeightValue = "normal" | "bold" | "bolder" | "lighter" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | number | (string & {});
5
+ export type FontStyleValue = "normal" | "italic" | "oblique" | `oblique ${string}` | (string & {});
6
+ export type TextTransformValue = "none" | "capitalize" | "uppercase" | "lowercase" | "full-width" | "full-size-kana" | (string & {});
7
+ export type TextDecorationValue = "none" | "underline" | "overline" | "line-through" | "blink" | (string & {});
8
+ export type TextDecorationStyleValue = "solid" | "double" | "dotted" | "dashed" | "wavy" | (string & {});
9
+ export type TextDecorationLineValue = "none" | "underline" | "overline" | "line-through" | "blink" | (string & {});
10
+ export type WhiteSpaceValue = "normal" | "nowrap" | "pre" | "pre-wrap" | "pre-line" | "break-spaces" | (string & {});
11
+ export type OverflowValue = "visible" | "hidden" | "clip" | "scroll" | "auto" | (string & {});
12
+ export type VisibilityValue = "visible" | "hidden" | "collapse" | (string & {});
13
+ export type FlexDirectionValue = "row" | "row-reverse" | "column" | "column-reverse" | (string & {});
14
+ export type FlexWrapValue = "nowrap" | "wrap" | "wrap-reverse" | (string & {});
15
+ export type AlignItemsValue = "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | (string & {});
16
+ export type JustifyContentValue = "normal" | "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | "start" | "end" | "left" | "right" | (string & {});
17
+ export type AlignSelfValue = "auto" | "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | (string & {});
18
+ export type AlignContentValue = "normal" | "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | "start" | "end" | "baseline" | "first baseline" | "last baseline" | (string & {});
19
+ export type JustifySelfValue = "auto" | "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | "left" | "right" | (string & {});
20
+ export type JustifyItemsValue = "normal" | "stretch" | "flex-start" | "flex-end" | "center" | "baseline" | "first baseline" | "last baseline" | "start" | "end" | "self-start" | "self-end" | "left" | "right" | "legacy" | (string & {});
21
+ export type GridAutoFlowValue = "row" | "column" | "dense" | "row dense" | "column dense" | (string & {});
22
+ export type BorderStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | (string & {});
23
+ export type OutlineStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | (string & {});
24
+ export type BoxSizingValue = "content-box" | "border-box" | (string & {});
25
+ export type ObjectFitValue = "fill" | "contain" | "cover" | "none" | "scale-down" | (string & {});
26
+ export type VerticalAlignValue = "baseline" | "sub" | "super" | "text-top" | "text-bottom" | "middle" | "top" | "bottom" | `${number}%` | `${number}px` | `${number}em` | `${number}rem` | (string & {});
27
+ export type TextAlignLastValue = "auto" | "left" | "right" | "center" | "justify" | "start" | "end" | (string & {});
28
+ export type TextJustifyValue = "auto" | "inter-word" | "inter-character" | "none" | (string & {});
29
+ export type TextOverflowValue = "clip" | "ellipsis" | (string & {});
30
+ export type WordWrapValue = "normal" | "break-word" | "anywhere" | (string & {});
31
+ export type OverflowWrapValue = "normal" | "break-word" | "anywhere" | (string & {});
32
+ export type BackgroundRepeatValue = "repeat" | "repeat-x" | "repeat-y" | "no-repeat" | "space" | "round" | (string & {});
33
+ export type BackgroundAttachmentValue = "scroll" | "fixed" | "local" | (string & {});
34
+ export type BackgroundClipValue = "border-box" | "padding-box" | "content-box" | "text" | (string & {});
35
+ export type BackgroundOriginValue = "border-box" | "padding-box" | "content-box" | (string & {});
36
+ export type TransformStyleValue = "flat" | "preserve-3d" | (string & {});
37
+ export type BackfaceVisibilityValue = "visible" | "hidden" | (string & {});
38
+ export type AnimationDirectionValue = "normal" | "reverse" | "alternate" | "alternate-reverse" | (string & {});
39
+ export type AnimationFillModeValue = "none" | "forwards" | "backwards" | "both" | (string & {});
40
+ export type AnimationPlayStateValue = "running" | "paused" | (string & {});
41
+ export type ListStyleTypeValue = "none" | "disc" | "circle" | "square" | "decimal" | "decimal-leading-zero" | "lower-roman" | "upper-roman" | "lower-greek" | "lower-latin" | "upper-latin" | "armenian" | "georgian" | "lower-alpha" | "upper-alpha" | (string & {});
42
+ export type ListStylePositionValue = "inside" | "outside" | (string & {});
43
+ export type BorderCollapseValue = "separate" | "collapse" | (string & {});
44
+ export type CaptionSideValue = "top" | "bottom" | "left" | "right" | (string & {});
45
+ export type EmptyCellsValue = "show" | "hide" | (string & {});
46
+ export type TableLayoutValue = "auto" | "fixed" | (string & {});
47
+ export type AppearanceValue = "none" | "auto" | "button" | "textfield" | "menulist-button" | "searchfield" | "textarea" | "push-button" | "slider-horizontal" | "checkbox" | "radio" | "square-button" | "menulist" | "listbox" | "meter" | "progress-bar" | (string & {});
48
+ export type UserSelectValue = "none" | "auto" | "text" | "contain" | "all" | (string & {});
49
+ export type PointerEventsValue = "auto" | "none" | "visiblePainted" | "visibleFill" | "visibleStroke" | "visible" | "painted" | "fill" | "stroke" | "all" | (string & {});
50
+ export type ResizeValue = "none" | "both" | "horizontal" | "vertical" | "block" | "inline" | (string & {});
51
+ export type ScrollBehaviorValue = "auto" | "smooth" | (string & {});
52
+ export type IsolationValue = "auto" | "isolate" | (string & {});
53
+ export type MixBlendModeValue = "normal" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | (string & {});
54
+ export type ContainValue = "none" | "strict" | "content" | "size" | "layout" | "style" | "paint" | (string & {});
55
+ export type PageBreakValue = "auto" | "always" | "avoid" | "left" | "right" | "recto" | "verso" | (string & {});
56
+ export type BreakValue = "auto" | "avoid" | "avoid-page" | "page" | "left" | "right" | "recto" | "verso" | "avoid-column" | "column" | "avoid-region" | "region" | (string & {});
57
+ export type ColumnFillValue = "auto" | "balance" | "balance-all" | (string & {});
58
+ export type ColumnRuleStyleValue = "none" | "hidden" | "dotted" | "dashed" | "solid" | "double" | "groove" | "ridge" | "inset" | "outset" | (string & {});
59
+ export type ColumnSpanValue = "none" | "all" | (string & {});
60
+ export type CursorValue = "auto" | "default" | "none" | "context-menu" | "help" | "pointer" | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text" | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "e-resize" | "n-resize" | "ne-resize" | "nw-resize" | "s-resize" | "se-resize" | "sw-resize" | "w-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "col-resize" | "row-resize" | "all-scroll" | "zoom-in" | "zoom-out" | "grab" | "grabbing" | (string & {});
61
+ export type FloatValue = "none" | "left" | "right" | "inline-start" | "inline-end" | (string & {});
62
+ export type ClearValue = "none" | "left" | "right" | "both" | "inline-start" | "inline-end" | (string & {});
63
+ export type WritingModeValue = "horizontal-tb" | "vertical-rl" | "vertical-lr" | "sideways-rl" | "sideways-lr" | (string & {});
64
+ export type DirectionValue = "ltr" | "rtl" | (string & {});
65
+ export type UnicodeBidiValue = "normal" | "embed" | "bidi-override" | "isolate" | "isolate-override" | "plaintext" | (string & {});
66
+ export type TextOrientationValue = "mixed" | "upright" | "sideways" | "sideways-right" | "use-glyph-orientation" | (string & {});
67
+ export type HyphensValue = "none" | "manual" | "auto" | (string & {});
68
+ export type LineBreakValue = "auto" | "loose" | "normal" | "strict" | "anywhere" | (string & {});
69
+ export type WordBreakValue = "normal" | "break-all" | "keep-all" | "break-word" | (string & {});
70
+ export type TouchActionValue = "auto" | "none" | "pan-x" | "pan-y" | "pan-left" | "pan-right" | "pan-up" | "pan-down" | "pinch-zoom" | "manipulation" | (string & {});
71
+ export type OverscrollBehaviorValue = "auto" | "contain" | "none" | (string & {});
72
+ export type ImageRenderingValue = "auto" | "smooth" | "crisp-edges" | "pixelated" | (string & {});
73
+ export type ColorSchemeValue = "normal" | "light" | "dark" | "light dark" | "only light" | "only dark" | (string & {});
74
74
  export type CaretColorValue = CSSColorValue | "auto";
75
- export type CaretShapeValue = "auto" | "bar" | "block" | "underscore" | string;
76
- export type BackgroundBlendModeValue = "normal" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | string;
77
- export type ContentVisibilityValue = "visible" | "auto" | "hidden" | string;
78
- export type ContainerTypeValue = "normal" | "size" | "inline-size" | "block-size" | string;
79
- export type FontKerningValue = "auto" | "normal" | "none" | string;
80
- export type FontSynthesisValue = "none" | "weight" | "style" | "small-caps" | "weight style" | "weight small-caps" | "style small-caps" | "weight style small-caps" | string;
81
- export type FontOpticalSizingValue = "auto" | "none" | string;
82
- export type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional" | string;
83
- export type FontVariantCapsValue = "normal" | "small-caps" | "all-small-caps" | "petite-caps" | "all-petite-caps" | "unicase" | "titling-caps" | string;
84
- export type TextRenderingValue = "auto" | "optimizeSpeed" | "optimizeLegibility" | "geometricPrecision" | string;
85
- export type TextCombineUprightValue = "none" | "all" | "digits" | string;
86
- export type MaskCompositeValue = "add" | "subtract" | "intersect" | "exclude" | string;
87
- export type ClipRuleValue = "nonzero" | "evenodd" | string;
88
- export type CSSLengthValue = string | number | `${number}px` | `${number}em` | `${number}rem` | `${number}%` | `${number}vw` | `${number}vh` | `${number}vmin` | `${number}vmax` | `${number}ch` | `${number}ex` | `${number}cm` | `${number}mm` | `${number}in` | `${number}pt` | `${number}pc`;
89
- export type CSSColorValue = string;
90
- export type CSSFontFamilyValue = string;
91
- export type CSSTimingFunctionValue = string;
92
- export type CSSTransformValue = string;
93
- export type CSSFilterValue = string;
94
- export type CSSBackgroundImageValue = string;
95
- export type CSSAnimationNameValue = string;
96
- export type CSSContentValue = string;
97
- export type CSSAspectRatioValue = string | number | "auto" | `${number} / ${number}`;
75
+ export type CaretShapeValue = "auto" | "bar" | "block" | "underscore" | (string & {});
76
+ export type BackgroundBlendModeValue = "normal" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | (string & {});
77
+ export type ContentVisibilityValue = "visible" | "auto" | "hidden" | (string & {});
78
+ export type ContainerTypeValue = "normal" | "size" | "inline-size" | "block-size" | (string & {});
79
+ export type FontKerningValue = "auto" | "normal" | "none" | (string & {});
80
+ export type FontSynthesisValue = "none" | "weight" | "style" | "small-caps" | "weight style" | "weight small-caps" | "style small-caps" | "weight style small-caps" | (string & {});
81
+ export type FontOpticalSizingValue = "auto" | "none" | (string & {});
82
+ export type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional" | (string & {});
83
+ export type FontVariantCapsValue = "normal" | "small-caps" | "all-small-caps" | "petite-caps" | "all-petite-caps" | "unicase" | "titling-caps" | (string & {});
84
+ export type TextRenderingValue = "auto" | "optimizeSpeed" | "optimizeLegibility" | "geometricPrecision" | (string & {});
85
+ export type TextCombineUprightValue = "none" | "all" | "digits" | (string & {});
86
+ export type MaskCompositeValue = "add" | "subtract" | "intersect" | "exclude" | (string & {});
87
+ export type ClipRuleValue = "nonzero" | "evenodd" | (string & {});
88
+ export type CSSLengthValue = number | `${number}px` | `${number}em` | `${number}rem` | `${number}%` | `${number}vw` | `${number}vh` | `${number}vmin` | `${number}vmax` | `${number}ch` | `${number}ex` | `${number}cm` | `${number}mm` | `${number}in` | `${number}pt` | `${number}pc` | (string & {});
89
+ export type CSSColorValue = (string & {});
90
+ export type CSSFontFamilyValue = (string & {});
91
+ export type CSSTimingFunctionValue = "ease" | "linear" | "ease-in" | "ease-out" | "ease-in-out" | "step-start" | "step-end" | (string & {});
92
+ export type CSSTransformValue = (string & {});
93
+ export type CSSFilterValue = (string & {});
94
+ export type CSSBackgroundImageValue = (string & {});
95
+ export type CSSAnimationNameValue = "none" | (string & {});
96
+ export type CSSContentValue = "none" | "normal" | (string & {});
97
+ export type CSSAspectRatioValue = number | "auto" | `${number} / ${number}` | (string & {});
98
98
  //# sourceMappingURL=cssPropertyTypes.d.ts.map