@typed/template 0.1.4 → 0.3.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 (234) hide show
  1. package/Directive/package.json +6 -0
  2. package/ElementRef/package.json +6 -0
  3. package/ElementSource/package.json +6 -0
  4. package/Entry/package.json +6 -0
  5. package/EventHandler/package.json +6 -0
  6. package/Html/package.json +6 -0
  7. package/HtmlChunk/package.json +6 -0
  8. package/Hydrate/package.json +6 -0
  9. package/Many/package.json +6 -0
  10. package/Meta/package.json +6 -0
  11. package/Parser/package.json +6 -0
  12. package/Part/package.json +6 -0
  13. package/Placeholder/package.json +6 -0
  14. package/Platform/package.json +6 -0
  15. package/Render/package.json +6 -0
  16. package/RenderContext/package.json +6 -0
  17. package/RenderEvent/package.json +6 -0
  18. package/RenderTemplate/package.json +6 -0
  19. package/Renderable/package.json +6 -0
  20. package/Template/package.json +6 -0
  21. package/TemplateInstance/package.json +6 -0
  22. package/Test/package.json +6 -0
  23. package/Vitest/package.json +6 -0
  24. package/dist/cjs/Directive.js +1 -1
  25. package/dist/cjs/Directive.js.map +1 -1
  26. package/dist/cjs/ElementRef.js +23 -13
  27. package/dist/cjs/ElementRef.js.map +1 -1
  28. package/dist/cjs/ElementSource.js +16 -18
  29. package/dist/cjs/ElementSource.js.map +1 -1
  30. package/dist/cjs/EventHandler.js +1 -1
  31. package/dist/cjs/EventHandler.js.map +1 -1
  32. package/dist/cjs/Html.js +31 -32
  33. package/dist/cjs/Html.js.map +1 -1
  34. package/dist/cjs/HtmlChunk.js +4 -1
  35. package/dist/cjs/HtmlChunk.js.map +1 -1
  36. package/dist/cjs/Hydrate.js +1 -1
  37. package/dist/cjs/Hydrate.js.map +1 -1
  38. package/dist/cjs/Many.js +14 -13
  39. package/dist/cjs/Many.js.map +1 -1
  40. package/dist/cjs/Parser.js +11 -323
  41. package/dist/cjs/Parser.js.map +1 -1
  42. package/dist/cjs/Placeholder.js +3 -3
  43. package/dist/cjs/Placeholder.js.map +1 -1
  44. package/dist/cjs/Platform.js +4 -4
  45. package/dist/cjs/Platform.js.map +1 -1
  46. package/dist/cjs/Render.js +1 -1
  47. package/dist/cjs/Render.js.map +1 -1
  48. package/dist/cjs/RenderContext.js +48 -27
  49. package/dist/cjs/RenderContext.js.map +1 -1
  50. package/dist/cjs/RenderTemplate.js +2 -17
  51. package/dist/cjs/RenderTemplate.js.map +1 -1
  52. package/dist/cjs/Template.js +27 -1
  53. package/dist/cjs/Template.js.map +1 -1
  54. package/dist/cjs/TemplateInstance.js +2 -2
  55. package/dist/cjs/TemplateInstance.js.map +1 -1
  56. package/dist/cjs/Test.js +20 -7
  57. package/dist/cjs/Test.js.map +1 -1
  58. package/dist/cjs/index.js +0 -12
  59. package/dist/cjs/index.js.map +1 -1
  60. package/dist/cjs/internal/EventSource.js +95 -0
  61. package/dist/cjs/internal/EventSource.js.map +1 -0
  62. package/dist/cjs/internal/browser.js +11 -11
  63. package/dist/cjs/internal/browser.js.map +1 -1
  64. package/dist/cjs/internal/hydrate.js +49 -50
  65. package/dist/cjs/internal/hydrate.js.map +1 -1
  66. package/dist/cjs/internal/indexRefCounter.js +49 -2
  67. package/dist/cjs/internal/indexRefCounter.js.map +1 -1
  68. package/dist/cjs/internal/parser.js +60 -17
  69. package/dist/cjs/internal/parser.js.map +1 -1
  70. package/dist/cjs/internal/parts.js +128 -28
  71. package/dist/cjs/internal/parts.js.map +1 -1
  72. package/dist/cjs/internal/render.js +486 -53
  73. package/dist/cjs/internal/render.js.map +1 -1
  74. package/dist/cjs/internal/server.js +5 -2
  75. package/dist/cjs/internal/server.js.map +1 -1
  76. package/dist/dts/Directive.d.ts.map +1 -1
  77. package/dist/dts/ElementRef.d.ts +4 -2
  78. package/dist/dts/ElementRef.d.ts.map +1 -1
  79. package/dist/dts/ElementSource.d.ts +10 -5
  80. package/dist/dts/ElementSource.d.ts.map +1 -1
  81. package/dist/dts/EventHandler.d.ts.map +1 -1
  82. package/dist/dts/Html.d.ts +1 -1
  83. package/dist/dts/Html.d.ts.map +1 -1
  84. package/dist/dts/HtmlChunk.d.ts.map +1 -1
  85. package/dist/dts/Many.d.ts +13 -11
  86. package/dist/dts/Many.d.ts.map +1 -1
  87. package/dist/dts/Parser.d.ts +3 -6
  88. package/dist/dts/Parser.d.ts.map +1 -1
  89. package/dist/dts/Part.d.ts +13 -3
  90. package/dist/dts/Part.d.ts.map +1 -1
  91. package/dist/dts/Placeholder.d.ts +2 -2
  92. package/dist/dts/Placeholder.d.ts.map +1 -1
  93. package/dist/dts/Render.d.ts +2 -1
  94. package/dist/dts/Render.d.ts.map +1 -1
  95. package/dist/dts/RenderContext.d.ts +5 -4
  96. package/dist/dts/RenderContext.d.ts.map +1 -1
  97. package/dist/dts/RenderTemplate.d.ts +2 -16
  98. package/dist/dts/RenderTemplate.d.ts.map +1 -1
  99. package/dist/dts/Renderable.d.ts +2 -2
  100. package/dist/dts/Renderable.d.ts.map +1 -1
  101. package/dist/dts/Template.d.ts +21 -3
  102. package/dist/dts/Template.d.ts.map +1 -1
  103. package/dist/dts/TemplateInstance.d.ts +3 -2
  104. package/dist/dts/TemplateInstance.d.ts.map +1 -1
  105. package/dist/dts/Test.d.ts +4 -6
  106. package/dist/dts/Test.d.ts.map +1 -1
  107. package/dist/dts/index.d.ts +0 -4
  108. package/dist/dts/index.d.ts.map +1 -1
  109. package/dist/dts/internal/EventSource.d.ts +12 -0
  110. package/dist/dts/internal/EventSource.d.ts.map +1 -0
  111. package/dist/dts/internal/browser.d.ts.map +1 -1
  112. package/dist/dts/internal/hydrate.d.ts +5 -5
  113. package/dist/dts/internal/hydrate.d.ts.map +1 -1
  114. package/dist/dts/internal/indexRefCounter.d.ts +5 -0
  115. package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
  116. package/dist/dts/internal/module-augmentation.d.ts +0 -4
  117. package/dist/dts/internal/module-augmentation.d.ts.map +1 -1
  118. package/dist/dts/internal/parser.d.ts +8 -0
  119. package/dist/dts/internal/parser.d.ts.map +1 -1
  120. package/dist/dts/internal/parts.d.ts +66 -56
  121. package/dist/dts/internal/parts.d.ts.map +1 -1
  122. package/dist/dts/internal/render.d.ts +7 -7
  123. package/dist/dts/internal/render.d.ts.map +1 -1
  124. package/dist/dts/internal/server.d.ts.map +1 -1
  125. package/dist/esm/Directive.js +1 -1
  126. package/dist/esm/Directive.js.map +1 -1
  127. package/dist/esm/ElementRef.js +12 -7
  128. package/dist/esm/ElementRef.js.map +1 -1
  129. package/dist/esm/ElementSource.js +16 -13
  130. package/dist/esm/ElementSource.js.map +1 -1
  131. package/dist/esm/EventHandler.js +1 -1
  132. package/dist/esm/EventHandler.js.map +1 -1
  133. package/dist/esm/Html.js +29 -24
  134. package/dist/esm/Html.js.map +1 -1
  135. package/dist/esm/HtmlChunk.js +6 -1
  136. package/dist/esm/HtmlChunk.js.map +1 -1
  137. package/dist/esm/Hydrate.js +1 -1
  138. package/dist/esm/Hydrate.js.map +1 -1
  139. package/dist/esm/Many.js +14 -10
  140. package/dist/esm/Many.js.map +1 -1
  141. package/dist/esm/Parser.js +6 -335
  142. package/dist/esm/Parser.js.map +1 -1
  143. package/dist/esm/Placeholder.js +2 -2
  144. package/dist/esm/Placeholder.js.map +1 -1
  145. package/dist/esm/Platform.js +2 -2
  146. package/dist/esm/Platform.js.map +1 -1
  147. package/dist/esm/Render.js +1 -1
  148. package/dist/esm/Render.js.map +1 -1
  149. package/dist/esm/RenderContext.js +38 -17
  150. package/dist/esm/RenderContext.js.map +1 -1
  151. package/dist/esm/RenderTemplate.js +2 -12
  152. package/dist/esm/RenderTemplate.js.map +1 -1
  153. package/dist/esm/Template.js +24 -0
  154. package/dist/esm/Template.js.map +1 -1
  155. package/dist/esm/TemplateInstance.js +2 -2
  156. package/dist/esm/TemplateInstance.js.map +1 -1
  157. package/dist/esm/Test.js +20 -7
  158. package/dist/esm/Test.js.map +1 -1
  159. package/dist/esm/index.js +0 -4
  160. package/dist/esm/index.js.map +1 -1
  161. package/dist/esm/internal/EventSource.js +91 -0
  162. package/dist/esm/internal/EventSource.js.map +1 -0
  163. package/dist/esm/internal/browser.js +12 -12
  164. package/dist/esm/internal/browser.js.map +1 -1
  165. package/dist/esm/internal/hydrate.js +45 -46
  166. package/dist/esm/internal/hydrate.js.map +1 -1
  167. package/dist/esm/internal/indexRefCounter.js +50 -2
  168. package/dist/esm/internal/indexRefCounter.js.map +1 -1
  169. package/dist/esm/internal/parser.js +84 -17
  170. package/dist/esm/internal/parser.js.map +1 -1
  171. package/dist/esm/internal/parts.js +110 -27
  172. package/dist/esm/internal/parts.js.map +1 -1
  173. package/dist/esm/internal/render.js +476 -58
  174. package/dist/esm/internal/render.js.map +1 -1
  175. package/dist/esm/internal/server.js +5 -4
  176. package/dist/esm/internal/server.js.map +1 -1
  177. package/package.json +10 -26
  178. package/src/Directive.ts +1 -1
  179. package/src/ElementRef.ts +18 -14
  180. package/src/ElementSource.ts +62 -47
  181. package/src/EventHandler.ts +1 -1
  182. package/src/Html.ts +58 -57
  183. package/src/HtmlChunk.ts +15 -1
  184. package/src/Hydrate.ts +1 -1
  185. package/src/Many.ts +53 -43
  186. package/src/Parser.ts +10 -453
  187. package/src/Part.ts +15 -3
  188. package/src/Placeholder.ts +4 -4
  189. package/src/Platform.ts +2 -2
  190. package/src/Render.ts +7 -2
  191. package/src/RenderContext.ts +49 -21
  192. package/src/RenderTemplate.ts +9 -54
  193. package/src/Renderable.ts +2 -1
  194. package/src/Template.ts +26 -0
  195. package/src/TemplateInstance.ts +9 -9
  196. package/src/Test.ts +40 -21
  197. package/src/index.ts +0 -4
  198. package/src/internal/EventSource.ts +153 -0
  199. package/src/internal/browser.ts +26 -25
  200. package/src/internal/hydrate.ts +68 -61
  201. package/src/internal/indexRefCounter.ts +63 -2
  202. package/src/internal/module-augmentation.ts +0 -4
  203. package/src/internal/parser.ts +92 -19
  204. package/src/internal/parts.ts +158 -73
  205. package/src/internal/render.ts +701 -89
  206. package/src/internal/server.ts +5 -3
  207. package/dist/cjs/Token.js +0 -270
  208. package/dist/cjs/Token.js.map +0 -1
  209. package/dist/cjs/Tokenizer.js +0 -18
  210. package/dist/cjs/Tokenizer.js.map +0 -1
  211. package/dist/cjs/internal/readAttribute.js +0 -34
  212. package/dist/cjs/internal/readAttribute.js.map +0 -1
  213. package/dist/cjs/internal/tokenizer.js +0 -264
  214. package/dist/cjs/internal/tokenizer.js.map +0 -1
  215. package/dist/dts/Token.d.ts +0 -202
  216. package/dist/dts/Token.d.ts.map +0 -1
  217. package/dist/dts/Tokenizer.d.ts +0 -6
  218. package/dist/dts/Tokenizer.d.ts.map +0 -1
  219. package/dist/dts/internal/readAttribute.d.ts +0 -9
  220. package/dist/dts/internal/readAttribute.d.ts.map +0 -1
  221. package/dist/dts/internal/tokenizer.d.ts +0 -3
  222. package/dist/dts/internal/tokenizer.d.ts.map +0 -1
  223. package/dist/esm/Token.js +0 -264
  224. package/dist/esm/Token.js.map +0 -1
  225. package/dist/esm/Tokenizer.js +0 -9
  226. package/dist/esm/Tokenizer.js.map +0 -1
  227. package/dist/esm/internal/readAttribute.js +0 -24
  228. package/dist/esm/internal/readAttribute.js.map +0 -1
  229. package/dist/esm/internal/tokenizer.js +0 -296
  230. package/dist/esm/internal/tokenizer.js.map +0 -1
  231. package/src/Token.ts +0 -269
  232. package/src/Tokenizer.ts +0 -10
  233. package/src/internal/readAttribute.ts +0 -28
  234. package/src/internal/tokenizer.ts +0 -338
package/src/Parser.ts CHANGED
@@ -2,456 +2,13 @@
2
2
  * @since 1.0.0
3
3
  */
4
4
 
5
- import * as Chunk from "effect/Chunk"
6
- import { globalValue } from "effect/GlobalValue"
7
- import { templateHash } from "./internal/parser.js"
8
- import * as Template from "./Template.js"
9
- import type { Token } from "./Token.js"
10
- import { tokenize } from "./Tokenizer.js"
11
-
12
- /**
13
- * @since 1.0.0
14
- */
15
- export interface Parser {
16
- parse(template: ReadonlyArray<string>, tokenStream?: Iterator<Token>): Template.Template
17
- }
18
-
19
- const iterator = <A>(iterable: Iterable<A>): Iterator<A> => iterable[Symbol.iterator]()
20
-
21
- const dropLast = Chunk.dropRight(1)
22
-
23
- class ParserImpl {
24
- protected _template: ReadonlyArray<string> = []
25
- protected _tokenStream!: Iterator<Token>
26
- protected _lookahead!: Token | null
27
- protected _stack!: Chunk.Chunk<number>
28
- protected _parts!: Array<[Template.PartNode | Template.SparsePartNode, Chunk.Chunk<number>]>
29
- protected _skipWhitespace!: boolean
30
-
31
- parse(
32
- template: ReadonlyArray<string>,
33
- tokenStream: Iterator<Token> = iterator(tokenize(template))
34
- ): Template.Template {
35
- this._template = template
36
- this._tokenStream = tokenStream
37
- this._lookahead = this.getNextToken()
38
- this._stack = Chunk.empty()
39
- this._parts = []
40
- this._skipWhitespace = true
41
-
42
- const ast = this.Template(templateHash(template))
43
-
44
- return ast
45
- }
46
-
47
- protected Template(hash: string): Template.Template {
48
- const template = new Template.Template(this.Children(), hash, this._parts)
49
-
50
- return template
51
- }
52
-
53
- protected Node(): Template.Node | null {
54
- const token = this.findTokenOfType(
55
- "opening-tag",
56
- "text",
57
- "comment",
58
- "comment-start",
59
- "part-token",
60
- "closing-tag"
61
- )
62
-
63
- if (token._tag === "closing-tag") return null
64
-
65
- if (token._tag === "text") {
66
- if (this._skipWhitespace && token.value.trim() === "") return null
67
-
68
- return new Template.TextNode(token.value)
69
- }
70
-
71
- if (token._tag === "comment") {
72
- return new Template.CommentNode(token.value)
73
- }
74
-
75
- if (token._tag === "comment-start") {
76
- const node = this.Comment("")
77
- return node
78
- }
79
-
80
- // Some annoyances here for generating the correct path for node parts
81
- if (token._tag === "part-token") {
82
- this._skipWhitespace = false
83
- return this.addPartWithoutCurrent(new Template.NodePart(token.index))
84
- }
85
-
86
- this._skipWhitespace = true
87
-
88
- if (token.isSelfClosing) {
89
- return this.SelfClosingElementNode(token.name)
90
- } else if (token.textOnly) {
91
- return this.TextOnlyElement(token.name)
92
- } else {
93
- return this.ElementNode(token.name)
94
- }
95
- }
96
-
97
- protected ElementNode(tagName: string): Template.ElementNode {
98
- const attrs: Array<Template.Attribute> = []
99
- const children: Array<Template.Node> = []
100
- const element = new Template.ElementNode(tagName, attrs, children)
101
-
102
- this.Attributes(attrs)
103
- this.Children(children)
104
-
105
- return element
106
- }
107
-
108
- protected SelfClosingElementNode(tagName: string): Template.SelfClosingElementNode {
109
- const attrs: Array<Template.Attribute> = []
110
- const element = new Template.SelfClosingElementNode(tagName, attrs)
111
-
112
- this.Attributes(attrs)
113
-
114
- return element
115
- }
116
-
117
- protected TextOnlyElement(tagName: string): Template.TextOnlyElement {
118
- const attrs: Array<Template.Attribute> = []
119
- const children: Array<Template.Text> = []
120
- const element = new Template.TextOnlyElement(tagName, attrs, children)
121
-
122
- this.Attributes(attrs)
123
- this.TextChildren(children)
124
-
125
- return element
126
- }
127
-
128
- protected Attributes(attributes: Array<Template.Attribute> = []): Array<Template.Attribute> {
129
- while (this._lookahead !== null) {
130
- if (this._lookahead._tag === "opening-tag-end") {
131
- this._lookahead = this.getNextToken()
132
- break
133
- } else {
134
- const attr = this.Attribute()
135
- if (attr) {
136
- attributes.push(attr)
137
- } else {
138
- break
139
- }
140
- }
141
- }
142
-
143
- return attributes
144
- }
145
-
146
- protected Attribute(): Template.Attribute | null {
147
- const token = this.findTokenOfType(
148
- "attribute",
149
- "attribute-start",
150
- "boolean-attribute",
151
- "boolean-attribute-start",
152
- "className-attribute-start",
153
- "data-attribute-start",
154
- "event-attribute-start",
155
- "property-attribute-start",
156
- "ref-attribute-start",
157
- "text"
158
- )
159
-
160
- switch (token._tag) {
161
- case "attribute":
162
- return new Template.AttributeNode(token.name, token.value)
163
- case "attribute-start":
164
- return this.SparseAttrNode(token.name)
165
- case "boolean-attribute":
166
- return new Template.BooleanNode(token.name)
167
- case "boolean-attribute-start":
168
- return this.BooleanNode(token.name)
169
- case "className-attribute-start":
170
- return this.SparseClassNameNode()
171
- case "data-attribute-start":
172
- return this.DataNode()
173
- case "event-attribute-start":
174
- return this.EventNode(token.name)
175
- case "property-attribute-start":
176
- return this.PropertyNode(token.name)
177
- case "ref-attribute-start":
178
- return this.RefNode()
179
- case "text":
180
- return null
181
- }
182
- }
183
-
184
- protected SparseAttrNode(name: string): Template.SparseAttrNode | Template.AttrPartNode | Template.BooleanNode {
185
- const nodes: Array<Template.AttrPartNode | Template.TextNode> = []
186
-
187
- while (this._lookahead !== null) {
188
- const token = this.findTokenOfType("text", "part-token", "attribute-end")
189
-
190
- if (token._tag === "text") {
191
- if (token.value === "") continue
192
- nodes.push(new Template.TextNode(token.value))
193
- } else if (token._tag === "part-token") {
194
- nodes.push(new Template.AttrPartNode(name, token.index))
195
- } else {
196
- if (nodes.length === 0) {
197
- return new Template.BooleanNode(name)
198
- }
199
-
200
- break
201
- }
202
- }
203
-
204
- if (nodes.length === 1) {
205
- return this.addPart(nodes[0] as Template.AttrPartNode)
206
- }
207
-
208
- if (nodes.length === 0) {
209
- return new Template.BooleanNode(name)
210
- }
211
-
212
- return this.addPart(new Template.SparseAttrNode(name, nodes))
213
- }
214
-
215
- protected BooleanNode(name: string): Template.BooleanPartNode {
216
- // We know that the next token MUST be a part-token
217
- const part = this.predictNextToken("part-token")
218
-
219
- // We don't need to do anything with a boolean-attribute-end token, skip it
220
- this.skipIfNextToken("boolean-attribute-end")
221
-
222
- return this.addPart(new Template.BooleanPartNode(name, part.index))
223
- }
224
-
225
- protected SparseClassNameNode(): Template.SparseClassNameNode | Template.ClassNameNode {
226
- const nodes: Array<Template.ClassNameNode> = []
227
-
228
- while (this._lookahead !== null) {
229
- const token = this.findTokenOfType("text", "part-token", "className-attribute-end")
230
-
231
- if (token._tag === "text") {
232
- if (token.value.trim() === "") continue
233
- nodes.push(new Template.TextNode(token.value))
234
- } else if (token._tag === "part-token") {
235
- nodes.push(new Template.ClassNamePartNode(token.index))
236
- } else {
237
- break
238
- }
239
- }
240
-
241
- if (nodes.length === 0) {
242
- throw new SyntaxError("Expected at least one node in class name attribute")
243
- }
244
-
245
- if (nodes.length === 1) {
246
- return this.addPart(nodes[0] as Template.ClassNamePartNode)
247
- }
248
-
249
- return this.addPart(new Template.SparseClassNameNode(nodes))
250
- }
251
-
252
- protected DataNode(): Template.DataPartNode {
253
- const part = this.predictNextToken("part-token")
254
-
255
- // We don't need to do anything with a data-attribute-end token, skip it
256
- this.skipIfNextToken("data-attribute-end")
257
-
258
- return this.addPart(new Template.DataPartNode(part.index))
259
- }
260
-
261
- protected EventNode(name: string): Template.EventPartNode {
262
- const part = this.predictNextToken("part-token")
263
-
264
- // We don't need to do anything with a event-attribute-end token, skip it
265
- this.skipIfNextToken("event-attribute-end")
266
-
267
- return this.addPart(new Template.EventPartNode(name, part.index))
268
- }
269
-
270
- protected PropertyNode(name: string): Template.PropertyPartNode {
271
- const part = this.predictNextToken("part-token")
272
-
273
- // We don't need to do anything with a property-attribute-end token, skip it
274
- this.skipIfNextToken("property-attribute-end")
275
-
276
- return this.addPart(new Template.PropertyPartNode(name, part.index))
277
- }
278
-
279
- protected RefNode(): Template.RefPartNode {
280
- const part = this.predictNextToken("part-token")
281
-
282
- // We don't need to do anything with a ref-attribute-end token, skip it
283
- this.skipIfNextToken("ref-attribute-end")
284
-
285
- return this.addPart(new Template.RefPartNode(part.index))
286
- }
287
-
288
- protected TextPartNode(): Template.TextPartNode {
289
- const token = this.predictNextToken("part-token")
290
-
291
- return this.addPart(new Template.TextPartNode(token.index))
292
- }
293
-
294
- protected Children(children: Array<Template.Node> = []): Array<Template.Node> {
295
- let i = 0
296
- while (this._lookahead) {
297
- if (this._lookahead._tag === "closing-tag") {
298
- this._lookahead = this.getNextToken()
299
- this._skipWhitespace = true
300
-
301
- break
302
- } else if (
303
- this._skipWhitespace &&
304
- this._lookahead._tag === "text" &&
305
- this._lookahead.value.trim() === ""
306
- ) {
307
- this._lookahead = this.getNextToken()
308
- } else {
309
- this._stack = Chunk.append(this._stack, i++)
310
- const child = this.Node()
311
- this._stack = Chunk.dropRight(this._stack, 1)
312
-
313
- if (child) {
314
- children.push(child)
315
- } else {
316
- break
317
- }
318
- }
319
- }
320
-
321
- return children
322
- }
323
-
324
- protected TextChildren(children: Array<Template.Text> = []): Array<Template.Text> {
325
- while (this._lookahead !== null) {
326
- const token = this.findTokenOfType("text", "part-token", "closing-tag")
327
-
328
- if (token._tag === "text") {
329
- if (token.value) children.push(new Template.TextNode(token.value))
330
- } else if (token._tag === `part-token`) {
331
- children.push(this.addPart(new Template.TextPartNode(token.index)))
332
- } else {
333
- this._skipWhitespace = true
334
- break
335
- }
336
- }
337
-
338
- return children
339
- }
340
-
341
- protected Comment(before: string): Template.Comment {
342
- const nodes: Array<Template.CommentPartNode | Template.TextNode> = []
343
-
344
- if (before) {
345
- nodes.push(new Template.TextNode(before))
346
- }
347
-
348
- while (this._lookahead !== null) {
349
- const token = this.findTokenOfType("part-token", "text", "comment-end")
350
-
351
- if (token._tag === "part-token") {
352
- nodes.push(new Template.CommentPartNode(token.index))
353
- } else if (token._tag === "text") {
354
- nodes.push(new Template.TextNode(token.value))
355
- } else {
356
- break
357
- }
358
- }
359
-
360
- if (nodes.length === 1) {
361
- const node = nodes[0]
362
-
363
- if (node._tag === "comment-part") {
364
- return new Template.CommentPartNode(node.index)
365
- } else {
366
- return new Template.CommentNode(node.value)
367
- }
368
- }
369
-
370
- return this.addPart(new Template.SparseCommentNode(nodes))
371
- }
372
-
373
- protected findTokenOfType<T extends ReadonlyArray<Token["_tag"]>>(
374
- ...tokenTypes: T
375
- ): Extract<Token, { readonly _tag: T[number] }> {
376
- const token = this._lookahead
377
-
378
- if (token === null) {
379
- throw new SyntaxError(
380
- `Unexpected end of template. Expected one of types ${tokenTypes.join(", ")}.`
381
- )
382
- }
383
-
384
- for (let i = 0; i < tokenTypes.length; i++) {
385
- if (token._tag === tokenTypes[i]) {
386
- this._lookahead = this.getNextToken()
387
-
388
- return token as Extract<Token, { readonly _tag: T[number] }>
389
- }
390
- }
391
-
392
- throw new SyntaxError(
393
- `Unexpected token ${token._tag}. Expected one of types ${tokenTypes.join(", ")}.`
394
- )
395
- }
396
-
397
- protected predictNextToken<T extends Token["_tag"]>(
398
- type: T
399
- ): Extract<Token, { readonly _tag: T }> {
400
- const token = this._lookahead
401
-
402
- if (token === null) {
403
- throw new SyntaxError(`Unexpected end of template. Expected ${type}.`)
404
- }
405
-
406
- if (token._tag !== type) {
407
- throw new SyntaxError(`Unexpected token ${token._tag}. Expected ${type}.`)
408
- }
409
-
410
- this._lookahead = this.getNextToken()
411
-
412
- return token as Extract<Token, { readonly _tag: T }>
413
- }
414
-
415
- protected skipIfNextToken<T extends Token["_tag"]>(type: T): boolean {
416
- const token = this._lookahead
417
-
418
- if (token === null) {
419
- return false
420
- }
421
-
422
- if (token._tag !== type) {
423
- return false
424
- }
425
-
426
- this._lookahead = this.getNextToken()
427
-
428
- return true
429
- }
430
-
431
- protected getNextToken(): Token | null {
432
- const { done, value } = this._tokenStream.next()
433
-
434
- if (done) {
435
- return null
436
- }
437
-
438
- return value
439
- }
440
-
441
- protected addPart<A extends Template.PartNode | Template.SparsePartNode>(part: A): A {
442
- this._parts.push([part, this._stack])
443
-
444
- return part
445
- }
446
-
447
- protected addPartWithoutCurrent<A extends Template.PartNode>(part: A): A {
448
- this._parts.push([part, dropLast(this._stack)])
449
-
450
- return part
451
- }
452
- }
453
-
454
- /**
455
- * @since 1.0.0
456
- */
457
- export const parser: Parser = globalValue(Symbol.for("./Parser.js"), () => new ParserImpl())
5
+ export {
6
+ /**
7
+ * @since 1.0.0
8
+ */
9
+ parse,
10
+ /**
11
+ * @since 1.0.0
12
+ */
13
+ templateHash
14
+ } from "./internal/parser.js"
package/src/Part.ts CHANGED
@@ -22,6 +22,7 @@ export type Part =
22
22
  | PropertyPart
23
23
  | RefPart
24
24
  | TextPart
25
+ | PropertiesPart
25
26
 
26
27
  /**
27
28
  * @since 1.0.0
@@ -75,11 +76,11 @@ export interface DataPart {
75
76
  export interface EventPart {
76
77
  readonly _tag: "event"
77
78
  readonly name: string
78
- readonly value: EventHandler<unknown, never> | null | undefined
79
+ readonly source: ElementSource<any>
80
+ readonly value: null
79
81
  readonly index: number
80
82
  readonly onCause: (cause: Cause<unknown>) => Effect<never, never, unknown>
81
-
82
- readonly update: <R = never>(value: EventHandler<R, never> | null | undefined) => Effect<R | Scope, never, void>
83
+ readonly addEventListener: (handler: EventHandler<never, never, Event>) => void
83
84
  }
84
85
 
85
86
  /**
@@ -136,6 +137,17 @@ export interface NodePart {
136
137
  readonly update: (value: this["value"]) => Effect<Scope, never, void>
137
138
  }
138
139
 
140
+ /**
141
+ * @since 1.0.0
142
+ */
143
+ export interface PropertiesPart {
144
+ readonly _tag: "properties"
145
+ readonly value: Readonly<Record<string, any>> | null | undefined
146
+ readonly index: number
147
+
148
+ readonly update: (value: this["value"]) => Effect<Scope, never, void>
149
+ }
150
+
139
151
  /**
140
152
  * @since 1.0.0
141
153
  */
@@ -6,13 +6,13 @@ import "./internal/module-augmentation.js"
6
6
  import type { Fx } from "@typed/fx/Fx"
7
7
  import { isFx } from "@typed/fx/Fx"
8
8
  import * as RefSubject from "@typed/fx/RefSubject"
9
- import type { Scope } from "effect"
10
- import { Effect } from "effect"
9
+ import * as Effect from "effect/Effect"
10
+ import type * as Scope from "effect/Scope"
11
11
 
12
12
  /**
13
13
  * @since 1.0.0
14
14
  */
15
- export const PlaceholderTypeId = Symbol.for("./Placholder.js")
15
+ export const PlaceholderTypeId = Symbol.for("@typed/template/Placholder")
16
16
  /**
17
17
  * @since 1.0.0
18
18
  */
@@ -64,7 +64,7 @@ export namespace Placeholder {
64
64
  if (isFx<R, E, A>(placeholder) || Effect.isEffect(placeholder)) {
65
65
  return RefSubject.make(placeholder as Fx<R, E, A>)
66
66
  } else {
67
- return RefSubject.of(placeholder as A)
67
+ return RefSubject.of<A, E>(placeholder as A)
68
68
  }
69
69
  }
70
70
  }
package/src/Platform.ts CHANGED
@@ -30,7 +30,7 @@ export function htmlResponse<R, E>(
30
30
  {
31
31
  ...CAMEL_CASE_CONTENT_TYPE,
32
32
  ...options,
33
- headers: { ...HYPHENATED_CONTENT_TYPE, ...options?.headers }
33
+ headers: Headers.unsafeFromRecord({ ...HYPHENATED_CONTENT_TYPE, ...options?.headers })
34
34
  }
35
35
  )
36
36
  )
@@ -48,7 +48,7 @@ export function htmlResponseString(
48
48
  {
49
49
  ...CAMEL_CASE_CONTENT_TYPE,
50
50
  ...options,
51
- headers: { ...HYPHENATED_CONTENT_TYPE, ...options?.headers }
51
+ headers: Headers.unsafeFromRecord({ ...HYPHENATED_CONTENT_TYPE, ...options?.headers })
52
52
  }
53
53
  )
54
54
  }
package/src/Render.ts CHANGED
@@ -7,6 +7,7 @@ import { Document } from "@typed/dom/Document"
7
7
  import { RootElement } from "@typed/dom/RootElement"
8
8
  import * as Fx from "@typed/fx/Fx"
9
9
  import { type Rendered } from "@typed/wire"
10
+ import type { Layer, Scope } from "effect"
10
11
  import * as Effect from "effect/Effect"
11
12
  import { attachRoot, renderTemplate } from "./internal/render.js"
12
13
  import { RenderContext } from "./RenderContext.js"
@@ -40,6 +41,10 @@ export function render<R, E, T extends RenderEvent | null>(
40
41
  */
41
42
  export function renderLayer<R, E, T extends RenderEvent | null>(
42
43
  rendered: Fx.Fx<R, E, T>
43
- ) {
44
- return Fx.drainLayer(Fx.switchMapCause(render(rendered), Effect.logError))
44
+ ): Layer.Layer<
45
+ Document | RenderContext | RootElement | Exclude<Exclude<R, RenderTemplate>, Scope.Scope>,
46
+ never,
47
+ never
48
+ > {
49
+ return Fx.drainLayer(Fx.switchMapCause(render(rendered), (e) => Fx.fromEffect(Effect.logError(e))))
45
50
  }