@typed/template 0.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 (285) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/cjs/Directive.js +76 -0
  4. package/dist/cjs/Directive.js.map +1 -0
  5. package/dist/cjs/ElementRef.js +83 -0
  6. package/dist/cjs/ElementRef.js.map +1 -0
  7. package/dist/cjs/ElementSource.js +244 -0
  8. package/dist/cjs/ElementSource.js.map +1 -0
  9. package/dist/cjs/Entry.js +6 -0
  10. package/dist/cjs/Entry.js.map +1 -0
  11. package/dist/cjs/EventHandler.js +65 -0
  12. package/dist/cjs/EventHandler.js.map +1 -0
  13. package/dist/cjs/Html.js +169 -0
  14. package/dist/cjs/Html.js.map +1 -0
  15. package/dist/cjs/HtmlChunk.js +257 -0
  16. package/dist/cjs/HtmlChunk.js.map +1 -0
  17. package/dist/cjs/Hydrate.js +49 -0
  18. package/dist/cjs/Hydrate.js.map +1 -0
  19. package/dist/cjs/Many.js +45 -0
  20. package/dist/cjs/Many.js.map +1 -0
  21. package/dist/cjs/Meta.js +37 -0
  22. package/dist/cjs/Meta.js.map +1 -0
  23. package/dist/cjs/Parser.js +331 -0
  24. package/dist/cjs/Parser.js.map +1 -0
  25. package/dist/cjs/Part.js +6 -0
  26. package/dist/cjs/Part.js.map +1 -0
  27. package/dist/cjs/Placeholder.js +38 -0
  28. package/dist/cjs/Placeholder.js.map +1 -0
  29. package/dist/cjs/Platform.js +64 -0
  30. package/dist/cjs/Platform.js.map +1 -0
  31. package/dist/cjs/Render.js +39 -0
  32. package/dist/cjs/Render.js.map +1 -0
  33. package/dist/cjs/RenderContext.js +130 -0
  34. package/dist/cjs/RenderContext.js.map +1 -0
  35. package/dist/cjs/RenderEvent.js +44 -0
  36. package/dist/cjs/RenderEvent.js.map +1 -0
  37. package/dist/cjs/RenderTemplate.js +41 -0
  38. package/dist/cjs/RenderTemplate.js.map +1 -0
  39. package/dist/cjs/Renderable.js +6 -0
  40. package/dist/cjs/Renderable.js.map +1 -0
  41. package/dist/cjs/Template.js +266 -0
  42. package/dist/cjs/Template.js.map +1 -0
  43. package/dist/cjs/TemplateInstance.js +51 -0
  44. package/dist/cjs/TemplateInstance.js.map +1 -0
  45. package/dist/cjs/Test.js +90 -0
  46. package/dist/cjs/Test.js.map +1 -0
  47. package/dist/cjs/Token.js +270 -0
  48. package/dist/cjs/Token.js.map +1 -0
  49. package/dist/cjs/Tokenizer.js +18 -0
  50. package/dist/cjs/Tokenizer.js.map +1 -0
  51. package/dist/cjs/Vitest.js +44 -0
  52. package/dist/cjs/Vitest.js.map +1 -0
  53. package/dist/cjs/index.js +147 -0
  54. package/dist/cjs/index.js.map +1 -0
  55. package/dist/cjs/internal/HydrateContext.js +13 -0
  56. package/dist/cjs/internal/HydrateContext.js.map +1 -0
  57. package/dist/cjs/internal/browser.js +109 -0
  58. package/dist/cjs/internal/browser.js.map +1 -0
  59. package/dist/cjs/internal/chunks.js +54 -0
  60. package/dist/cjs/internal/chunks.js.map +1 -0
  61. package/dist/cjs/internal/errors.js +23 -0
  62. package/dist/cjs/internal/errors.js.map +1 -0
  63. package/dist/cjs/internal/hydrate.js +197 -0
  64. package/dist/cjs/internal/hydrate.js.map +1 -0
  65. package/dist/cjs/internal/indexRefCounter.js +32 -0
  66. package/dist/cjs/internal/indexRefCounter.js.map +1 -0
  67. package/dist/cjs/internal/module-augmentation.js +6 -0
  68. package/dist/cjs/internal/module-augmentation.js.map +1 -0
  69. package/dist/cjs/internal/parser.js +492 -0
  70. package/dist/cjs/internal/parser.js.map +1 -0
  71. package/dist/cjs/internal/parts.js +350 -0
  72. package/dist/cjs/internal/parts.js.map +1 -0
  73. package/dist/cjs/internal/readAttribute.js +34 -0
  74. package/dist/cjs/internal/readAttribute.js.map +1 -0
  75. package/dist/cjs/internal/render.js +332 -0
  76. package/dist/cjs/internal/render.js.map +1 -0
  77. package/dist/cjs/internal/server.js +219 -0
  78. package/dist/cjs/internal/server.js.map +1 -0
  79. package/dist/cjs/internal/tokenizer.js +264 -0
  80. package/dist/cjs/internal/tokenizer.js.map +1 -0
  81. package/dist/cjs/internal/utils.js +68 -0
  82. package/dist/cjs/internal/utils.js.map +1 -0
  83. package/dist/dts/Directive.d.ts +70 -0
  84. package/dist/dts/Directive.d.ts.map +1 -0
  85. package/dist/dts/ElementRef.d.ts +40 -0
  86. package/dist/dts/ElementRef.d.ts.map +1 -0
  87. package/dist/dts/ElementSource.d.ts +72 -0
  88. package/dist/dts/ElementSource.d.ts.map +1 -0
  89. package/dist/dts/Entry.d.ts +26 -0
  90. package/dist/dts/Entry.d.ts.map +1 -0
  91. package/dist/dts/EventHandler.d.ts +61 -0
  92. package/dist/dts/EventHandler.d.ts.map +1 -0
  93. package/dist/dts/Html.d.ts +17 -0
  94. package/dist/dts/Html.d.ts.map +1 -0
  95. package/dist/dts/HtmlChunk.d.ts +56 -0
  96. package/dist/dts/HtmlChunk.d.ts.map +1 -0
  97. package/dist/dts/Hydrate.d.ts +20 -0
  98. package/dist/dts/Hydrate.d.ts.map +1 -0
  99. package/dist/dts/Many.d.ts +32 -0
  100. package/dist/dts/Many.d.ts.map +1 -0
  101. package/dist/dts/Meta.d.ts +24 -0
  102. package/dist/dts/Meta.d.ts.map +1 -0
  103. package/dist/dts/Parser.d.ts +16 -0
  104. package/dist/dts/Parser.d.ts.map +1 -0
  105. package/dist/dts/Part.d.ts +147 -0
  106. package/dist/dts/Part.d.ts.map +1 -0
  107. package/dist/dts/Placeholder.d.ts +51 -0
  108. package/dist/dts/Placeholder.d.ts.map +1 -0
  109. package/dist/dts/Platform.d.ts +23 -0
  110. package/dist/dts/Platform.d.ts.map +1 -0
  111. package/dist/dts/Render.d.ts +23 -0
  112. package/dist/dts/Render.d.ts.map +1 -0
  113. package/dist/dts/RenderContext.d.ts +88 -0
  114. package/dist/dts/RenderContext.d.ts.map +1 -0
  115. package/dist/dts/RenderEvent.d.ts +37 -0
  116. package/dist/dts/RenderEvent.d.ts.map +1 -0
  117. package/dist/dts/RenderTemplate.d.ts +38 -0
  118. package/dist/dts/RenderTemplate.d.ts.map +1 -0
  119. package/dist/dts/Renderable.d.ts +28 -0
  120. package/dist/dts/Renderable.d.ts.map +1 -0
  121. package/dist/dts/Template.d.ts +218 -0
  122. package/dist/dts/Template.d.ts.map +1 -0
  123. package/dist/dts/TemplateInstance.d.ts +32 -0
  124. package/dist/dts/TemplateInstance.d.ts.map +1 -0
  125. package/dist/dts/Test.d.ts +58 -0
  126. package/dist/dts/Test.d.ts.map +1 -0
  127. package/dist/dts/Token.d.ts +202 -0
  128. package/dist/dts/Token.d.ts.map +1 -0
  129. package/dist/dts/Tokenizer.d.ts +6 -0
  130. package/dist/dts/Tokenizer.d.ts.map +1 -0
  131. package/dist/dts/Vitest.d.ts +28 -0
  132. package/dist/dts/Vitest.d.ts.map +1 -0
  133. package/dist/dts/index.d.ts +65 -0
  134. package/dist/dts/index.d.ts.map +1 -0
  135. package/dist/dts/internal/HydrateContext.d.ts +2 -0
  136. package/dist/dts/internal/HydrateContext.d.ts.map +1 -0
  137. package/dist/dts/internal/browser.d.ts +8 -0
  138. package/dist/dts/internal/browser.d.ts.map +1 -0
  139. package/dist/dts/internal/chunks.d.ts +22 -0
  140. package/dist/dts/internal/chunks.d.ts.map +1 -0
  141. package/dist/dts/internal/errors.d.ts +9 -0
  142. package/dist/dts/internal/errors.d.ts.map +1 -0
  143. package/dist/dts/internal/hydrate.d.ts +37 -0
  144. package/dist/dts/internal/hydrate.d.ts.map +1 -0
  145. package/dist/dts/internal/indexRefCounter.d.ts +6 -0
  146. package/dist/dts/internal/indexRefCounter.d.ts.map +1 -0
  147. package/dist/dts/internal/module-augmentation.d.ts +36 -0
  148. package/dist/dts/internal/module-augmentation.d.ts.map +1 -0
  149. package/dist/dts/internal/parser.d.ts +12 -0
  150. package/dist/dts/internal/parser.d.ts.map +1 -0
  151. package/dist/dts/internal/parts.d.ts +304 -0
  152. package/dist/dts/internal/parts.d.ts.map +1 -0
  153. package/dist/dts/internal/readAttribute.d.ts +9 -0
  154. package/dist/dts/internal/readAttribute.d.ts.map +1 -0
  155. package/dist/dts/internal/render.d.ts +30 -0
  156. package/dist/dts/internal/render.d.ts.map +1 -0
  157. package/dist/dts/internal/server.d.ts +31 -0
  158. package/dist/dts/internal/server.d.ts.map +1 -0
  159. package/dist/dts/internal/tokenizer.d.ts +3 -0
  160. package/dist/dts/internal/tokenizer.d.ts.map +1 -0
  161. package/dist/dts/internal/utils.d.ts +15 -0
  162. package/dist/dts/internal/utils.d.ts.map +1 -0
  163. package/dist/esm/Directive.js +64 -0
  164. package/dist/esm/Directive.js.map +1 -0
  165. package/dist/esm/ElementRef.js +72 -0
  166. package/dist/esm/ElementRef.js.map +1 -0
  167. package/dist/esm/ElementSource.js +237 -0
  168. package/dist/esm/ElementSource.js.map +1 -0
  169. package/dist/esm/Entry.js +2 -0
  170. package/dist/esm/Entry.js.map +1 -0
  171. package/dist/esm/EventHandler.js +52 -0
  172. package/dist/esm/EventHandler.js.map +1 -0
  173. package/dist/esm/Html.js +167 -0
  174. package/dist/esm/Html.js.map +1 -0
  175. package/dist/esm/HtmlChunk.js +274 -0
  176. package/dist/esm/HtmlChunk.js.map +1 -0
  177. package/dist/esm/Hydrate.js +37 -0
  178. package/dist/esm/Hydrate.js.map +1 -0
  179. package/dist/esm/Many.js +33 -0
  180. package/dist/esm/Many.js.map +1 -0
  181. package/dist/esm/Meta.js +29 -0
  182. package/dist/esm/Meta.js.map +1 -0
  183. package/dist/esm/Parser.js +342 -0
  184. package/dist/esm/Parser.js.map +1 -0
  185. package/dist/esm/Part.js +5 -0
  186. package/dist/esm/Part.js.map +1 -0
  187. package/dist/esm/Placeholder.js +30 -0
  188. package/dist/esm/Placeholder.js.map +1 -0
  189. package/dist/esm/Platform.js +41 -0
  190. package/dist/esm/Platform.js.map +1 -0
  191. package/dist/esm/Render.js +27 -0
  192. package/dist/esm/Render.js.map +1 -0
  193. package/dist/esm/RenderContext.js +113 -0
  194. package/dist/esm/RenderContext.js.map +1 -0
  195. package/dist/esm/RenderEvent.js +36 -0
  196. package/dist/esm/RenderEvent.js.map +1 -0
  197. package/dist/esm/RenderTemplate.js +26 -0
  198. package/dist/esm/RenderTemplate.js.map +1 -0
  199. package/dist/esm/Renderable.js +2 -0
  200. package/dist/esm/Renderable.js.map +1 -0
  201. package/dist/esm/Template.js +239 -0
  202. package/dist/esm/Template.js.map +1 -0
  203. package/dist/esm/TemplateInstance.js +43 -0
  204. package/dist/esm/TemplateInstance.js.map +1 -0
  205. package/dist/esm/Test.js +68 -0
  206. package/dist/esm/Test.js.map +1 -0
  207. package/dist/esm/Token.js +264 -0
  208. package/dist/esm/Token.js.map +1 -0
  209. package/dist/esm/Tokenizer.js +9 -0
  210. package/dist/esm/Tokenizer.js.map +1 -0
  211. package/dist/esm/Vitest.js +29 -0
  212. package/dist/esm/Vitest.js.map +1 -0
  213. package/dist/esm/index.js +65 -0
  214. package/dist/esm/index.js.map +1 -0
  215. package/dist/esm/internal/HydrateContext.js +7 -0
  216. package/dist/esm/internal/HydrateContext.js.map +1 -0
  217. package/dist/esm/internal/browser.js +102 -0
  218. package/dist/esm/internal/browser.js.map +1 -0
  219. package/dist/esm/internal/chunks.js +47 -0
  220. package/dist/esm/internal/chunks.js.map +1 -0
  221. package/dist/esm/internal/errors.js +15 -0
  222. package/dist/esm/internal/errors.js.map +1 -0
  223. package/dist/esm/internal/hydrate.js +165 -0
  224. package/dist/esm/internal/hydrate.js.map +1 -0
  225. package/dist/esm/internal/indexRefCounter.js +24 -0
  226. package/dist/esm/internal/indexRefCounter.js.map +1 -0
  227. package/dist/esm/internal/module-augmentation.js +2 -0
  228. package/dist/esm/internal/module-augmentation.js.map +1 -0
  229. package/dist/esm/internal/parser.js +493 -0
  230. package/dist/esm/internal/parser.js.map +1 -0
  231. package/dist/esm/internal/parts.js +291 -0
  232. package/dist/esm/internal/parts.js.map +1 -0
  233. package/dist/esm/internal/readAttribute.js +24 -0
  234. package/dist/esm/internal/readAttribute.js.map +1 -0
  235. package/dist/esm/internal/render.js +329 -0
  236. package/dist/esm/internal/render.js.map +1 -0
  237. package/dist/esm/internal/server.js +174 -0
  238. package/dist/esm/internal/server.js.map +1 -0
  239. package/dist/esm/internal/tokenizer.js +296 -0
  240. package/dist/esm/internal/tokenizer.js.map +1 -0
  241. package/dist/esm/internal/utils.js +52 -0
  242. package/dist/esm/internal/utils.js.map +1 -0
  243. package/dist/esm/package.json +4 -0
  244. package/package.json +242 -0
  245. package/src/Directive.ts +114 -0
  246. package/src/ElementRef.ts +123 -0
  247. package/src/ElementSource.ts +417 -0
  248. package/src/Entry.ts +28 -0
  249. package/src/EventHandler.ts +104 -0
  250. package/src/Html.ts +258 -0
  251. package/src/HtmlChunk.ts +346 -0
  252. package/src/Hydrate.ts +53 -0
  253. package/src/Many.ts +128 -0
  254. package/src/Meta.ts +32 -0
  255. package/src/Parser.ts +457 -0
  256. package/src/Part.ts +186 -0
  257. package/src/Placeholder.ts +70 -0
  258. package/src/Platform.ts +71 -0
  259. package/src/Render.ts +45 -0
  260. package/src/RenderContext.ts +221 -0
  261. package/src/RenderEvent.ts +67 -0
  262. package/src/RenderTemplate.ts +88 -0
  263. package/src/Renderable.ts +34 -0
  264. package/src/Template.ts +284 -0
  265. package/src/TemplateInstance.ts +83 -0
  266. package/src/Test.ts +151 -0
  267. package/src/Token.ts +269 -0
  268. package/src/Tokenizer.ts +10 -0
  269. package/src/Vitest.ts +61 -0
  270. package/src/index.ts +66 -0
  271. package/src/internal/HydrateContext.ts +23 -0
  272. package/src/internal/browser.ts +132 -0
  273. package/src/internal/chunks.ts +73 -0
  274. package/src/internal/errors.ts +11 -0
  275. package/src/internal/external.d.ts +11 -0
  276. package/src/internal/hydrate.ts +262 -0
  277. package/src/internal/indexRefCounter.ts +33 -0
  278. package/src/internal/module-augmentation.ts +48 -0
  279. package/src/internal/parser.ts +637 -0
  280. package/src/internal/parts.ts +527 -0
  281. package/src/internal/readAttribute.ts +28 -0
  282. package/src/internal/render.ts +529 -0
  283. package/src/internal/server.ts +293 -0
  284. package/src/internal/tokenizer.ts +338 -0
  285. package/src/internal/utils.ts +73 -0
package/src/Token.ts ADDED
@@ -0,0 +1,269 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+
5
+ /**
6
+ * @since 1.0.0
7
+ */
8
+ export type Token =
9
+ | OpeningTagToken
10
+ | OpeningTagEndToken
11
+ | ClosingTagToken
12
+ | AttributeToken
13
+ | AttributeStartToken
14
+ | AttributeEndToken
15
+ | BooleanAttributeToken
16
+ | BooleanAttributeStartToken
17
+ | BooleanAttributeEndToken
18
+ | ClassNameAttributeStartToken
19
+ | ClassNameAttributeEndToken
20
+ | DataAttributeStartToken
21
+ | DataAttributeEndToken
22
+ | EventAttributeStartToken
23
+ | EventAttributeEndToken
24
+ | PropertyAttributeStartToken
25
+ | PropertyAttributeEndToken
26
+ | RefAttributeStartToken
27
+ | RefAttributeEndToken
28
+ | CommentToken
29
+ | CommentStartToken
30
+ | CommentEndToken
31
+ | TextToken
32
+ | PartToken
33
+
34
+ /**
35
+ * @since 1.0.0
36
+ */
37
+ export class OpeningTagToken {
38
+ readonly _tag = "opening-tag"
39
+
40
+ constructor(
41
+ readonly name: string,
42
+ readonly isSelfClosing: boolean = SELF_CLOSING_TAGS.has(name),
43
+ readonly textOnly: boolean = TEXT_ONLY_NODES_REGEX.has(name)
44
+ ) {}
45
+ }
46
+
47
+ /**
48
+ * @since 1.0.0
49
+ */
50
+ export class AttributeStartToken {
51
+ readonly _tag = "attribute-start"
52
+ constructor(readonly name: string) {}
53
+ }
54
+
55
+ /**
56
+ * @since 1.0.0
57
+ */
58
+ export class AttributeEndToken {
59
+ readonly _tag = "attribute-end"
60
+ constructor(readonly name: string) {}
61
+ }
62
+
63
+ /**
64
+ * @since 1.0.0
65
+ */
66
+ export class BooleanAttributeStartToken {
67
+ readonly _tag = "boolean-attribute-start"
68
+ constructor(readonly name: string) {}
69
+ }
70
+
71
+ /**
72
+ * @since 1.0.0
73
+ */
74
+ export class BooleanAttributeEndToken {
75
+ readonly _tag = "boolean-attribute-end"
76
+ constructor(readonly name: string) {}
77
+ }
78
+
79
+ /**
80
+ * @since 1.0.0
81
+ */
82
+ export class ClassNameAttributeStartToken {
83
+ readonly _tag = "className-attribute-start"
84
+ }
85
+
86
+ /**
87
+ * @since 1.0.0
88
+ */
89
+ export class ClassNameAttributeEndToken {
90
+ readonly _tag = "className-attribute-end"
91
+ }
92
+
93
+ /**
94
+ * @since 1.0.0
95
+ */
96
+ export class DataAttributeStartToken {
97
+ readonly _tag = "data-attribute-start"
98
+ }
99
+
100
+ /**
101
+ * @since 1.0.0
102
+ */
103
+ export class DataAttributeEndToken {
104
+ readonly _tag = "data-attribute-end"
105
+ }
106
+
107
+ /**
108
+ * @since 1.0.0
109
+ */
110
+ export class EventAttributeStartToken {
111
+ readonly _tag = "event-attribute-start"
112
+ constructor(readonly name: string) {}
113
+ }
114
+
115
+ /**
116
+ * @since 1.0.0
117
+ */
118
+ export class EventAttributeEndToken {
119
+ readonly _tag = "event-attribute-end"
120
+ constructor(readonly name: string) {}
121
+ }
122
+
123
+ /**
124
+ * @since 1.0.0
125
+ */
126
+ export class PropertyAttributeStartToken {
127
+ readonly _tag = "property-attribute-start"
128
+ constructor(readonly name: string) {}
129
+ }
130
+
131
+ /**
132
+ * @since 1.0.0
133
+ */
134
+ export class PropertyAttributeEndToken {
135
+ readonly _tag = "property-attribute-end"
136
+ constructor(readonly name: string) {}
137
+ }
138
+
139
+ /**
140
+ * @since 1.0.0
141
+ */
142
+ export class RefAttributeStartToken {
143
+ readonly _tag = "ref-attribute-start"
144
+ }
145
+
146
+ /**
147
+ * @since 1.0.0
148
+ */
149
+ export class RefAttributeEndToken {
150
+ readonly _tag = "ref-attribute-end"
151
+ }
152
+
153
+ /**
154
+ * @since 1.0.0
155
+ */
156
+ export class AttributeToken {
157
+ readonly _tag = "attribute"
158
+ constructor(
159
+ readonly name: string,
160
+ readonly value: string
161
+ ) {}
162
+ }
163
+
164
+ /**
165
+ * @since 1.0.0
166
+ */
167
+ export class BooleanAttributeToken {
168
+ readonly _tag = "boolean-attribute"
169
+ constructor(readonly name: string) {}
170
+ }
171
+
172
+ /**
173
+ * @since 1.0.0
174
+ */
175
+ export class OpeningTagEndToken {
176
+ readonly _tag = "opening-tag-end"
177
+
178
+ constructor(
179
+ readonly name: string,
180
+ readonly selfClosing: boolean = SELF_CLOSING_TAGS.has(name),
181
+ readonly textOnly: boolean = TEXT_ONLY_NODES_REGEX.has(name)
182
+ ) {}
183
+ }
184
+
185
+ /**
186
+ * @since 1.0.0
187
+ */
188
+ export class ClosingTagToken {
189
+ readonly _tag = "closing-tag"
190
+
191
+ constructor(
192
+ readonly name: string,
193
+ readonly textOnly: boolean = TEXT_ONLY_NODES_REGEX.has(name)
194
+ ) {}
195
+ }
196
+
197
+ /**
198
+ * @since 1.0.0
199
+ */
200
+ export class CommentToken {
201
+ readonly _tag = "comment"
202
+ constructor(readonly value: string) {}
203
+ }
204
+
205
+ /**
206
+ * @since 1.0.0
207
+ */
208
+ export class CommentStartToken {
209
+ readonly _tag = "comment-start"
210
+ constructor(readonly value: string) {}
211
+ }
212
+
213
+ /**
214
+ * @since 1.0.0
215
+ */
216
+ export class CommentEndToken {
217
+ readonly _tag = "comment-end"
218
+ constructor(readonly value: string) {}
219
+ }
220
+
221
+ /**
222
+ * @since 1.0.0
223
+ */
224
+ export class TextToken {
225
+ readonly _tag = "text"
226
+ constructor(readonly value: string) {}
227
+ }
228
+
229
+ /**
230
+ * @since 1.0.0
231
+ */
232
+ export class PartToken {
233
+ readonly _tag = "part-token"
234
+ constructor(readonly index: number) {}
235
+ }
236
+
237
+ /**
238
+ * @since 1.0.0
239
+ */
240
+ export const TEXT_ONLY_NODES_REGEX = new Set([
241
+ "textarea",
242
+ "script",
243
+ "style",
244
+ "title",
245
+ "plaintext",
246
+ "xmp"
247
+ ])
248
+
249
+ /**
250
+ * @since 1.0.0
251
+ */
252
+ export const SELF_CLOSING_TAGS = new Set([
253
+ "area",
254
+ "base",
255
+ "br",
256
+ "col",
257
+ "command",
258
+ "embed",
259
+ "hr",
260
+ "img",
261
+ "input",
262
+ "keygen",
263
+ "link",
264
+ "meta",
265
+ "param",
266
+ "source",
267
+ "track",
268
+ "wbr"
269
+ ])
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as tokenizer from "./internal/tokenizer"
5
+ import type { Token } from "./Token"
6
+
7
+ /**
8
+ * @since 1.0.0
9
+ */
10
+ export const tokenize: (template: ReadonlyArray<string>) => Iterable<Token> = tokenizer.tokenize
package/src/Vitest.ts ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as Effect from "effect/Effect"
5
+ import type { Scope } from "effect/Scope"
6
+ import * as TestClock from "effect/TestClock"
7
+ import * as TestContext from "effect/TestContext"
8
+ import type * as TestServices from "effect/TestServices"
9
+ import * as vitest from "vitest"
10
+
11
+ export {
12
+ /**
13
+ * @since 1.0.0
14
+ */
15
+ describe,
16
+ /**
17
+ * @since 1.0.0
18
+ */
19
+ expect
20
+ } from "vitest"
21
+
22
+ /**
23
+ * @since 1.0.0
24
+ */
25
+ export function it<E, A>(
26
+ name: string,
27
+ test: () => Effect.Effect<Scope, E, A>,
28
+ options?: vitest.TestOptions
29
+ ) {
30
+ return vitest.it(
31
+ name,
32
+ () =>
33
+ test().pipe(
34
+ Effect.scoped,
35
+ Effect.runPromise
36
+ ),
37
+ options
38
+ )
39
+ }
40
+
41
+ /**
42
+ * @since 1.0.0
43
+ */
44
+ export function test<E, A>(
45
+ name: string,
46
+ test: (options: {
47
+ readonly clock: TestClock.TestClock
48
+ }) => Effect.Effect<Scope | TestServices.TestServices, E, A>,
49
+ options?: vitest.TestOptions
50
+ ) {
51
+ return vitest.it(
52
+ name,
53
+ () =>
54
+ TestClock.testClockWith((clock) => test({ clock })).pipe(
55
+ Effect.provide(TestContext.TestContext),
56
+ Effect.scoped,
57
+ Effect.runPromise
58
+ ),
59
+ options
60
+ )
61
+ }
package/src/index.ts ADDED
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+
5
+ import "./internal/module-augmentation"
6
+
7
+ /**
8
+ * @since 1.0.0
9
+ */
10
+ export * as Directive from "./Directive"
11
+ /**
12
+ * @since 1.0.0
13
+ */
14
+ export * as ElementRef from "./ElementRef"
15
+ /**
16
+ * @since 1.0.0
17
+ */
18
+ export * as ElementSource from "./ElementSource"
19
+ /**
20
+ * @since 1.0.0
21
+ */
22
+ export * as EventHandler from "./EventHandler"
23
+ /**
24
+ * @since 1.0.0
25
+ */
26
+ export * from "./Html"
27
+ /**
28
+ * @since 1.0.0
29
+ */
30
+ export * from "./Hydrate"
31
+ /**
32
+ * @since 1.0.0
33
+ */
34
+ export * from "./Many"
35
+ /**
36
+ * @since 1.0.0
37
+ */
38
+ export * from "./Part"
39
+ /**
40
+ * @since 1.0.0
41
+ */
42
+ export * from "./Placeholder"
43
+ /**
44
+ * @since 1.0.0
45
+ */
46
+ export * from "./Render"
47
+ /**
48
+ * @since 1.0.0
49
+ */
50
+ export * from "./Renderable"
51
+ /**
52
+ * @since 1.0.0
53
+ */
54
+ export * as RenderContext from "./RenderContext"
55
+ /**
56
+ * @since 1.0.0
57
+ */
58
+ export * from "./RenderEvent"
59
+ /**
60
+ * @since 1.0.0
61
+ */
62
+ export * from "./RenderTemplate"
63
+ /**
64
+ * @since 1.0.0
65
+ */
66
+ export * from "./TemplateInstance"
@@ -0,0 +1,23 @@
1
+ import { Tagged } from "@typed/context"
2
+ import type { Template } from "../Template"
3
+ import type { ParentChildNodes } from "./utils"
4
+
5
+ /**
6
+ * Used Internally to pass context down to components for hydration
7
+ * @internal
8
+ */
9
+ export type HydrateContext = {
10
+ readonly where: ParentChildNodes
11
+ readonly rootIndex: number
12
+ readonly parentTemplate: Template | null
13
+ readonly childIndex?: number
14
+
15
+ /**@internal */
16
+ hydrate: boolean
17
+ }
18
+
19
+ /**
20
+ * Used Internally to pass context down to components for hydration
21
+ * @internal
22
+ */
23
+ export const HydrateContext = Tagged<HydrateContext>("@typed/html/HydrateContext")
@@ -0,0 +1,132 @@
1
+ import { diffable, isComment } from "@typed/wire"
2
+ import udomdiff from "udomdiff"
3
+ import type { RenderContext } from "../RenderContext"
4
+ import type { RenderEvent } from "../RenderEvent"
5
+ import { isRenderEvent } from "../RenderEvent"
6
+ import { NodePartImpl } from "./parts"
7
+ import { findHoleComment, isCommentWithValue } from "./utils"
8
+
9
+ export function makeRenderNodePart(
10
+ index: number,
11
+ parent: HTMLElement | SVGElement,
12
+ ctx: RenderContext,
13
+ document: Document,
14
+ isHydrating: boolean
15
+ ) {
16
+ const comment = findHoleComment(parent, index)
17
+ let text: Text
18
+ let nodes = isHydrating ? findPreviousNodes(comment, index) : []
19
+
20
+ return new NodePartImpl(index, ({ part, value }) => {
21
+ return ctx.queue.add(part, () => {
22
+ matchValue(value, (content) => {
23
+ if (text === undefined) {
24
+ text = document.createTextNode("")
25
+ }
26
+ text.textContent = content
27
+
28
+ nodes = diffChildren(comment, nodes, [text], document)
29
+ }, (updatedNodes) => {
30
+ nodes = diffChildren(comment, nodes, updatedNodes, document)
31
+ })
32
+ })
33
+ }, nodes)
34
+ }
35
+
36
+ export function getPreviousTextSibling(node: Node | null) {
37
+ if (!node) return null
38
+
39
+ if (node && node.nodeType === node.TEXT_NODE) {
40
+ // During hydration there should be a comment to separate these values
41
+ if (
42
+ node.previousSibling &&
43
+ isComment(node.previousSibling) &&
44
+ isCommentWithValue(node.previousSibling, "text")
45
+ ) {
46
+ return node as Text
47
+ }
48
+ }
49
+
50
+ return null
51
+ }
52
+
53
+ export function notIsEmptyTextNode(node: Node) {
54
+ if (node.nodeType === node.COMMENT_NODE) {
55
+ return node.nodeValue?.trim() === ""
56
+ }
57
+
58
+ return true
59
+ }
60
+
61
+ export function findPreviousNodes(comment: Comment, index: number) {
62
+ const previousIndex = `hole${index - 1}`
63
+
64
+ const nodes: Array<Node> = []
65
+
66
+ let node = comment.previousSibling
67
+ while (node && !isCommentWithValue(node, previousIndex) && !isCommentWithValue(node, "text")) {
68
+ nodes.unshift(node)
69
+ node = node.previousSibling
70
+ }
71
+
72
+ return nodes
73
+ }
74
+
75
+ export function diffChildren(
76
+ comment: Comment,
77
+ currentNodes: Array<Node>,
78
+ nextNodes: Array<Node>,
79
+ document: Document
80
+ ) {
81
+ return udomdiff(
82
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
83
+ comment.parentNode!,
84
+ // Document Fragments cannot be removed, so we filter them out
85
+ currentNodes.filter((x) => x.nodeType !== x.DOCUMENT_FRAGMENT_NODE),
86
+ nextNodes.flatMap(flattenRenderEvent),
87
+ diffable(document),
88
+ comment
89
+ )
90
+ }
91
+
92
+ function flattenRenderEvent(x: Node | RenderEvent): Array<Node> {
93
+ if (isRenderEvent(x)) {
94
+ const value = x.valueOf()
95
+
96
+ return Array.isArray(value) ? value : [value]
97
+ } else {
98
+ return [x]
99
+ }
100
+ }
101
+
102
+ function matchValue<A, B>(value: unknown, onText: (text: string) => A, onNodes: (nodes: Array<Node>) => B): A | B {
103
+ switch (typeof value) {
104
+ // primitives are handled as text content
105
+ case "string":
106
+ case "symbol":
107
+ case "number":
108
+ case "bigint":
109
+ case "boolean":
110
+ return onText(String(value))
111
+ case "undefined":
112
+ case "object": {
113
+ if (!value) {
114
+ return onNodes([])
115
+ } else if (Array.isArray(value)) {
116
+ // arrays can be used to cleanup, if empty
117
+ if (value.length === 0) return onNodes([])
118
+ // or diffed, if these contains nodes or "wires"
119
+ else if (value.some((x) => typeof x === "object")) {
120
+ return onNodes(
121
+ value.flatMap((x) => (x === null ? [] : [isRenderEvent(x) ? x.valueOf() : x]))
122
+ )
123
+ } // in all other cases the content is stringified as is
124
+ else return onText(String(value))
125
+ } else {
126
+ return onNodes([isRenderEvent(value) ? (value.valueOf() as Node) : (value as Node)])
127
+ }
128
+ }
129
+ case "function":
130
+ return onNodes([])
131
+ }
132
+ }
@@ -0,0 +1,73 @@
1
+ export type TextChunk = {
2
+ readonly length: number
3
+ readonly match: RegExpExecArray
4
+ }
5
+
6
+ export const PART_STRING = (i: number) => `{{__PART${i}__}}`
7
+
8
+ export const PART_REGEX = /(\{\{__PART(\d+)__\}\})/g
9
+
10
+ export const getPart = chunker(PART_REGEX)
11
+
12
+ export const STRICT_PART_REGEX = /^(\{\{__PART(\d+)__\}\})$/g
13
+
14
+ export const getStrictPart = chunker(STRICT_PART_REGEX)
15
+
16
+ export const getOpeningTag = chunker(/(\s?<(([a-z0-9-]+:)?[a-z0-9-]+))\s?/gi)
17
+
18
+ export const getOpeningTagEnd = chunker(/((\s+)?>)/gi)
19
+
20
+ // Matches the closing of a tag
21
+ // Allows for whitespace between the tag name and the closing brackets
22
+ // allows for namespaced tags
23
+ export const getClosingTag = chunker(/(\s?<\/(\s+)?(([a-z0-9-]+:)?[a-z0-9-]+)(\s+)?>)/gi)
24
+
25
+ export const getSelfClosingTagEnd = chunker(/(\s+\/>)/gi)
26
+
27
+ export const getComment = chunker(/(<!--(.+)-->)/gu)
28
+
29
+ // Get all the text that does not lead to a Part
30
+ // Uses a negative lookahead to ensure to match all text that does not lead to a Part
31
+ export const getTextUntilPart = chunker(/((?:(?!{{__PART\d+__}}).)*)/gi)
32
+
33
+ // Get all the text that does not lead to a Part
34
+ // Uses a negative lookahead to ensure to match all text that does not lead to a brace
35
+ export const getTextUntilCloseBrace = chunker(/((?:(?!<).)*)/gi)
36
+
37
+ // Get an attribute and its value within quotes
38
+ export const getAttributeWithQuotes = chunker(
39
+ /(\s+(([?.@a-z0-9\-_]+:)?[?.@a-z0-9\-_]+)="([^"]*)")/gi
40
+ )
41
+
42
+ // Get an attribute and its value without quotes up to the next whitespace
43
+ export const getAttributeWithoutQuotes = chunker(
44
+ /(\s+(([?.@a-z0-9\-_]+:)?[?.@a-z0-9\-_]+)=([^\s>]*))/gi
45
+ )
46
+
47
+ // Get a boolean attribute up to the next whitespace
48
+
49
+ export const getBooleanAttribute = chunker(/(\s+(([?.@a-z0-9\-_]+:)?[?.@a-z0-9\-_]+)(?=[\s>]))/gi)
50
+
51
+ // Takes all text content until </ tagName > with optional whitespace
52
+ export const getAllTextUntilElementClose = (tagName: string) => {
53
+ return chunker(new RegExp(`([^<]+)(\\s*<\\/${tagName}\\s*>)`, "gi"))
54
+ }
55
+
56
+ export const getWhitespace = chunker(/(\s+)/g)
57
+
58
+ function chunker(regex: RegExp) {
59
+ return (str: string, pos: number): TextChunk | undefined => {
60
+ regex.lastIndex = pos
61
+ const match = regex.exec(str)
62
+ regex.lastIndex = 0
63
+
64
+ if (!match || match.index !== pos) {
65
+ return
66
+ } else {
67
+ return {
68
+ length: match[1].length,
69
+ match
70
+ } as const
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,11 @@
1
+ export class CouldNotFindCommentError extends Error {
2
+ constructor(readonly partIndex: number) {
3
+ super(`Could not find comment for part ${partIndex}`)
4
+ }
5
+ }
6
+
7
+ export class CouldNotFindRootElement extends Error {
8
+ constructor(readonly partIndex: number) {
9
+ super(`Could not find root elements for part ${partIndex}`)
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ declare module "udomdiff" {
2
+ const udomdiff: (
3
+ parentNode: Node,
4
+ current: Array<Node>,
5
+ updated: Array<Node>,
6
+ get: (n: Node, x: number) => Node | DocumentFragment | null,
7
+ before: Node
8
+ ) => Array<Node>
9
+
10
+ export default udomdiff
11
+ }