@typed/template 0.14.0 → 1.0.0-beta.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 (453) hide show
  1. package/README.md +108 -2
  2. package/dist/EventHandler.d.ts +273 -0
  3. package/dist/EventHandler.d.ts.map +1 -0
  4. package/dist/EventHandler.js +261 -0
  5. package/dist/EventSource.d.ts +82 -0
  6. package/dist/EventSource.d.ts.map +1 -0
  7. package/dist/EventSource.js +127 -0
  8. package/dist/Html.d.ts +122 -0
  9. package/dist/Html.d.ts.map +1 -0
  10. package/dist/Html.js +250 -0
  11. package/dist/HtmlChunk.d.ts +118 -0
  12. package/dist/HtmlChunk.d.ts.map +1 -0
  13. package/dist/HtmlChunk.js +211 -0
  14. package/dist/HydrateContext.d.ts +28 -0
  15. package/dist/HydrateContext.d.ts.map +1 -0
  16. package/dist/HydrateContext.js +25 -0
  17. package/dist/Parser.d.ts +35 -0
  18. package/dist/Parser.d.ts.map +1 -0
  19. package/dist/Parser.js +437 -0
  20. package/dist/Render.d.ts +195 -0
  21. package/dist/Render.d.ts.map +1 -0
  22. package/dist/Render.js +609 -0
  23. package/dist/RenderEvent.d.ts +179 -0
  24. package/dist/RenderEvent.d.ts.map +1 -0
  25. package/dist/RenderEvent.js +102 -0
  26. package/dist/RenderQueue.d.ts +167 -0
  27. package/dist/RenderQueue.d.ts.map +1 -0
  28. package/dist/RenderQueue.js +297 -0
  29. package/dist/RenderTemplate.d.ts +90 -0
  30. package/dist/RenderTemplate.d.ts.map +1 -0
  31. package/dist/RenderTemplate.js +87 -0
  32. package/dist/Renderable.d.ts +88 -0
  33. package/dist/Renderable.d.ts.map +1 -0
  34. package/dist/Renderable.js +3 -0
  35. package/dist/{dts/Template.d.ts → Template.d.ts} +109 -74
  36. package/dist/Template.d.ts.map +1 -0
  37. package/dist/{esm/Template.js → Template.js} +96 -56
  38. package/dist/Wire.d.ts +169 -0
  39. package/dist/Wire.d.ts.map +1 -0
  40. package/dist/Wire.js +217 -0
  41. package/dist/errors.d.ts +145 -0
  42. package/dist/errors.d.ts.map +1 -0
  43. package/dist/errors.js +159 -0
  44. package/dist/index.d.ts +15 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +14 -0
  47. package/dist/internal/IndexRefCounter.d.ts +11 -0
  48. package/dist/internal/IndexRefCounter.d.ts.map +1 -0
  49. package/dist/internal/IndexRefCounter.js +42 -0
  50. package/dist/internal/ParentChildNodes.d.ts +6 -0
  51. package/dist/internal/ParentChildNodes.d.ts.map +1 -0
  52. package/dist/internal/ParentChildNodes.js +1 -0
  53. package/dist/internal/PathStack.d.ts +9 -0
  54. package/dist/internal/PathStack.d.ts.map +1 -0
  55. package/dist/internal/PathStack.js +18 -0
  56. package/dist/internal/buildTemplateFragement.d.ts +3 -0
  57. package/dist/internal/buildTemplateFragement.d.ts.map +1 -0
  58. package/dist/internal/buildTemplateFragement.js +61 -0
  59. package/dist/internal/diff.d.ts +2 -0
  60. package/dist/internal/diff.d.ts.map +1 -0
  61. package/dist/internal/diff.js +119 -0
  62. package/dist/internal/dom.d.ts +45 -0
  63. package/dist/internal/dom.d.ts.map +1 -0
  64. package/dist/internal/dom.js +304 -0
  65. package/dist/internal/encoding.d.ts +7 -0
  66. package/dist/internal/encoding.d.ts.map +1 -0
  67. package/dist/internal/encoding.js +134 -0
  68. package/dist/{dts/internal/v2/hydration-template.d.ts → internal/hydration.d.ts} +10 -7
  69. package/dist/internal/hydration.d.ts.map +1 -0
  70. package/dist/{esm/internal/v2/hydration-template.js → internal/hydration.js} +80 -26
  71. package/dist/internal/keyToPartType.d.ts +2 -0
  72. package/dist/internal/keyToPartType.d.ts.map +1 -0
  73. package/dist/internal/keyToPartType.js +110 -0
  74. package/dist/internal/meta.d.ts +17 -0
  75. package/dist/internal/meta.d.ts.map +1 -0
  76. package/dist/internal/meta.js +14 -0
  77. package/dist/internal/takeOneIfNotRenderEvent.d.ts +4 -0
  78. package/dist/internal/takeOneIfNotRenderEvent.d.ts.map +1 -0
  79. package/dist/internal/takeOneIfNotRenderEvent.js +10 -0
  80. package/dist/internal/templateHash.d.ts +2 -0
  81. package/dist/internal/templateHash.d.ts.map +1 -0
  82. package/dist/internal/templateHash.js +14 -0
  83. package/dist/many.d.ts +68 -0
  84. package/dist/many.d.ts.map +1 -0
  85. package/dist/many.js +107 -0
  86. package/package.json +22 -224
  87. package/src/EventHandler.ts +318 -86
  88. package/src/EventSource.ts +202 -0
  89. package/src/Html.test.ts +490 -0
  90. package/src/Html.ts +292 -333
  91. package/src/HtmlChunk.ts +290 -332
  92. package/src/HydrateContext.ts +40 -0
  93. package/src/Hydration.test.ts +409 -0
  94. package/src/Parser.test.ts +924 -0
  95. package/src/Parser.ts +598 -10
  96. package/src/Render.test.ts +338 -0
  97. package/src/Render.ts +878 -63
  98. package/src/RenderEvent.ts +169 -40
  99. package/src/RenderQueue.ts +290 -385
  100. package/src/RenderTemplate.ts +98 -31
  101. package/src/Renderable.ts +122 -24
  102. package/src/Template.ts +246 -145
  103. package/src/Wire.ts +309 -0
  104. package/src/errors.ts +173 -0
  105. package/src/index.ts +14 -66
  106. package/src/internal/IndexRefCounter.ts +53 -0
  107. package/src/internal/ParentChildNodes.ts +7 -0
  108. package/src/internal/PathStack.ts +23 -0
  109. package/src/internal/buildTemplateFragement.ts +82 -0
  110. package/src/internal/diff.ts +127 -0
  111. package/src/internal/dom.ts +357 -0
  112. package/src/internal/encoding.ts +147 -0
  113. package/src/internal/hydration.ts +406 -0
  114. package/src/internal/keyToPartType.ts +113 -0
  115. package/src/internal/meta.ts +25 -0
  116. package/src/internal/takeOneIfNotRenderEvent.ts +19 -0
  117. package/src/internal/templateHash.ts +18 -0
  118. package/src/many.ts +148 -0
  119. package/tsconfig.json +6 -0
  120. package/Directive/package.json +0 -6
  121. package/ElementRef/package.json +0 -6
  122. package/ElementSource/package.json +0 -6
  123. package/Entry/package.json +0 -6
  124. package/EventHandler/package.json +0 -6
  125. package/Html/package.json +0 -6
  126. package/HtmlChunk/package.json +0 -6
  127. package/Hydrate/package.json +0 -6
  128. package/LICENSE +0 -21
  129. package/Many/package.json +0 -6
  130. package/Meta/package.json +0 -6
  131. package/Parser/package.json +0 -6
  132. package/Part/package.json +0 -6
  133. package/Placeholder/package.json +0 -6
  134. package/Platform/package.json +0 -6
  135. package/Render/package.json +0 -6
  136. package/RenderContext/package.json +0 -6
  137. package/RenderEvent/package.json +0 -6
  138. package/RenderQueue/package.json +0 -6
  139. package/RenderTemplate/package.json +0 -6
  140. package/Renderable/package.json +0 -6
  141. package/Template/package.json +0 -6
  142. package/Test/package.json +0 -6
  143. package/Vitest/package.json +0 -6
  144. package/compiler-tools/package.json +0 -6
  145. package/dist/cjs/Directive.js +0 -76
  146. package/dist/cjs/Directive.js.map +0 -1
  147. package/dist/cjs/ElementRef.js +0 -92
  148. package/dist/cjs/ElementRef.js.map +0 -1
  149. package/dist/cjs/ElementSource.js +0 -246
  150. package/dist/cjs/ElementSource.js.map +0 -1
  151. package/dist/cjs/Entry.js +0 -6
  152. package/dist/cjs/Entry.js.map +0 -1
  153. package/dist/cjs/EventHandler.js +0 -76
  154. package/dist/cjs/EventHandler.js.map +0 -1
  155. package/dist/cjs/Html.js +0 -224
  156. package/dist/cjs/Html.js.map +0 -1
  157. package/dist/cjs/HtmlChunk.js +0 -306
  158. package/dist/cjs/HtmlChunk.js.map +0 -1
  159. package/dist/cjs/Hydrate.js +0 -43
  160. package/dist/cjs/Hydrate.js.map +0 -1
  161. package/dist/cjs/Many.js +0 -66
  162. package/dist/cjs/Many.js.map +0 -1
  163. package/dist/cjs/Meta.js +0 -50
  164. package/dist/cjs/Meta.js.map +0 -1
  165. package/dist/cjs/Parser.js +0 -19
  166. package/dist/cjs/Parser.js.map +0 -1
  167. package/dist/cjs/Part.js +0 -6
  168. package/dist/cjs/Part.js.map +0 -1
  169. package/dist/cjs/Placeholder.js +0 -34
  170. package/dist/cjs/Placeholder.js.map +0 -1
  171. package/dist/cjs/Platform.js +0 -65
  172. package/dist/cjs/Platform.js.map +0 -1
  173. package/dist/cjs/Render.js +0 -50
  174. package/dist/cjs/Render.js.map +0 -1
  175. package/dist/cjs/RenderContext.js +0 -67
  176. package/dist/cjs/RenderContext.js.map +0 -1
  177. package/dist/cjs/RenderEvent.js +0 -52
  178. package/dist/cjs/RenderEvent.js.map +0 -1
  179. package/dist/cjs/RenderQueue.js +0 -343
  180. package/dist/cjs/RenderQueue.js.map +0 -1
  181. package/dist/cjs/RenderTemplate.js +0 -26
  182. package/dist/cjs/RenderTemplate.js.map +0 -1
  183. package/dist/cjs/Renderable.js +0 -6
  184. package/dist/cjs/Renderable.js.map +0 -1
  185. package/dist/cjs/Template.js +0 -305
  186. package/dist/cjs/Template.js.map +0 -1
  187. package/dist/cjs/Test.js +0 -184
  188. package/dist/cjs/Test.js.map +0 -1
  189. package/dist/cjs/Vitest.js +0 -52
  190. package/dist/cjs/Vitest.js.map +0 -1
  191. package/dist/cjs/compiler-tools.js +0 -100
  192. package/dist/cjs/compiler-tools.js.map +0 -1
  193. package/dist/cjs/index.js +0 -138
  194. package/dist/cjs/index.js.map +0 -1
  195. package/dist/cjs/internal/EventSource.js +0 -129
  196. package/dist/cjs/internal/EventSource.js.map +0 -1
  197. package/dist/cjs/internal/HydrateContext.js +0 -13
  198. package/dist/cjs/internal/HydrateContext.js.map +0 -1
  199. package/dist/cjs/internal/browser.js +0 -110
  200. package/dist/cjs/internal/browser.js.map +0 -1
  201. package/dist/cjs/internal/character-entities.js +0 -2141
  202. package/dist/cjs/internal/character-entities.js.map +0 -1
  203. package/dist/cjs/internal/chunks.js +0 -68
  204. package/dist/cjs/internal/chunks.js.map +0 -1
  205. package/dist/cjs/internal/errors.js +0 -52
  206. package/dist/cjs/internal/errors.js.map +0 -1
  207. package/dist/cjs/internal/indexRefCounter.js +0 -52
  208. package/dist/cjs/internal/indexRefCounter.js.map +0 -1
  209. package/dist/cjs/internal/module-augmentation.js +0 -6
  210. package/dist/cjs/internal/module-augmentation.js.map +0 -1
  211. package/dist/cjs/internal/parser.js +0 -568
  212. package/dist/cjs/internal/parser.js.map +0 -1
  213. package/dist/cjs/internal/parser2.js +0 -382
  214. package/dist/cjs/internal/parser2.js.map +0 -1
  215. package/dist/cjs/internal/server-parts.js +0 -124
  216. package/dist/cjs/internal/server-parts.js.map +0 -1
  217. package/dist/cjs/internal/server.js +0 -48
  218. package/dist/cjs/internal/server.js.map +0 -1
  219. package/dist/cjs/internal/utils.js +0 -136
  220. package/dist/cjs/internal/utils.js.map +0 -1
  221. package/dist/cjs/internal/v2/SyncPart.js +0 -6
  222. package/dist/cjs/internal/v2/SyncPart.js.map +0 -1
  223. package/dist/cjs/internal/v2/helpers.js +0 -15
  224. package/dist/cjs/internal/v2/helpers.js.map +0 -1
  225. package/dist/cjs/internal/v2/hydration-template.js +0 -269
  226. package/dist/cjs/internal/v2/hydration-template.js.map +0 -1
  227. package/dist/cjs/internal/v2/parts.js +0 -169
  228. package/dist/cjs/internal/v2/parts.js.map +0 -1
  229. package/dist/cjs/internal/v2/render-entry.js +0 -110
  230. package/dist/cjs/internal/v2/render-entry.js.map +0 -1
  231. package/dist/cjs/internal/v2/render-sync-parts.js +0 -318
  232. package/dist/cjs/internal/v2/render-sync-parts.js.map +0 -1
  233. package/dist/cjs/internal/v2/render.js +0 -592
  234. package/dist/cjs/internal/v2/render.js.map +0 -1
  235. package/dist/cjs/internal/v2/sync-parts.js +0 -115
  236. package/dist/cjs/internal/v2/sync-parts.js.map +0 -1
  237. package/dist/dts/Directive.d.ts +0 -70
  238. package/dist/dts/Directive.d.ts.map +0 -1
  239. package/dist/dts/ElementRef.d.ts +0 -42
  240. package/dist/dts/ElementRef.d.ts.map +0 -1
  241. package/dist/dts/ElementSource.d.ts +0 -79
  242. package/dist/dts/ElementSource.d.ts.map +0 -1
  243. package/dist/dts/Entry.d.ts +0 -26
  244. package/dist/dts/Entry.d.ts.map +0 -1
  245. package/dist/dts/EventHandler.d.ts +0 -73
  246. package/dist/dts/EventHandler.d.ts.map +0 -1
  247. package/dist/dts/Html.d.ts +0 -35
  248. package/dist/dts/Html.d.ts.map +0 -1
  249. package/dist/dts/HtmlChunk.d.ts +0 -56
  250. package/dist/dts/HtmlChunk.d.ts.map +0 -1
  251. package/dist/dts/Hydrate.d.ts +0 -19
  252. package/dist/dts/Hydrate.d.ts.map +0 -1
  253. package/dist/dts/Many.d.ts +0 -32
  254. package/dist/dts/Many.d.ts.map +0 -1
  255. package/dist/dts/Meta.d.ts +0 -33
  256. package/dist/dts/Meta.d.ts.map +0 -1
  257. package/dist/dts/Parser.d.ts +0 -13
  258. package/dist/dts/Parser.d.ts.map +0 -1
  259. package/dist/dts/Part.d.ts +0 -121
  260. package/dist/dts/Part.d.ts.map +0 -1
  261. package/dist/dts/Placeholder.d.ts +0 -48
  262. package/dist/dts/Placeholder.d.ts.map +0 -1
  263. package/dist/dts/Platform.d.ts +0 -21
  264. package/dist/dts/Platform.d.ts.map +0 -1
  265. package/dist/dts/Render.d.ts +0 -31
  266. package/dist/dts/Render.d.ts.map +0 -1
  267. package/dist/dts/RenderContext.d.ts +0 -70
  268. package/dist/dts/RenderContext.d.ts.map +0 -1
  269. package/dist/dts/RenderEvent.d.ts +0 -42
  270. package/dist/dts/RenderEvent.d.ts.map +0 -1
  271. package/dist/dts/RenderQueue.d.ts +0 -103
  272. package/dist/dts/RenderQueue.d.ts.map +0 -1
  273. package/dist/dts/RenderTemplate.d.ts +0 -25
  274. package/dist/dts/RenderTemplate.d.ts.map +0 -1
  275. package/dist/dts/Renderable.d.ts +0 -28
  276. package/dist/dts/Renderable.d.ts.map +0 -1
  277. package/dist/dts/Template.d.ts.map +0 -1
  278. package/dist/dts/Test.d.ts +0 -85
  279. package/dist/dts/Test.d.ts.map +0 -1
  280. package/dist/dts/Vitest.d.ts +0 -43
  281. package/dist/dts/Vitest.d.ts.map +0 -1
  282. package/dist/dts/compiler-tools.d.ts +0 -143
  283. package/dist/dts/compiler-tools.d.ts.map +0 -1
  284. package/dist/dts/index.d.ts +0 -65
  285. package/dist/dts/index.d.ts.map +0 -1
  286. package/dist/dts/internal/EventSource.d.ts +0 -13
  287. package/dist/dts/internal/EventSource.d.ts.map +0 -1
  288. package/dist/dts/internal/HydrateContext.d.ts +0 -2
  289. package/dist/dts/internal/HydrateContext.d.ts.map +0 -1
  290. package/dist/dts/internal/browser.d.ts +0 -8
  291. package/dist/dts/internal/browser.d.ts.map +0 -1
  292. package/dist/dts/internal/character-entities.d.ts +0 -2133
  293. package/dist/dts/internal/character-entities.d.ts.map +0 -1
  294. package/dist/dts/internal/chunks.d.ts +0 -23
  295. package/dist/dts/internal/chunks.d.ts.map +0 -1
  296. package/dist/dts/internal/errors.d.ts +0 -22
  297. package/dist/dts/internal/errors.d.ts.map +0 -1
  298. package/dist/dts/internal/indexRefCounter.d.ts +0 -7
  299. package/dist/dts/internal/indexRefCounter.d.ts.map +0 -1
  300. package/dist/dts/internal/module-augmentation.d.ts +0 -32
  301. package/dist/dts/internal/module-augmentation.d.ts.map +0 -1
  302. package/dist/dts/internal/parser.d.ts +0 -33
  303. package/dist/dts/internal/parser.d.ts.map +0 -1
  304. package/dist/dts/internal/parser2.d.ts +0 -12
  305. package/dist/dts/internal/parser2.d.ts.map +0 -1
  306. package/dist/dts/internal/server-parts.d.ts +0 -223
  307. package/dist/dts/internal/server-parts.d.ts.map +0 -1
  308. package/dist/dts/internal/server.d.ts +0 -5
  309. package/dist/dts/internal/server.d.ts.map +0 -1
  310. package/dist/dts/internal/utils.d.ts +0 -19
  311. package/dist/dts/internal/utils.d.ts.map +0 -1
  312. package/dist/dts/internal/v2/SyncPart.d.ts +0 -87
  313. package/dist/dts/internal/v2/SyncPart.d.ts.map +0 -1
  314. package/dist/dts/internal/v2/helpers.d.ts +0 -3
  315. package/dist/dts/internal/v2/helpers.d.ts.map +0 -1
  316. package/dist/dts/internal/v2/hydration-template.d.ts.map +0 -1
  317. package/dist/dts/internal/v2/parts.d.ts +0 -245
  318. package/dist/dts/internal/v2/parts.d.ts.map +0 -1
  319. package/dist/dts/internal/v2/render-entry.d.ts +0 -6
  320. package/dist/dts/internal/v2/render-entry.d.ts.map +0 -1
  321. package/dist/dts/internal/v2/render-sync-parts.d.ts +0 -22
  322. package/dist/dts/internal/v2/render-sync-parts.d.ts.map +0 -1
  323. package/dist/dts/internal/v2/render.d.ts +0 -83
  324. package/dist/dts/internal/v2/render.d.ts.map +0 -1
  325. package/dist/dts/internal/v2/sync-parts.d.ts +0 -129
  326. package/dist/dts/internal/v2/sync-parts.d.ts.map +0 -1
  327. package/dist/esm/Directive.js +0 -64
  328. package/dist/esm/Directive.js.map +0 -1
  329. package/dist/esm/ElementRef.js +0 -76
  330. package/dist/esm/ElementRef.js.map +0 -1
  331. package/dist/esm/ElementSource.js +0 -246
  332. package/dist/esm/ElementSource.js.map +0 -1
  333. package/dist/esm/Entry.js +0 -2
  334. package/dist/esm/Entry.js.map +0 -1
  335. package/dist/esm/EventHandler.js +0 -68
  336. package/dist/esm/EventHandler.js.map +0 -1
  337. package/dist/esm/Html.js +0 -230
  338. package/dist/esm/Html.js.map +0 -1
  339. package/dist/esm/HtmlChunk.js +0 -330
  340. package/dist/esm/HtmlChunk.js.map +0 -1
  341. package/dist/esm/Hydrate.js +0 -31
  342. package/dist/esm/Hydrate.js.map +0 -1
  343. package/dist/esm/Many.js +0 -54
  344. package/dist/esm/Many.js.map +0 -1
  345. package/dist/esm/Meta.js +0 -40
  346. package/dist/esm/Meta.js.map +0 -1
  347. package/dist/esm/Parser.js +0 -13
  348. package/dist/esm/Parser.js.map +0 -1
  349. package/dist/esm/Part.js +0 -5
  350. package/dist/esm/Part.js.map +0 -1
  351. package/dist/esm/Placeholder.js +0 -26
  352. package/dist/esm/Placeholder.js.map +0 -1
  353. package/dist/esm/Platform.js +0 -42
  354. package/dist/esm/Platform.js.map +0 -1
  355. package/dist/esm/Render.js +0 -36
  356. package/dist/esm/Render.js.map +0 -1
  357. package/dist/esm/RenderContext.js +0 -54
  358. package/dist/esm/RenderContext.js.map +0 -1
  359. package/dist/esm/RenderEvent.js +0 -43
  360. package/dist/esm/RenderEvent.js.map +0 -1
  361. package/dist/esm/RenderQueue.js +0 -338
  362. package/dist/esm/RenderQueue.js.map +0 -1
  363. package/dist/esm/RenderTemplate.js +0 -16
  364. package/dist/esm/RenderTemplate.js.map +0 -1
  365. package/dist/esm/Renderable.js +0 -2
  366. package/dist/esm/Renderable.js.map +0 -1
  367. package/dist/esm/Template.js.map +0 -1
  368. package/dist/esm/Test.js +0 -167
  369. package/dist/esm/Test.js.map +0 -1
  370. package/dist/esm/Vitest.js +0 -44
  371. package/dist/esm/Vitest.js.map +0 -1
  372. package/dist/esm/compiler-tools.js +0 -91
  373. package/dist/esm/compiler-tools.js.map +0 -1
  374. package/dist/esm/index.js +0 -65
  375. package/dist/esm/index.js.map +0 -1
  376. package/dist/esm/internal/EventSource.js +0 -126
  377. package/dist/esm/internal/EventSource.js.map +0 -1
  378. package/dist/esm/internal/HydrateContext.js +0 -7
  379. package/dist/esm/internal/HydrateContext.js.map +0 -1
  380. package/dist/esm/internal/browser.js +0 -103
  381. package/dist/esm/internal/browser.js.map +0 -1
  382. package/dist/esm/internal/character-entities.js +0 -2134
  383. package/dist/esm/internal/character-entities.js.map +0 -1
  384. package/dist/esm/internal/chunks.js +0 -60
  385. package/dist/esm/internal/chunks.js.map +0 -1
  386. package/dist/esm/internal/errors.js +0 -46
  387. package/dist/esm/internal/errors.js.map +0 -1
  388. package/dist/esm/internal/indexRefCounter.js +0 -47
  389. package/dist/esm/internal/indexRefCounter.js.map +0 -1
  390. package/dist/esm/internal/module-augmentation.js +0 -2
  391. package/dist/esm/internal/module-augmentation.js.map +0 -1
  392. package/dist/esm/internal/parser.js +0 -596
  393. package/dist/esm/internal/parser.js.map +0 -1
  394. package/dist/esm/internal/parser2.js +0 -393
  395. package/dist/esm/internal/parser2.js.map +0 -1
  396. package/dist/esm/internal/server-parts.js +0 -109
  397. package/dist/esm/internal/server-parts.js.map +0 -1
  398. package/dist/esm/internal/server.js +0 -22
  399. package/dist/esm/internal/server.js.map +0 -1
  400. package/dist/esm/internal/utils.js +0 -119
  401. package/dist/esm/internal/utils.js.map +0 -1
  402. package/dist/esm/internal/v2/SyncPart.js +0 -5
  403. package/dist/esm/internal/v2/SyncPart.js.map +0 -1
  404. package/dist/esm/internal/v2/helpers.js +0 -12
  405. package/dist/esm/internal/v2/helpers.js.map +0 -1
  406. package/dist/esm/internal/v2/hydration-template.js.map +0 -1
  407. package/dist/esm/internal/v2/parts.js +0 -150
  408. package/dist/esm/internal/v2/parts.js.map +0 -1
  409. package/dist/esm/internal/v2/render-entry.js +0 -102
  410. package/dist/esm/internal/v2/render-entry.js.map +0 -1
  411. package/dist/esm/internal/v2/render-sync-parts.js +0 -265
  412. package/dist/esm/internal/v2/render-sync-parts.js.map +0 -1
  413. package/dist/esm/internal/v2/render.js +0 -521
  414. package/dist/esm/internal/v2/render.js.map +0 -1
  415. package/dist/esm/internal/v2/sync-parts.js +0 -102
  416. package/dist/esm/internal/v2/sync-parts.js.map +0 -1
  417. package/dist/esm/package.json +0 -4
  418. package/src/Directive.ts +0 -114
  419. package/src/ElementRef.ts +0 -148
  420. package/src/ElementSource.ts +0 -510
  421. package/src/Entry.ts +0 -28
  422. package/src/Hydrate.ts +0 -51
  423. package/src/Many.ts +0 -161
  424. package/src/Meta.ts +0 -45
  425. package/src/Part.ts +0 -154
  426. package/src/Placeholder.ts +0 -78
  427. package/src/Platform.ts +0 -70
  428. package/src/RenderContext.ts +0 -121
  429. package/src/Test.ts +0 -354
  430. package/src/Vitest.ts +0 -141
  431. package/src/compiler-tools.ts +0 -250
  432. package/src/internal/EventSource.ts +0 -188
  433. package/src/internal/HydrateContext.ts +0 -22
  434. package/src/internal/browser.ts +0 -138
  435. package/src/internal/character-entities.ts +0 -2136
  436. package/src/internal/chunks.ts +0 -89
  437. package/src/internal/errors.ts +0 -49
  438. package/src/internal/external.d.ts +0 -11
  439. package/src/internal/indexRefCounter.ts +0 -54
  440. package/src/internal/module-augmentation.ts +0 -44
  441. package/src/internal/parser.ts +0 -757
  442. package/src/internal/parser2.ts +0 -468
  443. package/src/internal/server-parts.ts +0 -161
  444. package/src/internal/server.ts +0 -37
  445. package/src/internal/utils.ts +0 -153
  446. package/src/internal/v2/SyncPart.ts +0 -112
  447. package/src/internal/v2/helpers.ts +0 -13
  448. package/src/internal/v2/hydration-template.ts +0 -308
  449. package/src/internal/v2/parts.ts +0 -254
  450. package/src/internal/v2/render-entry.ts +0 -131
  451. package/src/internal/v2/render-sync-parts.ts +0 -440
  452. package/src/internal/v2/render.ts +0 -813
  453. package/src/internal/v2/sync-parts.ts +0 -133
@@ -0,0 +1,82 @@
1
+ import type * as Template from "../Template.js";
2
+
3
+ export function buildTemplateFragment(
4
+ document: Document,
5
+ template: Template.Template,
6
+ ): DocumentFragment {
7
+ const root = document.createDocumentFragment();
8
+ for (const node of template.nodes) {
9
+ root.appendChild(buildTemplateNode(document, node));
10
+ }
11
+ return root;
12
+ }
13
+
14
+ function buildTemplateNode(document: Document, node: Template.Node): Node {
15
+ switch (node._tag) {
16
+ case "comment":
17
+ return document.createComment(node.value);
18
+ case "comment-part":
19
+ return document.createComment(`c_${node.index}`);
20
+ case "sparse-comment": {
21
+ return document.createComment(
22
+ `c_${node.nodes.map((n) => (n._tag === "text" ? "" : n.index)).join("_")}`,
23
+ );
24
+ }
25
+ case "doctype":
26
+ return document.implementation.createDocumentType(
27
+ node.name,
28
+ node.publicId ?? "",
29
+ node.systemId ?? "",
30
+ );
31
+ case "element":
32
+ return buildTemplateElement(document, node);
33
+ case "self-closing-element":
34
+ return buildTemplateSelfClosingElement(document, node);
35
+ case "text-only-element":
36
+ return buildTemplateTextOnlyElement(document, node);
37
+ case "text":
38
+ return document.createTextNode(node.value);
39
+ case "node":
40
+ return document.createComment(`/n_${node.index}`);
41
+ }
42
+ }
43
+
44
+ function buildTemplateElement(document: Document, node: Template.ElementNode): HTMLElement {
45
+ const element = document.createElement(node.tagName);
46
+ addStaticAttributes(element, node.attributes);
47
+ for (const child of node.children) {
48
+ element.appendChild(buildTemplateNode(document, child));
49
+ }
50
+ return element;
51
+ }
52
+
53
+ function addStaticAttributes(element: HTMLElement, attributes: Array<Template.Attribute>): void {
54
+ for (const attribute of attributes) {
55
+ if (attribute._tag === "attribute") {
56
+ element.setAttribute(attribute.name, attribute.value);
57
+ } else if (attribute._tag === "boolean") {
58
+ element.toggleAttribute(attribute.name, true);
59
+ }
60
+ }
61
+ }
62
+
63
+ function buildTemplateSelfClosingElement(
64
+ document: Document,
65
+ node: Template.SelfClosingElementNode,
66
+ ): HTMLElement {
67
+ const element = document.createElement(node.tagName);
68
+ addStaticAttributes(element, node.attributes);
69
+ return element;
70
+ }
71
+
72
+ function buildTemplateTextOnlyElement(
73
+ document: Document,
74
+ node: Template.TextOnlyElement,
75
+ ): HTMLElement {
76
+ const element = document.createElement(node.tagName);
77
+ addStaticAttributes(element, node.attributes);
78
+ if (node.textContent && node.textContent._tag === "text") {
79
+ element.textContent = node.textContent.value;
80
+ }
81
+ return element;
82
+ }
@@ -0,0 +1,127 @@
1
+ // @see https://github.com/WebReflection/udomdiff
2
+
3
+ export const diff = (
4
+ a: Array<Node>,
5
+ b: Array<Node>,
6
+ get: (entry: Node, action: number) => Node,
7
+ before: Node,
8
+ ) => {
9
+ const parentNode = before.parentNode!;
10
+ const bLength = b.length;
11
+ let aEnd = a.length;
12
+ let bEnd = bLength;
13
+ let aStart = 0;
14
+ let bStart = 0;
15
+ let map = null;
16
+ while (aStart < aEnd || bStart < bEnd) {
17
+ // append head, tail, or nodes in between: fast path
18
+ if (aEnd === aStart) {
19
+ // we could be in a situation where the rest of nodes that
20
+ // need to be added are not at the end, and in such case
21
+ // the node to `insertBefore`, if the index is more than 0
22
+ // must be retrieved, otherwise it's gonna be the first item.
23
+ const node =
24
+ bEnd < bLength ? (bStart ? get(b[bStart - 1], -0).nextSibling : get(b[bEnd], 0)) : before;
25
+ while (bStart < bEnd) {
26
+ parentNode!.insertBefore(get(b[bStart++], 1), node);
27
+ }
28
+ } // remove head or tail: fast path
29
+ else if (bEnd === bStart) {
30
+ while (aStart < aEnd) {
31
+ // remove the node only if it's unknown or not live
32
+ if (!map || !map.has(a[aStart])) {
33
+ // @ts-ignore
34
+ get(a[aStart], -1).remove();
35
+ }
36
+ aStart++;
37
+ }
38
+ } // same node: fast path
39
+ else if (a[aStart] === b[bStart]) {
40
+ aStart++;
41
+ bStart++;
42
+ } // same tail: fast path
43
+ else if (a[aEnd - 1] === b[bEnd - 1]) {
44
+ aEnd--;
45
+ bEnd--;
46
+ } // The once here single last swap "fast path" has been removed in v1.1.0
47
+ // https://github.com/WebReflection/udomdiff/blob/single-final-swap/esm/index.js#L69-L85
48
+ // reverse swap: also fast path
49
+ else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
50
+ // this is a "shrink" operation that could happen in these cases:
51
+ // [1, 2, 3, 4, 5]
52
+ // [1, 4, 3, 2, 5]
53
+ // or asymmetric too
54
+ // [1, 2, 3, 4, 5]
55
+ // [1, 2, 3, 5, 6, 4]
56
+ const node = get(a[--aEnd], -0).nextSibling;
57
+ parentNode.insertBefore(get(b[bStart++], 1), get(a[aStart++], -0).nextSibling);
58
+ parentNode.insertBefore(get(b[--bEnd], 1), node);
59
+ // mark the future index as identical (yeah, it's dirty, but cheap 👍)
60
+ // The main reason to do this, is that when a[aEnd] will be reached,
61
+ // the loop will likely be on the fast path, as identical to b[bEnd].
62
+ // In the best case scenario, the next loop will skip the tail,
63
+ // but in the worst one, this node will be considered as already
64
+ // processed, bailing out pretty quickly from the map index check
65
+ a[aEnd] = b[bEnd];
66
+ } // map based fallback, "slow" path
67
+ else {
68
+ // the map requires an O(bEnd - bStart) operation once
69
+ // to store all future nodes indexes for later purposes.
70
+ // In the worst case scenario, this is a full O(N) cost,
71
+ // and such scenario happens at least when all nodes are different,
72
+ // but also if both first and last items of the lists are different
73
+ if (!map) {
74
+ map = new Map();
75
+ let i = bStart;
76
+ while (i < bEnd) {
77
+ map.set(b[i], i++);
78
+ }
79
+ }
80
+
81
+ const index = map.get(a[aStart]) ?? -1;
82
+
83
+ // this node has no meaning in the future list, so it's more than safe
84
+ // to remove it, and check the next live node out instead, meaning
85
+ // that only the live list index should be forwarded
86
+ if (index < 0) (get(a[aStart++], -1) as ChildNode).remove();
87
+ // it's a future node, hence it needs some handling
88
+ else {
89
+ // if it's not already processed, look on demand for the next LCS
90
+ if (bStart < index && index < bEnd) {
91
+ let i = aStart;
92
+ // counts the amount of nodes that are the same in the future
93
+ let sequence = 1;
94
+ while (++i < aEnd && i < bEnd && map.get(a[i]) === index + sequence) {
95
+ sequence++;
96
+ }
97
+ // effort decision here: if the sequence is longer than replaces
98
+ // needed to reach such sequence, which would brings again this loop
99
+ // to the fast path, prepend the difference before a sequence,
100
+ // and move only the future list index forward, so that aStart
101
+ // and bStart will be aligned again, hence on the fast path.
102
+ // An example considering aStart and bStart are both 0:
103
+ // a: [1, 2, 3, 4]
104
+ // b: [7, 1, 2, 3, 6]
105
+ // this would place 7 before 1 and, from that time on, 1, 2, and 3
106
+ // will be processed at zero cost
107
+ if (sequence > index - bStart) {
108
+ const node = get(a[aStart], 0);
109
+ while (bStart < index) {
110
+ parentNode.insertBefore(get(b[bStart++], 1), node);
111
+ }
112
+ } // if the effort wasn't good enough, fallback to a replace,
113
+ // moving both source and target indexes forward, hoping that some
114
+ // similar node will be found later on, to go back to the fast path
115
+ else {
116
+ // TODO: benchmark replaceWith instead
117
+ parentNode.replaceChild(get(b[bStart++], 1), get(a[aStart++], -1));
118
+ }
119
+ } // otherwise move the source forward, 'cause there's nothing to do
120
+ else {
121
+ aStart++;
122
+ }
123
+ }
124
+ }
125
+ }
126
+ return b;
127
+ };
@@ -0,0 +1,357 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { isNullish, isObject } from "effect/Predicate";
3
+ import { CouldNotFindCommentError } from "../errors.js";
4
+ import { type EventHandler, fromEffectOrEventHandler, isEventHandler } from "../EventHandler.js";
5
+ import {
6
+ type DomRenderEvent,
7
+ type HtmlRenderEvent,
8
+ isRenderEvent,
9
+ type RenderEvent,
10
+ RenderEventTypeId,
11
+ } from "../RenderEvent.js";
12
+ import { diffable, isComment } from "../Wire.js";
13
+ import { diff } from "./diff.js";
14
+ import { renderToString } from "./encoding.js";
15
+
16
+ export function makeTextContentUpdater(element: Node) {
17
+ return (value: unknown) => {
18
+ element.textContent = renderToString(value, "");
19
+ };
20
+ }
21
+
22
+ export function makeAttributeValueUpdater(element: HTMLElement | SVGElement, attr: Attr) {
23
+ let isSet = false;
24
+ const setValue = (value: string | null | undefined) => {
25
+ if (isNullish(value)) {
26
+ element.removeAttribute(attr.name);
27
+ isSet = false;
28
+ } else {
29
+ attr.value = value;
30
+ if (isSet === false) {
31
+ element.setAttributeNode(attr);
32
+ isSet = true;
33
+ }
34
+ }
35
+ };
36
+
37
+ return setValue;
38
+ }
39
+
40
+ export function makeClassListUpdater(element: HTMLElement | SVGElement) {
41
+ // We do double-bookeeping such that we don't assume we know everything about the classList
42
+ // Other DOM-based libraries might have additional classes in the classList, so we need to allow them to exist
43
+ // outside of our control.
44
+ let classList: ReadonlyArray<string> = Array.from(element.classList);
45
+ return (classNames: ReadonlyArray<string>) => {
46
+ const { added, removed } = diffStrings(classList, classNames);
47
+ if (added.length > 0) {
48
+ element.classList.add(...added);
49
+ }
50
+ if (removed.length > 0) {
51
+ element.classList.remove(...removed);
52
+ }
53
+ classList = classNames;
54
+ };
55
+ }
56
+
57
+ export function makeDatasetUpdater(element: HTMLElement | SVGElement) {
58
+ // We do double-bookeeping such that we don't assume we know everything about the dataset
59
+ // Other DOM-based libraries might have additional keys in the dataset, so we need to allow them to exist
60
+ // outside of our control.
61
+ const previous = { ...element.dataset };
62
+ return (value: unknown) => {
63
+ const diff = diffDataSet(previous, value as Record<string, string | undefined>);
64
+ if (diff) {
65
+ const { added, removed } = diff;
66
+ removed.forEach((k) => {
67
+ delete element.dataset[k];
68
+ delete previous[k];
69
+ });
70
+ added.forEach(([k, v]) => {
71
+ element.dataset[k] = v;
72
+ previous[k] = v;
73
+ });
74
+ }
75
+ };
76
+ }
77
+
78
+ export function diffStrings(
79
+ previous: ReadonlyArray<string> | null | undefined,
80
+ current: ReadonlyArray<string> | null | undefined,
81
+ ): {
82
+ added: ReadonlyArray<string>;
83
+ removed: ReadonlyArray<string>;
84
+ unchanged: ReadonlyArray<string>;
85
+ } {
86
+ if (previous == null || previous.length === 0) {
87
+ return {
88
+ added: current || [],
89
+ removed: [],
90
+ unchanged: [],
91
+ };
92
+ } else if (current == null || current.length === 0) {
93
+ return {
94
+ added: [],
95
+ removed: previous,
96
+ unchanged: [],
97
+ };
98
+ } else {
99
+ const previousSet = new Set(previous);
100
+ const currentSet = new Set(current);
101
+ const added = current.filter((c) => !previousSet.has(c));
102
+ const removed: Array<string> = [];
103
+ const unchanged: Array<string> = [];
104
+
105
+ for (let i = 0; i < previous.length; ++i) {
106
+ if (currentSet.has(previous[i])) {
107
+ unchanged.push(previous[i]);
108
+ } else {
109
+ removed.push(previous[i]);
110
+ }
111
+ }
112
+
113
+ return {
114
+ added,
115
+ removed,
116
+ unchanged,
117
+ };
118
+ }
119
+ }
120
+
121
+ export function diffDataSet(
122
+ a: Record<string, string | undefined> | null | undefined,
123
+ b: Record<string, string | undefined> | null | undefined,
124
+ ): { added: Array<readonly [string, string | undefined]>; removed: ReadonlyArray<string> } | null {
125
+ if (!a) return b ? { added: Object.entries(b), removed: [] } : null;
126
+ if (!b) return { added: [], removed: Object.keys(a) };
127
+
128
+ const { added, removed, unchanged } = diffStrings(Object.keys(a), Object.keys(b));
129
+
130
+ return {
131
+ added: added.concat(unchanged).map((k) => [k, b[k]] as const),
132
+ removed,
133
+ };
134
+ }
135
+
136
+ export function getClassList(value: unknown): ReadonlyArray<string> {
137
+ if (isNullish(value)) return [];
138
+ if (Array.isArray(value)) return value.flatMap(getClassList);
139
+ return splitClassNames(renderToString(value, ""));
140
+ }
141
+
142
+ const ASCII_SPACE_CODE = 32;
143
+
144
+ /**
145
+ * Splits a string of class names (like those used in HTML `class=""` attributes)
146
+ * into an array of individual class names (words), separated by whitespace.
147
+ *
148
+ * This function avoids creating intermediate arrays and unnecessary string copying by:
149
+ * - Scanning the string one character at a time
150
+ * - Skipping over all leading whitespace for each word
151
+ * - Collecting all consecutive non-whitespace characters as a "word"
152
+ * - Repeating until the input is exhausted
153
+ *
154
+ * All ASCII "whitespace" characters with code <= 32 are considered as delimiters.
155
+ * This is more efficient than `String.prototype.trim` and `String.prototype.split(/\s+/)`
156
+ * as it only allocates memory for the result array, not for intermediate or empty strings.
157
+ *
158
+ * Example:
159
+ * splitClassNames(" foo bar\tbaz\nqux ") // => ["foo", "bar", "baz", "qux"]
160
+ */
161
+ export function splitClassNames(value: string): Array<string> {
162
+ const result: Array<string> = [];
163
+ let start = 0;
164
+ const len = value.length;
165
+
166
+ while (start < len) {
167
+ // Skip leading whitespace (all ASCII <= 32)
168
+ while (start < len && value.charCodeAt(start) <= ASCII_SPACE_CODE) start++;
169
+ if (start >= len) break;
170
+ // Find the end of the word (next whitespace)
171
+ let end = start + 1;
172
+ while (end < len && value.charCodeAt(end) > ASCII_SPACE_CODE) end++;
173
+ result.push(value.slice(start, end));
174
+ // Move start past the end of the last word (one char after end)
175
+ start = end + 1;
176
+ }
177
+
178
+ return result;
179
+ }
180
+
181
+ export function matchNodeValue<A, B>(
182
+ document: Document,
183
+ value: unknown,
184
+ onText: (text: string) => A,
185
+ onNodes: (nodes: Array<Node>) => B,
186
+ ): A | B {
187
+ switch (typeof value) {
188
+ // primitives are handled as text content
189
+ case "string":
190
+ case "symbol":
191
+ case "number":
192
+ case "bigint":
193
+ case "boolean":
194
+ return onText(String(value));
195
+ case "undefined":
196
+ case "function":
197
+ case "object": {
198
+ if (isNullish(value)) {
199
+ return onNodes([]);
200
+ } else if (isRenderEvent(value)) {
201
+ return onNodes(unwrapRenderEvent(document, value));
202
+ } else if (Array.isArray(value)) {
203
+ return onNodes(value.flatMap((_) => renderEventToArray(document, _)));
204
+ } else {
205
+ return onNodes(renderEventToArray(document, value));
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ export function renderEventToArray(document: Document, x: unknown): Array<Node> {
212
+ switch (typeof x) {
213
+ case "string":
214
+ case "number":
215
+ case "bigint":
216
+ case "boolean":
217
+ case "symbol":
218
+ return [document.createTextNode(String(x))];
219
+ case "undefined":
220
+ case "function":
221
+ case "object":
222
+ if (isNullish(x)) return [];
223
+ if (isRenderEvent(x)) return unwrapRenderEvent(document, x);
224
+ if (Array.isArray(x)) return x.flatMap((_) => renderEventToArray(document, _));
225
+ return [x as Node];
226
+ default:
227
+ return [];
228
+ }
229
+ }
230
+
231
+ function unwrapRenderEvent(document: Document, x: RenderEvent): Array<Node> {
232
+ if (x[RenderEventTypeId] === "dom") return unwrapDomRenderEvent(x);
233
+ return unwrapHtmlRenderEvent(document, x);
234
+ }
235
+
236
+ function unwrapDomRenderEvent(x: DomRenderEvent): Array<Node> {
237
+ const value = x.content;
238
+ return Array.isArray(value) ? value : [value as Node];
239
+ }
240
+
241
+ function unwrapHtmlRenderEvent(document: Document, x: HtmlRenderEvent): Array<Node> {
242
+ const tmp = document.createElement("template");
243
+ tmp.innerHTML = x.html;
244
+ return Array.from(tmp.childNodes);
245
+ }
246
+
247
+ export function diffChildren(
248
+ comment: Comment,
249
+ currentNodes: Array<Node>,
250
+ nextNodes: Array<Node>,
251
+ get: (entry: Node, action: number) => Node,
252
+ ) {
253
+ return diff(currentNodes, nextNodes, get, comment);
254
+ }
255
+
256
+ const commentCache = new WeakMap<Element, Map<number, Comment>>();
257
+
258
+ function getCommentCacheKey(index: number, isEnd: boolean): number {
259
+ return isEnd ? -index - 1 : index;
260
+ }
261
+
262
+ function findCommentInElement(parent: Element, index: number, isEnd: boolean): Comment {
263
+ let cache = commentCache.get(parent);
264
+ if (cache === undefined) {
265
+ cache = new Map();
266
+ commentCache.set(parent, cache);
267
+ }
268
+
269
+ const cacheKey = getCommentCacheKey(index, isEnd);
270
+ const cached = cache.get(cacheKey);
271
+ if (cached !== undefined) {
272
+ return cached;
273
+ }
274
+
275
+ const childNodes = parent.childNodes;
276
+ const searchValue = isEnd ? `/n_${index}` : `n_${index}`;
277
+
278
+ for (let i = 0; i < childNodes.length; ++i) {
279
+ const node = childNodes[i];
280
+ if (isCommentWithValue(node, searchValue)) {
281
+ cache.set(cacheKey, node);
282
+ return node;
283
+ }
284
+ }
285
+
286
+ throw new CouldNotFindCommentError(index);
287
+ }
288
+
289
+ export function findNodePartEndComment(parent: Element, index: number) {
290
+ return findCommentInElement(parent, index, true);
291
+ }
292
+
293
+ export function findNodePartStartComment(parent: Element, index: number) {
294
+ return findCommentInElement(parent, index, false);
295
+ }
296
+
297
+ function isCommentWithValue(node: Node, value: string): node is Comment {
298
+ return isComment(node) && node.nodeValue === value;
299
+ }
300
+
301
+ export function makeNodeUpdater(
302
+ document: Document,
303
+ comment: Comment,
304
+ text: Text | null = null,
305
+ nodes: Array<Node> = [],
306
+ ) {
307
+ const element = comment.parentNode as HTMLElement | SVGElement;
308
+ const get = diffable(document);
309
+ const updateCommentText = (value: unknown) => {
310
+ if (text === null) {
311
+ text = document.createTextNode("");
312
+ element.insertBefore(text, comment);
313
+ }
314
+
315
+ text.textContent = renderToString(value, "");
316
+ nodes = diffChildren(comment, nodes, [text], get);
317
+ };
318
+
319
+ const updateNodes = (updatedNodes: Array<Node>) => {
320
+ nodes = diffChildren(comment, nodes, updatedNodes, get);
321
+ };
322
+
323
+ return (value: unknown) => {
324
+ matchNodeValue(document, value, updateCommentText, updateNodes);
325
+ };
326
+ }
327
+
328
+ export function makeBooleanUpdater(element: HTMLElement | SVGElement, name: string) {
329
+ return (value: boolean) => {
330
+ element.toggleAttribute(name, value);
331
+ };
332
+ }
333
+
334
+ export function getAttributeValue(value: unknown): string | null | undefined {
335
+ if (isNullish(value)) return null;
336
+ return renderToString(value, "");
337
+ }
338
+
339
+ export function getBooleanValue(value: unknown): boolean {
340
+ return !!value;
341
+ }
342
+
343
+ export function getDatasetValue(
344
+ value: unknown,
345
+ ): Record<string, string | undefined> | null | undefined {
346
+ if (isNullish(value)) return null;
347
+ if (isObject(value)) return value as Record<string, string | undefined>;
348
+ return null;
349
+ }
350
+
351
+ export function getEventHandlerValue<E, R>(
352
+ value: unknown,
353
+ ): EventHandler<Event, E, R> | null | undefined {
354
+ if (isNullish(value)) return null;
355
+ if (isEventHandler(value) || Effect.isEffect(value)) return fromEffectOrEventHandler(value);
356
+ return null;
357
+ }
@@ -0,0 +1,147 @@
1
+ import { isOption, match } from "effect/Option";
2
+ import { hasProperty, isNullish } from "effect/Predicate";
3
+ import { isHtmlRenderEvent } from "../RenderEvent.js";
4
+
5
+ export function escape(s: unknown): string {
6
+ switch (typeof s) {
7
+ case "string":
8
+ case "number":
9
+ case "boolean":
10
+ case "bigint":
11
+ return escapeHtml(String(s));
12
+ case "object": {
13
+ if (isNullish(s)) {
14
+ return "";
15
+ } else if (Array.isArray(s)) {
16
+ return s.map(escape).join("");
17
+ } else if (s instanceof Date) {
18
+ return escapeHtml(s.toISOString());
19
+ } else if (s instanceof RegExp) {
20
+ return escapeHtml(s.toString());
21
+ } else {
22
+ return escapeHtml(JSON.stringify(s));
23
+ }
24
+ }
25
+ default:
26
+ return escapeHtml(JSON.stringify(s));
27
+ }
28
+ }
29
+
30
+ export function unescape(s: string) {
31
+ const unescaped = unescapeHtml(s);
32
+ const couldBeJson = unescaped[0] === "[" || unescaped === "{";
33
+ if (couldBeJson) {
34
+ try {
35
+ return JSON.parse(unescaped);
36
+ } catch {
37
+ return unescaped;
38
+ }
39
+ } else {
40
+ return unescaped;
41
+ }
42
+ }
43
+
44
+ const unescapeHtmlRules = [
45
+ [/&quot;/g, '"'],
46
+ [/&#39;/g, "'"],
47
+ [/&#x3A;/g, ":"],
48
+ [/&lt;/g, "<"],
49
+ [/&gt;/g, ">"],
50
+ [/&amp;/g, "&"],
51
+ ] as const;
52
+
53
+ const matchHtmlRegExp = /["'&<>]/;
54
+
55
+ export function escapeHtml(str: string): string {
56
+ if (str.length === 0) {
57
+ return str;
58
+ }
59
+
60
+ const match = matchHtmlRegExp.exec(str);
61
+
62
+ if (!match) {
63
+ return str;
64
+ }
65
+
66
+ let escape;
67
+ let html = "";
68
+ let index = 0;
69
+ let lastIndex = 0;
70
+
71
+ for (index = match.index; index < str.length; index++) {
72
+ switch (str.charCodeAt(index)) {
73
+ case 34: // "
74
+ escape = "&quot;";
75
+ break;
76
+ case 38: // &
77
+ escape = "&amp;";
78
+ break;
79
+ case 39: // '
80
+ escape = "&#39;";
81
+ break;
82
+ case 60: // <
83
+ escape = "&lt;";
84
+ break;
85
+ case 62: // >
86
+ escape = "&gt;";
87
+ break;
88
+ default:
89
+ continue;
90
+ }
91
+
92
+ if (lastIndex !== index) {
93
+ html += str.substring(lastIndex, index);
94
+ }
95
+
96
+ lastIndex = index + 1;
97
+ html += escape;
98
+ }
99
+
100
+ return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
101
+ }
102
+
103
+ export function unescapeHtml(html: string) {
104
+ for (const [from, to] of unescapeHtmlRules) {
105
+ html = html.replace(from, to);
106
+ }
107
+
108
+ return html;
109
+ }
110
+
111
+ export function renderToString(value: unknown, delimiter: string = ""): string {
112
+ if (Array.isArray(value)) {
113
+ return value.map((v) => renderToString(v, delimiter)).join(delimiter);
114
+ }
115
+ if (isNullish(value)) {
116
+ return "";
117
+ }
118
+ if (isOption(value)) {
119
+ return match(value, {
120
+ onNone: () => "",
121
+ onSome: (v: unknown) => renderToString(v, delimiter),
122
+ });
123
+ }
124
+ if (isHtmlRenderEvent(value)) {
125
+ return value.html;
126
+ }
127
+
128
+ if (typeof value === "string") {
129
+ return value;
130
+ }
131
+
132
+ if (hasProperty(value, "toString") && typeof value.toString === "function") {
133
+ const s = value.toString();
134
+ if (s !== "[object Object]") {
135
+ return s;
136
+ }
137
+ }
138
+
139
+ if (typeof value === "object") {
140
+ return JSON.stringify(value);
141
+ }
142
+ return String(value);
143
+ }
144
+
145
+ export function renderToEscapedString(value: unknown, delimiter: string): string {
146
+ return escape(renderToString(value, delimiter));
147
+ }