@vielzeug/craftit 2.0.1 → 2.1.0

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 (400) hide show
  1. package/README.md +71 -53
  2. package/dist/component.cjs +2 -0
  3. package/dist/component.cjs.map +1 -0
  4. package/dist/component.d.ts +39 -0
  5. package/dist/component.d.ts.map +1 -0
  6. package/dist/component.js +2 -0
  7. package/dist/component.js.map +1 -0
  8. package/dist/controls/a11y-control.cjs +2 -0
  9. package/dist/controls/a11y-control.cjs.map +1 -0
  10. package/dist/controls/a11y-control.d.ts +16 -0
  11. package/dist/controls/a11y-control.d.ts.map +1 -0
  12. package/dist/controls/a11y-control.js +2 -0
  13. package/dist/controls/a11y-control.js.map +1 -0
  14. package/dist/controls/checkable-control.cjs +2 -0
  15. package/dist/controls/checkable-control.cjs.map +1 -0
  16. package/dist/controls/checkable-control.d.ts +15 -0
  17. package/dist/controls/checkable-control.d.ts.map +1 -0
  18. package/dist/controls/checkable-control.js +2 -0
  19. package/dist/controls/checkable-control.js.map +1 -0
  20. package/dist/controls/field-control.cjs +2 -0
  21. package/dist/controls/field-control.cjs.map +1 -0
  22. package/dist/controls/field-control.d.ts +156 -0
  23. package/dist/controls/field-control.d.ts.map +1 -0
  24. package/dist/controls/field-control.js +2 -0
  25. package/dist/controls/field-control.js.map +1 -0
  26. package/dist/controls/index.d.ts +10 -0
  27. package/dist/controls/index.d.ts.map +1 -0
  28. package/dist/controls/internal/control-state.cjs +2 -0
  29. package/dist/controls/internal/control-state.cjs.map +1 -0
  30. package/dist/controls/internal/control-state.d.ts +19 -0
  31. package/dist/controls/internal/control-state.d.ts.map +1 -0
  32. package/dist/controls/internal/control-state.js +2 -0
  33. package/dist/controls/internal/control-state.js.map +1 -0
  34. package/dist/controls/internal/keyboard-utils.cjs +2 -0
  35. package/dist/controls/internal/keyboard-utils.cjs.map +1 -0
  36. package/dist/controls/internal/keyboard-utils.d.ts +7 -0
  37. package/dist/controls/internal/keyboard-utils.d.ts.map +1 -0
  38. package/dist/controls/internal/keyboard-utils.js +2 -0
  39. package/dist/controls/internal/keyboard-utils.js.map +1 -0
  40. package/dist/controls/internal/number-utils.cjs +2 -0
  41. package/dist/controls/internal/number-utils.cjs.map +1 -0
  42. package/dist/controls/internal/number-utils.d.ts +6 -0
  43. package/dist/controls/internal/number-utils.d.ts.map +1 -0
  44. package/dist/controls/internal/number-utils.js +2 -0
  45. package/dist/controls/internal/number-utils.js.map +1 -0
  46. package/dist/controls/internal/validation-utils.cjs +2 -0
  47. package/dist/controls/internal/validation-utils.cjs.map +1 -0
  48. package/dist/controls/internal/validation-utils.d.ts +13 -0
  49. package/dist/controls/internal/validation-utils.d.ts.map +1 -0
  50. package/dist/controls/internal/validation-utils.js +2 -0
  51. package/dist/controls/internal/validation-utils.js.map +1 -0
  52. package/dist/controls/list-control.cjs +2 -0
  53. package/dist/controls/list-control.cjs.map +1 -0
  54. package/dist/controls/list-control.d.ts +21 -0
  55. package/dist/controls/list-control.d.ts.map +1 -0
  56. package/dist/controls/list-control.js +2 -0
  57. package/dist/controls/list-control.js.map +1 -0
  58. package/dist/controls/list-key-control.cjs +2 -0
  59. package/dist/controls/list-key-control.cjs.map +1 -0
  60. package/dist/controls/list-key-control.d.ts +14 -0
  61. package/dist/controls/list-key-control.d.ts.map +1 -0
  62. package/dist/controls/list-key-control.js +2 -0
  63. package/dist/controls/list-key-control.js.map +1 -0
  64. package/dist/controls/overlay-control.cjs +2 -0
  65. package/dist/controls/overlay-control.cjs.map +1 -0
  66. package/dist/controls/overlay-control.d.ts +37 -0
  67. package/dist/controls/overlay-control.d.ts.map +1 -0
  68. package/dist/controls/overlay-control.js +2 -0
  69. package/dist/controls/overlay-control.js.map +1 -0
  70. package/dist/controls/press-control.cjs +2 -0
  71. package/dist/controls/press-control.cjs.map +1 -0
  72. package/dist/controls/press-control.d.ts +12 -0
  73. package/dist/controls/press-control.d.ts.map +1 -0
  74. package/dist/controls/press-control.js +2 -0
  75. package/dist/controls/press-control.js.map +1 -0
  76. package/dist/controls/slider-control.cjs +2 -0
  77. package/dist/controls/slider-control.cjs.map +1 -0
  78. package/dist/controls/slider-control.d.ts +19 -0
  79. package/dist/controls/slider-control.d.ts.map +1 -0
  80. package/dist/controls/slider-control.js +2 -0
  81. package/dist/controls/slider-control.js.map +1 -0
  82. package/dist/controls/spinner-control.cjs +2 -0
  83. package/dist/controls/spinner-control.cjs.map +1 -0
  84. package/dist/controls/spinner-control.d.ts +18 -0
  85. package/dist/controls/spinner-control.d.ts.map +1 -0
  86. package/dist/controls/spinner-control.js +2 -0
  87. package/dist/controls/spinner-control.js.map +1 -0
  88. package/dist/controls.cjs +1 -0
  89. package/dist/controls.js +1 -0
  90. package/dist/craftit.cjs +1 -1
  91. package/dist/craftit.cjs.map +1 -1
  92. package/dist/craftit.js +1 -1
  93. package/dist/craftit.js.map +1 -1
  94. package/dist/directives/attr.cjs +1 -1
  95. package/dist/directives/attr.cjs.map +1 -1
  96. package/dist/directives/attr.d.ts +4 -6
  97. package/dist/directives/attr.d.ts.map +1 -1
  98. package/dist/directives/attr.js +1 -1
  99. package/dist/directives/attr.js.map +1 -1
  100. package/dist/directives/bind.cjs +1 -1
  101. package/dist/directives/bind.cjs.map +1 -1
  102. package/dist/directives/bind.d.ts +20 -12
  103. package/dist/directives/bind.d.ts.map +1 -1
  104. package/dist/directives/bind.js +1 -1
  105. package/dist/directives/bind.js.map +1 -1
  106. package/dist/directives/choose.cjs +1 -1
  107. package/dist/directives/choose.cjs.map +1 -1
  108. package/dist/directives/choose.d.ts +17 -12
  109. package/dist/directives/choose.d.ts.map +1 -1
  110. package/dist/directives/choose.js +1 -1
  111. package/dist/directives/choose.js.map +1 -1
  112. package/dist/directives/each.cjs +1 -1
  113. package/dist/directives/each.cjs.map +1 -1
  114. package/dist/directives/each.d.ts +19 -31
  115. package/dist/directives/each.d.ts.map +1 -1
  116. package/dist/directives/each.js +1 -1
  117. package/dist/directives/each.js.map +1 -1
  118. package/dist/directives/index.d.ts +1 -2
  119. package/dist/directives/index.d.ts.map +1 -1
  120. package/dist/directives/memo.cjs +1 -1
  121. package/dist/directives/memo.cjs.map +1 -1
  122. package/dist/directives/memo.d.ts +8 -4
  123. package/dist/directives/memo.d.ts.map +1 -1
  124. package/dist/directives/memo.js +1 -1
  125. package/dist/directives/memo.js.map +1 -1
  126. package/dist/directives/on.cjs +1 -1
  127. package/dist/directives/on.cjs.map +1 -1
  128. package/dist/directives/on.d.ts +1 -1
  129. package/dist/directives/on.d.ts.map +1 -1
  130. package/dist/directives/on.js +1 -1
  131. package/dist/directives/on.js.map +1 -1
  132. package/dist/directives/raw.cjs +1 -1
  133. package/dist/directives/raw.cjs.map +1 -1
  134. package/dist/directives/raw.d.ts +1 -1
  135. package/dist/directives/raw.d.ts.map +1 -1
  136. package/dist/directives/raw.js +1 -1
  137. package/dist/directives/raw.js.map +1 -1
  138. package/dist/directives/spread.cjs +1 -1
  139. package/dist/directives/spread.cjs.map +1 -1
  140. package/dist/directives/spread.d.ts +1 -1
  141. package/dist/directives/spread.d.ts.map +1 -1
  142. package/dist/directives/spread.js +1 -1
  143. package/dist/directives/spread.js.map +1 -1
  144. package/dist/directives/style.cjs +1 -1
  145. package/dist/directives/style.cjs.map +1 -1
  146. package/dist/directives/style.js +1 -1
  147. package/dist/directives/style.js.map +1 -1
  148. package/dist/directives/until.cjs.map +1 -1
  149. package/dist/directives/until.d.ts +1 -1
  150. package/dist/directives/until.d.ts.map +1 -1
  151. package/dist/directives/until.js.map +1 -1
  152. package/dist/directives/when.cjs +1 -1
  153. package/dist/directives/when.cjs.map +1 -1
  154. package/dist/directives/when.d.ts +11 -5
  155. package/dist/directives/when.d.ts.map +1 -1
  156. package/dist/directives/when.js +1 -1
  157. package/dist/directives/when.js.map +1 -1
  158. package/dist/directives.cjs +1 -0
  159. package/dist/directives.js +1 -0
  160. package/dist/form.cjs +2 -0
  161. package/dist/form.cjs.map +1 -0
  162. package/dist/form.d.ts +29 -0
  163. package/dist/form.d.ts.map +1 -0
  164. package/dist/form.js +2 -0
  165. package/dist/form.js.map +1 -0
  166. package/dist/host.cjs +2 -0
  167. package/dist/host.cjs.map +1 -0
  168. package/dist/host.d.ts +75 -0
  169. package/dist/host.d.ts.map +1 -0
  170. package/dist/host.js +2 -0
  171. package/dist/host.js.map +1 -0
  172. package/dist/index.cjs +1 -1
  173. package/dist/index.d.ts +8 -9
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +1 -1
  176. package/dist/internal.cjs +2 -0
  177. package/dist/internal.cjs.map +1 -0
  178. package/dist/internal.d.ts +171 -0
  179. package/dist/internal.d.ts.map +1 -0
  180. package/dist/internal.js +2 -0
  181. package/dist/internal.js.map +1 -0
  182. package/dist/observers/index.d.ts +4 -0
  183. package/dist/observers/index.d.ts.map +1 -0
  184. package/dist/observers/intersection-observe.cjs +2 -0
  185. package/dist/observers/intersection-observe.cjs.map +1 -0
  186. package/dist/observers/intersection-observe.d.ts +9 -0
  187. package/dist/observers/intersection-observe.d.ts.map +1 -0
  188. package/dist/observers/intersection-observe.js +2 -0
  189. package/dist/observers/intersection-observe.js.map +1 -0
  190. package/dist/observers/media-observe.cjs +2 -0
  191. package/dist/observers/media-observe.cjs.map +1 -0
  192. package/dist/observers/media-observe.d.ts +8 -0
  193. package/dist/observers/media-observe.d.ts.map +1 -0
  194. package/dist/observers/media-observe.js +2 -0
  195. package/dist/observers/media-observe.js.map +1 -0
  196. package/dist/observers/resize-observe.cjs +2 -0
  197. package/dist/observers/resize-observe.cjs.map +1 -0
  198. package/dist/observers/resize-observe.d.ts +11 -0
  199. package/dist/observers/resize-observe.d.ts.map +1 -0
  200. package/dist/observers/resize-observe.js +2 -0
  201. package/dist/observers/resize-observe.js.map +1 -0
  202. package/dist/observers.cjs +1 -0
  203. package/dist/observers.js +1 -0
  204. package/dist/props.cjs +2 -0
  205. package/dist/props.cjs.map +1 -0
  206. package/dist/props.d.ts +52 -0
  207. package/dist/props.d.ts.map +1 -0
  208. package/dist/props.js +2 -0
  209. package/dist/props.js.map +1 -0
  210. package/dist/registration.cjs +2 -0
  211. package/dist/registration.cjs.map +1 -0
  212. package/dist/registration.d.ts +18 -0
  213. package/dist/registration.d.ts.map +1 -0
  214. package/dist/registration.js +2 -0
  215. package/dist/registration.js.map +1 -0
  216. package/dist/runtime-bindings.cjs +2 -0
  217. package/dist/runtime-bindings.cjs.map +1 -0
  218. package/dist/runtime-bindings.d.ts.map +1 -0
  219. package/dist/runtime-bindings.js +2 -0
  220. package/dist/runtime-bindings.js.map +1 -0
  221. package/dist/runtime-core.cjs +2 -0
  222. package/dist/runtime-core.cjs.map +1 -0
  223. package/dist/runtime-core.d.ts +21 -0
  224. package/dist/runtime-core.d.ts.map +1 -0
  225. package/dist/runtime-core.js +2 -0
  226. package/dist/runtime-core.js.map +1 -0
  227. package/dist/runtime-lifecycle.cjs +2 -0
  228. package/dist/runtime-lifecycle.cjs.map +1 -0
  229. package/dist/runtime-lifecycle.d.ts +24 -0
  230. package/dist/runtime-lifecycle.d.ts.map +1 -0
  231. package/dist/runtime-lifecycle.js +2 -0
  232. package/dist/runtime-lifecycle.js.map +1 -0
  233. package/dist/runtime.cjs +2 -0
  234. package/dist/runtime.cjs.map +1 -0
  235. package/dist/runtime.d.ts +21 -0
  236. package/dist/runtime.d.ts.map +1 -0
  237. package/dist/runtime.js +2 -0
  238. package/dist/runtime.js.map +1 -0
  239. package/dist/template-bindings.cjs +2 -0
  240. package/dist/template-bindings.cjs.map +1 -0
  241. package/dist/{core/template-bindings.d.ts → template-bindings.d.ts} +4 -1
  242. package/dist/template-bindings.d.ts.map +1 -0
  243. package/dist/template-bindings.js +2 -0
  244. package/dist/template-bindings.js.map +1 -0
  245. package/dist/template-compiler.cjs +2 -0
  246. package/dist/template-compiler.cjs.map +1 -0
  247. package/dist/{core/template-compiler.d.ts → template-compiler.d.ts} +1 -2
  248. package/dist/template-compiler.d.ts.map +1 -0
  249. package/dist/template-compiler.js +2 -0
  250. package/dist/template-compiler.js.map +1 -0
  251. package/dist/template-dom.cjs +2 -0
  252. package/dist/{core/template-dom.js.map → template-dom.cjs.map} +1 -1
  253. package/dist/template-dom.d.ts.map +1 -0
  254. package/dist/template-dom.js +2 -0
  255. package/dist/template-dom.js.map +1 -0
  256. package/dist/template-html.cjs +2 -0
  257. package/dist/template-html.cjs.map +1 -0
  258. package/dist/{core/template-html.d.ts → template-html.d.ts} +1 -4
  259. package/dist/template-html.d.ts.map +1 -0
  260. package/dist/template-html.js +2 -0
  261. package/dist/template-html.js.map +1 -0
  262. package/dist/template.cjs +2 -0
  263. package/dist/template.cjs.map +1 -0
  264. package/dist/{core/template.d.ts → template.d.ts} +2 -3
  265. package/dist/template.d.ts.map +1 -0
  266. package/dist/template.js +2 -0
  267. package/dist/template.js.map +1 -0
  268. package/dist/testing/index.d.ts +2 -0
  269. package/dist/testing/index.d.ts.map +1 -0
  270. package/dist/testing/testing.cjs +2 -0
  271. package/dist/testing/testing.cjs.map +1 -0
  272. package/dist/{test/test.d.ts → testing/testing.d.ts} +8 -8
  273. package/dist/testing/testing.d.ts.map +1 -0
  274. package/dist/testing/testing.js +2 -0
  275. package/dist/testing/testing.js.map +1 -0
  276. package/dist/testing.cjs +1 -0
  277. package/dist/testing.js +1 -0
  278. package/package.json +19 -14
  279. package/dist/core/component.cjs +0 -2
  280. package/dist/core/component.cjs.map +0 -1
  281. package/dist/core/component.d.ts +0 -172
  282. package/dist/core/component.d.ts.map +0 -1
  283. package/dist/core/component.js +0 -2
  284. package/dist/core/component.js.map +0 -1
  285. package/dist/core/host.cjs +0 -2
  286. package/dist/core/host.cjs.map +0 -1
  287. package/dist/core/host.d.ts +0 -77
  288. package/dist/core/host.d.ts.map +0 -1
  289. package/dist/core/host.js +0 -2
  290. package/dist/core/host.js.map +0 -1
  291. package/dist/core/internal.cjs +0 -2
  292. package/dist/core/internal.cjs.map +0 -1
  293. package/dist/core/internal.d.ts +0 -107
  294. package/dist/core/internal.d.ts.map +0 -1
  295. package/dist/core/internal.js +0 -2
  296. package/dist/core/internal.js.map +0 -1
  297. package/dist/core/runtime-bindings.cjs +0 -2
  298. package/dist/core/runtime-bindings.cjs.map +0 -1
  299. package/dist/core/runtime-bindings.d.ts.map +0 -1
  300. package/dist/core/runtime-bindings.js +0 -2
  301. package/dist/core/runtime-bindings.js.map +0 -1
  302. package/dist/core/runtime-lifecycle.cjs +0 -2
  303. package/dist/core/runtime-lifecycle.cjs.map +0 -1
  304. package/dist/core/runtime-lifecycle.d.ts +0 -116
  305. package/dist/core/runtime-lifecycle.d.ts.map +0 -1
  306. package/dist/core/runtime-lifecycle.js +0 -2
  307. package/dist/core/runtime-lifecycle.js.map +0 -1
  308. package/dist/core/runtime.cjs +0 -1
  309. package/dist/core/runtime.d.ts +0 -3
  310. package/dist/core/runtime.d.ts.map +0 -1
  311. package/dist/core/runtime.js +0 -1
  312. package/dist/core/template-bindings.cjs +0 -2
  313. package/dist/core/template-bindings.cjs.map +0 -1
  314. package/dist/core/template-bindings.d.ts.map +0 -1
  315. package/dist/core/template-bindings.js +0 -2
  316. package/dist/core/template-bindings.js.map +0 -1
  317. package/dist/core/template-compiler.cjs +0 -2
  318. package/dist/core/template-compiler.cjs.map +0 -1
  319. package/dist/core/template-compiler.d.ts.map +0 -1
  320. package/dist/core/template-compiler.js +0 -2
  321. package/dist/core/template-compiler.js.map +0 -1
  322. package/dist/core/template-dom.cjs +0 -2
  323. package/dist/core/template-dom.cjs.map +0 -1
  324. package/dist/core/template-dom.d.ts.map +0 -1
  325. package/dist/core/template-dom.js +0 -2
  326. package/dist/core/template-html.cjs +0 -2
  327. package/dist/core/template-html.cjs.map +0 -1
  328. package/dist/core/template-html.d.ts.map +0 -1
  329. package/dist/core/template-html.js +0 -2
  330. package/dist/core/template-html.js.map +0 -1
  331. package/dist/core/template.cjs +0 -2
  332. package/dist/core/template.cjs.map +0 -1
  333. package/dist/core/template.d.ts.map +0 -1
  334. package/dist/core/template.js +0 -2
  335. package/dist/core/template.js.map +0 -1
  336. package/dist/core/utilities.cjs +0 -2
  337. package/dist/core/utilities.cjs.map +0 -1
  338. package/dist/core/utilities.d.ts +0 -68
  339. package/dist/core/utilities.d.ts.map +0 -1
  340. package/dist/core/utilities.js +0 -2
  341. package/dist/core/utilities.js.map +0 -1
  342. package/dist/directives/index.cjs +0 -1
  343. package/dist/directives/index.js +0 -1
  344. package/dist/directives/match.cjs +0 -2
  345. package/dist/directives/match.cjs.map +0 -1
  346. package/dist/directives/match.d.ts +0 -31
  347. package/dist/directives/match.d.ts.map +0 -1
  348. package/dist/directives/match.js +0 -2
  349. package/dist/directives/match.js.map +0 -1
  350. package/dist/labs/a11y.cjs +0 -2
  351. package/dist/labs/a11y.cjs.map +0 -1
  352. package/dist/labs/a11y.d.ts +0 -61
  353. package/dist/labs/a11y.d.ts.map +0 -1
  354. package/dist/labs/a11y.js +0 -2
  355. package/dist/labs/a11y.js.map +0 -1
  356. package/dist/labs/index.d.ts +0 -8
  357. package/dist/labs/index.d.ts.map +0 -1
  358. package/dist/labs/list.cjs +0 -2
  359. package/dist/labs/list.cjs.map +0 -1
  360. package/dist/labs/list.d.ts +0 -26
  361. package/dist/labs/list.d.ts.map +0 -1
  362. package/dist/labs/list.js +0 -2
  363. package/dist/labs/list.js.map +0 -1
  364. package/dist/labs/observers.cjs +0 -2
  365. package/dist/labs/observers.cjs.map +0 -1
  366. package/dist/labs/observers.d.ts +0 -42
  367. package/dist/labs/observers.d.ts.map +0 -1
  368. package/dist/labs/observers.js +0 -2
  369. package/dist/labs/observers.js.map +0 -1
  370. package/dist/labs/overlay.cjs +0 -2
  371. package/dist/labs/overlay.cjs.map +0 -1
  372. package/dist/labs/overlay.d.ts +0 -35
  373. package/dist/labs/overlay.d.ts.map +0 -1
  374. package/dist/labs/overlay.js +0 -2
  375. package/dist/labs/overlay.js.map +0 -1
  376. package/dist/labs/selectable.cjs +0 -2
  377. package/dist/labs/selectable.cjs.map +0 -1
  378. package/dist/labs/selectable.d.ts +0 -70
  379. package/dist/labs/selectable.d.ts.map +0 -1
  380. package/dist/labs/selectable.js +0 -2
  381. package/dist/labs/selectable.js.map +0 -1
  382. package/dist/labs/selection.cjs +0 -2
  383. package/dist/labs/selection.cjs.map +0 -1
  384. package/dist/labs/selection.d.ts +0 -68
  385. package/dist/labs/selection.d.ts.map +0 -1
  386. package/dist/labs/selection.js +0 -2
  387. package/dist/labs/selection.js.map +0 -1
  388. package/dist/labs.cjs +0 -1
  389. package/dist/labs.js +0 -1
  390. package/dist/test/index.d.ts +0 -2
  391. package/dist/test/index.d.ts.map +0 -1
  392. package/dist/test/test.cjs +0 -2
  393. package/dist/test/test.cjs.map +0 -1
  394. package/dist/test/test.d.ts.map +0 -1
  395. package/dist/test/test.js +0 -2
  396. package/dist/test/test.js.map +0 -1
  397. package/dist/test.cjs +0 -1
  398. package/dist/test.js +0 -1
  399. /package/dist/{core/runtime-bindings.d.ts → runtime-bindings.d.ts} +0 -0
  400. /package/dist/{core/template-dom.d.ts → template-dom.d.ts} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-compiler.cjs","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n isHtmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: resolveDirectiveValue(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-compiler.d.ts","sourceRoot":"","sources":["../../src/core/template-compiler.ts"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAsPpB,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,oBAAoB,EAC7B,QAAQ,OAAO,EAAE,EACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,KAC/B,UA2LF,CAAC"}
@@ -1,2 +0,0 @@
1
- import{EACH_SIGNAL as e,htmlResult as t,isHtmlResult as n}from"./internal.js";import{escapeHtml as r}from"./utilities.js";import{createAttrBinding as i,createPropBinding as a}from"./template-bindings.js";import{computed as o,isSignal as s,signal as c}from"@vielzeug/stateit";var l=RegExp(`u="([^"]+)"`,`g`),u=e=>e.replace(/>\s+</g,`><`).trim(),d=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],f=new WeakMap,p=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},m=e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of d){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=p(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}},h=e=>{let t=f.get(e);return t||(t=m(e),f.set(e,t)),t},g=()=>{let e=0;return()=>String(e++)},_=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(l,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`<!--${r(t)}-->`)}},v=t=>typeof t!=`object`||!t||!(e in t)?null:t[e],y=e=>typeof e==`string`?r(e):e==null?``:n(e)?e.__html:r(String(e)),b=(e,t)=>{let r={bindings:[],html:``},i=c(r);return t(()=>{let t=e(),a=Array.isArray(t)?t:[t],o=g(),s=``,c=[];for(let e of a)if(n(e)){let t=_(e,o);s+=t.html,c.push(...t.bindings)}else s+=y(e);let l=c.length!==r.bindings.length||c.some((e,t)=>e!==r.bindings[t]);(s!==r.html||l)&&(r={bindings:c,html:s},i.value=r)}),{bindings:[],signal:i}},x=(e,t)=>{let r=v(e);if(r)return{keyed:!0,signal:r};if(typeof e==`function`&&!s(e)){let{signal:n}=b(e,t);return{keyed:!1,signal:n}}return s(e)&&n(e.value)?{keyed:!1,signal:o(()=>{let t=e.value;if(!n(t))return{bindings:[],html:y(t)};let r=_(t,g());return{bindings:r.bindings,html:r.html}})}:null},S=()=>{},C=(e,r,o)=>{let l=h(e),d=``,f=[],p=null,m=g(),v=e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`),b=e=>((!p||v(e))&&(p=m()),p),S=()=>{p=null};for(let e=0;e<l.slots.length;e++){let t=l.slots[e],u=r[e];if(t.kind===`event`){if(typeof u==`function`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({handler:u,modifiers:t.modifiers,name:t.name,type:`event`,uid:e})}else d+=t.raw;continue}if(t.kind===`ref`){if(u){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push({ref:u,type:`ref`,uid:e})}else d+=t.raw;continue}if(t.kind===`specialAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(i(t.mode,t.name,e,u));continue}if(t.kind===`prop`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(a(t.name,e,u));continue}if(t.kind===`plainAttr`){let e=b(t.prefix);d+=`${t.prefix} u="${e}"`,f.push(i(`attr`,t.name,e,u));continue}if(typeof u==`object`&&u&&(`mount`in u||`render`in u)){let e=`render`in u,r=e?m():b(t.raw);e?d+=`${t.raw}<!--${r}-->`:d+=`${t.raw} u="${r}"`;let i=u.mount?.bind(u);if(i&&f.push({apply:(e,t)=>{i(e,{registerCleanup:t})},type:`callback`,uid:r}),e){let e=u.render.bind(u),t={bindings:[],html:``},i=c(t);o(()=>{let r=e(),a=Array.isArray(r)?r:[r],o=g(),s=``,c=[];for(let e of a)if(n(e)){let t=_(e,o);s+=t.html,c.push(...t.bindings)}else s+=y(e);let l=c.length!==t.bindings.length||c.some((e,n)=>e!==t.bindings[n]);(s!==t.html||l)&&(t={bindings:c,html:s},i.value=t)}),f.push({keyed:!1,signal:i,type:`html`,uid:r})}continue}S();let p=x(u,o);if(p){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({keyed:p.keyed,signal:p.signal,type:`html`,uid:e});continue}if(Array.isArray(u)){let e=``;for(let t of u)if(n(t)){let n=_(t,m);e+=n.html,f.push(...n.bindings)}else e+=y(t);d+=t.raw+e;continue}if(s(u)){let e=m();d+=`${t.raw}<!--${e}-->`,f.push({signal:u,type:`text`,uid:e})}else if(n(u)){let e=_(u,m);d+=t.raw+e.html,f.push(...e.bindings)}else d+=t.raw+y(u)}return d+=l.tail,t(u(d),f)};export{C as compileTemplate,S as resetTemplateCompilerState};
2
- //# sourceMappingURL=template-compiler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-compiler.js","names":[],"sources":["../../src/core/template-compiler.ts"],"sourcesContent":["import { computed, isSignal, signal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport {\n CF_ID_ATTR,\n EACH_SIGNAL,\n htmlResult,\n isHtmlResult,\n type Binding,\n type Directive,\n type EventBinding,\n type HTMLResult,\n type Ref,\n type RefCallback,\n} from './internal';\nimport { createAttrBinding, createPropBinding } from './template-bindings';\nimport { escapeHtml } from './utilities';\n\nconst ATTR_ID_RE = new RegExp(`${CF_ID_ATTR}=\"([^\"]+)\"`, 'g');\n\nconst normalizeCompiledHtml = (html: string): string => html.replace(/>\\s+</g, '><').trim();\n\n// Slot patterns applied in priority order; first match wins\nconst SLOT_PATTERNS = [\n { kind: 'event' as const, regex: /\\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\\s*=\\s*[\"']?$/ },\n { kind: 'ref' as const, regex: /\\s+ref\\s*=\\s*[\"']?$/ },\n { kind: 'specialAttr' as const, regex: /\\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'prop' as const, regex: /\\.([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n { kind: 'plainAttr' as const, regex: /\\s+([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/ },\n] as const;\n\ntype CompiledTemplateSlot = {\n kind: (typeof SLOT_PATTERNS)[number]['kind'] | 'node';\n // For 'specialAttr' slots\n mode?: 'attr' | 'bool';\n modifiers?: EventBinding['modifiers'];\n // For 'event' slots\n name?: string;\n prefix: string;\n raw: string;\n};\n\ntype CompiledTemplatePlan = {\n slots: CompiledTemplateSlot[];\n tail: string;\n};\n\nconst templatePlanCache = new WeakMap<TemplateStringsArray, CompiledTemplatePlan>();\n\n/**\n * Parses event descriptor string into name and modifiers.\n * @example\n * parseEventDescriptor('click.stop.prevent') → { name: 'click', modifiers: { stop, prevent } }\n */\nconst parseEventDescriptor = (descriptor: string): { modifiers: EventBinding['modifiers']; name: string } => {\n const [name, ...rawModifiers] = descriptor.split('.');\n const modifiers: NonNullable<EventBinding['modifiers']> = {};\n\n for (const modifier of rawModifiers) {\n if (modifier === 'capture') modifiers.capture = true;\n else if (modifier === 'once') modifiers.once = true;\n else if (modifier === 'passive') modifiers.passive = true;\n else if (modifier === 'prevent') modifiers.prevent = true;\n else if (modifier === 'self') modifiers.self = true;\n else if (modifier === 'stop') modifiers.stop = true;\n }\n\n return { modifiers: Object.keys(modifiers).length ? modifiers : undefined, name };\n};\n\nconst buildTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n const slots: CompiledTemplateSlot[] = [];\n\n for (let i = 0; i < strings.length - 1; i++) {\n const str = strings[i];\n let matched = false;\n\n for (const pattern of SLOT_PATTERNS) {\n const m = pattern.regex.exec(str);\n\n if (!m) continue;\n\n const prefix = str.slice(0, -m[0].length);\n\n matched = true;\n\n if (pattern.kind === 'event') {\n const parsed = parseEventDescriptor(m[1]);\n\n slots.push({ kind: 'event', modifiers: parsed.modifiers, name: parsed.name, prefix, raw: str });\n } else if (pattern.kind === 'ref') {\n slots.push({ kind: 'ref', prefix, raw: str });\n } else if (pattern.kind === 'specialAttr') {\n slots.push({ kind: 'specialAttr', mode: m[1] === '?' ? 'bool' : 'attr', name: m[2], prefix, raw: str });\n } else if (pattern.kind === 'prop') {\n slots.push({ kind: 'prop', name: m[1], prefix, raw: str });\n } else if (pattern.kind === 'plainAttr') {\n slots.push({ kind: 'plainAttr', name: m[1], prefix, raw: str });\n }\n\n break; // first match wins\n }\n\n if (!matched) {\n slots.push({ kind: 'node', prefix: str, raw: str });\n }\n }\n\n return { slots, tail: strings[strings.length - 1] ?? '' };\n};\n\nconst getCompiledTemplatePlan = (strings: TemplateStringsArray): CompiledTemplatePlan => {\n let plan = templatePlanCache.get(strings);\n\n if (!plan) {\n plan = buildTemplatePlan(strings);\n templatePlanCache.set(strings, plan);\n }\n\n return plan;\n};\n\nconst createMarkerIdFactory = (): (() => string) => {\n let markerIndex = 0;\n\n return () => String(markerIndex++);\n};\n\nconst rekeyHtmlResult = (\n result: HTMLResult,\n getNextId: () => string,\n): {\n bindings: Binding[];\n html: string;\n} => {\n const idMap = new Map<string, string>();\n const getMappedId = (id: string): string => {\n const mapped = idMap.get(id);\n\n if (mapped) return mapped;\n\n const next = getNextId();\n\n idMap.set(id, next);\n\n return next;\n };\n\n return {\n bindings: result.__bindings.map((binding) => ({ ...binding, uid: getMappedId(binding.uid) }) as Binding),\n html: result.__html\n .replace(ATTR_ID_RE, (_, id: string) => `${CF_ID_ATTR}=\"${getMappedId(id)}\"`)\n .replace(/<!--(\\d+)-->/g, (_, id: string) => `<!--${getMappedId(id)}-->`),\n };\n};\n\nconst getEachSignalSource = (\n value: unknown,\n): ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n}> | null => {\n if (typeof value !== 'object' || value === null || !(EACH_SIGNAL in value)) return null;\n\n return (value as { [EACH_SIGNAL]: ReadonlySignal<{ bindings: Binding[]; html: string }> })[EACH_SIGNAL];\n};\n\nconst resolveDirectiveValue = (value: unknown): string => {\n if (typeof value === 'string') return escapeHtml(value);\n\n if (value == null) return '';\n\n if (isHtmlResult(value)) return value.__html;\n\n return escapeHtml(String(value));\n};\n\nconst renderHtmlItems = (\n getter: () => unknown,\n effect: (fn: () => void) => void,\n): { bindings: Binding[]; signal: Signal<any> } => {\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = getter();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n return { bindings: [], signal: fnSignal };\n};\n\nconst createHtmlWrapperSignal = (\n value: unknown,\n effect: (fn: () => void) => void,\n): {\n keyed: boolean;\n signal: ReadonlySignal<{\n bindings: Binding[];\n html: string;\n items?: Array<{ bindings: Binding[]; html: string }>;\n keys?: (string | number)[];\n }>;\n} | null => {\n const eachSignal = getEachSignalSource(value);\n\n if (eachSignal) {\n return { keyed: true, signal: eachSignal };\n }\n\n if (typeof value === 'function' && !isSignal(value)) {\n const { signal: sig } = renderHtmlItems(value as () => unknown, effect);\n\n return { keyed: false, signal: sig };\n }\n\n if (isSignal(value) && isHtmlResult(value.value)) {\n return {\n keyed: false,\n signal: computed(() => {\n const next = (value as ReadonlySignal<unknown>).value;\n\n if (!isHtmlResult(next)) {\n return { bindings: [], html: resolveDirectiveValue(next) };\n }\n\n const entry = rekeyHtmlResult(next, createMarkerIdFactory());\n\n return { bindings: entry.bindings, html: entry.html };\n }),\n };\n }\n\n return null;\n};\n\nexport const resetTemplateCompilerState = (): void => {\n // Marker IDs are deterministic per compiled template; no global state to reset.\n};\n\n/**\n * Compiles a tagged template into an HTMLResult with reactive bindings.\n *\n * Detects interpolation slots using regex patterns:\n * - `@event-name` → event listener binding\n * - `ref` → ref binding\n * - `:prop` or `?bool` → special attributes\n * - `.prop` → property binding\n * - plain attributes → attribute binding\n *\n * Rekeys nested HTMLResult bindings to avoid ID collisions.\n *\n * @param strings - Template string parts\n * @param values - Interpolated values (signals, functions, directives, primitives)\n * @param effect - Effect hook for reactive bindings\n * @returns HTMLResult with compiled HTML and bindings array\n *\n * @example\n * const name = signal('Alice');\n * const html = compileTemplate`<h1>${() => name.value}</h1>`;\n */\nexport const compileTemplate = (\n strings: TemplateStringsArray,\n values: unknown[],\n effect: (fn: () => void) => void,\n): HTMLResult => {\n const plan = getCompiledTemplatePlan(strings);\n let result = '';\n const bindings: Binding[] = [];\n let activeElementId: string | null = null;\n\n const getNextId = createMarkerIdFactory();\n const isInsideStartTag = (prefix: string) => prefix.lastIndexOf('<') > prefix.lastIndexOf('>');\n const getElementBindingId = (prefix: string): string => {\n if (!activeElementId || isInsideStartTag(prefix)) {\n activeElementId = getNextId();\n }\n\n return activeElementId;\n };\n const resetElementBindingId = (): void => {\n activeElementId = null;\n };\n\n for (let i = 0; i < plan.slots.length; i++) {\n const slot = plan.slots[i];\n const value = values[i];\n\n if (slot.kind === 'event') {\n if (typeof value === 'function') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n handler: value as (e: Event) => void,\n modifiers: slot.modifiers,\n name: slot.name!,\n type: 'event',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'ref') {\n if (value) {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push({\n ref: value as Ref<Element> | RefCallback<Element>,\n type: 'ref',\n uid: id,\n });\n } else {\n result += slot.raw;\n }\n\n continue;\n }\n\n if (slot.kind === 'specialAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding(slot.mode!, slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'prop') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createPropBinding(slot.name!, id, value));\n continue;\n }\n\n if (slot.kind === 'plainAttr') {\n const id = getElementBindingId(slot.prefix);\n\n result += `${slot.prefix} ${CF_ID_ATTR}=\"${id}\"`;\n bindings.push(createAttrBinding('attr', slot.name!, id, value));\n continue;\n }\n\n if (typeof value === 'object' && value !== null && ('mount' in value || 'render' in value)) {\n const isInterpolation = 'render' in value;\n const id = isInterpolation ? getNextId() : getElementBindingId(slot.raw);\n\n if (isInterpolation) result += `${slot.raw}<!--${id}-->`;\n else result += `${slot.raw} ${CF_ID_ATTR}=\"${id}\"`;\n\n const apply = (value as Directive).mount?.bind(value);\n\n if (apply) {\n bindings.push({\n apply: (el: HTMLElement, registerCleanup: (fn: () => void) => void) => {\n apply(el, { registerCleanup });\n },\n type: 'callback',\n uid: id,\n });\n }\n\n if (isInterpolation) {\n const render = (value as Directive).render!.bind(value);\n let cached = { bindings: [] as Binding[], html: '' };\n const fnSignal = signal(cached);\n\n effect(() => {\n const res = render();\n const items = Array.isArray(res) ? res : [res];\n const getNestedId = createMarkerIdFactory();\n let html = '';\n const nextBindings: Binding[] = [];\n\n for (const item of items) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNestedId);\n\n html += entry.html;\n nextBindings.push(...entry.bindings);\n } else {\n html += resolveDirectiveValue(item);\n }\n }\n\n const bindingsChanged =\n nextBindings.length !== cached.bindings.length || nextBindings.some((b, i) => b !== cached.bindings[i]);\n\n if (html !== cached.html || bindingsChanged) {\n cached = { bindings: nextBindings, html };\n fnSignal.value = cached;\n }\n });\n\n bindings.push({ keyed: false, signal: fnSignal, type: 'html', uid: id });\n }\n\n continue;\n }\n\n resetElementBindingId();\n\n const htmlWrapper = createHtmlWrapperSignal(value, effect);\n\n if (htmlWrapper) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ keyed: htmlWrapper.keyed, signal: htmlWrapper.signal, type: 'html', uid: id });\n continue;\n }\n\n if (Array.isArray(value)) {\n let combinedHtml = '';\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n const entry = rekeyHtmlResult(item, getNextId);\n\n combinedHtml += entry.html;\n bindings.push(...entry.bindings);\n } else {\n combinedHtml += resolveDirectiveValue(item);\n }\n }\n result += slot.raw + combinedHtml;\n continue;\n }\n\n if (isSignal(value)) {\n const id = getNextId();\n\n result += `${slot.raw}<!--${id}-->`;\n bindings.push({ signal: value as Signal<unknown>, type: 'text', uid: id });\n } else if (isHtmlResult(value)) {\n const entry = rekeyHtmlResult(value, getNextId);\n\n result += slot.raw + entry.html;\n bindings.push(...entry.bindings);\n } else {\n result += slot.raw + resolveDirectiveValue(value);\n }\n }\n\n result += plan.tail;\n\n return htmlResult(normalizeCompiledHtml(result), bindings);\n};\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- require(`./internal.cjs`);var e=new Map,t=1e3,n=n=>{let r=e.get(n);if(!r){if(r=document.createElement(`template`),r.innerHTML=n,e.size>=t){let t=e.keys().next().value;t!==void 0&&e.delete(t)}e.set(n,r)}return r},r=e=>n(e).content.cloneNode(!0),i=(e,t)=>{if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;n&&t.comments.set(n,e);return}if(e.nodeType!==Node.ELEMENT_NODE)return;let n=e.getAttribute(`u`);n&&t.elements.set(n,e)},a=e=>{let t={comments:new Map,elements:new Map},n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(i(e,t);n.nextNode();)i(n.currentNode,t);return t},o=e=>{let t={comments:new Map,elements:new Map};for(let n of e){let e=document.createTreeWalker(n,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(i(n,t);e.nextNode();)i(e.currentNode,t)}return t},s=(e,t)=>{let n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT);for(;n.nextNode();){let e=n.currentNode;if(e.nodeValue===t)return e}return null},c=e=>Array.from(r(e).childNodes),l=(e,t,n)=>{if(e.parentNode)for(let r of t)e.parentNode.insertBefore(r,n)};exports.createNodes=c,exports.findCommentMarker=s,exports.indexBindings=a,exports.indexBindingsInNodes=o,exports.insertNodes=l,exports.parseHTML=r;
2
- //# sourceMappingURL=template-dom.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-dom.cjs","names":[],"sources":["../../src/core/template-dom.ts"],"sourcesContent":["import { CF_ID_ATTR } from './internal';\n\nexport type BindingTargets = {\n comments: Map<string, Comment>;\n elements: Map<string, HTMLElement>;\n};\n\nconst templateCache = new Map<string, HTMLTemplateElement>();\nconst TEMPLATE_CACHE_MAX = 1000;\n\nconst getCachedTemplate = (html: string): HTMLTemplateElement => {\n let tpl = templateCache.get(html);\n\n if (!tpl) {\n tpl = document.createElement('template');\n tpl.innerHTML = html;\n\n if (templateCache.size >= TEMPLATE_CACHE_MAX) {\n const oldestKey = templateCache.keys().next().value as string | undefined;\n\n if (oldestKey !== undefined) templateCache.delete(oldestKey);\n }\n\n templateCache.set(html, tpl);\n }\n\n return tpl;\n};\n\nexport const parseHTML = (html: string): DocumentFragment =>\n getCachedTemplate(html).content.cloneNode(true) as DocumentFragment;\n\nconst collectBindingTarget = (node: Node, targets: BindingTargets): void => {\n if (node.nodeType === Node.COMMENT_NODE) {\n const marker = (node as Comment).nodeValue;\n\n if (marker) targets.comments.set(marker, node as Comment);\n\n return;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n\n const id = (node as Element).getAttribute(CF_ID_ATTR);\n\n if (id) targets.elements.set(id, node as HTMLElement);\n};\n\nexport const indexBindings = (root: Node): BindingTargets => {\n const targets: BindingTargets = { comments: new Map(), elements: new Map() };\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT);\n\n collectBindingTarget(root, targets);\n\n while (walker.nextNode()) collectBindingTarget(walker.currentNode, targets);\n\n return targets;\n};\n\nexport const indexBindingsInNodes = (nodes: Iterable<Node>): BindingTargets => {\n const targets: BindingTargets = { comments: new Map(), elements: new Map() };\n\n for (const node of nodes) {\n const walker = document.createTreeWalker(node, NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT);\n\n collectBindingTarget(node, targets);\n\n while (walker.nextNode()) collectBindingTarget(walker.currentNode, targets);\n }\n\n return targets;\n};\nexport const findCommentMarker = (root: Node, marker: string): Comment | null => {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT);\n\n while (walker.nextNode()) {\n const comment = walker.currentNode as Comment;\n\n if (comment.nodeValue === marker) return comment;\n }\n\n return null;\n};\n\nexport const isHtmlBindingMarker = (node: Node): boolean =>\n node.nodeType === Node.COMMENT_NODE &&\n ((node as Comment).data === 'html-binding' || (node as Comment).data.startsWith('__h_'));\n\nexport const clearAfterMarker = (marker: Comment): void => {\n let next = marker.nextSibling;\n\n while (next) {\n if (isHtmlBindingMarker(next)) break;\n\n const toRemove = next;\n\n next = next.nextSibling;\n toRemove.remove();\n }\n};\n\nexport const createNodes = (htmlString: string): Node[] => Array.from(parseHTML(htmlString).childNodes);\n\nexport const insertNodes = (marker: Comment, nodes: Node[], before: Node | null): void => {\n if (marker.parentNode) {\n for (const node of nodes) marker.parentNode.insertBefore(node, before);\n }\n};\n"],"mappings":"0BAOA,IAAM,EAAgB,IAAI,IACpB,EAAqB,IAErB,EAAqB,GAAsC,CAC/D,IAAI,EAAM,EAAc,IAAI,EAAK,CAEjC,GAAI,CAAC,EAAK,CAIR,GAHA,EAAM,SAAS,cAAc,WAAW,CACxC,EAAI,UAAY,EAEZ,EAAc,MAAQ,EAAoB,CAC5C,IAAM,EAAY,EAAc,MAAM,CAAC,MAAM,CAAC,MAE1C,IAAc,IAAA,IAAW,EAAc,OAAO,EAAU,CAG9D,EAAc,IAAI,EAAM,EAAI,CAG9B,OAAO,GAGI,EAAa,GACxB,EAAkB,EAAK,CAAC,QAAQ,UAAU,GAAK,CAE3C,GAAwB,EAAY,IAAkC,CAC1E,GAAI,EAAK,WAAa,KAAK,aAAc,CACvC,IAAM,EAAU,EAAiB,UAE7B,GAAQ,EAAQ,SAAS,IAAI,EAAQ,EAAgB,CAEzD,OAGF,GAAI,EAAK,WAAa,KAAK,aAAc,OAEzC,IAAM,EAAM,EAAiB,aAAA,IAAwB,CAEjD,GAAI,EAAQ,SAAS,IAAI,EAAI,EAAoB,EAG1C,EAAiB,GAA+B,CAC3D,IAAM,EAA0B,CAAE,SAAU,IAAI,IAAO,SAAU,IAAI,IAAO,CACtE,EAAS,SAAS,iBAAiB,EAAM,WAAW,aAAe,WAAW,aAAa,CAIjG,IAFA,EAAqB,EAAM,EAAQ,CAE5B,EAAO,UAAU,EAAE,EAAqB,EAAO,YAAa,EAAQ,CAE3E,OAAO,GAGI,EAAwB,GAA0C,CAC7E,IAAM,EAA0B,CAAE,SAAU,IAAI,IAAO,SAAU,IAAI,IAAO,CAE5E,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAS,SAAS,iBAAiB,EAAM,WAAW,aAAe,WAAW,aAAa,CAIjG,IAFA,EAAqB,EAAM,EAAQ,CAE5B,EAAO,UAAU,EAAE,EAAqB,EAAO,YAAa,EAAQ,CAG7E,OAAO,GAEI,GAAqB,EAAY,IAAmC,CAC/E,IAAM,EAAS,SAAS,iBAAiB,EAAM,WAAW,aAAa,CAEvE,KAAO,EAAO,UAAU,EAAE,CACxB,IAAM,EAAU,EAAO,YAEvB,GAAI,EAAQ,YAAc,EAAQ,OAAO,EAG3C,OAAO,MAoBI,EAAe,GAA+B,MAAM,KAAK,EAAU,EAAW,CAAC,WAAW,CAE1F,GAAe,EAAiB,EAAe,IAA8B,CACxF,GAAI,EAAO,WACT,IAAK,IAAM,KAAQ,EAAO,EAAO,WAAW,aAAa,EAAM,EAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-dom.d.ts","sourceRoot":"","sources":["../../src/core/template-dom.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC,CAAC;AAwBF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,gBAC4B,CAAC;AAkBtE,eAAO,MAAM,aAAa,GAAI,MAAM,IAAI,KAAG,cAS1C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAG,cAY5D,CAAC;AACF,eAAO,MAAM,iBAAiB,GAAI,MAAM,IAAI,EAAE,QAAQ,MAAM,KAAG,OAAO,GAAG,IAUxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,MAAM,IAAI,KAAG,OAEyC,CAAC;AAE3F,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,KAAG,IAWlD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,YAAY,MAAM,KAAG,IAAI,EAAkD,CAAC;AAExG,eAAO,MAAM,WAAW,GAAI,QAAQ,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,QAAQ,IAAI,GAAG,IAAI,KAAG,IAIjF,CAAC"}
@@ -1,2 +0,0 @@
1
- import"./internal.js";var e=new Map,t=1e3,n=n=>{let r=e.get(n);if(!r){if(r=document.createElement(`template`),r.innerHTML=n,e.size>=t){let t=e.keys().next().value;t!==void 0&&e.delete(t)}e.set(n,r)}return r},r=e=>n(e).content.cloneNode(!0),i=(e,t)=>{if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;n&&t.comments.set(n,e);return}if(e.nodeType!==Node.ELEMENT_NODE)return;let n=e.getAttribute(`u`);n&&t.elements.set(n,e)},a=e=>{let t={comments:new Map,elements:new Map},n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(i(e,t);n.nextNode();)i(n.currentNode,t);return t},o=e=>{let t={comments:new Map,elements:new Map};for(let n of e){let e=document.createTreeWalker(n,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(i(n,t);e.nextNode();)i(e.currentNode,t)}return t},s=(e,t)=>{let n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT);for(;n.nextNode();){let e=n.currentNode;if(e.nodeValue===t)return e}return null},c=e=>Array.from(r(e).childNodes),l=(e,t,n)=>{if(e.parentNode)for(let r of t)e.parentNode.insertBefore(r,n)};export{c as createNodes,s as findCommentMarker,a as indexBindings,o as indexBindingsInNodes,l as insertNodes,r as parseHTML};
2
- //# sourceMappingURL=template-dom.js.map
@@ -1,2 +0,0 @@
1
- require(`./internal.cjs`);const e=require(`./utilities.cjs`),t=require(`./template-dom.cjs`),n=require(`./template-bindings.cjs`);let r=require(`@vielzeug/stateit`);var i=t=>{e.runAll(t.cleanups);for(let e of t.nodes)e.remove()},a=(e,r,i=t.indexBindingsInNodes(e))=>{let a=[];return n.applyBindingsWithTargets(r,e=>a.push(e),i),a},o=(n,s,c,l,u)=>{let d=t.findCommentMarker(n,s.uid);if(!d)return;let f=document.createComment(`html-binding`);d.replaceWith(f);let p=[],m=e=>p.push(e),h=()=>{e.runAll(p),p=[]},g=null,_=[];c((0,r.effect)(()=>{(0,r.batch)(()=>{let c=s.signal.value;if(!s.keyed&&c.html===g)return;g=c.html,h();let{bindings:d,html:p,keys:v}=c;s.keyed&&!l.has(s.uid)&&l.set(s.uid,new Map);let y=s.keyed?l.get(s.uid):null,b=f.parentElement||n,x=!1;(0,r.untrack)(()=>{(0,r.batch)(()=>{if(y&&v?.length&&c.items?.length===v.length){if(x=!0,y.size===0&&_.length>0){for(let e of _)e.remove();_=[]}let n=new Map;for(let r=0;r<v.length;r++){let i=v[r],o=c.items[r],s=y.get(i),l=r>0?n.get(v[r-1])?.nodes:null,u=l?.length?l[l.length-1].nextSibling:f.nextSibling;if(s?.html===o.html){s.nodes[0]&&t.insertNodes(f,s.nodes,u),e.runAll(s.cleanups);let r=t.indexBindingsInNodes(s.nodes),c=a(s.nodes,o.bindings,r);n.set(i,{...s,bindings:o.bindings,cleanups:c,targets:r})}else if(s){e.runAll(s.cleanups);let r=t.createNodes(o.html),c=t.indexBindingsInNodes(r);t.insertNodes(f,r,u);let l=a(r,o.bindings,c);n.set(i,{bindings:o.bindings,cleanups:l,html:o.html,nodes:r,targets:c});for(let e of s.nodes)e.remove()}else{let e=t.createNodes(o.html),r=t.indexBindingsInNodes(e);t.insertNodes(f,e,u);let s=a(e,o.bindings,r);n.set(i,{bindings:o.bindings,cleanups:s,html:o.html,nodes:e,targets:r})}}for(let[e,t]of y)n.has(e)||i(t);l.set(s.uid,n)}else{if(s.keyed&&y&&y.size>0)for(let[,e]of y)i(e);else for(let e of _)e.remove();let e=t.parseHTML(p);_=Array.from(e.childNodes),f.after(e),s.keyed&&l.set(s.uid,new Map)}}),x||u(b,d,m,{onHtml:e=>o(b,e,m,l,u)})})})})),c(h),s.keyed&&c(()=>l.delete(s.uid))};exports.applyHtmlBinding=o;
2
- //# sourceMappingURL=template-html.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-html.cjs","names":[],"sources":["../../src/core/template-html.ts"],"sourcesContent":["import { batch, untrack, effect as _effect, type CleanupFn } from '@vielzeug/stateit';\n\nimport { type Binding, type HtmlBinding } from './internal';\nimport { applyBindingsWithTargets } from './template-bindings';\nimport { type RegisterCleanup } from './template-bindings';\nimport {\n createNodes,\n findCommentMarker,\n indexBindingsInNodes,\n insertNodes,\n parseHTML,\n type BindingTargets,\n} from './template-dom';\nimport { runAll } from './utilities';\n\n/** Keyed reconciliation node — holds DOM nodes + lifecycle for one `each()` item. */\nexport type KeyedNode = {\n bindings: Binding[];\n cleanups: CleanupFn[];\n html: string;\n nodes: Node[];\n targets: BindingTargets;\n};\n\nconst removeKeyed = (keyedNode: KeyedNode) => {\n runAll(keyedNode.cleanups);\n for (const n of keyedNode.nodes) (n as ChildNode).remove();\n};\n\n/** Apply bindings to keyed item nodes using pre-indexed targets. */\nconst applyKeyedItemBindings = (\n nodes: Node[],\n itemBindings: Binding[],\n targets = indexBindingsInNodes(nodes),\n): CleanupFn[] => {\n const itemCleanups: CleanupFn[] = [];\n const itemRegisterCleanup: RegisterCleanup = (fn) => itemCleanups.push(fn);\n\n applyBindingsWithTargets(itemBindings, itemRegisterCleanup, targets);\n\n return itemCleanups;\n};\n\n/**\n * Sets up the reactive effect for an html-binding marker. Handles both non-keyed\n * (full replace) and keyed (`each()`) reconciliation.\n *\n * @param root The root node containing the marker comment.\n * @param b The HtmlBinding descriptor.\n * @param registerCleanup Function that registers a cleanup tied to the outer container's lifetime.\n * @param keyedStates Per-element map of `marker → (key → KeyedNode)` — caller owns this state.\n * @param applyBindingsInContainer Function to apply bindings to container.\n */\nexport const applyHtmlBinding = (\n root: Node,\n b: HtmlBinding,\n registerCleanup: RegisterCleanup,\n keyedStates: Map<string, Map<string | number, KeyedNode>>,\n applyBindingsInContainer: (\n container: ParentNode,\n bindings: Binding[],\n registerCleanup: RegisterCleanup,\n opts?: { onHtml?: (b: HtmlBinding) => void },\n ) => void,\n): void => {\n const found = findCommentMarker(root, b.uid);\n\n if (!found) return;\n\n const marker = document.createComment('html-binding');\n\n found.replaceWith(marker);\n\n let currentCleanups: CleanupFn[] = [];\n const registerInnerCleanup: RegisterCleanup = (fn) => currentCleanups.push(fn);\n const runCurrentCleanups = () => {\n runAll(currentCleanups);\n currentCleanups = [];\n };\n let lastHtml: string | null = null;\n let lastInsertedNodes: Node[] = [];\n\n // Use stateit.effect directly so cleanup is managed manually via registerCleanup, not autoCleanup.\n const stop = _effect(() => {\n batch(() => {\n const data = b.signal.value;\n\n if (!b.keyed && data.html === lastHtml) {\n return;\n }\n\n lastHtml = data.html;\n\n runCurrentCleanups();\n\n const { bindings, html, keys } = data;\n\n if (b.keyed && !keyedStates.has(b.uid)) keyedStates.set(b.uid, new Map());\n\n const keyedState = b.keyed ? keyedStates.get(b.uid)! : null;\n const container = (marker.parentElement || root) as ParentNode;\n\n let bindingsAlreadyApplied = false;\n\n untrack(() => {\n batch(() => {\n if (keyedState && keys?.length && data.items?.length === keys.length) {\n bindingsAlreadyApplied = true;\n\n // Transition from empty/fallback insertion back to keyed list items.\n if (keyedState.size === 0 && lastInsertedNodes.length > 0) {\n for (const n of lastInsertedNodes) (n as ChildNode).remove();\n lastInsertedNodes = [];\n }\n\n const newKeyedState = new Map<string | number, KeyedNode>();\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const itemData = data.items[i];\n const existing = keyedState.get(key);\n\n const prevNodes = i > 0 ? newKeyedState.get(keys[i - 1])?.nodes : null;\n const insertPoint = prevNodes?.length ? prevNodes[prevNodes.length - 1].nextSibling : marker.nextSibling;\n\n if (existing?.html === itemData.html) {\n // UPDATE: Same HTML — reuse nodes, reapply bindings\n if (existing.nodes[0]) insertNodes(marker, existing.nodes, insertPoint);\n\n runAll(existing.cleanups);\n\n const itemTargets = indexBindingsInNodes(existing.nodes);\n const itemCleanups = applyKeyedItemBindings(existing.nodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n ...existing,\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n targets: itemTargets,\n });\n } else if (existing) {\n // REPLACE: Different HTML — create new nodes, remove old\n runAll(existing.cleanups);\n\n const newNodes = createNodes(itemData.html);\n const itemTargets = indexBindingsInNodes(newNodes);\n\n insertNodes(marker, newNodes, insertPoint);\n\n const itemCleanups = applyKeyedItemBindings(newNodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n html: itemData.html,\n nodes: newNodes,\n targets: itemTargets,\n });\n for (const n of existing.nodes) (n as ChildNode).remove();\n } else {\n // CREATE: New item\n const newNodes = createNodes(itemData.html);\n const itemTargets = indexBindingsInNodes(newNodes);\n\n insertNodes(marker, newNodes, insertPoint);\n\n const itemCleanups = applyKeyedItemBindings(newNodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n html: itemData.html,\n nodes: newNodes,\n targets: itemTargets,\n });\n }\n }\n\n // DELETE: Remove old items not in new state\n for (const [oldKey, oldNode] of keyedState) {\n if (!newKeyedState.has(oldKey)) removeKeyed(oldNode);\n }\n\n keyedStates.set(b.uid, newKeyedState);\n } else {\n // Non-keyed or empty list: replace previously inserted nodes.\n if (b.keyed && keyedState && keyedState.size > 0) {\n for (const [, kn] of keyedState) removeKeyed(kn);\n } else {\n for (const n of lastInsertedNodes) (n as ChildNode).remove();\n }\n\n const parsed = parseHTML(html);\n\n lastInsertedNodes = Array.from(parsed.childNodes);\n marker.after(parsed);\n\n if (b.keyed) keyedStates.set(b.uid, new Map());\n }\n });\n\n if (!bindingsAlreadyApplied) {\n applyBindingsInContainer(container, bindings, registerInnerCleanup, {\n onHtml: (binding) =>\n applyHtmlBinding(container, binding, registerInnerCleanup, keyedStates, applyBindingsInContainer),\n });\n }\n });\n });\n });\n\n registerCleanup(stop);\n registerCleanup(runCurrentCleanups);\n\n if (b.keyed) registerCleanup(() => keyedStates.delete(b.uid));\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-html.d.ts","sourceRoot":"","sources":["../../src/core/template-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAGxB,qFAAqF;AACrF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;CACzB,CAAC;AAqBF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAC3B,MAAM,IAAI,EACV,GAAG,WAAW,EACd,iBAAiB,eAAe,EAChC,aAAa,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,EACzD,0BAA0B,CACxB,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,OAAO,EAAE,EACnB,eAAe,EAAE,eAAe,EAChC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;CAAE,KACzC,IAAI,KACR,IAuJF,CAAC"}
@@ -1,2 +0,0 @@
1
- import"./internal.js";import{runAll as e}from"./utilities.js";import{createNodes as t,findCommentMarker as n,indexBindingsInNodes as r,insertNodes as i,parseHTML as a}from"./template-dom.js";import{applyBindingsWithTargets as o}from"./template-bindings.js";import{batch as s,effect as c,untrack as l}from"@vielzeug/stateit";var u=t=>{e(t.cleanups);for(let e of t.nodes)e.remove()},d=(e,t,n=r(e))=>{let i=[];return o(t,e=>i.push(e),n),i},f=(o,p,m,h,g)=>{let _=n(o,p.uid);if(!_)return;let v=document.createComment(`html-binding`);_.replaceWith(v);let y=[],b=e=>y.push(e),x=()=>{e(y),y=[]},S=null,C=[];m(c(()=>{s(()=>{let n=p.signal.value;if(!p.keyed&&n.html===S)return;S=n.html,x();let{bindings:c,html:m,keys:_}=n;p.keyed&&!h.has(p.uid)&&h.set(p.uid,new Map);let y=p.keyed?h.get(p.uid):null,w=v.parentElement||o,T=!1;l(()=>{s(()=>{if(y&&_?.length&&n.items?.length===_.length){if(T=!0,y.size===0&&C.length>0){for(let e of C)e.remove();C=[]}let a=new Map;for(let o=0;o<_.length;o++){let s=_[o],c=n.items[o],l=y.get(s),u=o>0?a.get(_[o-1])?.nodes:null,f=u?.length?u[u.length-1].nextSibling:v.nextSibling;if(l?.html===c.html){l.nodes[0]&&i(v,l.nodes,f),e(l.cleanups);let t=r(l.nodes),n=d(l.nodes,c.bindings,t);a.set(s,{...l,bindings:c.bindings,cleanups:n,targets:t})}else if(l){e(l.cleanups);let n=t(c.html),o=r(n);i(v,n,f);let u=d(n,c.bindings,o);a.set(s,{bindings:c.bindings,cleanups:u,html:c.html,nodes:n,targets:o});for(let e of l.nodes)e.remove()}else{let e=t(c.html),n=r(e);i(v,e,f);let o=d(e,c.bindings,n);a.set(s,{bindings:c.bindings,cleanups:o,html:c.html,nodes:e,targets:n})}}for(let[e,t]of y)a.has(e)||u(t);h.set(p.uid,a)}else{if(p.keyed&&y&&y.size>0)for(let[,e]of y)u(e);else for(let e of C)e.remove();let e=a(m);C=Array.from(e.childNodes),v.after(e),p.keyed&&h.set(p.uid,new Map)}}),T||g(w,c,b,{onHtml:e=>f(w,e,b,h,g)})})})})),m(x),p.keyed&&m(()=>h.delete(p.uid))};export{f as applyHtmlBinding};
2
- //# sourceMappingURL=template-html.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-html.js","names":[],"sources":["../../src/core/template-html.ts"],"sourcesContent":["import { batch, untrack, effect as _effect, type CleanupFn } from '@vielzeug/stateit';\n\nimport { type Binding, type HtmlBinding } from './internal';\nimport { applyBindingsWithTargets } from './template-bindings';\nimport { type RegisterCleanup } from './template-bindings';\nimport {\n createNodes,\n findCommentMarker,\n indexBindingsInNodes,\n insertNodes,\n parseHTML,\n type BindingTargets,\n} from './template-dom';\nimport { runAll } from './utilities';\n\n/** Keyed reconciliation node — holds DOM nodes + lifecycle for one `each()` item. */\nexport type KeyedNode = {\n bindings: Binding[];\n cleanups: CleanupFn[];\n html: string;\n nodes: Node[];\n targets: BindingTargets;\n};\n\nconst removeKeyed = (keyedNode: KeyedNode) => {\n runAll(keyedNode.cleanups);\n for (const n of keyedNode.nodes) (n as ChildNode).remove();\n};\n\n/** Apply bindings to keyed item nodes using pre-indexed targets. */\nconst applyKeyedItemBindings = (\n nodes: Node[],\n itemBindings: Binding[],\n targets = indexBindingsInNodes(nodes),\n): CleanupFn[] => {\n const itemCleanups: CleanupFn[] = [];\n const itemRegisterCleanup: RegisterCleanup = (fn) => itemCleanups.push(fn);\n\n applyBindingsWithTargets(itemBindings, itemRegisterCleanup, targets);\n\n return itemCleanups;\n};\n\n/**\n * Sets up the reactive effect for an html-binding marker. Handles both non-keyed\n * (full replace) and keyed (`each()`) reconciliation.\n *\n * @param root The root node containing the marker comment.\n * @param b The HtmlBinding descriptor.\n * @param registerCleanup Function that registers a cleanup tied to the outer container's lifetime.\n * @param keyedStates Per-element map of `marker → (key → KeyedNode)` — caller owns this state.\n * @param applyBindingsInContainer Function to apply bindings to container.\n */\nexport const applyHtmlBinding = (\n root: Node,\n b: HtmlBinding,\n registerCleanup: RegisterCleanup,\n keyedStates: Map<string, Map<string | number, KeyedNode>>,\n applyBindingsInContainer: (\n container: ParentNode,\n bindings: Binding[],\n registerCleanup: RegisterCleanup,\n opts?: { onHtml?: (b: HtmlBinding) => void },\n ) => void,\n): void => {\n const found = findCommentMarker(root, b.uid);\n\n if (!found) return;\n\n const marker = document.createComment('html-binding');\n\n found.replaceWith(marker);\n\n let currentCleanups: CleanupFn[] = [];\n const registerInnerCleanup: RegisterCleanup = (fn) => currentCleanups.push(fn);\n const runCurrentCleanups = () => {\n runAll(currentCleanups);\n currentCleanups = [];\n };\n let lastHtml: string | null = null;\n let lastInsertedNodes: Node[] = [];\n\n // Use stateit.effect directly so cleanup is managed manually via registerCleanup, not autoCleanup.\n const stop = _effect(() => {\n batch(() => {\n const data = b.signal.value;\n\n if (!b.keyed && data.html === lastHtml) {\n return;\n }\n\n lastHtml = data.html;\n\n runCurrentCleanups();\n\n const { bindings, html, keys } = data;\n\n if (b.keyed && !keyedStates.has(b.uid)) keyedStates.set(b.uid, new Map());\n\n const keyedState = b.keyed ? keyedStates.get(b.uid)! : null;\n const container = (marker.parentElement || root) as ParentNode;\n\n let bindingsAlreadyApplied = false;\n\n untrack(() => {\n batch(() => {\n if (keyedState && keys?.length && data.items?.length === keys.length) {\n bindingsAlreadyApplied = true;\n\n // Transition from empty/fallback insertion back to keyed list items.\n if (keyedState.size === 0 && lastInsertedNodes.length > 0) {\n for (const n of lastInsertedNodes) (n as ChildNode).remove();\n lastInsertedNodes = [];\n }\n\n const newKeyedState = new Map<string | number, KeyedNode>();\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const itemData = data.items[i];\n const existing = keyedState.get(key);\n\n const prevNodes = i > 0 ? newKeyedState.get(keys[i - 1])?.nodes : null;\n const insertPoint = prevNodes?.length ? prevNodes[prevNodes.length - 1].nextSibling : marker.nextSibling;\n\n if (existing?.html === itemData.html) {\n // UPDATE: Same HTML — reuse nodes, reapply bindings\n if (existing.nodes[0]) insertNodes(marker, existing.nodes, insertPoint);\n\n runAll(existing.cleanups);\n\n const itemTargets = indexBindingsInNodes(existing.nodes);\n const itemCleanups = applyKeyedItemBindings(existing.nodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n ...existing,\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n targets: itemTargets,\n });\n } else if (existing) {\n // REPLACE: Different HTML — create new nodes, remove old\n runAll(existing.cleanups);\n\n const newNodes = createNodes(itemData.html);\n const itemTargets = indexBindingsInNodes(newNodes);\n\n insertNodes(marker, newNodes, insertPoint);\n\n const itemCleanups = applyKeyedItemBindings(newNodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n html: itemData.html,\n nodes: newNodes,\n targets: itemTargets,\n });\n for (const n of existing.nodes) (n as ChildNode).remove();\n } else {\n // CREATE: New item\n const newNodes = createNodes(itemData.html);\n const itemTargets = indexBindingsInNodes(newNodes);\n\n insertNodes(marker, newNodes, insertPoint);\n\n const itemCleanups = applyKeyedItemBindings(newNodes, itemData.bindings, itemTargets);\n\n newKeyedState.set(key, {\n bindings: itemData.bindings,\n cleanups: itemCleanups,\n html: itemData.html,\n nodes: newNodes,\n targets: itemTargets,\n });\n }\n }\n\n // DELETE: Remove old items not in new state\n for (const [oldKey, oldNode] of keyedState) {\n if (!newKeyedState.has(oldKey)) removeKeyed(oldNode);\n }\n\n keyedStates.set(b.uid, newKeyedState);\n } else {\n // Non-keyed or empty list: replace previously inserted nodes.\n if (b.keyed && keyedState && keyedState.size > 0) {\n for (const [, kn] of keyedState) removeKeyed(kn);\n } else {\n for (const n of lastInsertedNodes) (n as ChildNode).remove();\n }\n\n const parsed = parseHTML(html);\n\n lastInsertedNodes = Array.from(parsed.childNodes);\n marker.after(parsed);\n\n if (b.keyed) keyedStates.set(b.uid, new Map());\n }\n });\n\n if (!bindingsAlreadyApplied) {\n applyBindingsInContainer(container, bindings, registerInnerCleanup, {\n onHtml: (binding) =>\n applyHtmlBinding(container, binding, registerInnerCleanup, keyedStates, applyBindingsInContainer),\n });\n }\n });\n });\n });\n\n registerCleanup(stop);\n registerCleanup(runCurrentCleanups);\n\n if (b.keyed) registerCleanup(() => keyedStates.delete(b.uid));\n};\n"],"mappings":"oUAwBA,IAAM,EAAe,GAAyB,CAC5C,EAAO,EAAU,SAAS,CAC1B,IAAK,IAAM,KAAK,EAAU,MAAQ,EAAgB,QAAQ,EAItD,GACJ,EACA,EACA,EAAU,EAAqB,EAAM,GACrB,CAChB,IAAM,EAA4B,EAAE,CAKpC,OAFA,EAAyB,EAFqB,GAAO,EAAa,KAAK,EAAG,CAEd,EAAQ,CAE7D,GAaI,GACX,EACA,EACA,EACA,EACA,IAMS,CACT,IAAM,EAAQ,EAAkB,EAAM,EAAE,IAAI,CAE5C,GAAI,CAAC,EAAO,OAEZ,IAAM,EAAS,SAAS,cAAc,eAAe,CAErD,EAAM,YAAY,EAAO,CAEzB,IAAI,EAA+B,EAAE,CAC/B,EAAyC,GAAO,EAAgB,KAAK,EAAG,CACxE,MAA2B,CAC/B,EAAO,EAAgB,CACvB,EAAkB,EAAE,EAElB,EAA0B,KAC1B,EAA4B,EAAE,CAmIlC,EAhIa,MAAc,CACzB,MAAY,CACV,IAAM,EAAO,EAAE,OAAO,MAEtB,GAAI,CAAC,EAAE,OAAS,EAAK,OAAS,EAC5B,OAGF,EAAW,EAAK,KAEhB,GAAoB,CAEpB,GAAM,CAAE,WAAU,OAAM,QAAS,EAE7B,EAAE,OAAS,CAAC,EAAY,IAAI,EAAE,IAAI,EAAE,EAAY,IAAI,EAAE,IAAK,IAAI,IAAM,CAEzE,IAAM,EAAa,EAAE,MAAQ,EAAY,IAAI,EAAE,IAAI,CAAI,KACjD,EAAa,EAAO,eAAiB,EAEvC,EAAyB,GAE7B,MAAc,CACZ,MAAY,CACV,GAAI,GAAc,GAAM,QAAU,EAAK,OAAO,SAAW,EAAK,OAAQ,CAIpE,GAHA,EAAyB,GAGrB,EAAW,OAAS,GAAK,EAAkB,OAAS,EAAG,CACzD,IAAK,IAAM,KAAK,EAAoB,EAAgB,QAAQ,CAC5D,EAAoB,EAAE,CAGxB,IAAM,EAAgB,IAAI,IAE1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACX,EAAW,EAAK,MAAM,GACtB,EAAW,EAAW,IAAI,EAAI,CAE9B,EAAY,EAAI,EAAI,EAAc,IAAI,EAAK,EAAI,GAAG,EAAE,MAAQ,KAC5D,EAAc,GAAW,OAAS,EAAU,EAAU,OAAS,GAAG,YAAc,EAAO,YAE7F,GAAI,GAAU,OAAS,EAAS,KAAM,CAEhC,EAAS,MAAM,IAAI,EAAY,EAAQ,EAAS,MAAO,EAAY,CAEvE,EAAO,EAAS,SAAS,CAEzB,IAAM,EAAc,EAAqB,EAAS,MAAM,CAClD,EAAe,EAAuB,EAAS,MAAO,EAAS,SAAU,EAAY,CAE3F,EAAc,IAAI,EAAK,CACrB,GAAG,EACH,SAAU,EAAS,SACnB,SAAU,EACV,QAAS,EACV,CAAC,SACO,EAAU,CAEnB,EAAO,EAAS,SAAS,CAEzB,IAAM,EAAW,EAAY,EAAS,KAAK,CACrC,EAAc,EAAqB,EAAS,CAElD,EAAY,EAAQ,EAAU,EAAY,CAE1C,IAAM,EAAe,EAAuB,EAAU,EAAS,SAAU,EAAY,CAErF,EAAc,IAAI,EAAK,CACrB,SAAU,EAAS,SACnB,SAAU,EACV,KAAM,EAAS,KACf,MAAO,EACP,QAAS,EACV,CAAC,CACF,IAAK,IAAM,KAAK,EAAS,MAAQ,EAAgB,QAAQ,KACpD,CAEL,IAAM,EAAW,EAAY,EAAS,KAAK,CACrC,EAAc,EAAqB,EAAS,CAElD,EAAY,EAAQ,EAAU,EAAY,CAE1C,IAAM,EAAe,EAAuB,EAAU,EAAS,SAAU,EAAY,CAErF,EAAc,IAAI,EAAK,CACrB,SAAU,EAAS,SACnB,SAAU,EACV,KAAM,EAAS,KACf,MAAO,EACP,QAAS,EACV,CAAC,EAKN,IAAK,GAAM,CAAC,EAAQ,KAAY,EACzB,EAAc,IAAI,EAAO,EAAE,EAAY,EAAQ,CAGtD,EAAY,IAAI,EAAE,IAAK,EAAc,KAChC,CAEL,GAAI,EAAE,OAAS,GAAc,EAAW,KAAO,EAC7C,IAAK,GAAM,EAAG,KAAO,EAAY,EAAY,EAAG,MAEhD,IAAK,IAAM,KAAK,EAAoB,EAAgB,QAAQ,CAG9D,IAAM,EAAS,EAAU,EAAK,CAE9B,EAAoB,MAAM,KAAK,EAAO,WAAW,CACjD,EAAO,MAAM,EAAO,CAEhB,EAAE,OAAO,EAAY,IAAI,EAAE,IAAK,IAAI,IAAM,GAEhD,CAEG,GACH,EAAyB,EAAW,EAAU,EAAsB,CAClE,OAAS,GACP,EAAiB,EAAW,EAAS,EAAsB,EAAa,EAAyB,CACpG,CAAC,EAEJ,EACF,EACF,CAEmB,CACrB,EAAgB,EAAmB,CAE/B,EAAE,OAAO,MAAsB,EAAY,OAAO,EAAE,IAAI,CAAC"}
@@ -1,2 +0,0 @@
1
- require(`./internal.cjs`);const e=require(`./runtime-lifecycle.cjs`),t=require(`./template-dom.cjs`),n=require(`./template-bindings.cjs`),r=require(`./template-compiler.cjs`),i=require(`./template-html.cjs`);var a=(e,r,i,a)=>{n.applyBindingsWithTargets(r,i,t.indexBindings(e),a)},o=()=>{},s=(t,...n)=>r.compileTemplate(t,n,e.effect),c=(e,t,n,r)=>{i.applyHtmlBinding(e,t,n,r,a)};exports._resetMarkerIndex=o,exports.applyBindingsInContainer=a,exports.applyHtmlBinding=c,exports.html=s;
2
- //# sourceMappingURL=template.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template.cjs","names":[],"sources":["../../src/core/template.ts"],"sourcesContent":["import { type Binding, type HtmlBinding, type HTMLResult } from './internal';\nimport { effect } from './runtime-lifecycle';\nimport { applyBindingsWithTargets } from './template-bindings';\nimport { type RegisterCleanup } from './template-bindings';\nimport { compileTemplate, resetTemplateCompilerState } from './template-compiler';\nimport { indexBindings } from './template-dom';\nimport { applyHtmlBinding as applyHtmlBindingImpl, type KeyedNode } from './template-html';\n\n// ─── Re-exports for consumers ─────────────────────────────────────────────────\nexport type { KeyedNode };\n\n// ─── Binding application orchestration ────────────────────────────────────────\n\nexport const applyBindingsInContainer = (\n container: ParentNode,\n bindings: Binding[],\n registerCleanup: RegisterCleanup,\n opts?: { onHtml?: (b: HtmlBinding) => void },\n) => {\n applyBindingsWithTargets(bindings, registerCleanup, indexBindings(container), opts);\n};\n\n// ─── Reset and compilation ────────────────────────────────────────────────────\n\nexport const _resetMarkerIndex = (): void => {\n resetTemplateCompilerState();\n};\n\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): HTMLResult =>\n compileTemplate(strings, values, effect);\n\n// ─── HTML binding with keyed reconciliation ────────────────────────────────────\n\nexport const applyHtmlBinding = (\n root: Node,\n b: HtmlBinding,\n registerCleanup: RegisterCleanup,\n keyedStates: Map<string, Map<string | number, KeyedNode>>,\n): void => {\n applyHtmlBindingImpl(root, b, registerCleanup, keyedStates, applyBindingsInContainer);\n};\n"],"mappings":"gNAaA,IAAa,GACX,EACA,EACA,EACA,IACG,CACH,EAAA,yBAAyB,EAAU,EAAiB,EAAA,cAAc,EAAU,CAAE,EAAK,EAKxE,MAAgC,GAIhC,GAAQ,EAA+B,GAAG,IACrD,EAAA,gBAAgB,EAAS,EAAQ,EAAA,OAAO,CAI7B,GACX,EACA,EACA,EACA,IACS,CACT,EAAA,iBAAqB,EAAM,EAAG,EAAiB,EAAa,EAAyB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/core/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG3F,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,eAAO,MAAM,wBAAwB,GACnC,WAAW,UAAU,EACrB,UAAU,OAAO,EAAE,EACnB,iBAAiB,eAAe,EAChC,OAAO;IAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;CAAE,SAG7C,CAAC;AAIF,eAAO,MAAM,iBAAiB,QAAO,IAEpC,CAAC;AAEF,eAAO,MAAM,IAAI,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,UACjC,CAAC;AAI3C,eAAO,MAAM,gBAAgB,GAC3B,MAAM,IAAI,EACV,GAAG,WAAW,EACd,iBAAiB,eAAe,EAChC,aAAa,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,KACxD,IAEF,CAAC"}
@@ -1,2 +0,0 @@
1
- import"./internal.js";import{effect as e}from"./runtime-lifecycle.js";import{indexBindings as t}from"./template-dom.js";import{applyBindingsWithTargets as n}from"./template-bindings.js";import{compileTemplate as r}from"./template-compiler.js";import{applyHtmlBinding as i}from"./template-html.js";var a=(e,r,i,a)=>{n(r,i,t(e),a)},o=()=>{},s=(t,...n)=>r(t,n,e),c=(e,t,n,r)=>{i(e,t,n,r,a)};export{o as _resetMarkerIndex,a as applyBindingsInContainer,c as applyHtmlBinding,s as html};
2
- //# sourceMappingURL=template.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template.js","names":[],"sources":["../../src/core/template.ts"],"sourcesContent":["import { type Binding, type HtmlBinding, type HTMLResult } from './internal';\nimport { effect } from './runtime-lifecycle';\nimport { applyBindingsWithTargets } from './template-bindings';\nimport { type RegisterCleanup } from './template-bindings';\nimport { compileTemplate, resetTemplateCompilerState } from './template-compiler';\nimport { indexBindings } from './template-dom';\nimport { applyHtmlBinding as applyHtmlBindingImpl, type KeyedNode } from './template-html';\n\n// ─── Re-exports for consumers ─────────────────────────────────────────────────\nexport type { KeyedNode };\n\n// ─── Binding application orchestration ────────────────────────────────────────\n\nexport const applyBindingsInContainer = (\n container: ParentNode,\n bindings: Binding[],\n registerCleanup: RegisterCleanup,\n opts?: { onHtml?: (b: HtmlBinding) => void },\n) => {\n applyBindingsWithTargets(bindings, registerCleanup, indexBindings(container), opts);\n};\n\n// ─── Reset and compilation ────────────────────────────────────────────────────\n\nexport const _resetMarkerIndex = (): void => {\n resetTemplateCompilerState();\n};\n\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): HTMLResult =>\n compileTemplate(strings, values, effect);\n\n// ─── HTML binding with keyed reconciliation ────────────────────────────────────\n\nexport const applyHtmlBinding = (\n root: Node,\n b: HtmlBinding,\n registerCleanup: RegisterCleanup,\n keyedStates: Map<string, Map<string | number, KeyedNode>>,\n): void => {\n applyHtmlBindingImpl(root, b, registerCleanup, keyedStates, applyBindingsInContainer);\n};\n"],"mappings":"ySAaA,IAAa,GACX,EACA,EACA,EACA,IACG,CACH,EAAyB,EAAU,EAAiB,EAAc,EAAU,CAAE,EAAK,EAKxE,MAAgC,GAIhC,GAAQ,EAA+B,GAAG,IACrD,EAAgB,EAAS,EAAQ,EAAO,CAI7B,GACX,EACA,EACA,EACA,IACS,CACT,EAAqB,EAAM,EAAG,EAAiB,EAAa,EAAyB"}
@@ -1,2 +0,0 @@
1
- const e=require(`./runtime-lifecycle.cjs`);var t=0,n=()=>{t=0},r=e=>{for(let t of e)t()},i=(e,t,n)=>{if(/^on/i.test(t)){e.removeAttribute(t);return}n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},a=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},o=e=>`${e?`${e}-`:`cft-`}${++t}`,s=(e,t)=>{let n=`${e}-${t&&t.trim()?t:o(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},c=(e,t)=>n=>{e()&&t(n)},l=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),u={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},d=e=>String(e).replace(/[&<>"']/g,e=>u[e]),f=()=>{let t=e.currentRuntime().el;return((n,...r)=>{e.fire.custom(t,String(n),r.length>0?{detail:r[0]}:void 0)})},p=function(){return this.content},m=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:p}},h=new Map,g=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=h.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),h.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};exports._resetIdCounter=n,exports.createEmitFn=f,exports.createFormIds=s,exports.createId=o,exports.css=m,exports.escapeHtml=d,exports.guard=c,exports.listen=a,exports.loadStylesheet=g,exports.runAll=r,exports.setAttr=i,exports.toKebab=l;
2
- //# sourceMappingURL=utilities.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utilities.cjs","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n // Avoid inline event-handler attributes (onclick, onerror, ...) to reduce injection risk.\n if (/^on/i.test(name)) {\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"2CAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CAExE,GAAI,OAAO,KAAK,EAAK,CAAE,CACrB,EAAG,gBAAgB,EAAK,CAExB,OAGE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,EAAA,gBAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAA,KAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}
@@ -1,68 +0,0 @@
1
- /**
2
- * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.
3
- *
4
- * This module consolidates:
5
- * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)
6
- * - ID generation and form field ID helpers
7
- * - Emitter for type-safe custom events
8
- * - CSS template tag and stylesheet caching
9
- * - Style loader for adoptedStyleSheets
10
- */
11
- /** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */
12
- export declare const _resetIdCounter: () => void;
13
- /** Iterate an iterable and call every function in it. */
14
- export declare const runAll: (fns: Iterable<() => void>) => void;
15
- export declare const setAttr: (el: Element, name: string, val: unknown) => void;
16
- export declare const listen: (el: EventTarget, name: string, handler: (e: any) => void, options?: AddEventListenerOptions) => (() => void);
17
- /**
18
- * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,
19
- * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).
20
- */
21
- export declare const createId: (prefix?: string) => string;
22
- /**
23
- * Generates a stable set of ARIA-related IDs for a form control.
24
- * Snapshot `name` at call time — IDs are stable strings, not reactive.
25
- * `name` must be a non-empty string — callers that need a generated ID should
26
- * pass `createId(prefix)` as the name argument.
27
- *
28
- * @example
29
- * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);
30
- */
31
- export declare const createFormIds: (prefix: string, name?: string | null) => {
32
- errorId: string;
33
- fieldId: string;
34
- helperId: string;
35
- labelId: string;
36
- };
37
- /**
38
- * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.
39
- * Use for disabled checks, readonly guards, or any runtime condition.
40
- *
41
- * @example
42
- * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));
43
- */
44
- export declare const guard: <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void) => ((e: E) => void);
45
- export declare const toKebab: (str: string) => string;
46
- /**
47
- * Escapes HTML entity characters (`&`, `<`, `>`, `"`, `'`) in a value.
48
- * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,
49
- * `javascript:` URLs, event handler attributes, or inline `<script>` content.
50
- */
51
- export declare const escapeHtml: (value: unknown) => string;
52
- type NoDetail = void | undefined | never;
53
- type KeysWithoutDetail<T extends Record<string, unknown>> = {
54
- [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;
55
- }[keyof T];
56
- export type EmitFn<T extends Record<string, unknown>> = {
57
- <K extends KeysWithoutDetail<T>>(event: K): void;
58
- <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;
59
- };
60
- export declare const createEmitFn: <T extends Record<string, unknown>>() => EmitFn<T>;
61
- export type CSSResult = {
62
- content: string;
63
- toString(): string;
64
- };
65
- export declare const css: (strings: TemplateStringsArray, ...values: unknown[]) => CSSResult;
66
- export declare const loadStylesheet: (style: string | CSSStyleSheet | CSSResult) => CSSStyleSheet;
67
- export {};
68
- //# sourceMappingURL=utilities.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/core/utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,iFAAiF;AACjF,eAAO,MAAM,eAAe,QAAO,IAElC,CAAC;AAGF,yDAAyD;AACzD,eAAO,MAAM,MAAM,GAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAG,IAElD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,IAAI,OAAO,EAAE,MAAM,MAAM,EAAE,KAAK,OAAO,KAAG,IAejE,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,IAAI,WAAW,EACf,MAAM,MAAM,EACZ,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,EACzB,UAAU,uBAAuB,KAChC,CAAC,MAAM,IAAI,CAMb,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,MAA4D,CAAC;AAExG;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,OAAO,MAAM,GAAG,IAAI;;;;;CAUjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GACf,CAAC,SAAS,KAAK,GAAG,KAAK,EAAE,WAAW,MAAM,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAG5F,CAAC;AAEJ,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAA6D,CAAC;AAIpG;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,MAA2D,CAAC;AAMxG,KAAK,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;AACzC,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK;CACtD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACtD,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACjD,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAClF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAK,MAAM,CAAC,CAAC,CAM1E,CAAC;AAMF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC;AAMF,eAAO,MAAM,GAAG,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,SAczE,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,aAAa,GAAG,SAAS,KAAG,aAkB1E,CAAC"}
@@ -1,2 +0,0 @@
1
- import{currentRuntime as e,fire as t}from"./runtime-lifecycle.js";var n=0,r=()=>{n=0},i=e=>{for(let t of e)t()},a=(e,t,n)=>{if(/^on/i.test(t)){e.removeAttribute(t);return}n==null||n===!1?e.removeAttribute(t):n===!0?e.setAttribute(t,``):e.setAttribute(t,String(n))},o=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},s=e=>`${e?`${e}-`:`cft-`}${++n}`,c=(e,t)=>{let n=`${e}-${t&&t.trim()?t:s(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},l=(e,t)=>n=>{e()&&t(n)},u=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),d={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},f=e=>String(e).replace(/[&<>"']/g,e=>d[e]),p=()=>{let n=e().el;return((e,...r)=>{t.custom(n,String(e),r.length>0?{detail:r[0]}:void 0)})},m=function(){return this.content},h=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:m}},g=new Map,_=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=g.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),g.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r};export{r as _resetIdCounter,p as createEmitFn,c as createFormIds,s as createId,h as css,f as escapeHtml,l as guard,o as listen,_ as loadStylesheet,i as runAll,a as setAttr,u as toKebab};
2
- //# sourceMappingURL=utilities.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utilities.js","names":[],"sources":["../../src/core/utilities.ts"],"sourcesContent":["/**\n * Utilities — DOM helpers, ID generation, event handling, CSS compilation, and emit functions.\n *\n * This module consolidates:\n * - DOM and string utilities (setAttr, listen, createId, createFormIds, guard, escapeHtml, toKebab)\n * - ID generation and form field ID helpers\n * - Emitter for type-safe custom events\n * - CSS template tag and stylesheet caching\n * - Style loader for adoptedStyleSheets\n */\n\nimport { currentRuntime, fire } from './runtime-lifecycle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// COMMON DOM & STRING UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Counter singletons ───────────────────────────────────────────────────────\nlet _idCounter = 0;\n\n/** @internal — resets the ID counter. Used by _resetCounters in test/test.ts. */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n};\n\n// ─── Shared DOM/string utilities ──────────────────────────────────────────────\n/** Iterate an iterable and call every function in it. */\nexport const runAll = (fns: Iterable<() => void>): void => {\n for (const fn of fns) fn();\n};\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n // Avoid inline event-handler attributes (onclick, onerror, ...) to reduce injection risk.\n if (/^on/i.test(name)) {\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n } else if (val === true) {\n el.setAttribute(name, '');\n } else {\n el.setAttribute(name, String(val));\n }\n};\n\nexport const listen = (\n el: EventTarget,\n name: string,\n handler: (e: any) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const listener: EventListener = handler as EventListener;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\n/**\n * Creates a unique, stable ID string — suitable for `aria-labelledby`, `aria-describedby`,\n * and similar accessibility linkages. Call once per component instance (at setup time or inside `onMount`).\n */\nexport const createId = (prefix?: string): string => `${prefix ? `${prefix}-` : 'cft-'}${++_idCounter}`;\n\n/**\n * Generates a stable set of ARIA-related IDs for a form control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n * `name` must be a non-empty string — callers that need a generated ID should\n * pass `createId(prefix)` as the name argument.\n *\n * @example\n * const { fieldId, labelId, helperId, errorId } = createFormIds('input', props.name.value);\n */\nexport const createFormIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name : createId(prefix);\n const fieldId = `${prefix}-${normalizedName}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelId: `label-${fieldId}`,\n };\n};\n\n/**\n * Wraps an event handler with a guard condition. The handler is only invoked when `condition()` returns `true`.\n * Use for disabled checks, readonly guards, or any runtime condition.\n *\n * @example\n * const handleClick = guard(() => !props.disabled.value, (e) => toggle(e));\n */\nexport const guard =\n <E extends Event = Event>(condition: () => unknown, handler: (e: E) => void): ((e: E) => void) =>\n (e) => {\n if (condition()) handler(e);\n };\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nconst _ESC: Record<string, string> = { \"'\": '&#39;', '\"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };\n\n/**\n * Escapes HTML entity characters (`&`, `<`, `>`, `\"`, `'`) in a value.\n * **Safe only in HTML text/attribute contexts.** Do NOT use for CSS values,\n * `javascript:` URLs, event handler attributes, or inline `<script>` content.\n */\nexport const escapeHtml = (value: unknown): string => String(value).replace(/[&<>\"']/g, (c) => _ESC[c]);\n\n// ─────────────────────────────────────────────────────────────────────────────\n// EMIT FUNCTION (TYPE-SAFE CUSTOM EVENTS)\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\nexport type EmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): void;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): void;\n};\n\nexport const createEmitFn = <T extends Record<string, unknown>>(): EmitFn<T> => {\n const el = currentRuntime().el;\n\n return ((event: keyof T, ...rest: unknown[]) => {\n fire.custom(el, String(event), rest.length > 0 ? { detail: rest[0] } : undefined);\n }) as EmitFn<T>;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS & STYLESHEET UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: unknown[]): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += v && typeof v === 'object' && 'content' in v ? (v as CSSResult).content : (v ?? '');\n }\n }\n\n return { content: content.trim(), toString: cssResultToString };\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n stylesheetStringCache.set(cssText, sheet);\n } catch (err) {\n console.error(`[craftit:E2] style replace failed`, err);\n }\n\n return sheet;\n};\n"],"mappings":"kEAkBA,IAAI,EAAa,EAGJ,MAA8B,CACzC,EAAa,GAKF,EAAU,GAAoC,CACzD,IAAK,IAAM,KAAM,EAAK,GAAI,EAGf,GAAW,EAAa,EAAc,IAAuB,CAExE,GAAI,OAAO,KAAK,EAAK,CAAE,CACrB,EAAG,gBAAgB,EAAK,CAExB,OAGE,GAAO,MAAQ,IAAQ,GACzB,EAAG,gBAAgB,EAAK,CACf,IAAQ,GACjB,EAAG,aAAa,EAAM,GAAG,CAEzB,EAAG,aAAa,EAAM,OAAO,EAAI,CAAC,EAIzB,GACX,EACA,EACA,EACA,IACiB,CACjB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,EAAQ,KAE/B,EAAG,oBAAoB,EAAM,EAAU,EAAQ,EAOjD,EAAY,GAA4B,GAAG,EAAS,GAAG,EAAO,GAAK,SAAS,EAAE,IAW9E,GAAiB,EAAgB,IAAyB,CAErE,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,MAAM,CAAG,EAAO,EAAS,EAAO,GAGpE,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,QAAS,SAAS,IACnB,EAUU,GACe,EAA0B,IACnD,GAAM,CACD,GAAW,EAAE,EAAQ,EAAE,EAGlB,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,aAAa,GAAG,CAE7F,EAA+B,CAAE,IAAK,QAAS,IAAK,SAAU,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,CAO/F,EAAc,GAA2B,OAAO,EAAM,CAAC,QAAQ,WAAa,GAAM,EAAK,GAAG,CAgB1F,MAAmE,CAC9E,IAAM,EAAK,GAAgB,CAAC,GAE5B,QAAS,EAAgB,GAAG,IAAoB,CAC9C,EAAK,OAAO,EAAI,OAAO,EAAM,CAAE,EAAK,OAAS,EAAI,CAAE,OAAQ,EAAK,GAAI,CAAG,IAAA,GAAU,IAa/E,EAAoB,UAAmC,CAC3D,OAAO,KAAK,SAGD,GAAO,EAA+B,GAAG,IAAiC,CACrF,IAAI,EAAU,GAEd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAGlC,GAFA,GAAW,EAAQ,GAEf,EAAI,EAAO,OAAQ,CACrB,IAAM,EAAI,EAAO,GAEjB,GAAW,GAAK,OAAO,GAAM,UAAY,YAAa,EAAK,EAAgB,QAAW,GAAK,GAI/F,MAAO,CAAE,QAAS,EAAQ,MAAM,CAAE,SAAU,EAAmB,EAG3D,EAAwB,IAAI,IAErB,EAAkB,GAA6D,CAC1F,GAAI,aAAiB,cAAe,OAAO,EAE3C,IAAM,EAAU,OAAO,GAAU,SAAW,EAAQ,EAAM,QACpD,EAAS,EAAsB,IAAI,EAAQ,CAEjD,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAQ,IAAI,cAElB,GAAI,CACF,EAAM,YAAY,EAAQ,CAC1B,EAAsB,IAAI,EAAS,EAAM,OAClC,EAAK,CACZ,QAAQ,MAAM,oCAAqC,EAAI,CAGzD,OAAO"}
@@ -1 +0,0 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./spread.cjs`),t=require(`./attr.cjs`),n=require(`./bind.cjs`),r=require(`./choose.cjs`),i=require(`./classes.cjs`),a=require(`./each.cjs`),o=require(`./match.cjs`),s=require(`./memo.cjs`),c=require(`./on.cjs`),l=require(`./raw.cjs`),u=require(`./style.cjs`),d=require(`./until.cjs`),f=require(`./when.cjs`);exports.attr=t.attr,exports.bind=n.bind,exports.choose=r.choose,exports.classes=i.classes,exports.each=a.each,exports.match=o.match,exports.memo=s.memo,exports.on=c.on,exports.raw=l.raw,exports.spread=e.spread,exports.style=u.style,exports.until=d.until,exports.when=f.when;
@@ -1 +0,0 @@
1
- import{spread as e}from"./spread.js";import{attr as t}from"./attr.js";import{bind as n}from"./bind.js";import{choose as r}from"./choose.js";import{classes as i}from"./classes.js";import{each as a}from"./each.js";import{match as o}from"./match.js";import{memo as s}from"./memo.js";import{on as c}from"./on.js";import{raw as l}from"./raw.js";import{style as u}from"./style.js";import{until as d}from"./until.js";import{when as f}from"./when.js";export{t as attr,n as bind,r as choose,i as classes,a as each,o as match,s as memo,c as on,l as raw,e as spread,u as style,d as until,f as when};
@@ -1,2 +0,0 @@
1
- let e=require(`@vielzeug/stateit`);function t(...t){let n=t[t.length-1],r=typeof n==`function`&&!Array.isArray(n),i=r?t.slice(0,-1):t,a=r?n:void 0,o=t=>(0,e.isSignal)(t)?!!t.value:typeof t==`function`?!!t():!!t,s=()=>{for(let[e,t]of i)if(o(e))return t();return a?.()??``};return i.some(([t])=>(0,e.isSignal)(t)||typeof t==`function`)?s:s()}exports.match=t;
2
- //# sourceMappingURL=match.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"match.cjs","names":[],"sources":["../../src/directives/match.ts"],"sourcesContent":["import { isSignal, type ReadonlySignal } from '@vielzeug/stateit';\n\nimport type { HTMLResult } from '../core/internal';\n\ntype TemplateFn = () => string | HTMLResult;\ntype Branch = readonly [unknown, TemplateFn];\n\n/**\n * Multi-branch conditional rendering. Pass branches as individual `[condition, templateFn]`\n * tuples (variadic), with an optional trailing `fallback` function.\n * Renders the first truthy branch, or the fallback when no branch matches.\n *\n * Reactive when any condition is a Signal or getter function — the output updates\n * automatically whenever a reactive condition changes.\n *\n * @example\n * import { match } from '@vielzeug/craftit/directives';\n *\n * // Static — evaluated once\n * html`${match(\n * [isAdmin, () => html`<admin-panel>`],\n * [isModerator, () => html`<mod-panel>`],\n * () => html`<user-panel>`,\n * )}`\n *\n * // Reactive Signal conditions\n * html`${match(\n * [isAdmin, () => html`<admin-panel>`],\n * [isLoggedIn, () => html`<user-panel>`],\n * () => html`<guest-panel>`,\n * )}`\n */\nexport function match(...args: (Branch | TemplateFn)[]): TemplateFn | string | HTMLResult {\n // Separate branches from optional trailing fallback function.\n // A Branch is a tuple [condition, fn] (an array); a TemplateFn is a bare () => ... function.\n const lastArg = args[args.length - 1];\n const hasFallback = typeof lastArg === 'function' && !Array.isArray(lastArg);\n const branches = (hasFallback ? args.slice(0, -1) : args) as Branch[];\n const fallback = hasFallback ? (lastArg as TemplateFn) : undefined;\n\n const resolve = (cond: unknown): boolean => {\n if (isSignal(cond)) return !!(cond as ReadonlySignal<unknown>).value;\n\n if (typeof cond === 'function') return !!(cond as () => unknown)();\n\n return !!cond;\n };\n\n const evaluate = (): string | HTMLResult => {\n for (const [cond, fn] of branches) {\n if (resolve(cond)) return fn();\n }\n\n return fallback?.() ?? '';\n };\n\n const reactive = branches.some(([cond]) => isSignal(cond) || typeof cond === 'function');\n\n return reactive ? evaluate : evaluate();\n}\n"],"mappings":"mCAgCA,SAAgB,EAAM,GAAG,EAAiE,CAGxF,IAAM,EAAU,EAAK,EAAK,OAAS,GAC7B,EAAc,OAAO,GAAY,YAAc,CAAC,MAAM,QAAQ,EAAQ,CACtE,EAAY,EAAc,EAAK,MAAM,EAAG,GAAG,CAAG,EAC9C,EAAW,EAAe,EAAyB,IAAA,GAEnD,EAAW,IACf,EAAA,EAAA,UAAa,EAAK,CAAS,CAAC,CAAE,EAAiC,MAE3D,OAAO,GAAS,WAAmB,CAAC,CAAE,GAAwB,CAE3D,CAAC,CAAC,EAGL,MAAsC,CAC1C,IAAK,GAAM,CAAC,EAAM,KAAO,EACvB,GAAI,EAAQ,EAAK,CAAE,OAAO,GAAI,CAGhC,OAAO,KAAY,EAAI,IAKzB,OAFiB,EAAS,MAAM,CAAC,MAAA,EAAA,EAAA,UAAmB,EAAK,EAAI,OAAO,GAAS,WAAW,CAEtE,EAAW,GAAU"}
@@ -1,31 +0,0 @@
1
- import type { HTMLResult } from '../core/internal';
2
- type TemplateFn = () => string | HTMLResult;
3
- type Branch = readonly [unknown, TemplateFn];
4
- /**
5
- * Multi-branch conditional rendering. Pass branches as individual `[condition, templateFn]`
6
- * tuples (variadic), with an optional trailing `fallback` function.
7
- * Renders the first truthy branch, or the fallback when no branch matches.
8
- *
9
- * Reactive when any condition is a Signal or getter function — the output updates
10
- * automatically whenever a reactive condition changes.
11
- *
12
- * @example
13
- * import { match } from '@vielzeug/craftit/directives';
14
- *
15
- * // Static — evaluated once
16
- * html`${match(
17
- * [isAdmin, () => html`<admin-panel>`],
18
- * [isModerator, () => html`<mod-panel>`],
19
- * () => html`<user-panel>`,
20
- * )}`
21
- *
22
- * // Reactive Signal conditions
23
- * html`${match(
24
- * [isAdmin, () => html`<admin-panel>`],
25
- * [isLoggedIn, () => html`<user-panel>`],
26
- * () => html`<guest-panel>`,
27
- * )}`
28
- */
29
- export declare function match(...args: (Branch | TemplateFn)[]): TemplateFn | string | HTMLResult;
30
- export {};
31
- //# sourceMappingURL=match.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/directives/match.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,KAAK,UAAU,GAAG,MAAM,MAAM,GAAG,UAAU,CAAC;AAC5C,KAAK,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CA2BxF"}
@@ -1,2 +0,0 @@
1
- import{isSignal as e}from"@vielzeug/stateit";function t(...t){let n=t[t.length-1],r=typeof n==`function`&&!Array.isArray(n),i=r?t.slice(0,-1):t,a=r?n:void 0,o=t=>e(t)?!!t.value:typeof t==`function`?!!t():!!t,s=()=>{for(let[e,t]of i)if(o(e))return t();return a?.()??``};return i.some(([t])=>e(t)||typeof t==`function`)?s:s()}export{t as match};
2
- //# sourceMappingURL=match.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"match.js","names":[],"sources":["../../src/directives/match.ts"],"sourcesContent":["import { isSignal, type ReadonlySignal } from '@vielzeug/stateit';\n\nimport type { HTMLResult } from '../core/internal';\n\ntype TemplateFn = () => string | HTMLResult;\ntype Branch = readonly [unknown, TemplateFn];\n\n/**\n * Multi-branch conditional rendering. Pass branches as individual `[condition, templateFn]`\n * tuples (variadic), with an optional trailing `fallback` function.\n * Renders the first truthy branch, or the fallback when no branch matches.\n *\n * Reactive when any condition is a Signal or getter function — the output updates\n * automatically whenever a reactive condition changes.\n *\n * @example\n * import { match } from '@vielzeug/craftit/directives';\n *\n * // Static — evaluated once\n * html`${match(\n * [isAdmin, () => html`<admin-panel>`],\n * [isModerator, () => html`<mod-panel>`],\n * () => html`<user-panel>`,\n * )}`\n *\n * // Reactive Signal conditions\n * html`${match(\n * [isAdmin, () => html`<admin-panel>`],\n * [isLoggedIn, () => html`<user-panel>`],\n * () => html`<guest-panel>`,\n * )}`\n */\nexport function match(...args: (Branch | TemplateFn)[]): TemplateFn | string | HTMLResult {\n // Separate branches from optional trailing fallback function.\n // A Branch is a tuple [condition, fn] (an array); a TemplateFn is a bare () => ... function.\n const lastArg = args[args.length - 1];\n const hasFallback = typeof lastArg === 'function' && !Array.isArray(lastArg);\n const branches = (hasFallback ? args.slice(0, -1) : args) as Branch[];\n const fallback = hasFallback ? (lastArg as TemplateFn) : undefined;\n\n const resolve = (cond: unknown): boolean => {\n if (isSignal(cond)) return !!(cond as ReadonlySignal<unknown>).value;\n\n if (typeof cond === 'function') return !!(cond as () => unknown)();\n\n return !!cond;\n };\n\n const evaluate = (): string | HTMLResult => {\n for (const [cond, fn] of branches) {\n if (resolve(cond)) return fn();\n }\n\n return fallback?.() ?? '';\n };\n\n const reactive = branches.some(([cond]) => isSignal(cond) || typeof cond === 'function');\n\n return reactive ? evaluate : evaluate();\n}\n"],"mappings":"6CAgCA,SAAgB,EAAM,GAAG,EAAiE,CAGxF,IAAM,EAAU,EAAK,EAAK,OAAS,GAC7B,EAAc,OAAO,GAAY,YAAc,CAAC,MAAM,QAAQ,EAAQ,CACtE,EAAY,EAAc,EAAK,MAAM,EAAG,GAAG,CAAG,EAC9C,EAAW,EAAe,EAAyB,IAAA,GAEnD,EAAW,GACX,EAAS,EAAK,CAAS,CAAC,CAAE,EAAiC,MAE3D,OAAO,GAAS,WAAmB,CAAC,CAAE,GAAwB,CAE3D,CAAC,CAAC,EAGL,MAAsC,CAC1C,IAAK,GAAM,CAAC,EAAM,KAAO,EACvB,GAAI,EAAQ,EAAK,CAAE,OAAO,GAAI,CAGhC,OAAO,KAAY,EAAI,IAKzB,OAFiB,EAAS,MAAM,CAAC,KAAU,EAAS,EAAK,EAAI,OAAO,GAAS,WAAW,CAEtE,EAAW,GAAU"}
@@ -1,2 +0,0 @@
1
- const e=require(`../core/runtime-lifecycle.cjs`),t=require(`../core/utilities.cjs`);require(`../core/runtime.cjs`);function n(n,r){let i=r.labelId||t.createId(`a11y-label`),a=r.helperId||t.createId(`a11y-helper`),o=null;return n.setAttribute(`role`,r.role),e.onMount(()=>{let t=n.shadowRoot;if(t&&(o=t.querySelector(`[data-a11y-helper]`)),t){let e=t.querySelector(`[data-a11y-label]`);if(e){let t=e.querySelector(`slot`);(t?t.assignedNodes().length>0:e.textContent?.trim().length??!1)&&(e.id=i,n.setAttribute(`aria-labelledby`,i))}}e.effect(()=>{if(r.checked){let e=r.checked();e!==void 0&&n.setAttribute(`aria-checked`,e)}if(r.invalid){let e=r.invalid();n.setAttribute(`aria-invalid`,String(e))}if(r.helperText&&o){let e=r.helperText();e?(o.textContent=e,o.hidden=!1,n.setAttribute(`aria-describedby`,a),(r.helperTone?.()??`default`)===`error`?o.setAttribute(`role`,`alert`):o.removeAttribute(`role`)):(o.hidden=!0,n.removeAttribute(`aria-describedby`))}})}),{helperId:a,labelId:i}}exports.useA11yControl=n;
2
- //# sourceMappingURL=a11y.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"a11y.cjs","names":[],"sources":["../../src/labs/a11y.ts"],"sourcesContent":["import { effect, onMount } from '../core/runtime';\nimport { createId } from '../core/utilities';\n\n/**\n * Tone of helper/error text: 'default' for helper, 'error' for error message.\n */\nexport type A11yTone = 'default' | 'error';\n\n/**\n * Configuration for `useA11yControl()`.\n *\n * Label presence is detected via DOM query (not heuristics).\n * All other state getters are reactive and can change over time.\n */\nexport type A11yControlConfig = {\n /** Reactive aria-checked value ('true' | 'false' | 'mixed' | undefined) */\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n /** Optional: custom helper ID instead of auto-generated */\n helperId?: string;\n /** Helper text content (mutually exclusive with explicit label/helper management) */\n helperText?: () => string | undefined;\n /** Tone of helper text: 'error' to set role=\"alert\", 'default' otherwise */\n helperTone?: () => A11yTone;\n /** Reactive aria-invalid value */\n invalid?: () => boolean;\n /** Optional: custom label ID instead of auto-generated */\n labelId?: string;\n /** ARIA role (e.g., 'checkbox', 'radio', 'switch') */\n role: string;\n};\n\n/**\n * Return value from `useA11yControl()`.\n */\nexport type A11yControlHandle = {\n /** ID for helper text element */\n helperId: string;\n /** ID for label element */\n labelId: string;\n};\n\n/**\n * Manages ARIA attributes, IDs, and helper/error live region for accessible form controls.\n *\n * Encapsulates:\n * - Stable ID generation for labels and helpers\n * - `aria-labelledby` wiring when label is present (detected via DOM query)\n * - `aria-describedby` wiring when helper text is present\n * - `aria-invalid` sync with error state\n * - `aria-checked` for checkable controls\n * - Helper text live region with `aria-live=\"polite\"` or `role=\"alert\"` based on tone\n *\n * @example\n * const a11y = useA11yControl(host, {\n * role: 'checkbox',\n * checked: () => indeterminate.value ? 'mixed' : String(checked.value),\n * invalid: () => !!error.value,\n * helperText: () => error.value || helper.value,\n * helperTone: () => error.value ? 'error' : 'default',\n * });\n *\n * // Later in template:\n * // <span id=${a11y.labelId}>Label</span>\n * // <div id=${a11y.helperId} aria-live=\"polite\">Error or helper text</div>\n */\nexport function useA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle {\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n let helperElement: HTMLDivElement | null = null;\n\n // Set role once at setup\n host.setAttribute('role', config.role);\n\n onMount(() => {\n // Find helper element in shadow DOM\n const shadow = host.shadowRoot;\n\n if (shadow) {\n helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLDivElement | null;\n }\n\n // Detect label presence via DOM query: check if label span has slotted content\n if (shadow) {\n const labelSpan = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n\n if (labelSpan) {\n // Check if the label slot has any assigned nodes\n const slot = labelSpan.querySelector('slot') as HTMLSlotElement | null;\n const hasLabelContent = slot\n ? slot.assignedNodes().length > 0\n : (labelSpan.textContent?.trim().length ?? 0 > 0);\n\n if (hasLabelContent) {\n labelSpan.id = labelId;\n host.setAttribute('aria-labelledby', labelId);\n }\n }\n }\n\n // Reactive effects for aria attrs that can change\n effect(() => {\n // aria-checked\n if (config.checked) {\n const checked = config.checked();\n\n if (checked !== undefined) {\n host.setAttribute('aria-checked', checked);\n }\n }\n\n // aria-invalid\n if (config.invalid) {\n const invalid = config.invalid();\n\n host.setAttribute('aria-invalid', String(invalid));\n }\n\n // Helper text and describedby\n if (config.helperText && helperElement) {\n const text = config.helperText();\n\n if (text) {\n helperElement.textContent = text;\n helperElement.hidden = false;\n host.setAttribute('aria-describedby', helperId);\n\n // Set role based on explicit tone (no text heuristics)\n const tone = config.helperTone?.() ?? 'default';\n\n if (tone === 'error') {\n helperElement.setAttribute('role', 'alert');\n } else {\n helperElement.removeAttribute('role');\n }\n } else {\n helperElement.hidden = true;\n host.removeAttribute('aria-describedby');\n }\n }\n });\n });\n\n return {\n helperId,\n labelId,\n };\n}\n"],"mappings":"mHAiEA,SAAgB,EAAe,EAAmB,EAA8C,CAC9F,IAAM,EAAU,EAAO,SAAW,EAAA,SAAS,aAAa,CAClD,EAAW,EAAO,UAAY,EAAA,SAAS,cAAc,CAEvD,EAAuC,KA0E3C,OAvEA,EAAK,aAAa,OAAQ,EAAO,KAAK,CAEtC,EAAA,YAAc,CAEZ,IAAM,EAAS,EAAK,WAOpB,GALI,IACF,EAAgB,EAAO,cAAc,qBAAqB,EAIxD,EAAQ,CACV,IAAM,EAAY,EAAO,cAAc,oBAAoB,CAE3D,GAAI,EAAW,CAEb,IAAM,EAAO,EAAU,cAAc,OAAO,EACpB,EACpB,EAAK,eAAe,CAAC,OAAS,EAC7B,EAAU,aAAa,MAAM,CAAC,QAAU,MAG3C,EAAU,GAAK,EACf,EAAK,aAAa,kBAAmB,EAAQ,GAMnD,EAAA,WAAa,CAEX,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAE5B,IAAY,IAAA,IACd,EAAK,aAAa,eAAgB,EAAQ,CAK9C,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAEhC,EAAK,aAAa,eAAgB,OAAO,EAAQ,CAAC,CAIpD,GAAI,EAAO,YAAc,EAAe,CACtC,IAAM,EAAO,EAAO,YAAY,CAE5B,GACF,EAAc,YAAc,EAC5B,EAAc,OAAS,GACvB,EAAK,aAAa,mBAAoB,EAAS,EAGlC,EAAO,cAAc,EAAI,aAEzB,QACX,EAAc,aAAa,OAAQ,QAAQ,CAE3C,EAAc,gBAAgB,OAAO,GAGvC,EAAc,OAAS,GACvB,EAAK,gBAAgB,mBAAmB,IAG5C,EACF,CAEK,CACL,WACA,UACD"}
@@ -1,61 +0,0 @@
1
- /**
2
- * Tone of helper/error text: 'default' for helper, 'error' for error message.
3
- */
4
- export type A11yTone = 'default' | 'error';
5
- /**
6
- * Configuration for `useA11yControl()`.
7
- *
8
- * Label presence is detected via DOM query (not heuristics).
9
- * All other state getters are reactive and can change over time.
10
- */
11
- export type A11yControlConfig = {
12
- /** Reactive aria-checked value ('true' | 'false' | 'mixed' | undefined) */
13
- checked?: () => 'true' | 'false' | 'mixed' | undefined;
14
- /** Optional: custom helper ID instead of auto-generated */
15
- helperId?: string;
16
- /** Helper text content (mutually exclusive with explicit label/helper management) */
17
- helperText?: () => string | undefined;
18
- /** Tone of helper text: 'error' to set role="alert", 'default' otherwise */
19
- helperTone?: () => A11yTone;
20
- /** Reactive aria-invalid value */
21
- invalid?: () => boolean;
22
- /** Optional: custom label ID instead of auto-generated */
23
- labelId?: string;
24
- /** ARIA role (e.g., 'checkbox', 'radio', 'switch') */
25
- role: string;
26
- };
27
- /**
28
- * Return value from `useA11yControl()`.
29
- */
30
- export type A11yControlHandle = {
31
- /** ID for helper text element */
32
- helperId: string;
33
- /** ID for label element */
34
- labelId: string;
35
- };
36
- /**
37
- * Manages ARIA attributes, IDs, and helper/error live region for accessible form controls.
38
- *
39
- * Encapsulates:
40
- * - Stable ID generation for labels and helpers
41
- * - `aria-labelledby` wiring when label is present (detected via DOM query)
42
- * - `aria-describedby` wiring when helper text is present
43
- * - `aria-invalid` sync with error state
44
- * - `aria-checked` for checkable controls
45
- * - Helper text live region with `aria-live="polite"` or `role="alert"` based on tone
46
- *
47
- * @example
48
- * const a11y = useA11yControl(host, {
49
- * role: 'checkbox',
50
- * checked: () => indeterminate.value ? 'mixed' : String(checked.value),
51
- * invalid: () => !!error.value,
52
- * helperText: () => error.value || helper.value,
53
- * helperTone: () => error.value ? 'error' : 'default',
54
- * });
55
- *
56
- * // Later in template:
57
- * // <span id=${a11y.labelId}>Label</span>
58
- * // <div id=${a11y.helperId} aria-live="polite">Error or helper text</div>
59
- */
60
- export declare function useA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle;
61
- //# sourceMappingURL=a11y.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../src/labs/a11y.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC;IAC5B,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;IACxB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAkF9F"}
package/dist/labs/a11y.js DELETED
@@ -1,2 +0,0 @@
1
- import{effect as e,onMount as t}from"../core/runtime-lifecycle.js";import{createId as n}from"../core/utilities.js";import"../core/runtime.js";function r(r,i){let a=i.labelId||n(`a11y-label`),o=i.helperId||n(`a11y-helper`),s=null;return r.setAttribute(`role`,i.role),t(()=>{let t=r.shadowRoot;if(t&&(s=t.querySelector(`[data-a11y-helper]`)),t){let e=t.querySelector(`[data-a11y-label]`);if(e){let t=e.querySelector(`slot`);(t?t.assignedNodes().length>0:e.textContent?.trim().length??!1)&&(e.id=a,r.setAttribute(`aria-labelledby`,a))}}e(()=>{if(i.checked){let e=i.checked();e!==void 0&&r.setAttribute(`aria-checked`,e)}if(i.invalid){let e=i.invalid();r.setAttribute(`aria-invalid`,String(e))}if(i.helperText&&s){let e=i.helperText();e?(s.textContent=e,s.hidden=!1,r.setAttribute(`aria-describedby`,o),(i.helperTone?.()??`default`)===`error`?s.setAttribute(`role`,`alert`):s.removeAttribute(`role`)):(s.hidden=!0,r.removeAttribute(`aria-describedby`))}})}),{helperId:o,labelId:a}}export{r as useA11yControl};
2
- //# sourceMappingURL=a11y.js.map