create-nuclo 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (534) hide show
  1. package/README.md +60 -0
  2. package/package.json +35 -0
  3. package/src/create-nuclo.mjs +193 -0
  4. package/templates/basic/README.md +16 -0
  5. package/templates/basic/_gitignore +5 -0
  6. package/templates/basic/index.html +26 -0
  7. package/templates/basic/node_modules/.package-lock.json +348 -0
  8. package/templates/basic/node_modules/.vite/deps/_metadata.json +15 -0
  9. package/templates/basic/node_modules/.vite/deps/nuclo.js +1665 -0
  10. package/templates/basic/node_modules/.vite/deps/nuclo.js.map +1 -0
  11. package/templates/basic/node_modules/.vite/deps/package.json +3 -0
  12. package/templates/basic/node_modules/@oxc-project/types/LICENSE +22 -0
  13. package/templates/basic/node_modules/@oxc-project/types/README.md +3 -0
  14. package/templates/basic/node_modules/@oxc-project/types/package.json +26 -0
  15. package/templates/basic/node_modules/@oxc-project/types/types.d.ts +1912 -0
  16. package/templates/basic/node_modules/@rolldown/binding-darwin-arm64/README.md +3 -0
  17. package/templates/basic/node_modules/@rolldown/binding-darwin-arm64/package.json +37 -0
  18. package/templates/basic/node_modules/@rolldown/binding-darwin-arm64/rolldown-binding.darwin-arm64.node +0 -0
  19. package/templates/basic/node_modules/@rolldown/pluginutils/LICENSE +21 -0
  20. package/templates/basic/node_modules/@rolldown/pluginutils/README.md +145 -0
  21. package/templates/basic/node_modules/@rolldown/pluginutils/dist/filter/index.d.mts +194 -0
  22. package/templates/basic/node_modules/@rolldown/pluginutils/dist/filter/index.mjs +2 -0
  23. package/templates/basic/node_modules/@rolldown/pluginutils/dist/filter-B_mD-HGz.mjs +323 -0
  24. package/templates/basic/node_modules/@rolldown/pluginutils/dist/index.d.mts +2 -0
  25. package/templates/basic/node_modules/@rolldown/pluginutils/dist/index.mjs +2 -0
  26. package/templates/basic/node_modules/@rolldown/pluginutils/package.json +40 -0
  27. package/templates/basic/node_modules/detect-libc/LICENSE +201 -0
  28. package/templates/basic/node_modules/detect-libc/README.md +163 -0
  29. package/templates/basic/node_modules/detect-libc/index.d.ts +14 -0
  30. package/templates/basic/node_modules/detect-libc/lib/detect-libc.js +313 -0
  31. package/templates/basic/node_modules/detect-libc/lib/elf.js +39 -0
  32. package/templates/basic/node_modules/detect-libc/lib/filesystem.js +51 -0
  33. package/templates/basic/node_modules/detect-libc/lib/process.js +24 -0
  34. package/templates/basic/node_modules/detect-libc/package.json +44 -0
  35. package/templates/basic/node_modules/fdir/LICENSE +7 -0
  36. package/templates/basic/node_modules/fdir/README.md +91 -0
  37. package/templates/basic/node_modules/fdir/dist/index.cjs +588 -0
  38. package/templates/basic/node_modules/fdir/dist/index.d.cts +155 -0
  39. package/templates/basic/node_modules/fdir/dist/index.d.mts +155 -0
  40. package/templates/basic/node_modules/fdir/dist/index.mjs +570 -0
  41. package/templates/basic/node_modules/fdir/package.json +103 -0
  42. package/templates/basic/node_modules/lightningcss/LICENSE +373 -0
  43. package/templates/basic/node_modules/lightningcss/README.md +105 -0
  44. package/templates/basic/node_modules/lightningcss/node/ast.d.ts +9892 -0
  45. package/templates/basic/node_modules/lightningcss/node/ast.js.flow +10539 -0
  46. package/templates/basic/node_modules/lightningcss/node/browserslistToTargets.js +48 -0
  47. package/templates/basic/node_modules/lightningcss/node/composeVisitors.js +450 -0
  48. package/templates/basic/node_modules/lightningcss/node/flags.js +28 -0
  49. package/templates/basic/node_modules/lightningcss/node/index.d.ts +494 -0
  50. package/templates/basic/node_modules/lightningcss/node/index.js +59 -0
  51. package/templates/basic/node_modules/lightningcss/node/index.js.flow +843 -0
  52. package/templates/basic/node_modules/lightningcss/node/index.mjs +4 -0
  53. package/templates/basic/node_modules/lightningcss/node/targets.d.ts +40 -0
  54. package/templates/basic/node_modules/lightningcss/node/targets.js.flow +39 -0
  55. package/templates/basic/node_modules/lightningcss/package.json +110 -0
  56. package/templates/basic/node_modules/lightningcss-darwin-arm64/LICENSE +373 -0
  57. package/templates/basic/node_modules/lightningcss-darwin-arm64/README.md +1 -0
  58. package/templates/basic/node_modules/lightningcss-darwin-arm64/lightningcss.darwin-arm64.node +0 -0
  59. package/templates/basic/node_modules/lightningcss-darwin-arm64/package.json +34 -0
  60. package/templates/basic/node_modules/nanoid/LICENSE +20 -0
  61. package/templates/basic/node_modules/nanoid/README.md +36 -0
  62. package/templates/basic/node_modules/nanoid/async/index.browser.cjs +42 -0
  63. package/templates/basic/node_modules/nanoid/async/index.browser.js +42 -0
  64. package/templates/basic/node_modules/nanoid/async/index.cjs +44 -0
  65. package/templates/basic/node_modules/nanoid/async/index.d.ts +56 -0
  66. package/templates/basic/node_modules/nanoid/async/index.js +44 -0
  67. package/templates/basic/node_modules/nanoid/async/index.native.js +35 -0
  68. package/templates/basic/node_modules/nanoid/async/package.json +12 -0
  69. package/templates/basic/node_modules/nanoid/bin/nanoid.cjs +55 -0
  70. package/templates/basic/node_modules/nanoid/index.browser.cjs +44 -0
  71. package/templates/basic/node_modules/nanoid/index.browser.js +44 -0
  72. package/templates/basic/node_modules/nanoid/index.cjs +57 -0
  73. package/templates/basic/node_modules/nanoid/index.d.cts +91 -0
  74. package/templates/basic/node_modules/nanoid/index.d.ts +91 -0
  75. package/templates/basic/node_modules/nanoid/index.js +62 -0
  76. package/templates/basic/node_modules/nanoid/nanoid.js +1 -0
  77. package/templates/basic/node_modules/nanoid/non-secure/index.cjs +24 -0
  78. package/templates/basic/node_modules/nanoid/non-secure/index.d.ts +33 -0
  79. package/templates/basic/node_modules/nanoid/non-secure/index.js +24 -0
  80. package/templates/basic/node_modules/nanoid/non-secure/package.json +6 -0
  81. package/templates/basic/node_modules/nanoid/package.json +89 -0
  82. package/templates/basic/node_modules/nanoid/url-alphabet/index.cjs +4 -0
  83. package/templates/basic/node_modules/nanoid/url-alphabet/index.js +4 -0
  84. package/templates/basic/node_modules/nanoid/url-alphabet/package.json +6 -0
  85. package/templates/basic/node_modules/nuclo/LICENSE.md +45 -0
  86. package/templates/basic/node_modules/nuclo/README.md +727 -0
  87. package/templates/basic/node_modules/nuclo/dist/bootstrap.d.ts +5 -0
  88. package/templates/basic/node_modules/nuclo/dist/bootstrap.d.ts.map +1 -0
  89. package/templates/basic/node_modules/nuclo/dist/element/attributes.d.ts +3 -0
  90. package/templates/basic/node_modules/nuclo/dist/element/attributes.d.ts.map +1 -0
  91. package/templates/basic/node_modules/nuclo/dist/element/class-name.d.ts +6 -0
  92. package/templates/basic/node_modules/nuclo/dist/element/class-name.d.ts.map +1 -0
  93. package/templates/basic/node_modules/nuclo/dist/element/events.d.ts +35 -0
  94. package/templates/basic/node_modules/nuclo/dist/element/events.d.ts.map +1 -0
  95. package/templates/basic/node_modules/nuclo/dist/element/factory.d.ts +32 -0
  96. package/templates/basic/node_modules/nuclo/dist/element/factory.d.ts.map +1 -0
  97. package/templates/basic/node_modules/nuclo/dist/element/inline-style.d.ts +9 -0
  98. package/templates/basic/node_modules/nuclo/dist/element/inline-style.d.ts.map +1 -0
  99. package/templates/basic/node_modules/nuclo/dist/element/modifiers.d.ts +11 -0
  100. package/templates/basic/node_modules/nuclo/dist/element/modifiers.d.ts.map +1 -0
  101. package/templates/basic/node_modules/nuclo/dist/element/tags.d.ts +5 -0
  102. package/templates/basic/node_modules/nuclo/dist/element/tags.d.ts.map +1 -0
  103. package/templates/basic/node_modules/nuclo/dist/hydration.d.ts +73 -0
  104. package/templates/basic/node_modules/nuclo/dist/hydration.d.ts.map +1 -0
  105. package/templates/basic/node_modules/nuclo/dist/index.d.ts +17 -0
  106. package/templates/basic/node_modules/nuclo/dist/index.d.ts.map +1 -0
  107. package/templates/basic/node_modules/nuclo/dist/list/index.d.ts +7 -0
  108. package/templates/basic/node_modules/nuclo/dist/list/index.d.ts.map +1 -0
  109. package/templates/basic/node_modules/nuclo/dist/list/runtime.d.ts +6 -0
  110. package/templates/basic/node_modules/nuclo/dist/list/runtime.d.ts.map +1 -0
  111. package/templates/basic/node_modules/nuclo/dist/list/types.d.ts +18 -0
  112. package/templates/basic/node_modules/nuclo/dist/list/types.d.ts.map +1 -0
  113. package/templates/basic/node_modules/nuclo/dist/nuclo.cjs +2 -0
  114. package/templates/basic/node_modules/nuclo/dist/nuclo.cjs.map +1 -0
  115. package/templates/basic/node_modules/nuclo/dist/nuclo.mjs +2 -0
  116. package/templates/basic/node_modules/nuclo/dist/nuclo.mjs.map +1 -0
  117. package/templates/basic/node_modules/nuclo/dist/nuclo.umd.js +2 -0
  118. package/templates/basic/node_modules/nuclo/dist/nuclo.umd.js.map +1 -0
  119. package/templates/basic/node_modules/nuclo/dist/polyfill/Document.d.ts +19 -0
  120. package/templates/basic/node_modules/nuclo/dist/polyfill/Document.d.ts.map +1 -0
  121. package/templates/basic/node_modules/nuclo/dist/polyfill/Element.d.ts +48 -0
  122. package/templates/basic/node_modules/nuclo/dist/polyfill/Element.d.ts.map +1 -0
  123. package/templates/basic/node_modules/nuclo/dist/polyfill/Event.d.ts +43 -0
  124. package/templates/basic/node_modules/nuclo/dist/polyfill/Event.d.ts.map +1 -0
  125. package/templates/basic/node_modules/nuclo/dist/polyfill/Node.d.ts +13 -0
  126. package/templates/basic/node_modules/nuclo/dist/polyfill/Node.d.ts.map +1 -0
  127. package/templates/basic/node_modules/nuclo/dist/polyfill/Text.d.ts +11 -0
  128. package/templates/basic/node_modules/nuclo/dist/polyfill/Text.d.ts.map +1 -0
  129. package/templates/basic/node_modules/nuclo/dist/polyfill/index.d.ts +24 -0
  130. package/templates/basic/node_modules/nuclo/dist/polyfill/index.d.ts.map +1 -0
  131. package/templates/basic/node_modules/nuclo/dist/polyfill/nuclo.polyfill.cjs +2 -0
  132. package/templates/basic/node_modules/nuclo/dist/polyfill/nuclo.polyfill.cjs.map +1 -0
  133. package/templates/basic/node_modules/nuclo/dist/polyfill/nuclo.polyfill.mjs +2 -0
  134. package/templates/basic/node_modules/nuclo/dist/polyfill/nuclo.polyfill.mjs.map +1 -0
  135. package/templates/basic/node_modules/nuclo/dist/render.d.ts +33 -0
  136. package/templates/basic/node_modules/nuclo/dist/render.d.ts.map +1 -0
  137. package/templates/basic/node_modules/nuclo/dist/shared/conditions.d.ts +4 -0
  138. package/templates/basic/node_modules/nuclo/dist/shared/conditions.d.ts.map +1 -0
  139. package/templates/basic/node_modules/nuclo/dist/shared/dom.d.ts +69 -0
  140. package/templates/basic/node_modules/nuclo/dist/shared/dom.d.ts.map +1 -0
  141. package/templates/basic/node_modules/nuclo/dist/shared/environment.d.ts +5 -0
  142. package/templates/basic/node_modules/nuclo/dist/shared/environment.d.ts.map +1 -0
  143. package/templates/basic/node_modules/nuclo/dist/shared/errors.d.ts +2 -0
  144. package/templates/basic/node_modules/nuclo/dist/shared/errors.d.ts.map +1 -0
  145. package/templates/basic/node_modules/nuclo/dist/shared/renderables.d.ts +4 -0
  146. package/templates/basic/node_modules/nuclo/dist/shared/renderables.d.ts.map +1 -0
  147. package/templates/basic/node_modules/nuclo/dist/shared/strings.d.ts +19 -0
  148. package/templates/basic/node_modules/nuclo/dist/shared/strings.d.ts.map +1 -0
  149. package/templates/basic/node_modules/nuclo/dist/shared/type-guards.d.ts +16 -0
  150. package/templates/basic/node_modules/nuclo/dist/shared/type-guards.d.ts.map +1 -0
  151. package/templates/basic/node_modules/nuclo/dist/ssr/index.d.ts +19 -0
  152. package/templates/basic/node_modules/nuclo/dist/ssr/index.d.ts.map +1 -0
  153. package/templates/basic/node_modules/nuclo/dist/ssr/nuclo.ssr.cjs +2 -0
  154. package/templates/basic/node_modules/nuclo/dist/ssr/nuclo.ssr.cjs.map +1 -0
  155. package/templates/basic/node_modules/nuclo/dist/ssr/nuclo.ssr.mjs +2 -0
  156. package/templates/basic/node_modules/nuclo/dist/ssr/nuclo.ssr.mjs.map +1 -0
  157. package/templates/basic/node_modules/nuclo/dist/ssr/render-to-string.d.ts +41 -0
  158. package/templates/basic/node_modules/nuclo/dist/ssr/render-to-string.d.ts.map +1 -0
  159. package/templates/basic/node_modules/nuclo/dist/style/css.d.ts +19 -0
  160. package/templates/basic/node_modules/nuclo/dist/style/css.d.ts.map +1 -0
  161. package/templates/basic/node_modules/nuclo/dist/style/engine.d.ts +34 -0
  162. package/templates/basic/node_modules/nuclo/dist/style/engine.d.ts.map +1 -0
  163. package/templates/basic/node_modules/nuclo/dist/style/index.d.ts +3 -0
  164. package/templates/basic/node_modules/nuclo/dist/style/index.d.ts.map +1 -0
  165. package/templates/basic/node_modules/nuclo/dist/update/conditional.d.ts +3 -0
  166. package/templates/basic/node_modules/nuclo/dist/update/conditional.d.ts.map +1 -0
  167. package/templates/basic/node_modules/nuclo/dist/update/reactive-attributes.d.ts +45 -0
  168. package/templates/basic/node_modules/nuclo/dist/update/reactive-attributes.d.ts.map +1 -0
  169. package/templates/basic/node_modules/nuclo/dist/update/reactive-text.d.ts +38 -0
  170. package/templates/basic/node_modules/nuclo/dist/update/reactive-text.d.ts.map +1 -0
  171. package/templates/basic/node_modules/nuclo/dist/update/registry.d.ts +97 -0
  172. package/templates/basic/node_modules/nuclo/dist/update/registry.d.ts.map +1 -0
  173. package/templates/basic/node_modules/nuclo/dist/update/scope.d.ts +7 -0
  174. package/templates/basic/node_modules/nuclo/dist/update/scope.d.ts.map +1 -0
  175. package/templates/basic/node_modules/nuclo/dist/update/update.d.ts +4 -0
  176. package/templates/basic/node_modules/nuclo/dist/update/update.d.ts.map +1 -0
  177. package/templates/basic/node_modules/nuclo/dist/when/builder.d.ts +16 -0
  178. package/templates/basic/node_modules/nuclo/dist/when/builder.d.ts.map +1 -0
  179. package/templates/basic/node_modules/nuclo/dist/when/index.d.ts +44 -0
  180. package/templates/basic/node_modules/nuclo/dist/when/index.d.ts.map +1 -0
  181. package/templates/basic/node_modules/nuclo/dist/when/runtime.d.ts +59 -0
  182. package/templates/basic/node_modules/nuclo/dist/when/runtime.d.ts.map +1 -0
  183. package/templates/basic/node_modules/nuclo/package.json +88 -0
  184. package/templates/basic/node_modules/nuclo/types/core/base.d.ts +113 -0
  185. package/templates/basic/node_modules/nuclo/types/features/list.d.ts +38 -0
  186. package/templates/basic/node_modules/nuclo/types/features/on.d.ts +59 -0
  187. package/templates/basic/node_modules/nuclo/types/features/render.d.ts +49 -0
  188. package/templates/basic/node_modules/nuclo/types/features/scope.d.ts +6 -0
  189. package/templates/basic/node_modules/nuclo/types/features/style.d.ts +77 -0
  190. package/templates/basic/node_modules/nuclo/types/features/update.d.ts +6 -0
  191. package/templates/basic/node_modules/nuclo/types/features/when.d.ts +18 -0
  192. package/templates/basic/node_modules/nuclo/types/html/tags.d.ts +119 -0
  193. package/templates/basic/node_modules/nuclo/types/index.d.ts +137 -0
  194. package/templates/basic/node_modules/nuclo/types/polyfill.d.ts +131 -0
  195. package/templates/basic/node_modules/nuclo/types/ssr.d.ts +45 -0
  196. package/templates/basic/node_modules/nuclo/types/style.d.ts +404 -0
  197. package/templates/basic/node_modules/nuclo/types/svg/base.d.ts +118 -0
  198. package/templates/basic/node_modules/nuclo/types/svg/tags.d.ts +68 -0
  199. package/templates/basic/node_modules/picocolors/LICENSE +15 -0
  200. package/templates/basic/node_modules/picocolors/README.md +21 -0
  201. package/templates/basic/node_modules/picocolors/package.json +25 -0
  202. package/templates/basic/node_modules/picocolors/picocolors.browser.js +4 -0
  203. package/templates/basic/node_modules/picocolors/picocolors.d.ts +5 -0
  204. package/templates/basic/node_modules/picocolors/picocolors.js +75 -0
  205. package/templates/basic/node_modules/picocolors/types.d.ts +51 -0
  206. package/templates/basic/node_modules/picomatch/LICENSE +21 -0
  207. package/templates/basic/node_modules/picomatch/README.md +743 -0
  208. package/templates/basic/node_modules/picomatch/index.js +17 -0
  209. package/templates/basic/node_modules/picomatch/lib/constants.js +184 -0
  210. package/templates/basic/node_modules/picomatch/lib/parse.js +1416 -0
  211. package/templates/basic/node_modules/picomatch/lib/picomatch.js +361 -0
  212. package/templates/basic/node_modules/picomatch/lib/scan.js +391 -0
  213. package/templates/basic/node_modules/picomatch/lib/utils.js +72 -0
  214. package/templates/basic/node_modules/picomatch/package.json +83 -0
  215. package/templates/basic/node_modules/picomatch/posix.js +3 -0
  216. package/templates/basic/node_modules/postcss/LICENSE +20 -0
  217. package/templates/basic/node_modules/postcss/README.md +25 -0
  218. package/templates/basic/node_modules/postcss/lib/at-rule.d.ts +139 -0
  219. package/templates/basic/node_modules/postcss/lib/at-rule.js +25 -0
  220. package/templates/basic/node_modules/postcss/lib/comment.d.ts +67 -0
  221. package/templates/basic/node_modules/postcss/lib/comment.js +13 -0
  222. package/templates/basic/node_modules/postcss/lib/container.d.ts +478 -0
  223. package/templates/basic/node_modules/postcss/lib/container.js +447 -0
  224. package/templates/basic/node_modules/postcss/lib/css-syntax-error.d.ts +247 -0
  225. package/templates/basic/node_modules/postcss/lib/css-syntax-error.js +133 -0
  226. package/templates/basic/node_modules/postcss/lib/declaration.d.ts +150 -0
  227. package/templates/basic/node_modules/postcss/lib/declaration.js +24 -0
  228. package/templates/basic/node_modules/postcss/lib/document.d.ts +68 -0
  229. package/templates/basic/node_modules/postcss/lib/document.js +33 -0
  230. package/templates/basic/node_modules/postcss/lib/fromJSON.d.ts +9 -0
  231. package/templates/basic/node_modules/postcss/lib/fromJSON.js +68 -0
  232. package/templates/basic/node_modules/postcss/lib/input.d.ts +226 -0
  233. package/templates/basic/node_modules/postcss/lib/input.js +276 -0
  234. package/templates/basic/node_modules/postcss/lib/lazy-result.d.ts +189 -0
  235. package/templates/basic/node_modules/postcss/lib/lazy-result.js +563 -0
  236. package/templates/basic/node_modules/postcss/lib/list.d.ts +60 -0
  237. package/templates/basic/node_modules/postcss/lib/list.js +58 -0
  238. package/templates/basic/node_modules/postcss/lib/map-generator.js +376 -0
  239. package/templates/basic/node_modules/postcss/lib/no-work-result.d.ts +45 -0
  240. package/templates/basic/node_modules/postcss/lib/no-work-result.js +137 -0
  241. package/templates/basic/node_modules/postcss/lib/node.d.ts +555 -0
  242. package/templates/basic/node_modules/postcss/lib/node.js +456 -0
  243. package/templates/basic/node_modules/postcss/lib/parse.d.ts +9 -0
  244. package/templates/basic/node_modules/postcss/lib/parse.js +42 -0
  245. package/templates/basic/node_modules/postcss/lib/parser.js +618 -0
  246. package/templates/basic/node_modules/postcss/lib/postcss.d.mts +66 -0
  247. package/templates/basic/node_modules/postcss/lib/postcss.d.ts +461 -0
  248. package/templates/basic/node_modules/postcss/lib/postcss.js +101 -0
  249. package/templates/basic/node_modules/postcss/lib/postcss.mjs +30 -0
  250. package/templates/basic/node_modules/postcss/lib/previous-map.d.ts +80 -0
  251. package/templates/basic/node_modules/postcss/lib/previous-map.js +161 -0
  252. package/templates/basic/node_modules/postcss/lib/processor.d.ts +114 -0
  253. package/templates/basic/node_modules/postcss/lib/processor.js +67 -0
  254. package/templates/basic/node_modules/postcss/lib/result.d.ts +204 -0
  255. package/templates/basic/node_modules/postcss/lib/result.js +42 -0
  256. package/templates/basic/node_modules/postcss/lib/root.d.ts +86 -0
  257. package/templates/basic/node_modules/postcss/lib/root.js +61 -0
  258. package/templates/basic/node_modules/postcss/lib/rule.d.ts +126 -0
  259. package/templates/basic/node_modules/postcss/lib/rule.js +27 -0
  260. package/templates/basic/node_modules/postcss/lib/stringifier.d.ts +45 -0
  261. package/templates/basic/node_modules/postcss/lib/stringifier.js +374 -0
  262. package/templates/basic/node_modules/postcss/lib/stringify.d.ts +9 -0
  263. package/templates/basic/node_modules/postcss/lib/stringify.js +11 -0
  264. package/templates/basic/node_modules/postcss/lib/symbols.js +5 -0
  265. package/templates/basic/node_modules/postcss/lib/terminal-highlight.js +70 -0
  266. package/templates/basic/node_modules/postcss/lib/tokenize.js +270 -0
  267. package/templates/basic/node_modules/postcss/lib/warn-once.js +13 -0
  268. package/templates/basic/node_modules/postcss/lib/warning.d.ts +146 -0
  269. package/templates/basic/node_modules/postcss/lib/warning.js +37 -0
  270. package/templates/basic/node_modules/postcss/package.json +88 -0
  271. package/templates/basic/node_modules/rolldown/LICENSE +25 -0
  272. package/templates/basic/node_modules/rolldown/README.md +11 -0
  273. package/templates/basic/node_modules/rolldown/bin/cli.mjs +2 -0
  274. package/templates/basic/node_modules/rolldown/dist/cli.d.mts +1 -0
  275. package/templates/basic/node_modules/rolldown/dist/cli.mjs +1202 -0
  276. package/templates/basic/node_modules/rolldown/dist/config.d.mts +14 -0
  277. package/templates/basic/node_modules/rolldown/dist/config.mjs +4 -0
  278. package/templates/basic/node_modules/rolldown/dist/experimental-index.d.mts +280 -0
  279. package/templates/basic/node_modules/rolldown/dist/experimental-index.mjs +331 -0
  280. package/templates/basic/node_modules/rolldown/dist/experimental-runtime-types.d.ts +107 -0
  281. package/templates/basic/node_modules/rolldown/dist/filter-index.d.mts +195 -0
  282. package/templates/basic/node_modules/rolldown/dist/filter-index.mjs +380 -0
  283. package/templates/basic/node_modules/rolldown/dist/get-log-filter.d.mts +3 -0
  284. package/templates/basic/node_modules/rolldown/dist/get-log-filter.mjs +68 -0
  285. package/templates/basic/node_modules/rolldown/dist/index.d.mts +4 -0
  286. package/templates/basic/node_modules/rolldown/dist/index.mjs +50 -0
  287. package/templates/basic/node_modules/rolldown/dist/parallel-plugin-worker.d.mts +1 -0
  288. package/templates/basic/node_modules/rolldown/dist/parallel-plugin-worker.mjs +29 -0
  289. package/templates/basic/node_modules/rolldown/dist/parallel-plugin.d.mts +13 -0
  290. package/templates/basic/node_modules/rolldown/dist/parallel-plugin.mjs +6 -0
  291. package/templates/basic/node_modules/rolldown/dist/parse-ast-index.d.mts +32 -0
  292. package/templates/basic/node_modules/rolldown/dist/parse-ast-index.mjs +60 -0
  293. package/templates/basic/node_modules/rolldown/dist/plugins-index.d.mts +33 -0
  294. package/templates/basic/node_modules/rolldown/dist/plugins-index.mjs +40 -0
  295. package/templates/basic/node_modules/rolldown/dist/shared/binding-B1q9aYT-.d.mts +1947 -0
  296. package/templates/basic/node_modules/rolldown/dist/shared/binding-BmkJW3Wy.mjs +588 -0
  297. package/templates/basic/node_modules/rolldown/dist/shared/bindingify-input-options-BsDhfYrS.mjs +2240 -0
  298. package/templates/basic/node_modules/rolldown/dist/shared/constructors-2i1T9YcF.d.mts +36 -0
  299. package/templates/basic/node_modules/rolldown/dist/shared/constructors-CE6zZSUt.mjs +65 -0
  300. package/templates/basic/node_modules/rolldown/dist/shared/define-config-BBz954-q.d.mts +3901 -0
  301. package/templates/basic/node_modules/rolldown/dist/shared/define-config-Demdg3_4.mjs +6 -0
  302. package/templates/basic/node_modules/rolldown/dist/shared/error-BlQ0-ek7.mjs +85 -0
  303. package/templates/basic/node_modules/rolldown/dist/shared/get-log-filter-BpNVNJ5-.d.mts +35 -0
  304. package/templates/basic/node_modules/rolldown/dist/shared/load-config-FRmAU9xl.mjs +120 -0
  305. package/templates/basic/node_modules/rolldown/dist/shared/logging-BSNejiLS.d.mts +50 -0
  306. package/templates/basic/node_modules/rolldown/dist/shared/logs-aMKUxRpj.mjs +180 -0
  307. package/templates/basic/node_modules/rolldown/dist/shared/misc-CoQm4NHO.mjs +21 -0
  308. package/templates/basic/node_modules/rolldown/dist/shared/normalize-string-or-regex-BYkbbGqQ.mjs +68 -0
  309. package/templates/basic/node_modules/rolldown/dist/shared/parse-DVMnkavl.mjs +74 -0
  310. package/templates/basic/node_modules/rolldown/dist/shared/prompt-B1Yc1NPt.mjs +847 -0
  311. package/templates/basic/node_modules/rolldown/dist/shared/resolve-tsconfig-CdIAR1Eb.mjs +124 -0
  312. package/templates/basic/node_modules/rolldown/dist/shared/rolldown-build-aV0QeeTW.mjs +3264 -0
  313. package/templates/basic/node_modules/rolldown/dist/shared/rolldown-tbHvKzVl.mjs +40 -0
  314. package/templates/basic/node_modules/rolldown/dist/shared/transform-CEmFsvJW.d.mts +149 -0
  315. package/templates/basic/node_modules/rolldown/dist/shared/watch-DIhJ-T1s.mjs +374 -0
  316. package/templates/basic/node_modules/rolldown/dist/utils-index.d.mts +376 -0
  317. package/templates/basic/node_modules/rolldown/dist/utils-index.mjs +2414 -0
  318. package/templates/basic/node_modules/rolldown/package.json +153 -0
  319. package/templates/basic/node_modules/source-map-js/LICENSE +28 -0
  320. package/templates/basic/node_modules/source-map-js/README.md +765 -0
  321. package/templates/basic/node_modules/source-map-js/lib/array-set.js +121 -0
  322. package/templates/basic/node_modules/source-map-js/lib/base64-vlq.js +140 -0
  323. package/templates/basic/node_modules/source-map-js/lib/base64.js +67 -0
  324. package/templates/basic/node_modules/source-map-js/lib/binary-search.js +111 -0
  325. package/templates/basic/node_modules/source-map-js/lib/mapping-list.js +79 -0
  326. package/templates/basic/node_modules/source-map-js/lib/quick-sort.js +132 -0
  327. package/templates/basic/node_modules/source-map-js/lib/source-map-consumer.d.ts +1 -0
  328. package/templates/basic/node_modules/source-map-js/lib/source-map-consumer.js +1188 -0
  329. package/templates/basic/node_modules/source-map-js/lib/source-map-generator.d.ts +1 -0
  330. package/templates/basic/node_modules/source-map-js/lib/source-map-generator.js +444 -0
  331. package/templates/basic/node_modules/source-map-js/lib/source-node.d.ts +1 -0
  332. package/templates/basic/node_modules/source-map-js/lib/source-node.js +413 -0
  333. package/templates/basic/node_modules/source-map-js/lib/util.js +594 -0
  334. package/templates/basic/node_modules/source-map-js/package.json +71 -0
  335. package/templates/basic/node_modules/source-map-js/source-map.d.ts +104 -0
  336. package/templates/basic/node_modules/source-map-js/source-map.js +8 -0
  337. package/templates/basic/node_modules/tinyglobby/LICENSE +21 -0
  338. package/templates/basic/node_modules/tinyglobby/README.md +25 -0
  339. package/templates/basic/node_modules/tinyglobby/dist/index.cjs +335 -0
  340. package/templates/basic/node_modules/tinyglobby/dist/index.d.cts +148 -0
  341. package/templates/basic/node_modules/tinyglobby/dist/index.d.mts +148 -0
  342. package/templates/basic/node_modules/tinyglobby/dist/index.mjs +307 -0
  343. package/templates/basic/node_modules/tinyglobby/package.json +70 -0
  344. package/templates/basic/node_modules/typescript/LICENSE.txt +55 -0
  345. package/templates/basic/node_modules/typescript/README.md +50 -0
  346. package/templates/basic/node_modules/typescript/SECURITY.md +39 -0
  347. package/templates/basic/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  348. package/templates/basic/node_modules/typescript/bin/tsc +2 -0
  349. package/templates/basic/node_modules/typescript/bin/tsserver +2 -0
  350. package/templates/basic/node_modules/typescript/lib/_tsc.js +134465 -0
  351. package/templates/basic/node_modules/typescript/lib/_tsserver.js +659 -0
  352. package/templates/basic/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  353. package/templates/basic/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2129 -0
  354. package/templates/basic/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2125 -0
  355. package/templates/basic/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2129 -0
  356. package/templates/basic/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2129 -0
  357. package/templates/basic/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2125 -0
  358. package/templates/basic/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2129 -0
  359. package/templates/basic/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2129 -0
  360. package/templates/basic/node_modules/typescript/lib/lib.d.ts +20 -0
  361. package/templates/basic/node_modules/typescript/lib/lib.decorators.d.ts +382 -0
  362. package/templates/basic/node_modules/typescript/lib/lib.decorators.legacy.d.ts +20 -0
  363. package/templates/basic/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +18 -0
  364. package/templates/basic/node_modules/typescript/lib/lib.dom.d.ts +45125 -0
  365. package/templates/basic/node_modules/typescript/lib/lib.dom.iterable.d.ts +18 -0
  366. package/templates/basic/node_modules/typescript/lib/lib.es2015.collection.d.ts +150 -0
  367. package/templates/basic/node_modules/typescript/lib/lib.es2015.core.d.ts +595 -0
  368. package/templates/basic/node_modules/typescript/lib/lib.es2015.d.ts +26 -0
  369. package/templates/basic/node_modules/typescript/lib/lib.es2015.generator.d.ts +75 -0
  370. package/templates/basic/node_modules/typescript/lib/lib.es2015.iterable.d.ts +603 -0
  371. package/templates/basic/node_modules/typescript/lib/lib.es2015.promise.d.ts +79 -0
  372. package/templates/basic/node_modules/typescript/lib/lib.es2015.proxy.d.ts +126 -0
  373. package/templates/basic/node_modules/typescript/lib/lib.es2015.reflect.d.ts +142 -0
  374. package/templates/basic/node_modules/typescript/lib/lib.es2015.symbol.d.ts +44 -0
  375. package/templates/basic/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +324 -0
  376. package/templates/basic/node_modules/typescript/lib/lib.es2016.array.include.d.ts +114 -0
  377. package/templates/basic/node_modules/typescript/lib/lib.es2016.d.ts +19 -0
  378. package/templates/basic/node_modules/typescript/lib/lib.es2016.full.d.ts +21 -0
  379. package/templates/basic/node_modules/typescript/lib/lib.es2016.intl.d.ts +29 -0
  380. package/templates/basic/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +19 -0
  381. package/templates/basic/node_modules/typescript/lib/lib.es2017.d.ts +24 -0
  382. package/templates/basic/node_modules/typescript/lib/lib.es2017.date.d.ts +29 -0
  383. package/templates/basic/node_modules/typescript/lib/lib.es2017.full.d.ts +21 -0
  384. package/templates/basic/node_modules/typescript/lib/lib.es2017.intl.d.ts +42 -0
  385. package/templates/basic/node_modules/typescript/lib/lib.es2017.object.d.ts +47 -0
  386. package/templates/basic/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +133 -0
  387. package/templates/basic/node_modules/typescript/lib/lib.es2017.string.d.ts +43 -0
  388. package/templates/basic/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +51 -0
  389. package/templates/basic/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +75 -0
  390. package/templates/basic/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +51 -0
  391. package/templates/basic/node_modules/typescript/lib/lib.es2018.d.ts +22 -0
  392. package/templates/basic/node_modules/typescript/lib/lib.es2018.full.d.ts +22 -0
  393. package/templates/basic/node_modules/typescript/lib/lib.es2018.intl.d.ts +81 -0
  394. package/templates/basic/node_modules/typescript/lib/lib.es2018.promise.d.ts +28 -0
  395. package/templates/basic/node_modules/typescript/lib/lib.es2018.regexp.d.ts +35 -0
  396. package/templates/basic/node_modules/typescript/lib/lib.es2019.array.d.ts +77 -0
  397. package/templates/basic/node_modules/typescript/lib/lib.es2019.d.ts +22 -0
  398. package/templates/basic/node_modules/typescript/lib/lib.es2019.full.d.ts +22 -0
  399. package/templates/basic/node_modules/typescript/lib/lib.es2019.intl.d.ts +21 -0
  400. package/templates/basic/node_modules/typescript/lib/lib.es2019.object.d.ts +31 -0
  401. package/templates/basic/node_modules/typescript/lib/lib.es2019.string.d.ts +35 -0
  402. package/templates/basic/node_modules/typescript/lib/lib.es2019.symbol.d.ts +22 -0
  403. package/templates/basic/node_modules/typescript/lib/lib.es2020.bigint.d.ts +763 -0
  404. package/templates/basic/node_modules/typescript/lib/lib.es2020.d.ts +25 -0
  405. package/templates/basic/node_modules/typescript/lib/lib.es2020.date.d.ts +40 -0
  406. package/templates/basic/node_modules/typescript/lib/lib.es2020.full.d.ts +22 -0
  407. package/templates/basic/node_modules/typescript/lib/lib.es2020.intl.d.ts +472 -0
  408. package/templates/basic/node_modules/typescript/lib/lib.es2020.number.d.ts +26 -0
  409. package/templates/basic/node_modules/typescript/lib/lib.es2020.promise.d.ts +45 -0
  410. package/templates/basic/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +97 -0
  411. package/templates/basic/node_modules/typescript/lib/lib.es2020.string.d.ts +42 -0
  412. package/templates/basic/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +39 -0
  413. package/templates/basic/node_modules/typescript/lib/lib.es2021.d.ts +21 -0
  414. package/templates/basic/node_modules/typescript/lib/lib.es2021.full.d.ts +22 -0
  415. package/templates/basic/node_modules/typescript/lib/lib.es2021.intl.d.ts +164 -0
  416. package/templates/basic/node_modules/typescript/lib/lib.es2021.promise.d.ts +46 -0
  417. package/templates/basic/node_modules/typescript/lib/lib.es2021.string.d.ts +31 -0
  418. package/templates/basic/node_modules/typescript/lib/lib.es2021.weakref.d.ts +76 -0
  419. package/templates/basic/node_modules/typescript/lib/lib.es2022.array.d.ts +119 -0
  420. package/templates/basic/node_modules/typescript/lib/lib.es2022.d.ts +23 -0
  421. package/templates/basic/node_modules/typescript/lib/lib.es2022.error.d.ts +73 -0
  422. package/templates/basic/node_modules/typescript/lib/lib.es2022.full.d.ts +22 -0
  423. package/templates/basic/node_modules/typescript/lib/lib.es2022.intl.d.ts +143 -0
  424. package/templates/basic/node_modules/typescript/lib/lib.es2022.object.d.ts +24 -0
  425. package/templates/basic/node_modules/typescript/lib/lib.es2022.regexp.d.ts +37 -0
  426. package/templates/basic/node_modules/typescript/lib/lib.es2022.string.d.ts +23 -0
  427. package/templates/basic/node_modules/typescript/lib/lib.es2023.array.d.ts +922 -0
  428. package/templates/basic/node_modules/typescript/lib/lib.es2023.collection.d.ts +19 -0
  429. package/templates/basic/node_modules/typescript/lib/lib.es2023.d.ts +20 -0
  430. package/templates/basic/node_modules/typescript/lib/lib.es2023.full.d.ts +22 -0
  431. package/templates/basic/node_modules/typescript/lib/lib.es2023.intl.d.ts +62 -0
  432. package/templates/basic/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +63 -0
  433. package/templates/basic/node_modules/typescript/lib/lib.es2024.collection.d.ts +27 -0
  434. package/templates/basic/node_modules/typescript/lib/lib.es2024.d.ts +24 -0
  435. package/templates/basic/node_modules/typescript/lib/lib.es2024.full.d.ts +22 -0
  436. package/templates/basic/node_modules/typescript/lib/lib.es2024.object.d.ts +27 -0
  437. package/templates/basic/node_modules/typescript/lib/lib.es2024.promise.d.ts +33 -0
  438. package/templates/basic/node_modules/typescript/lib/lib.es2024.regexp.d.ts +23 -0
  439. package/templates/basic/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +66 -0
  440. package/templates/basic/node_modules/typescript/lib/lib.es2024.string.d.ts +27 -0
  441. package/templates/basic/node_modules/typescript/lib/lib.es2025.collection.d.ts +94 -0
  442. package/templates/basic/node_modules/typescript/lib/lib.es2025.d.ts +23 -0
  443. package/templates/basic/node_modules/typescript/lib/lib.es2025.float16.d.ts +443 -0
  444. package/templates/basic/node_modules/typescript/lib/lib.es2025.full.d.ts +22 -0
  445. package/templates/basic/node_modules/typescript/lib/lib.es2025.intl.d.ts +200 -0
  446. package/templates/basic/node_modules/typescript/lib/lib.es2025.iterator.d.ts +146 -0
  447. package/templates/basic/node_modules/typescript/lib/lib.es2025.promise.d.ts +32 -0
  448. package/templates/basic/node_modules/typescript/lib/lib.es2025.regexp.d.ts +30 -0
  449. package/templates/basic/node_modules/typescript/lib/lib.es5.d.ts +4599 -0
  450. package/templates/basic/node_modules/typescript/lib/lib.es6.d.ts +21 -0
  451. package/templates/basic/node_modules/typescript/lib/lib.esnext.array.d.ts +33 -0
  452. package/templates/basic/node_modules/typescript/lib/lib.esnext.collection.d.ts +47 -0
  453. package/templates/basic/node_modules/typescript/lib/lib.esnext.d.ts +27 -0
  454. package/templates/basic/node_modules/typescript/lib/lib.esnext.date.d.ts +21 -0
  455. package/templates/basic/node_modules/typescript/lib/lib.esnext.decorators.d.ts +26 -0
  456. package/templates/basic/node_modules/typescript/lib/lib.esnext.disposable.d.ts +191 -0
  457. package/templates/basic/node_modules/typescript/lib/lib.esnext.error.d.ts +22 -0
  458. package/templates/basic/node_modules/typescript/lib/lib.esnext.full.d.ts +22 -0
  459. package/templates/basic/node_modules/typescript/lib/lib.esnext.intl.d.ts +107 -0
  460. package/templates/basic/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +23 -0
  461. package/templates/basic/node_modules/typescript/lib/lib.esnext.temporal.d.ts +485 -0
  462. package/templates/basic/node_modules/typescript/lib/lib.esnext.typedarrays.d.ts +90 -0
  463. package/templates/basic/node_modules/typescript/lib/lib.scripthost.d.ts +320 -0
  464. package/templates/basic/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +18 -0
  465. package/templates/basic/node_modules/typescript/lib/lib.webworker.d.ts +15606 -0
  466. package/templates/basic/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +21 -0
  467. package/templates/basic/node_modules/typescript/lib/lib.webworker.iterable.d.ts +18 -0
  468. package/templates/basic/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2129 -0
  469. package/templates/basic/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2129 -0
  470. package/templates/basic/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2125 -0
  471. package/templates/basic/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2129 -0
  472. package/templates/basic/node_modules/typescript/lib/tsc.js +8 -0
  473. package/templates/basic/node_modules/typescript/lib/tsserver.js +8 -0
  474. package/templates/basic/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  475. package/templates/basic/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  476. package/templates/basic/node_modules/typescript/lib/typesMap.json +497 -0
  477. package/templates/basic/node_modules/typescript/lib/typescript.d.ts +11448 -0
  478. package/templates/basic/node_modules/typescript/lib/typescript.js +201039 -0
  479. package/templates/basic/node_modules/typescript/lib/typingsInstaller.js +8 -0
  480. package/templates/basic/node_modules/typescript/lib/watchGuard.js +53 -0
  481. package/templates/basic/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2129 -0
  482. package/templates/basic/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2125 -0
  483. package/templates/basic/node_modules/typescript/package.json +118 -0
  484. package/templates/basic/node_modules/vite/LICENSE.md +2287 -0
  485. package/templates/basic/node_modules/vite/README.md +20 -0
  486. package/templates/basic/node_modules/vite/bin/openChrome.js +68 -0
  487. package/templates/basic/node_modules/vite/bin/vite.js +79 -0
  488. package/templates/basic/node_modules/vite/client.d.ts +285 -0
  489. package/templates/basic/node_modules/vite/dist/client/client.mjs +1269 -0
  490. package/templates/basic/node_modules/vite/dist/client/env.mjs +18 -0
  491. package/templates/basic/node_modules/vite/dist/node/chunks/build.js +5371 -0
  492. package/templates/basic/node_modules/vite/dist/node/chunks/dist.js +6784 -0
  493. package/templates/basic/node_modules/vite/dist/node/chunks/lib.js +371 -0
  494. package/templates/basic/node_modules/vite/dist/node/chunks/logger.js +364 -0
  495. package/templates/basic/node_modules/vite/dist/node/chunks/moduleRunnerTransport.d.ts +96 -0
  496. package/templates/basic/node_modules/vite/dist/node/chunks/node.js +35836 -0
  497. package/templates/basic/node_modules/vite/dist/node/chunks/postcss-import.js +467 -0
  498. package/templates/basic/node_modules/vite/dist/node/cli.js +836 -0
  499. package/templates/basic/node_modules/vite/dist/node/index.d.ts +4011 -0
  500. package/templates/basic/node_modules/vite/dist/node/index.js +3 -0
  501. package/templates/basic/node_modules/vite/dist/node/internal.d.ts +2 -0
  502. package/templates/basic/node_modules/vite/dist/node/internal.js +2 -0
  503. package/templates/basic/node_modules/vite/dist/node/module-runner.d.ts +314 -0
  504. package/templates/basic/node_modules/vite/dist/node/module-runner.js +1274 -0
  505. package/templates/basic/node_modules/vite/misc/false.js +1 -0
  506. package/templates/basic/node_modules/vite/misc/true.js +1 -0
  507. package/templates/basic/node_modules/vite/package.json +194 -0
  508. package/templates/basic/node_modules/vite/types/customEvent.d.ts +79 -0
  509. package/templates/basic/node_modules/vite/types/hmrPayload.d.ts +80 -0
  510. package/templates/basic/node_modules/vite/types/hot.d.ts +39 -0
  511. package/templates/basic/node_modules/vite/types/import-meta.d.ts +5 -0
  512. package/templates/basic/node_modules/vite/types/importGlob.d.ts +131 -0
  513. package/templates/basic/node_modules/vite/types/importMeta.d.ts +30 -0
  514. package/templates/basic/node_modules/vite/types/internal/cssPreprocessorOptions.d.ts +44 -0
  515. package/templates/basic/node_modules/vite/types/internal/esbuildOptions.d.ts +28 -0
  516. package/templates/basic/node_modules/vite/types/internal/lightningcssOptions.d.ts +18 -0
  517. package/templates/basic/node_modules/vite/types/internal/rollupTypeCompat.d.ts +24 -0
  518. package/templates/basic/node_modules/vite/types/internal/terserOptions.d.ts +11 -0
  519. package/templates/basic/node_modules/vite/types/metadata.d.ts +47 -0
  520. package/templates/basic/package-lock.json +926 -0
  521. package/templates/basic/package.json +18 -0
  522. package/templates/basic/public/apple-touch-icon.png +0 -0
  523. package/templates/basic/public/favicon-16x16.png +0 -0
  524. package/templates/basic/public/favicon-32x32.png +0 -0
  525. package/templates/basic/public/favicon.ico +0 -0
  526. package/templates/basic/public/icon-192.png +0 -0
  527. package/templates/basic/public/icon-512.png +0 -0
  528. package/templates/basic/public/nuclo-logo.svg +24 -0
  529. package/templates/basic/public/site.webmanifest +23 -0
  530. package/templates/basic/src/app.ts +37 -0
  531. package/templates/basic/src/main.ts +5 -0
  532. package/templates/basic/src/styles.ts +85 -0
  533. package/templates/basic/tsconfig.json +23 -0
  534. package/templates/basic/vite.config.ts +3 -0
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){let t=0;for(;t<e.length;t++){let n=e.charCodeAt(t);if(n>=65&&n<=90)break}if(t===e.length)return e;let n=e.slice(0,t);for(let r=t;r<e.length;r++){let t=e.charCodeAt(r);t>=65&&t<=90?(r>0&&(n+=`-`),n+=String.fromCharCode(t+32)):n+=e[r]}return n}const t=/[&<>"']/,n=/[&<>]/;function r(e){let n=t.exec(e);if(!n)return e;let r=``,i=0;for(let t=n.index;t<e.length;t++){let n;switch(e.charCodeAt(t)){case 38:n=`&amp;`;break;case 60:n=`&lt;`;break;case 62:n=`&gt;`;break;case 34:n=`&quot;`;break;case 39:n=`&#039;`;break;default:continue}r+=e.slice(i,t)+n,i=t+1}return r+e.slice(i)}function i(e){let t=n.exec(e);if(!t)return e;let r=``,i=0;for(let n=t.index;n<e.length;n++){let t;switch(e.charCodeAt(n)){case 38:t=`&amp;`;break;case 60:t=`&lt;`;break;case 62:t=`&gt;`;break;default:continue}r+=e.slice(i,n)+t,i=n+1}return r+e.slice(i)}const a=new Set,o=new Set;typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{a.delete(e)}),typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{o.delete(e)});const s=new Set;typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{s.delete(e)});function c(e){return globalThis.document?document.createElement(e):null}let l=!1;function u(e){let t=l;l=!0;try{return e()}finally{l=t}}const d=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(`.`)),f=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 p(t,n){if(n==null||n===!1)return``;if(n===!0)return` ${t}`;if(f.has(t)){if(n===`false`)return``;if(n===`true`||n===``||n===t)return` ${t}`}if(t===`style`&&typeof n==`object`){let t=``;for(let r in n){let i=n[r];i==null||i===``||(t+=(t?` `:``)+e(r)+`: `+String(i)+`;`)}return t?` style="${r(t)}"`:``}return` ${t}="${r(String(n))}"`}function m(t){let n=``;if(Array.isArray(t.children)){let i=t,a=i._attributes;i.id&&!a?.has(`id`)&&(n+=p(`id`,i.id)),i.className&&!a?.has(`class`)&&(n+=p(`class`,i.className));let o=i._style;if(!a?.has(`style`)&&o){let t=o.cssText||``;if(t){let i=t.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&&(n+=` style="${r(i)}"`)}}if(a)for(let[t,r]of a){let i=d.has(t)?t:e(t);n+=p(i,r)}return n}if(t.attributes&&t.attributes.length)for(let e=0;e<t.attributes.length;e++){let r=t.attributes[e];r&&r.name&&(n+=p(r.name,r.value))}return n}const h=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]),g=new Set([`script`,`style`]);function _(e,t){return t.replace(RegExp(`</(`+e+`)`,`gi`),`<\\/$1`)}function v(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 y(e){if(e.nodeType===3)return i(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let t=e,n=t.tagName.toLowerCase(),r=m(t);if(h.has(n))return`<${n}${r} />`;if(g.has(n)){let i=``,a=v(t);if(a&&a.length>0)for(let e=0;e<a.length;e++){let t=a[e];t&&t.nodeType===3&&(i+=t.textContent||``)}else{let t=e.textContent;typeof t==`string`&&(i=t)}return`<${n}${r}>${_(n,i)}</${n}>`}let a=``,o=v(t);if(o&&o.length>0)for(let e=0;e<o.length;e++){let t=o[e];t&&(a+=y(t))}else{let t=e.textContent;typeof t==`string`&&t&&(a=i(t))}return`<${n}${r}>${a}</${n}>`}if(e.nodeType===11){let t=``,n=v(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&(t+=y(r))}return t}return``}function b(e){if(!e)return``;if(typeof e==`function`)try{let t=u(()=>{let t=c(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);return e(t,0)});return t&&typeof t==`object`&&`nodeType`in t?y(t):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?y(e):``}function x(e){return e.map(e=>b(e))}function S(e,t=`div`,n={}){let r=b(e);return`<${t}${Object.entries(n).map(([e,t])=>p(e,t)).join(``)}>${r}</${t}>`}function C(e){}const w=[],T=new Map;let E=null;function D(){if(E!==null)return E;let e=w.join(``);for(let[t,n]of T)n.length>0&&(e+=t+`{`+n.join(``)+`}`);return E=e,e}exports.getCssText=D,exports.renderManyToString=x,exports.renderToString=b,exports.renderToStringWithContainer=S,exports.setSSRCollector=C;
2
+ //# sourceMappingURL=nuclo.ssr.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuclo.ssr.cjs","names":[],"sources":["../../src/shared/strings.ts","../../src/update/registry.ts","../../src/shared/dom.ts","../../src/hydration.ts","../../src/ssr/render-to-string.ts","../../src/style/engine.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 // Fast path: attribute/property names are usually already lowercase.\n let firstUpper = 0;\n for (; firstUpper < str.length; firstUpper++) {\n const code = str.charCodeAt(firstUpper);\n if (code >= 65 && code <= 90) break;\n }\n if (firstUpper === str.length) return str;\n\n let result = str.slice(0, firstUpper);\n for (let i = firstUpper; 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\nconst ATTR_ESCAPE_RE = /[&<>\"']/;\nconst TEXT_ESCAPE_RE = /[&<>]/;\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n // Fast path: most strings contain no special characters at all.\n const first = ATTR_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n case 34: escaped = '&quot;'; break; // \"\n case 39: escaped = '&#039;'; break; // '\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\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 const first = TEXT_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\n}\n","/**\n * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactiveText.ts and reactiveAttributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the actual info\n * records live in WeakMaps keyed by the node. Info records may strongly\n * reference the node (e.g. attribute applyValue closures capture the\n * element), so storing them in a strongly-held map would pin the node in\n * memory forever. With WeakMap storage the whole record is collectible as\n * soon as the node is unreachable, and the FinalizationRegistry prunes the\n * leftover WeakRef from the iteration set. The notify passes also prune\n * dead/disconnected entries as they iterate.\n */\n\nexport type TextResolver = () => Primitive;\n\nexport interface ReactiveTextNodeInfo {\n resolver: TextResolver;\n lastValue: string;\n}\n\nexport type AttributeResolver = () => unknown;\n\nexport interface AttributeResolverRecord {\n resolver: AttributeResolver;\n applyValue: (value: unknown) => void;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementInfo {\n attributeResolvers: Map<string, AttributeResolverRecord>;\n}\n\n/**\n * Iteration set of weak references to reactive text nodes.\n */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/**\n * WeakMap for O(1) lookups of reactive text node info by node reference.\n */\nexport const reactiveTextNodesByNode = new WeakMap<Text, { ref: WeakRef<Text>; info: ReactiveTextNodeInfo }>();\n\n/**\n * Iteration set of weak references to reactive elements.\n */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/**\n * WeakMap for O(1) lookups of reactive element info by element reference.\n */\nexport const reactiveElementsByNode = new WeakMap<Element, { ref: WeakRef<Element>; info: ReactiveElementInfo }>();\n\nconst textNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Text>>((ref) => { reactiveTextNodes.delete(ref); })\n : null;\n\nconst elementFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Element>>((ref) => { reactiveElements.delete(ref); })\n : null;\n\n/**\n * Registers a reactive text node in both lookup structures.\n */\nexport function registerReactiveTextNode(node: Text, info: ReactiveTextNodeInfo): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n // Re-registration (e.g. repeated hydration): replace the info in place.\n existing.info.resolver = info.resolver;\n existing.info.lastValue = info.lastValue;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, info });\n textNodeFinalizer?.register(node, ref);\n}\n\n/**\n * Registers a reactive element in both lookup structures.\n */\nexport function registerReactiveElement(element: Element, info: ReactiveElementInfo): void {\n const ref = new WeakRef(element);\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, { ref, info });\n elementFinalizer?.register(element, ref);\n}\n\n/**\n * Removes a reactive text node's WeakRef entry from the iteration set.\n */\nexport function removeReactiveTextNodeRef(ref: WeakRef<Text>): void {\n reactiveTextNodes.delete(ref);\n}\n\n/**\n * Removes a reactive element's WeakRef entry from the iteration set.\n */\nexport function removeReactiveElementRef(ref: WeakRef<Element>): void {\n reactiveElements.delete(ref);\n}\n\n/**\n * Manually removes reactive text node info for a specific text node.\n * This should be called when a text node is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveTextNode(node: Text): void {\n const entry = reactiveTextNodesByNode.get(node);\n if (entry) {\n reactiveTextNodes.delete(entry.ref);\n reactiveTextNodesByNode.delete(node);\n }\n}\n\n/**\n * Manually removes reactive element info for a specific element.\n * This should be called when an element is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveElement(element: Element): void {\n const entry = reactiveElementsByNode.get(element);\n if (entry) {\n reactiveElements.delete(entry.ref);\n reactiveElementsByNode.delete(element);\n }\n}\n\n// ─── Conditional elements ────────────────────────────────────────────────────\n// Same idea as above, but for nodes created by conditional rendering: the\n// registry remembers each node's condition + modifiers so update() can\n// re-evaluate and swap the element in place.\n\nexport interface ConditionalInfo<TTagName extends ElementTagName = ElementTagName> {\n\tcondition: () => boolean;\n\ttagName: TTagName;\n\tmodifiers: Array<NodeMod<TTagName> | NodeModFn<TTagName>>;\n\tisSvg: boolean;\n}\n\n// WeakMap replaces the _conditionalInfo expando property — zero `any`, no DOM pollution, auto-GC.\nconst conditionalInfoMap = new WeakMap<Node, ConditionalInfo<ElementTagName>>();\n\n/**\n * Registry of all nodes that have conditional info attached.\n * Uses WeakRef to prevent memory leaks — allows garbage collection of removed nodes.\n * This enables O(nConditionals) updates instead of a full DOM tree walk.\n */\nconst activeConditionalNodes = new Set<WeakRef<Node>>();\n\n/**\n * Reverse lookup for O(1) unregister — maps node to its WeakRef in the active set.\n */\nconst refByNode = new WeakMap<Node, WeakRef<Node>>();\n\n/**\n * Prunes dead WeakRefs from the active set as soon as their node is\n * collected, instead of waiting for the next getActiveConditionalNodes() pass.\n */\nconst conditionalNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n\t? new FinalizationRegistry<WeakRef<Node>>((ref) => { activeConditionalNodes.delete(ref); })\n\t: null;\n\n/**\n * Attach conditional info to a node and register it.\n */\nexport function storeConditionalInfo<TTagName extends ElementTagName>(\n\tnode: Node,\n\tinfo: ConditionalInfo<TTagName>\n): void {\n\tconditionalInfoMap.set(node, info as ConditionalInfo<ElementTagName>);\n\tconst ref = new WeakRef(node);\n\tactiveConditionalNodes.add(ref);\n\trefByNode.set(node, ref);\n\tconditionalNodeFinalizer?.register(node, ref);\n}\n\n/**\n * Explicit unregister helper (optional use on teardown if needed).\n * O(1) via reverse lookup WeakMap.\n */\nexport function unregisterConditionalNode(node: Node): void {\n\tconditionalInfoMap.delete(node);\n\tconst ref = refByNode.get(node);\n\tif (ref) {\n\t\tactiveConditionalNodes.delete(ref);\n\t\trefByNode.delete(node);\n\t}\n}\n\n/**\n * Returns an array of currently tracked conditional nodes that are still alive.\n * Automatically cleans up garbage-collected nodes.\n */\nexport function getActiveConditionalNodes(): Node[] {\n\tconst nodes: Node[] = [];\n\tconst toDelete: WeakRef<Node>[] = [];\n\n\tfor (const ref of activeConditionalNodes) {\n\t\tconst node = ref.deref();\n\t\tif (node === undefined) {\n\t\t\ttoDelete.push(ref);\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t}\n\n\tfor (const ref of toDelete) {\n\t\tactiveConditionalNodes.delete(ref);\n\t}\n\n\treturn nodes;\n}\n\nexport function getConditionalInfo(node: Node): ConditionalInfo<ElementTagName> | null {\n\treturn conditionalInfoMap.get(node) ?? null;\n}\n","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement, unregisterConditionalNode } from \"../update/registry\";\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 cleanupNodeTree(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 cleanupNodeTree(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 cleanupNodeTree(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 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// ─── Type-safe DOM helpers ───────────────────────────────────────────────────\n\n/**\n * Safely casts an Element-like object to Node & ParentNode interface.\n * This is a common pattern needed when working with DOM manipulation.\n *\n * @param element - The element to cast\n * @returns The element typed as Node & ParentNode\n */\nexport function asParentNode<T extends Element | object>(element: T): Node & ParentNode {\n return element as unknown as Node & ParentNode;\n}\n\n/**\n * Creates a scoped DOM insertion context that temporarily redirects appendChild\n * to insertBefore at a specific reference node. This is useful for inserting\n * content at specific positions in the DOM tree.\n *\n * @param host - The host element\n * @param referenceNode - The node before which new nodes should be inserted\n * @param callback - Function to execute with the scoped context\n * @returns The result of the callback\n */\nexport function withScopedInsertion<T, THost extends Element | object>(\n host: THost,\n referenceNode: Node,\n callback: () => T\n): T {\n const parent = asParentNode(host);\n const originalAppend = parent.appendChild.bind(parent);\n const originalInsert = parent.insertBefore.bind(parent);\n\n // Temporarily override appendChild to insert before the reference node\n // TypeScript doesn't like this override but it's safe at runtime\n (parent as unknown as Record<string, unknown>).appendChild = function(node: Node): Node {\n return originalInsert(node, referenceNode);\n };\n\n try {\n return callback();\n } finally {\n // Restore original method\n (parent as unknown as Record<string, unknown>).appendChild = originalAppend;\n }\n}\n\n/**\n * Type-safe wrapper for setting CSS style properties.\n * Provides better error handling than direct CSSStyleDeclaration access.\n * Supports both camelCase and kebab-case property names.\n *\n * @param element - The element to apply styles to\n * @param property - The CSS property name (camelCase or kebab-case)\n * @param value - The value to set (string, number, or null to remove)\n * @returns true if the style was applied successfully, false otherwise\n */\nexport function setStyleProperty(\n element: HTMLElement,\n property: string,\n value: string | number | null\n): boolean {\n try {\n if (value === null || value === undefined || value === '') {\n // Use bracket notation to remove property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = '';\n return true;\n }\n\n // Convert value to string first (might throw if toString() throws)\n const stringValue = String(value);\n // Use bracket notation to set property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = stringValue;\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Hydration context — tracks global hydration state and per-parent cursor positions.\n *\n * During hydration the component tree is built against an existing DOM tree\n * (produced by SSR). Instead of creating new nodes, factories claim existing\n * children from their parent element by advancing a cursor.\n *\n * The cursor is a *node pointer* (the next unclaimed child), not an index.\n * Indexed childNodes access is O(n) after any tree/attribute mutation in\n * jsdom (live NodeList re-materialization) which made hydration O(n²);\n * firstChild/nextSibling pointers are O(1) in every DOM implementation.\n */\n\nlet _hydrating = false;\n// True while renderToString() is building a tree destined for serialization.\nlet _serializing = false;\n// Missing entry = cursor at parent.firstChild; null = past the last child.\nlet _cursors = new WeakMap<Node, Node | null>();\n\nexport function isHydrating(): boolean {\n return _hydrating;\n}\n\n/**\n * True while a tree is being built for SSR serialization (inside\n * renderToString). Text children must keep their `<!-- text-N -->` markers in\n * this mode so the emitted HTML stays hydratable — even when `isBrowser` is\n * true (SSR running under jsdom, or an isomorphic worker that provides a DOM).\n * A pure client render leaves this false and skips the markers.\n */\nexport function isSerializing(): boolean {\n return _serializing;\n}\n\n/**\n * Runs `fn` with serialization mode enabled, restoring the previous state\n * afterwards (so nested/re-entrant renderToString calls behave correctly).\n */\nexport function runSerializing<T>(fn: () => T): T {\n const previous = _serializing;\n _serializing = true;\n try {\n return fn();\n } finally {\n _serializing = previous;\n }\n}\n\nexport function startHydration(): void {\n _hydrating = true;\n // Each hydration pass starts with a clean cursor slate. Stale cursors from\n // a previous pass would desynchronize claims when a container's content is\n // replaced and re-hydrated (HMR, islands re-mounting).\n _cursors = new WeakMap<Node, Node | null>();\n}\n\nexport function endHydration(): void {\n _hydrating = false;\n}\n\n/**\n * Runs a callback with hydration temporarily disabled, restoring the previous\n * state afterwards. Used when a server/client mismatch forces a subtree to be\n * rendered fresh in the middle of a hydration pass — fresh rendering must not\n * claim nodes from the surrounding SSR DOM.\n */\nexport function runWithoutHydration<T>(fn: () => T): T {\n const wasHydrating = _hydrating;\n _hydrating = false;\n try {\n return fn();\n } finally {\n _hydrating = wasHydrating;\n }\n}\n\n/**\n * Returns the next unclaimed child of a parent node (or null at the end)\n * without advancing the cursor.\n */\nexport function peekChild(parent: Node): Node | null {\n const entry = _cursors.get(parent);\n return entry === undefined ? parent.firstChild : entry;\n}\n\n/**\n * Sets the cursor to a specific child node (or null for \"past the end\").\n */\nexport function setCursor(parent: Node, node: Node | null): void {\n _cursors.set(parent, node);\n}\n\nfunction isWhitespaceText(node: Node): boolean {\n return node.nodeType === 3 && !/\\S/.test(node.textContent || '');\n}\n\n/**\n * Advances the cursor past whitespace-only text nodes.\n *\n * Nuclo's own SSR output never produces bare whitespace text nodes (text\n * children are always preceded by a `<!-- text-N -->` marker), so unmarked\n * whitespace comes from the surrounding template or an HTML\n * formatter/minifier. Skipping (without removing) keeps the cursor aligned\n * while leaving the document's visual whitespace untouched.\n */\nexport function skipWhitespaceText(parent: Node): void {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n child = child.nextSibling;\n advanced = true;\n }\n if (advanced) {\n setCursor(parent, child);\n }\n}\n\n/**\n * Claims the next child node from parent at the current cursor position.\n * Advances the cursor by one.\n */\nexport function claimChild(parent: Node): Node | null {\n const child = peekChild(parent);\n if (child) {\n setCursor(parent, child.nextSibling);\n }\n return child;\n}\n\n/**\n * Attempts to claim an existing element from the parent during hydration.\n * Returns the claimed element if the next child matches the expected tag, or null.\n */\nexport function claimElement(parent: Node, tagName: string): Element | null {\n if (!_hydrating) return null;\n skipWhitespaceText(parent);\n const candidate = peekChild(parent);\n if (candidate && candidate.nodeType === 1 && (candidate as Element).tagName.toLowerCase() === tagName) {\n return claimChild(parent) as Element;\n }\n return null;\n}\n\n/**\n * Removes unclaimed SSR children from a hydrated element.\n * Must be called after modifiers have been applied to a claimed element.\n * Removes nodes from the cursor through `lastOriginalChild` (the element's\n * last child before modifiers ran) — nodes appended by modifiers come after\n * that boundary and are preserved.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null): void {\n if (!lastOriginalChild) return;\n let current = peekChild(node);\n while (current) {\n const next = current === lastOriginalChild ? null : current.nextSibling;\n node.removeChild(current);\n current = next;\n }\n setCursor(node, null);\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../shared/strings';\nimport { createElement } from '../shared/dom';\nimport { runSerializing } from '../hydration';\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 let styleStr = '';\n for (const key in value as Record<string, unknown>) {\n const val = (value as Record<string, unknown>)[key];\n if (val == null || val === '') continue;\n styleStr += (styleStr ? ' ' : '') + camelToKebab(key) + ': ' + String(val) + ';';\n }\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. NucloElement keeps every child in a plain Array\n // (`children`), which a real DOM element never does (HTMLCollection) — this is\n // the same allocation-free discriminator getChildNodes() uses. Reading\n // `el.attributes` directly would lazily allocate an empty Map for every\n // element being serialized, so the backing `_attributes` field is read instead.\n if (Array.isArray((element as any).children)) {\n const el = element as any;\n const attrs = el._attributes as Map<string, string> | undefined;\n\n // id — may live on the property rather than in the Map\n if (el.id && !attrs?.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 && !attrs?.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the backing _style object, not in the attributes Map.\n // Read the field directly (never `el.style`) so elements that never set a\n // style are not forced to lazily allocate an empty SSRStyle just to serialize.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n const styleObj = el._style;\n if (!attrs?.has('style') && styleObj) {\n const rawCssText: string = styleObj.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 if (attrs) {\n for (const [name, value] of attrs) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\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 * Raw-text elements — browsers never decode entities inside them, so their\n * text content must be emitted verbatim (escaping would corrupt inline JS/CSS,\n * e.g. `a < b` becoming `a &lt; b` inside a script). A closing-tag sequence\n * in the content would terminate the element early, so it is neutralized.\n */\nconst RAW_TEXT_ELEMENTS = new Set(['script', 'style']);\n\nfunction escapeRawText(tagName: string, text: string): string {\n // \"</script\" (any case) inside a script would close it — break the sequence\n // the same way JSON serializers do (\"<\\/script\").\n return text.replace(new RegExp('</(' + tagName + ')', 'gi'), '<\\\\/$1');\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 // Raw-text elements: emit text verbatim (no entity escaping, no Nuclo\n // text markers — `<!--` would act as a line comment inside a script).\n if (RAW_TEXT_ELEMENTS.has(tagName)) {\n let rawContent = '';\n const rawChildren = getChildNodes(element);\n if (rawChildren && rawChildren.length > 0) {\n for (let i = 0; i < rawChildren.length; i++) {\n const child = rawChildren[i];\n if (child && child.nodeType === 3) {\n rawContent += child.textContent || '';\n }\n }\n } else {\n const tc = (node as { textContent?: unknown }).textContent;\n if (typeof tc === 'string') rawContent = tc;\n }\n return `<${tagName}${attributes}>${escapeRawText(tagName, rawContent)}</${tagName}>`;\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 // Build the tree in serialization mode so text children keep their\n // <!-- text-N --> markers (needed for hydration) even when isBrowser is\n // true, e.g. SSR running under jsdom.\n const element = runSerializing(() => {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n return input(container as ExpandedElement<ElementTagName>, 0);\n });\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n // eslint-disable-next-line no-console\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","/**\n * Shared atomic-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n */\n\n// SSR collector — optional hook that receives every newly minted rule string\n// (wrapped in its at-rule, if any). Installed once at server startup.\ntype SSRCollector = (rule: string) => void;\nlet ssrCollector: SSRCollector | null = null;\n\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\tssrCollector = fn;\n}\n\n// Registry — the source of truth for all generated CSS.\n// atomCache: declaration key -> class name (dedup)\n// atomOwner: class name -> conflict key (query|suffix|property), used by cx()\nconst atomCache = new Map<string, string>();\nconst atomOwner = new Map<string, string>();\nconst rawKeys = new Set<string>();\nconst baseRules: string[] = [];\nconst queryRules = new Map<string, string[]>();\n\n// Memoized getCssText() output. SSR calls getCssText() once per request, but the\n// rule set is stable after warmup — so the serialized sheet is recomputed only\n// when a new rule is actually recorded. Invalidated in record() and resetStyles().\nlet cssTextCache: string | null = null;\n\n// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n// (one per query, created in registration order) live after them. CSSRule\n// references stay live when indices shift, so insertion never rescans.\nlet sheet: CSSStyleSheet | null = null;\nlet sheetDocument: Document | null = null;\nlet baseRuleCount = 0;\nconst groupRules = new Map<string, CSSGroupingRule>();\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>): void {\n\tfor (const query of queries) {\n\t\tif (!queryRules.has(query)) queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tgroupRules.set(query, group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string): void {\n\ttry {\n\t\ts.insertRule(rule, baseRuleCount);\n\t\tbaseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nfunction ensureSheet(): CSSStyleSheet | null {\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (sheet && sheetDocument === document && sheet.ownerNode && (sheet.ownerNode as Element).isConnected) {\n\t\treturn sheet;\n\t}\n\tlet el = document.getElementById(\"nuclo-styles\") as HTMLStyleElement | null;\n\tif (!el) {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tdocument.head.appendChild(el);\n\t}\n\tsheet = el.sheet;\n\tsheetDocument = document;\n\tgroupRules.clear();\n\tbaseRuleCount = 0;\n\tif (!sheet) return null;\n\tfor (const rule of baseRules) insertBase(sheet, rule);\n\tfor (const [query, rules] of queryRules) {\n\t\tconst group = createGroup(sheet, query);\n\t\tif (group) {\n\t\t\tfor (const rule of rules) {\n\t\t\t\ttry {\n\t\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t\t} catch { /* drop invalid rule */ }\n\t\t\t}\n\t\t}\n\t}\n\treturn sheet;\n}\n\nfunction record(rule: string, query: string | undefined): void {\n\tif (query === undefined) {\n\t\tbaseRules.push(rule);\n\t} else {\n\t\tlet bucket = queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tqueryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tcssTextCache = null; // a new rule changes the serialized sheet\n\tssrCollector?.(query === undefined ? rule : query + \"{\" + rule + \"}\");\n\n\tconst s = ensureSheet();\n\tif (!s) return;\n\tif (query === undefined) {\n\t\tinsertBase(s, rule);\n\t} else {\n\t\tconst group = groupRules.get(query) ?? createGroup(s, query);\n\t\tif (group) {\n\t\t\ttry {\n\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t} catch { /* drop invalid rule */ }\n\t\t}\n\t}\n}\n\n/**\n * Order-independent 53-bit content hash (two interleaved FNV-1a style passes).\n * Class names must match between server and client for SSR hydration, so a\n * counter is not an option; 53 bits keeps collision odds negligible (~1e-5 at\n * 10k unique declarations).\n */\nexport function hash(input: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\n/** One class per (query, selector-suffix, declaration) — the atomic core. */\nexport function atom(query: string | undefined, suffix: string, property: string, value: string): string {\n\tconst declKey = (query ?? \"\") + \"|\" + suffix + \"|\" + property + \":\" + value;\n\tlet className = atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\tclassName = \"n\" + hash(declKey);\n\tatomCache.set(declKey, className);\n\tatomOwner.set(className, (query ?? \"\") + \"|\" + suffix + \"|\" + property);\n\trecord(\".\" + className + suffix + \"{\" + property + \":\" + value + \"}\", query);\n\treturn className;\n}\n\n/** Conflict key for a generated class — lets cx() resolve overrides exactly. */\nexport function conflictKeyOf(className: string): string | undefined {\n\treturn atomOwner.get(className);\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string): void {\n\tif (rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\trawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText(): string {\n\tif (cssTextCache !== null) return cssTextCache;\n\tlet out = baseRules.join(\"\");\n\tfor (const [query, rules] of queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\tcssTextCache = out;\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles(): void {\n\tatomCache.clear();\n\tatomOwner.clear();\n\trawKeys.clear();\n\tbaseRules.length = 0;\n\tqueryRules.clear();\n\tgroupRules.clear();\n\tcssTextCache = null;\n\tbaseRuleCount = 0;\n\tsheet = null;\n\tsheetDocument = null;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ function e(e){let t=0;for(;t<e.length;t++){let n=e.charCodeAt(t);if(n>=65&&n<=90)break}if(t===e.length)return e;let n=e.slice(0,t);for(let r=t;r<e.length;r++){let t=e.charCodeAt(r);t>=65&&t<=90?(r>0&&(n+=`-`),n+=String.fromCharCode(t+32)):n+=e[r]}return n}const t=/[&<>"']/,n=/[&<>]/;function r(e){let n=t.exec(e);if(!n)return e;let r=``,i=0;for(let t=n.index;t<e.length;t++){let n;switch(e.charCodeAt(t)){case 38:n=`&amp;`;break;case 60:n=`&lt;`;break;case 62:n=`&gt;`;break;case 34:n=`&quot;`;break;case 39:n=`&#039;`;break;default:continue}r+=e.slice(i,t)+n,i=t+1}return r+e.slice(i)}function i(e){let t=n.exec(e);if(!t)return e;let r=``,i=0;for(let n=t.index;n<e.length;n++){let t;switch(e.charCodeAt(n)){case 38:t=`&amp;`;break;case 60:t=`&lt;`;break;case 62:t=`&gt;`;break;default:continue}r+=e.slice(i,n)+t,i=n+1}return r+e.slice(i)}const a=new Set,o=new Set;typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{a.delete(e)}),typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{o.delete(e)});const s=new Set;typeof FinalizationRegistry<`u`&&new FinalizationRegistry(e=>{s.delete(e)});function c(e){return globalThis.document?document.createElement(e):null}let l=!1;function u(e){let t=l;l=!0;try{return e()}finally{l=t}}const d=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(`.`)),f=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 p(t,n){if(n==null||n===!1)return``;if(n===!0)return` ${t}`;if(f.has(t)){if(n===`false`)return``;if(n===`true`||n===``||n===t)return` ${t}`}if(t===`style`&&typeof n==`object`){let t=``;for(let r in n){let i=n[r];i==null||i===``||(t+=(t?` `:``)+e(r)+`: `+String(i)+`;`)}return t?` style="${r(t)}"`:``}return` ${t}="${r(String(n))}"`}function m(t){let n=``;if(Array.isArray(t.children)){let i=t,a=i._attributes;i.id&&!a?.has(`id`)&&(n+=p(`id`,i.id)),i.className&&!a?.has(`class`)&&(n+=p(`class`,i.className));let o=i._style;if(!a?.has(`style`)&&o){let t=o.cssText||``;if(t){let i=t.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&&(n+=` style="${r(i)}"`)}}if(a)for(let[t,r]of a){let i=d.has(t)?t:e(t);n+=p(i,r)}return n}if(t.attributes&&t.attributes.length)for(let e=0;e<t.attributes.length;e++){let r=t.attributes[e];r&&r.name&&(n+=p(r.name,r.value))}return n}const h=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]),g=new Set([`script`,`style`]);function _(e,t){return t.replace(RegExp(`</(`+e+`)`,`gi`),`<\\/$1`)}function v(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 y(e){if(e.nodeType===3)return i(e.textContent||``);if(e.nodeType===8)return`<!--${e.textContent||``}-->`;if(e.nodeType===1){let t=e,n=t.tagName.toLowerCase(),r=m(t);if(h.has(n))return`<${n}${r} />`;if(g.has(n)){let i=``,a=v(t);if(a&&a.length>0)for(let e=0;e<a.length;e++){let t=a[e];t&&t.nodeType===3&&(i+=t.textContent||``)}else{let t=e.textContent;typeof t==`string`&&(i=t)}return`<${n}${r}>${_(n,i)}</${n}>`}let a=``,o=v(t);if(o&&o.length>0)for(let e=0;e<o.length;e++){let t=o[e];t&&(a+=y(t))}else{let t=e.textContent;typeof t==`string`&&t&&(a=i(t))}return`<${n}${r}>${a}</${n}>`}if(e.nodeType===11){let t=``,n=v(e);if(n&&n.length>0)for(let e=0;e<n.length;e++){let r=n[e];r&&(t+=y(r))}return t}return``}function b(e){if(!e)return``;if(typeof e==`function`)try{let t=u(()=>{let t=c(`div`);if(!t)throw Error(`Document is not available. Make sure polyfills are loaded.`);return e(t,0)});return t&&typeof t==`object`&&`nodeType`in t?y(t):``}catch(e){return console.error(`Error rendering component to string:`,e),``}return`nodeType`in e?y(e):``}function x(e){return e.map(e=>b(e))}function S(e,t=`div`,n={}){let r=b(e);return`<${t}${Object.entries(n).map(([e,t])=>p(e,t)).join(``)}>${r}</${t}>`}function C(e){}const w=[],T=new Map;let E=null;function D(){if(E!==null)return E;let e=w.join(``);for(let[t,n]of T)n.length>0&&(e+=t+`{`+n.join(``)+`}`);return E=e,e}export{D as getCssText,x as renderManyToString,b as renderToString,S as renderToStringWithContainer,C as setSSRCollector};
2
+ //# sourceMappingURL=nuclo.ssr.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuclo.ssr.mjs","names":[],"sources":["../../src/shared/strings.ts","../../src/update/registry.ts","../../src/shared/dom.ts","../../src/hydration.ts","../../src/ssr/render-to-string.ts","../../src/style/engine.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 // Fast path: attribute/property names are usually already lowercase.\n let firstUpper = 0;\n for (; firstUpper < str.length; firstUpper++) {\n const code = str.charCodeAt(firstUpper);\n if (code >= 65 && code <= 90) break;\n }\n if (firstUpper === str.length) return str;\n\n let result = str.slice(0, firstUpper);\n for (let i = firstUpper; 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\nconst ATTR_ESCAPE_RE = /[&<>\"']/;\nconst TEXT_ESCAPE_RE = /[&<>]/;\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n // Fast path: most strings contain no special characters at all.\n const first = ATTR_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n case 34: escaped = '&quot;'; break; // \"\n case 39: escaped = '&#039;'; break; // '\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\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 const first = TEXT_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\n}\n","/**\n * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactiveText.ts and reactiveAttributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the actual info\n * records live in WeakMaps keyed by the node. Info records may strongly\n * reference the node (e.g. attribute applyValue closures capture the\n * element), so storing them in a strongly-held map would pin the node in\n * memory forever. With WeakMap storage the whole record is collectible as\n * soon as the node is unreachable, and the FinalizationRegistry prunes the\n * leftover WeakRef from the iteration set. The notify passes also prune\n * dead/disconnected entries as they iterate.\n */\n\nexport type TextResolver = () => Primitive;\n\nexport interface ReactiveTextNodeInfo {\n resolver: TextResolver;\n lastValue: string;\n}\n\nexport type AttributeResolver = () => unknown;\n\nexport interface AttributeResolverRecord {\n resolver: AttributeResolver;\n applyValue: (value: unknown) => void;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementInfo {\n attributeResolvers: Map<string, AttributeResolverRecord>;\n}\n\n/**\n * Iteration set of weak references to reactive text nodes.\n */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/**\n * WeakMap for O(1) lookups of reactive text node info by node reference.\n */\nexport const reactiveTextNodesByNode = new WeakMap<Text, { ref: WeakRef<Text>; info: ReactiveTextNodeInfo }>();\n\n/**\n * Iteration set of weak references to reactive elements.\n */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/**\n * WeakMap for O(1) lookups of reactive element info by element reference.\n */\nexport const reactiveElementsByNode = new WeakMap<Element, { ref: WeakRef<Element>; info: ReactiveElementInfo }>();\n\nconst textNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Text>>((ref) => { reactiveTextNodes.delete(ref); })\n : null;\n\nconst elementFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Element>>((ref) => { reactiveElements.delete(ref); })\n : null;\n\n/**\n * Registers a reactive text node in both lookup structures.\n */\nexport function registerReactiveTextNode(node: Text, info: ReactiveTextNodeInfo): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n // Re-registration (e.g. repeated hydration): replace the info in place.\n existing.info.resolver = info.resolver;\n existing.info.lastValue = info.lastValue;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, info });\n textNodeFinalizer?.register(node, ref);\n}\n\n/**\n * Registers a reactive element in both lookup structures.\n */\nexport function registerReactiveElement(element: Element, info: ReactiveElementInfo): void {\n const ref = new WeakRef(element);\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, { ref, info });\n elementFinalizer?.register(element, ref);\n}\n\n/**\n * Removes a reactive text node's WeakRef entry from the iteration set.\n */\nexport function removeReactiveTextNodeRef(ref: WeakRef<Text>): void {\n reactiveTextNodes.delete(ref);\n}\n\n/**\n * Removes a reactive element's WeakRef entry from the iteration set.\n */\nexport function removeReactiveElementRef(ref: WeakRef<Element>): void {\n reactiveElements.delete(ref);\n}\n\n/**\n * Manually removes reactive text node info for a specific text node.\n * This should be called when a text node is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveTextNode(node: Text): void {\n const entry = reactiveTextNodesByNode.get(node);\n if (entry) {\n reactiveTextNodes.delete(entry.ref);\n reactiveTextNodesByNode.delete(node);\n }\n}\n\n/**\n * Manually removes reactive element info for a specific element.\n * This should be called when an element is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveElement(element: Element): void {\n const entry = reactiveElementsByNode.get(element);\n if (entry) {\n reactiveElements.delete(entry.ref);\n reactiveElementsByNode.delete(element);\n }\n}\n\n// ─── Conditional elements ────────────────────────────────────────────────────\n// Same idea as above, but for nodes created by conditional rendering: the\n// registry remembers each node's condition + modifiers so update() can\n// re-evaluate and swap the element in place.\n\nexport interface ConditionalInfo<TTagName extends ElementTagName = ElementTagName> {\n\tcondition: () => boolean;\n\ttagName: TTagName;\n\tmodifiers: Array<NodeMod<TTagName> | NodeModFn<TTagName>>;\n\tisSvg: boolean;\n}\n\n// WeakMap replaces the _conditionalInfo expando property — zero `any`, no DOM pollution, auto-GC.\nconst conditionalInfoMap = new WeakMap<Node, ConditionalInfo<ElementTagName>>();\n\n/**\n * Registry of all nodes that have conditional info attached.\n * Uses WeakRef to prevent memory leaks — allows garbage collection of removed nodes.\n * This enables O(nConditionals) updates instead of a full DOM tree walk.\n */\nconst activeConditionalNodes = new Set<WeakRef<Node>>();\n\n/**\n * Reverse lookup for O(1) unregister — maps node to its WeakRef in the active set.\n */\nconst refByNode = new WeakMap<Node, WeakRef<Node>>();\n\n/**\n * Prunes dead WeakRefs from the active set as soon as their node is\n * collected, instead of waiting for the next getActiveConditionalNodes() pass.\n */\nconst conditionalNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n\t? new FinalizationRegistry<WeakRef<Node>>((ref) => { activeConditionalNodes.delete(ref); })\n\t: null;\n\n/**\n * Attach conditional info to a node and register it.\n */\nexport function storeConditionalInfo<TTagName extends ElementTagName>(\n\tnode: Node,\n\tinfo: ConditionalInfo<TTagName>\n): void {\n\tconditionalInfoMap.set(node, info as ConditionalInfo<ElementTagName>);\n\tconst ref = new WeakRef(node);\n\tactiveConditionalNodes.add(ref);\n\trefByNode.set(node, ref);\n\tconditionalNodeFinalizer?.register(node, ref);\n}\n\n/**\n * Explicit unregister helper (optional use on teardown if needed).\n * O(1) via reverse lookup WeakMap.\n */\nexport function unregisterConditionalNode(node: Node): void {\n\tconditionalInfoMap.delete(node);\n\tconst ref = refByNode.get(node);\n\tif (ref) {\n\t\tactiveConditionalNodes.delete(ref);\n\t\trefByNode.delete(node);\n\t}\n}\n\n/**\n * Returns an array of currently tracked conditional nodes that are still alive.\n * Automatically cleans up garbage-collected nodes.\n */\nexport function getActiveConditionalNodes(): Node[] {\n\tconst nodes: Node[] = [];\n\tconst toDelete: WeakRef<Node>[] = [];\n\n\tfor (const ref of activeConditionalNodes) {\n\t\tconst node = ref.deref();\n\t\tif (node === undefined) {\n\t\t\ttoDelete.push(ref);\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t}\n\n\tfor (const ref of toDelete) {\n\t\tactiveConditionalNodes.delete(ref);\n\t}\n\n\treturn nodes;\n}\n\nexport function getConditionalInfo(node: Node): ConditionalInfo<ElementTagName> | null {\n\treturn conditionalInfoMap.get(node) ?? null;\n}\n","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement, unregisterConditionalNode } from \"../update/registry\";\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 cleanupNodeTree(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 cleanupNodeTree(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 cleanupNodeTree(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 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// ─── Type-safe DOM helpers ───────────────────────────────────────────────────\n\n/**\n * Safely casts an Element-like object to Node & ParentNode interface.\n * This is a common pattern needed when working with DOM manipulation.\n *\n * @param element - The element to cast\n * @returns The element typed as Node & ParentNode\n */\nexport function asParentNode<T extends Element | object>(element: T): Node & ParentNode {\n return element as unknown as Node & ParentNode;\n}\n\n/**\n * Creates a scoped DOM insertion context that temporarily redirects appendChild\n * to insertBefore at a specific reference node. This is useful for inserting\n * content at specific positions in the DOM tree.\n *\n * @param host - The host element\n * @param referenceNode - The node before which new nodes should be inserted\n * @param callback - Function to execute with the scoped context\n * @returns The result of the callback\n */\nexport function withScopedInsertion<T, THost extends Element | object>(\n host: THost,\n referenceNode: Node,\n callback: () => T\n): T {\n const parent = asParentNode(host);\n const originalAppend = parent.appendChild.bind(parent);\n const originalInsert = parent.insertBefore.bind(parent);\n\n // Temporarily override appendChild to insert before the reference node\n // TypeScript doesn't like this override but it's safe at runtime\n (parent as unknown as Record<string, unknown>).appendChild = function(node: Node): Node {\n return originalInsert(node, referenceNode);\n };\n\n try {\n return callback();\n } finally {\n // Restore original method\n (parent as unknown as Record<string, unknown>).appendChild = originalAppend;\n }\n}\n\n/**\n * Type-safe wrapper for setting CSS style properties.\n * Provides better error handling than direct CSSStyleDeclaration access.\n * Supports both camelCase and kebab-case property names.\n *\n * @param element - The element to apply styles to\n * @param property - The CSS property name (camelCase or kebab-case)\n * @param value - The value to set (string, number, or null to remove)\n * @returns true if the style was applied successfully, false otherwise\n */\nexport function setStyleProperty(\n element: HTMLElement,\n property: string,\n value: string | number | null\n): boolean {\n try {\n if (value === null || value === undefined || value === '') {\n // Use bracket notation to remove property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = '';\n return true;\n }\n\n // Convert value to string first (might throw if toString() throws)\n const stringValue = String(value);\n // Use bracket notation to set property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = stringValue;\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Hydration context — tracks global hydration state and per-parent cursor positions.\n *\n * During hydration the component tree is built against an existing DOM tree\n * (produced by SSR). Instead of creating new nodes, factories claim existing\n * children from their parent element by advancing a cursor.\n *\n * The cursor is a *node pointer* (the next unclaimed child), not an index.\n * Indexed childNodes access is O(n) after any tree/attribute mutation in\n * jsdom (live NodeList re-materialization) which made hydration O(n²);\n * firstChild/nextSibling pointers are O(1) in every DOM implementation.\n */\n\nlet _hydrating = false;\n// True while renderToString() is building a tree destined for serialization.\nlet _serializing = false;\n// Missing entry = cursor at parent.firstChild; null = past the last child.\nlet _cursors = new WeakMap<Node, Node | null>();\n\nexport function isHydrating(): boolean {\n return _hydrating;\n}\n\n/**\n * True while a tree is being built for SSR serialization (inside\n * renderToString). Text children must keep their `<!-- text-N -->` markers in\n * this mode so the emitted HTML stays hydratable — even when `isBrowser` is\n * true (SSR running under jsdom, or an isomorphic worker that provides a DOM).\n * A pure client render leaves this false and skips the markers.\n */\nexport function isSerializing(): boolean {\n return _serializing;\n}\n\n/**\n * Runs `fn` with serialization mode enabled, restoring the previous state\n * afterwards (so nested/re-entrant renderToString calls behave correctly).\n */\nexport function runSerializing<T>(fn: () => T): T {\n const previous = _serializing;\n _serializing = true;\n try {\n return fn();\n } finally {\n _serializing = previous;\n }\n}\n\nexport function startHydration(): void {\n _hydrating = true;\n // Each hydration pass starts with a clean cursor slate. Stale cursors from\n // a previous pass would desynchronize claims when a container's content is\n // replaced and re-hydrated (HMR, islands re-mounting).\n _cursors = new WeakMap<Node, Node | null>();\n}\n\nexport function endHydration(): void {\n _hydrating = false;\n}\n\n/**\n * Runs a callback with hydration temporarily disabled, restoring the previous\n * state afterwards. Used when a server/client mismatch forces a subtree to be\n * rendered fresh in the middle of a hydration pass — fresh rendering must not\n * claim nodes from the surrounding SSR DOM.\n */\nexport function runWithoutHydration<T>(fn: () => T): T {\n const wasHydrating = _hydrating;\n _hydrating = false;\n try {\n return fn();\n } finally {\n _hydrating = wasHydrating;\n }\n}\n\n/**\n * Returns the next unclaimed child of a parent node (or null at the end)\n * without advancing the cursor.\n */\nexport function peekChild(parent: Node): Node | null {\n const entry = _cursors.get(parent);\n return entry === undefined ? parent.firstChild : entry;\n}\n\n/**\n * Sets the cursor to a specific child node (or null for \"past the end\").\n */\nexport function setCursor(parent: Node, node: Node | null): void {\n _cursors.set(parent, node);\n}\n\nfunction isWhitespaceText(node: Node): boolean {\n return node.nodeType === 3 && !/\\S/.test(node.textContent || '');\n}\n\n/**\n * Advances the cursor past whitespace-only text nodes.\n *\n * Nuclo's own SSR output never produces bare whitespace text nodes (text\n * children are always preceded by a `<!-- text-N -->` marker), so unmarked\n * whitespace comes from the surrounding template or an HTML\n * formatter/minifier. Skipping (without removing) keeps the cursor aligned\n * while leaving the document's visual whitespace untouched.\n */\nexport function skipWhitespaceText(parent: Node): void {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n child = child.nextSibling;\n advanced = true;\n }\n if (advanced) {\n setCursor(parent, child);\n }\n}\n\n/**\n * Claims the next child node from parent at the current cursor position.\n * Advances the cursor by one.\n */\nexport function claimChild(parent: Node): Node | null {\n const child = peekChild(parent);\n if (child) {\n setCursor(parent, child.nextSibling);\n }\n return child;\n}\n\n/**\n * Attempts to claim an existing element from the parent during hydration.\n * Returns the claimed element if the next child matches the expected tag, or null.\n */\nexport function claimElement(parent: Node, tagName: string): Element | null {\n if (!_hydrating) return null;\n skipWhitespaceText(parent);\n const candidate = peekChild(parent);\n if (candidate && candidate.nodeType === 1 && (candidate as Element).tagName.toLowerCase() === tagName) {\n return claimChild(parent) as Element;\n }\n return null;\n}\n\n/**\n * Removes unclaimed SSR children from a hydrated element.\n * Must be called after modifiers have been applied to a claimed element.\n * Removes nodes from the cursor through `lastOriginalChild` (the element's\n * last child before modifiers ran) — nodes appended by modifiers come after\n * that boundary and are preserved.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null): void {\n if (!lastOriginalChild) return;\n let current = peekChild(node);\n while (current) {\n const next = current === lastOriginalChild ? null : current.nextSibling;\n node.removeChild(current);\n current = next;\n }\n setCursor(node, null);\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../shared/strings';\nimport { createElement } from '../shared/dom';\nimport { runSerializing } from '../hydration';\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 let styleStr = '';\n for (const key in value as Record<string, unknown>) {\n const val = (value as Record<string, unknown>)[key];\n if (val == null || val === '') continue;\n styleStr += (styleStr ? ' ' : '') + camelToKebab(key) + ': ' + String(val) + ';';\n }\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. NucloElement keeps every child in a plain Array\n // (`children`), which a real DOM element never does (HTMLCollection) — this is\n // the same allocation-free discriminator getChildNodes() uses. Reading\n // `el.attributes` directly would lazily allocate an empty Map for every\n // element being serialized, so the backing `_attributes` field is read instead.\n if (Array.isArray((element as any).children)) {\n const el = element as any;\n const attrs = el._attributes as Map<string, string> | undefined;\n\n // id — may live on the property rather than in the Map\n if (el.id && !attrs?.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 && !attrs?.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the backing _style object, not in the attributes Map.\n // Read the field directly (never `el.style`) so elements that never set a\n // style are not forced to lazily allocate an empty SSRStyle just to serialize.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n const styleObj = el._style;\n if (!attrs?.has('style') && styleObj) {\n const rawCssText: string = styleObj.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 if (attrs) {\n for (const [name, value] of attrs) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\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 * Raw-text elements — browsers never decode entities inside them, so their\n * text content must be emitted verbatim (escaping would corrupt inline JS/CSS,\n * e.g. `a < b` becoming `a &lt; b` inside a script). A closing-tag sequence\n * in the content would terminate the element early, so it is neutralized.\n */\nconst RAW_TEXT_ELEMENTS = new Set(['script', 'style']);\n\nfunction escapeRawText(tagName: string, text: string): string {\n // \"</script\" (any case) inside a script would close it — break the sequence\n // the same way JSON serializers do (\"<\\/script\").\n return text.replace(new RegExp('</(' + tagName + ')', 'gi'), '<\\\\/$1');\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 // Raw-text elements: emit text verbatim (no entity escaping, no Nuclo\n // text markers — `<!--` would act as a line comment inside a script).\n if (RAW_TEXT_ELEMENTS.has(tagName)) {\n let rawContent = '';\n const rawChildren = getChildNodes(element);\n if (rawChildren && rawChildren.length > 0) {\n for (let i = 0; i < rawChildren.length; i++) {\n const child = rawChildren[i];\n if (child && child.nodeType === 3) {\n rawContent += child.textContent || '';\n }\n }\n } else {\n const tc = (node as { textContent?: unknown }).textContent;\n if (typeof tc === 'string') rawContent = tc;\n }\n return `<${tagName}${attributes}>${escapeRawText(tagName, rawContent)}</${tagName}>`;\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 // Build the tree in serialization mode so text children keep their\n // <!-- text-N --> markers (needed for hydration) even when isBrowser is\n // true, e.g. SSR running under jsdom.\n const element = runSerializing(() => {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n return input(container as ExpandedElement<ElementTagName>, 0);\n });\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n // eslint-disable-next-line no-console\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","/**\n * Shared atomic-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n */\n\n// SSR collector — optional hook that receives every newly minted rule string\n// (wrapped in its at-rule, if any). Installed once at server startup.\ntype SSRCollector = (rule: string) => void;\nlet ssrCollector: SSRCollector | null = null;\n\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\tssrCollector = fn;\n}\n\n// Registry — the source of truth for all generated CSS.\n// atomCache: declaration key -> class name (dedup)\n// atomOwner: class name -> conflict key (query|suffix|property), used by cx()\nconst atomCache = new Map<string, string>();\nconst atomOwner = new Map<string, string>();\nconst rawKeys = new Set<string>();\nconst baseRules: string[] = [];\nconst queryRules = new Map<string, string[]>();\n\n// Memoized getCssText() output. SSR calls getCssText() once per request, but the\n// rule set is stable after warmup — so the serialized sheet is recomputed only\n// when a new rule is actually recorded. Invalidated in record() and resetStyles().\nlet cssTextCache: string | null = null;\n\n// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n// (one per query, created in registration order) live after them. CSSRule\n// references stay live when indices shift, so insertion never rescans.\nlet sheet: CSSStyleSheet | null = null;\nlet sheetDocument: Document | null = null;\nlet baseRuleCount = 0;\nconst groupRules = new Map<string, CSSGroupingRule>();\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>): void {\n\tfor (const query of queries) {\n\t\tif (!queryRules.has(query)) queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tgroupRules.set(query, group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string): void {\n\ttry {\n\t\ts.insertRule(rule, baseRuleCount);\n\t\tbaseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nfunction ensureSheet(): CSSStyleSheet | null {\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (sheet && sheetDocument === document && sheet.ownerNode && (sheet.ownerNode as Element).isConnected) {\n\t\treturn sheet;\n\t}\n\tlet el = document.getElementById(\"nuclo-styles\") as HTMLStyleElement | null;\n\tif (!el) {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tdocument.head.appendChild(el);\n\t}\n\tsheet = el.sheet;\n\tsheetDocument = document;\n\tgroupRules.clear();\n\tbaseRuleCount = 0;\n\tif (!sheet) return null;\n\tfor (const rule of baseRules) insertBase(sheet, rule);\n\tfor (const [query, rules] of queryRules) {\n\t\tconst group = createGroup(sheet, query);\n\t\tif (group) {\n\t\t\tfor (const rule of rules) {\n\t\t\t\ttry {\n\t\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t\t} catch { /* drop invalid rule */ }\n\t\t\t}\n\t\t}\n\t}\n\treturn sheet;\n}\n\nfunction record(rule: string, query: string | undefined): void {\n\tif (query === undefined) {\n\t\tbaseRules.push(rule);\n\t} else {\n\t\tlet bucket = queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tqueryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tcssTextCache = null; // a new rule changes the serialized sheet\n\tssrCollector?.(query === undefined ? rule : query + \"{\" + rule + \"}\");\n\n\tconst s = ensureSheet();\n\tif (!s) return;\n\tif (query === undefined) {\n\t\tinsertBase(s, rule);\n\t} else {\n\t\tconst group = groupRules.get(query) ?? createGroup(s, query);\n\t\tif (group) {\n\t\t\ttry {\n\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t} catch { /* drop invalid rule */ }\n\t\t}\n\t}\n}\n\n/**\n * Order-independent 53-bit content hash (two interleaved FNV-1a style passes).\n * Class names must match between server and client for SSR hydration, so a\n * counter is not an option; 53 bits keeps collision odds negligible (~1e-5 at\n * 10k unique declarations).\n */\nexport function hash(input: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\n/** One class per (query, selector-suffix, declaration) — the atomic core. */\nexport function atom(query: string | undefined, suffix: string, property: string, value: string): string {\n\tconst declKey = (query ?? \"\") + \"|\" + suffix + \"|\" + property + \":\" + value;\n\tlet className = atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\tclassName = \"n\" + hash(declKey);\n\tatomCache.set(declKey, className);\n\tatomOwner.set(className, (query ?? \"\") + \"|\" + suffix + \"|\" + property);\n\trecord(\".\" + className + suffix + \"{\" + property + \":\" + value + \"}\", query);\n\treturn className;\n}\n\n/** Conflict key for a generated class — lets cx() resolve overrides exactly. */\nexport function conflictKeyOf(className: string): string | undefined {\n\treturn atomOwner.get(className);\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string): void {\n\tif (rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\trawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText(): string {\n\tif (cssTextCache !== null) return cssTextCache;\n\tlet out = baseRules.join(\"\");\n\tfor (const [query, rules] of queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\tcssTextCache = out;\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles(): void {\n\tatomCache.clear();\n\tatomOwner.clear();\n\trawKeys.clear();\n\tbaseRules.length = 0;\n\tqueryRules.clear();\n\tgroupRules.clear();\n\tcssTextCache = null;\n\tbaseRuleCount = 0;\n\tsheet = null;\n\tsheetDocument = null;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Server-Side Rendering (SSR) utilities for Nuclo
3
+ * Renders Nuclo components to HTML strings in Node.js environment
4
+ */
5
+ type RenderableInput = NodeModFn<ElementTagName> | Element | Node | null | undefined;
6
+ /**
7
+ * Renders a Nuclo component to an HTML string for server-side rendering
8
+ *
9
+ * @param input - A Nuclo component function, DOM element, or node
10
+ * @returns HTML string representation of the component
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { renderToString } from 'nuclo/ssr';
15
+ * import { div } from 'nuclo';
16
+ *
17
+ * const html = renderToString(
18
+ * div("Hello, World!")
19
+ * );
20
+ * // Returns: '<div>Hello, World!</div>'
21
+ * ```
22
+ */
23
+ export declare function renderToString(input: RenderableInput): string;
24
+ /**
25
+ * Renders multiple Nuclo components to HTML strings
26
+ *
27
+ * @param inputs - Array of Nuclo components
28
+ * @returns Array of HTML strings
29
+ */
30
+ export declare function renderManyToString(inputs: RenderableInput[]): string[];
31
+ /**
32
+ * Renders a Nuclo component and wraps it in a container element
33
+ *
34
+ * @param input - A Nuclo component
35
+ * @param containerTag - The tag name for the container (default: 'div')
36
+ * @param containerAttrs - Attributes for the container element
37
+ * @returns HTML string with container wrapper
38
+ */
39
+ export declare function renderToStringWithContainer(input: RenderableInput, containerTag?: string, containerAttrs?: Record<string, string>): string;
40
+ export {};
41
+ //# sourceMappingURL=render-to-string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-to-string.d.ts","sourceRoot":"","sources":["../../src/ssr/render-to-string.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,KAAK,eAAe,GAChB,SAAS,CAAC,cAAc,CAAC,GACzB,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,CAAC;AAkRd;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CA0B7D;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"}
@@ -0,0 +1,19 @@
1
+ import type { ClassInput, CssInstance, FlatStyle, KeyframeFrames, Style, StyleResult, ThemeConfig, VariantDefinitions, VariantsConfig, VariantsFn } from "../../types/style";
2
+ export type { ClassInput, CssInstance, CSSProperties, FlatStyle, KeyframeFrames, KeyframeStop, Pseudo, Size, Style, StyleResult, ThemeConfig, VariantDefinitions, VariantProps, VariantsConfig, VariantsFn, } from "../../types/style";
3
+ /**
4
+ * Compose class lists with exact conflict resolution: when two inputs style
5
+ * the same (query, selector, property), the last one wins. Works because the
6
+ * engine knows what every class it generated means. Nested arrays are flattened,
7
+ * so `cx([a, cond && b], c)` composes the same as `cx(a, cond && b, c)`.
8
+ */
9
+ export declare function cx(...inputs: ClassInput[]): StyleResult;
10
+ export declare function createCss<const T extends ThemeConfig>(theme?: T): CssInstance<T>;
11
+ /** Themeless css() — full property/variant typing, no tokens or screens. */
12
+ export declare const css: (style: Style<object>) => StyleResult;
13
+ /** Themeless variants() recipe helper. */
14
+ export declare const variants: <const V extends VariantDefinitions<object>>(config: VariantsConfig<object, V>) => VariantsFn<V>;
15
+ /** Themeless keyframes() helper. */
16
+ export declare const keyframes: (frames: KeyframeFrames<object>) => string;
17
+ /** Themeless globalStyle() helper. */
18
+ export declare const globalStyle: (selector: string, style: FlatStyle<object>) => void;
19
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/style/css.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACX,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EAEd,KAAK,EACL,WAAW,EACX,WAAW,EACX,kBAAkB,EAElB,cAAc,EACd,UAAU,EACV,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,UAAU,GACV,MAAM,mBAAmB,CAAC;AAiJ3B;;;;;GAKG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAMvD;AAKD,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,GAAE,CAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CA2NzF;AAQD,4EAA4E;AAC5E,eAAO,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,WAAiC,CAAC;AAC9E,0CAA0C;AAC1C,eAAO,MAAM,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EACjE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,KAC7B,UAAU,CAAC,CAAC,CAA4B,CAAC;AAC9C,oCAAoC;AACpC,eAAO,MAAM,SAAS,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,MAAkC,CAAC;AAC/F,sCAAsC;AACtC,eAAO,MAAM,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,IAAkC,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared atomic-CSS engine state.
3
+ *
4
+ * One stylesheet, one rule registry, shared by every `createCss` instance so
5
+ * identical declarations dedupe globally and cascade order stays deterministic:
6
+ * base rules first (insertion order), then one grouping rule per at-rule query
7
+ * in registration order (theme `screens` order).
8
+ *
9
+ * Browser: rules are injected through CSSOM with O(1) appends — no rescans.
10
+ * SSR: rules accumulate in the registry; `getCssText()` serializes them.
11
+ */
12
+ type SSRCollector = (rule: string) => void;
13
+ export declare function setSSRCollector(fn: SSRCollector | null): void;
14
+ /** Pre-register at-rule queries so their cascade order follows theme order. */
15
+ export declare function registerQueries(queries: Iterable<string>): void;
16
+ /**
17
+ * Order-independent 53-bit content hash (two interleaved FNV-1a style passes).
18
+ * Class names must match between server and client for SSR hydration, so a
19
+ * counter is not an option; 53 bits keeps collision odds negligible (~1e-5 at
20
+ * 10k unique declarations).
21
+ */
22
+ export declare function hash(input: string): string;
23
+ /** One class per (query, selector-suffix, declaration) — the atomic core. */
24
+ export declare function atom(query: string | undefined, suffix: string, property: string, value: string): string;
25
+ /** Conflict key for a generated class — lets cx() resolve overrides exactly. */
26
+ export declare function conflictKeyOf(className: string): string | undefined;
27
+ /** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */
28
+ export declare function addRawRule(dedupeKey: string, rule: string): void;
29
+ /** All generated CSS — base rules first, then at-rule groups in registration order. */
30
+ export declare function getCssText(): string;
31
+ /** Clear all engine state (test helper). Removes the injected style element. */
32
+ export declare function resetStyles(): void;
33
+ export {};
34
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/style/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAG3C,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE7D;AAwBD,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAI/D;AA0FD;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS1C;AAED,6EAA6E;AAC7E,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAavG;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAOhE;AAED,uFAAuF;AACvF,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAED,gFAAgF;AAChF,wBAAgB,WAAW,IAAI,IAAI,CAclC"}
@@ -0,0 +1,3 @@
1
+ export { createCss, css, cx, variants, keyframes, globalStyle, type ClassInput, type CssInstance, type CSSProperties, type FlatStyle, type KeyframeFrames, type KeyframeStop, type Size, type Style, type StyleResult, type ThemeConfig, type VariantDefinitions, type VariantProps, type VariantsConfig, type VariantsFn, } from "./css";
2
+ export { getCssText, resetStyles, setSSRCollector } from "./engine";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,SAAS,EACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,UAAU,GACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { UpdateScope } from "./scope";
2
+ export declare function updateConditionalElements(scope?: UpdateScope): void;
3
+ //# sourceMappingURL=conditional.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditional.d.ts","sourceRoot":"","sources":["../../src/update/conditional.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAoD3C,wBAAgB,yBAAyB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAiBnE"}
@@ -0,0 +1,45 @@
1
+ import type { UpdateScope } from "./scope";
2
+ import type { AttributeResolver } from "./registry";
3
+ /**
4
+ * Registers a reactive attribute resolver for an element.
5
+ *
6
+ * The resolver will be called whenever reactive updates run (e.g. via `update()`),
7
+ * or when an `"update"` event is dispatched on the element (or a descendant),
8
+ * allowing attributes to reactively update based on application state.
9
+ *
10
+ * @param element - The DOM element to make reactive
11
+ * @param key - The attribute name being made reactive (e.g., 'class', 'style', 'disabled')
12
+ * @param resolver - Function that returns the new attribute value
13
+ * @param applyValue - Callback that applies the resolved value to the element
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const isActive = signal(false);
18
+ * const button = document.createElement('button');
19
+ * registerAttributeResolver(
20
+ * button,
21
+ * 'class',
22
+ * () => isActive.value ? 'active' : 'inactive',
23
+ * (value) => button.className = String(value)
24
+ * );
25
+ * ```
26
+ */
27
+ export declare function registerAttributeResolver<TTagName extends ElementTagName>(element: ExpandedElement<TTagName>, key: string, resolver: AttributeResolver, applyValue: (value: unknown) => void): void;
28
+ /**
29
+ * Updates all registered reactive elements by re-evaluating their attribute resolvers.
30
+ *
31
+ * Iterates through all reactive elements and triggers their registered attribute resolvers
32
+ * to update. Automatically cleans up disconnected elements and their event listeners.
33
+ *
34
+ * This function should be called after state changes to synchronize element attributes
35
+ * with application state.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // After updating application state
40
+ * isActive.value = true;
41
+ * notifyReactiveElements(); // All reactive attributes update
42
+ * ```
43
+ */
44
+ export declare function notifyReactiveElements(scope?: UpdateScope): void;
45
+ //# sourceMappingURL=reactive-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactive-attributes.d.ts","sourceRoot":"","sources":["../../src/update/reactive-attributes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAgD,MAAM,YAAY,CAAC;AA8ElG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,SAAS,cAAc,EACvE,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACnC,IAAI,CAkBN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CA6BhE"}
@@ -0,0 +1,38 @@
1
+ import type { UpdateScope } from "./scope";
2
+ import type { TextResolver } from "./registry";
3
+ /**
4
+ * Creates a reactive text node that automatically updates when its resolver function changes.
5
+ *
6
+ * The text node will be registered for reactive updates and its content will be synchronized
7
+ * whenever notifyReactiveTextNodes() is called.
8
+ *
9
+ * @param resolver - Function that returns the text content (string, number, boolean, etc.)
10
+ * @param preEvaluated - Optional pre-evaluated value to avoid calling resolver immediately
11
+ * @returns A Text node that will reactively update its content
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const count = signal(0);
16
+ * const textNode = createReactiveTextNode(() => `Count: ${count.value}`);
17
+ * // Later, when count changes and notifyReactiveTextNodes() is called,
18
+ * // the text content automatically updates
19
+ * ```
20
+ */
21
+ export declare function createReactiveTextNode(resolver: TextResolver, preEvaluated?: unknown): Text | DocumentFragment;
22
+ /**
23
+ * Updates all registered reactive text nodes.
24
+ *
25
+ * Iterates through all reactive text nodes, re-evaluates their resolver functions,
26
+ * and updates their content if it has changed. Automatically cleans up disconnected nodes.
27
+ *
28
+ * This function should be called after state changes to synchronize the DOM with application state.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * // After updating application state
33
+ * count.value++;
34
+ * notifyReactiveTextNodes(); // All reactive text nodes update
35
+ * ```
36
+ */
37
+ export declare function notifyReactiveTextNodes(scope?: UpdateScope): void;
38
+ //# sourceMappingURL=reactive-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactive-text.d.ts","sourceRoot":"","sources":["../../src/update/reactive-text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAgC9G;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CA2CjE"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Shared types and registries for reactive nodes.
3
+ * Single source of truth — imported by reactiveText.ts and reactiveAttributes.ts.
4
+ *
5
+ * Registry structure: the iteration sets only hold WeakRefs; the actual info
6
+ * records live in WeakMaps keyed by the node. Info records may strongly
7
+ * reference the node (e.g. attribute applyValue closures capture the
8
+ * element), so storing them in a strongly-held map would pin the node in
9
+ * memory forever. With WeakMap storage the whole record is collectible as
10
+ * soon as the node is unreachable, and the FinalizationRegistry prunes the
11
+ * leftover WeakRef from the iteration set. The notify passes also prune
12
+ * dead/disconnected entries as they iterate.
13
+ */
14
+ export type TextResolver = () => Primitive;
15
+ export interface ReactiveTextNodeInfo {
16
+ resolver: TextResolver;
17
+ lastValue: string;
18
+ }
19
+ export type AttributeResolver = () => unknown;
20
+ export interface AttributeResolverRecord {
21
+ resolver: AttributeResolver;
22
+ applyValue: (value: unknown) => void;
23
+ lastValue: unknown;
24
+ }
25
+ export interface ReactiveElementInfo {
26
+ attributeResolvers: Map<string, AttributeResolverRecord>;
27
+ }
28
+ /**
29
+ * Iteration set of weak references to reactive text nodes.
30
+ */
31
+ export declare const reactiveTextNodes: Set<WeakRef<Text>>;
32
+ /**
33
+ * WeakMap for O(1) lookups of reactive text node info by node reference.
34
+ */
35
+ export declare const reactiveTextNodesByNode: WeakMap<Text, {
36
+ ref: WeakRef<Text>;
37
+ info: ReactiveTextNodeInfo;
38
+ }>;
39
+ /**
40
+ * Iteration set of weak references to reactive elements.
41
+ */
42
+ export declare const reactiveElements: Set<WeakRef<Element>>;
43
+ /**
44
+ * WeakMap for O(1) lookups of reactive element info by element reference.
45
+ */
46
+ export declare const reactiveElementsByNode: WeakMap<Element, {
47
+ ref: WeakRef<Element>;
48
+ info: ReactiveElementInfo;
49
+ }>;
50
+ /**
51
+ * Registers a reactive text node in both lookup structures.
52
+ */
53
+ export declare function registerReactiveTextNode(node: Text, info: ReactiveTextNodeInfo): void;
54
+ /**
55
+ * Registers a reactive element in both lookup structures.
56
+ */
57
+ export declare function registerReactiveElement(element: Element, info: ReactiveElementInfo): void;
58
+ /**
59
+ * Removes a reactive text node's WeakRef entry from the iteration set.
60
+ */
61
+ export declare function removeReactiveTextNodeRef(ref: WeakRef<Text>): void;
62
+ /**
63
+ * Removes a reactive element's WeakRef entry from the iteration set.
64
+ */
65
+ export declare function removeReactiveElementRef(ref: WeakRef<Element>): void;
66
+ /**
67
+ * Manually removes reactive text node info for a specific text node.
68
+ * This should be called when a text node is removed from the DOM to prevent memory leaks.
69
+ */
70
+ export declare function cleanupReactiveTextNode(node: Text): void;
71
+ /**
72
+ * Manually removes reactive element info for a specific element.
73
+ * This should be called when an element is removed from the DOM to prevent memory leaks.
74
+ */
75
+ export declare function cleanupReactiveElement(element: Element): void;
76
+ export interface ConditionalInfo<TTagName extends ElementTagName = ElementTagName> {
77
+ condition: () => boolean;
78
+ tagName: TTagName;
79
+ modifiers: Array<NodeMod<TTagName> | NodeModFn<TTagName>>;
80
+ isSvg: boolean;
81
+ }
82
+ /**
83
+ * Attach conditional info to a node and register it.
84
+ */
85
+ export declare function storeConditionalInfo<TTagName extends ElementTagName>(node: Node, info: ConditionalInfo<TTagName>): void;
86
+ /**
87
+ * Explicit unregister helper (optional use on teardown if needed).
88
+ * O(1) via reverse lookup WeakMap.
89
+ */
90
+ export declare function unregisterConditionalNode(node: Node): void;
91
+ /**
92
+ * Returns an array of currently tracked conditional nodes that are still alive.
93
+ * Automatically cleans up garbage-collected nodes.
94
+ */
95
+ export declare function getActiveConditionalNodes(): Node[];
96
+ export declare function getConditionalInfo(node: Node): ConditionalInfo<ElementTagName> | null;
97
+ //# sourceMappingURL=registry.d.ts.map