@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.
- package/Directive/package.json +6 -0
- package/ElementRef/package.json +6 -0
- package/ElementSource/package.json +6 -0
- package/Entry/package.json +6 -0
- package/EventHandler/package.json +6 -0
- package/Html/package.json +6 -0
- package/HtmlChunk/package.json +6 -0
- package/Hydrate/package.json +6 -0
- package/Many/package.json +6 -0
- package/Meta/package.json +6 -0
- package/Parser/package.json +6 -0
- package/Part/package.json +6 -0
- package/Placeholder/package.json +6 -0
- package/Platform/package.json +6 -0
- package/Render/package.json +6 -0
- package/RenderContext/package.json +6 -0
- package/RenderEvent/package.json +6 -0
- package/RenderTemplate/package.json +6 -0
- package/Renderable/package.json +6 -0
- package/Template/package.json +6 -0
- package/TemplateInstance/package.json +6 -0
- package/Test/package.json +6 -0
- package/Vitest/package.json +6 -0
- package/dist/cjs/Directive.js +1 -1
- package/dist/cjs/Directive.js.map +1 -1
- package/dist/cjs/ElementRef.js +23 -13
- package/dist/cjs/ElementRef.js.map +1 -1
- package/dist/cjs/ElementSource.js +16 -18
- package/dist/cjs/ElementSource.js.map +1 -1
- package/dist/cjs/EventHandler.js +1 -1
- package/dist/cjs/EventHandler.js.map +1 -1
- package/dist/cjs/Html.js +31 -32
- package/dist/cjs/Html.js.map +1 -1
- package/dist/cjs/HtmlChunk.js +4 -1
- package/dist/cjs/HtmlChunk.js.map +1 -1
- package/dist/cjs/Hydrate.js +1 -1
- package/dist/cjs/Hydrate.js.map +1 -1
- package/dist/cjs/Many.js +14 -13
- package/dist/cjs/Many.js.map +1 -1
- package/dist/cjs/Parser.js +11 -323
- package/dist/cjs/Parser.js.map +1 -1
- package/dist/cjs/Placeholder.js +3 -3
- package/dist/cjs/Placeholder.js.map +1 -1
- package/dist/cjs/Platform.js +4 -4
- package/dist/cjs/Platform.js.map +1 -1
- package/dist/cjs/Render.js +1 -1
- package/dist/cjs/Render.js.map +1 -1
- package/dist/cjs/RenderContext.js +48 -27
- package/dist/cjs/RenderContext.js.map +1 -1
- package/dist/cjs/RenderTemplate.js +2 -17
- package/dist/cjs/RenderTemplate.js.map +1 -1
- package/dist/cjs/Template.js +27 -1
- package/dist/cjs/Template.js.map +1 -1
- package/dist/cjs/TemplateInstance.js +2 -2
- package/dist/cjs/TemplateInstance.js.map +1 -1
- package/dist/cjs/Test.js +20 -7
- package/dist/cjs/Test.js.map +1 -1
- package/dist/cjs/index.js +0 -12
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/EventSource.js +95 -0
- package/dist/cjs/internal/EventSource.js.map +1 -0
- package/dist/cjs/internal/browser.js +11 -11
- package/dist/cjs/internal/browser.js.map +1 -1
- package/dist/cjs/internal/hydrate.js +49 -50
- package/dist/cjs/internal/hydrate.js.map +1 -1
- package/dist/cjs/internal/indexRefCounter.js +49 -2
- package/dist/cjs/internal/indexRefCounter.js.map +1 -1
- package/dist/cjs/internal/parser.js +60 -17
- package/dist/cjs/internal/parser.js.map +1 -1
- package/dist/cjs/internal/parts.js +128 -28
- package/dist/cjs/internal/parts.js.map +1 -1
- package/dist/cjs/internal/render.js +486 -53
- package/dist/cjs/internal/render.js.map +1 -1
- package/dist/cjs/internal/server.js +5 -2
- package/dist/cjs/internal/server.js.map +1 -1
- package/dist/dts/Directive.d.ts.map +1 -1
- package/dist/dts/ElementRef.d.ts +4 -2
- package/dist/dts/ElementRef.d.ts.map +1 -1
- package/dist/dts/ElementSource.d.ts +10 -5
- package/dist/dts/ElementSource.d.ts.map +1 -1
- package/dist/dts/EventHandler.d.ts.map +1 -1
- package/dist/dts/Html.d.ts +1 -1
- package/dist/dts/Html.d.ts.map +1 -1
- package/dist/dts/HtmlChunk.d.ts.map +1 -1
- package/dist/dts/Many.d.ts +13 -11
- package/dist/dts/Many.d.ts.map +1 -1
- package/dist/dts/Parser.d.ts +3 -6
- package/dist/dts/Parser.d.ts.map +1 -1
- package/dist/dts/Part.d.ts +13 -3
- package/dist/dts/Part.d.ts.map +1 -1
- package/dist/dts/Placeholder.d.ts +2 -2
- package/dist/dts/Placeholder.d.ts.map +1 -1
- package/dist/dts/Render.d.ts +2 -1
- package/dist/dts/Render.d.ts.map +1 -1
- package/dist/dts/RenderContext.d.ts +5 -4
- package/dist/dts/RenderContext.d.ts.map +1 -1
- package/dist/dts/RenderTemplate.d.ts +2 -16
- package/dist/dts/RenderTemplate.d.ts.map +1 -1
- package/dist/dts/Renderable.d.ts +2 -2
- package/dist/dts/Renderable.d.ts.map +1 -1
- package/dist/dts/Template.d.ts +21 -3
- package/dist/dts/Template.d.ts.map +1 -1
- package/dist/dts/TemplateInstance.d.ts +3 -2
- package/dist/dts/TemplateInstance.d.ts.map +1 -1
- package/dist/dts/Test.d.ts +4 -6
- package/dist/dts/Test.d.ts.map +1 -1
- package/dist/dts/index.d.ts +0 -4
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/EventSource.d.ts +12 -0
- package/dist/dts/internal/EventSource.d.ts.map +1 -0
- package/dist/dts/internal/browser.d.ts.map +1 -1
- package/dist/dts/internal/hydrate.d.ts +5 -5
- package/dist/dts/internal/hydrate.d.ts.map +1 -1
- package/dist/dts/internal/indexRefCounter.d.ts +5 -0
- package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
- package/dist/dts/internal/module-augmentation.d.ts +0 -4
- package/dist/dts/internal/module-augmentation.d.ts.map +1 -1
- package/dist/dts/internal/parser.d.ts +8 -0
- package/dist/dts/internal/parser.d.ts.map +1 -1
- package/dist/dts/internal/parts.d.ts +66 -56
- package/dist/dts/internal/parts.d.ts.map +1 -1
- package/dist/dts/internal/render.d.ts +7 -7
- package/dist/dts/internal/render.d.ts.map +1 -1
- package/dist/dts/internal/server.d.ts.map +1 -1
- package/dist/esm/Directive.js +1 -1
- package/dist/esm/Directive.js.map +1 -1
- package/dist/esm/ElementRef.js +12 -7
- package/dist/esm/ElementRef.js.map +1 -1
- package/dist/esm/ElementSource.js +16 -13
- package/dist/esm/ElementSource.js.map +1 -1
- package/dist/esm/EventHandler.js +1 -1
- package/dist/esm/EventHandler.js.map +1 -1
- package/dist/esm/Html.js +29 -24
- package/dist/esm/Html.js.map +1 -1
- package/dist/esm/HtmlChunk.js +6 -1
- package/dist/esm/HtmlChunk.js.map +1 -1
- package/dist/esm/Hydrate.js +1 -1
- package/dist/esm/Hydrate.js.map +1 -1
- package/dist/esm/Many.js +14 -10
- package/dist/esm/Many.js.map +1 -1
- package/dist/esm/Parser.js +6 -335
- package/dist/esm/Parser.js.map +1 -1
- package/dist/esm/Placeholder.js +2 -2
- package/dist/esm/Placeholder.js.map +1 -1
- package/dist/esm/Platform.js +2 -2
- package/dist/esm/Platform.js.map +1 -1
- package/dist/esm/Render.js +1 -1
- package/dist/esm/Render.js.map +1 -1
- package/dist/esm/RenderContext.js +38 -17
- package/dist/esm/RenderContext.js.map +1 -1
- package/dist/esm/RenderTemplate.js +2 -12
- package/dist/esm/RenderTemplate.js.map +1 -1
- package/dist/esm/Template.js +24 -0
- package/dist/esm/Template.js.map +1 -1
- package/dist/esm/TemplateInstance.js +2 -2
- package/dist/esm/TemplateInstance.js.map +1 -1
- package/dist/esm/Test.js +20 -7
- package/dist/esm/Test.js.map +1 -1
- package/dist/esm/index.js +0 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/EventSource.js +91 -0
- package/dist/esm/internal/EventSource.js.map +1 -0
- package/dist/esm/internal/browser.js +12 -12
- package/dist/esm/internal/browser.js.map +1 -1
- package/dist/esm/internal/hydrate.js +45 -46
- package/dist/esm/internal/hydrate.js.map +1 -1
- package/dist/esm/internal/indexRefCounter.js +50 -2
- package/dist/esm/internal/indexRefCounter.js.map +1 -1
- package/dist/esm/internal/parser.js +84 -17
- package/dist/esm/internal/parser.js.map +1 -1
- package/dist/esm/internal/parts.js +110 -27
- package/dist/esm/internal/parts.js.map +1 -1
- package/dist/esm/internal/render.js +476 -58
- package/dist/esm/internal/render.js.map +1 -1
- package/dist/esm/internal/server.js +5 -4
- package/dist/esm/internal/server.js.map +1 -1
- package/package.json +10 -26
- package/src/Directive.ts +1 -1
- package/src/ElementRef.ts +18 -14
- package/src/ElementSource.ts +62 -47
- package/src/EventHandler.ts +1 -1
- package/src/Html.ts +58 -57
- package/src/HtmlChunk.ts +15 -1
- package/src/Hydrate.ts +1 -1
- package/src/Many.ts +53 -43
- package/src/Parser.ts +10 -453
- package/src/Part.ts +15 -3
- package/src/Placeholder.ts +4 -4
- package/src/Platform.ts +2 -2
- package/src/Render.ts +7 -2
- package/src/RenderContext.ts +49 -21
- package/src/RenderTemplate.ts +9 -54
- package/src/Renderable.ts +2 -1
- package/src/Template.ts +26 -0
- package/src/TemplateInstance.ts +9 -9
- package/src/Test.ts +40 -21
- package/src/index.ts +0 -4
- package/src/internal/EventSource.ts +153 -0
- package/src/internal/browser.ts +26 -25
- package/src/internal/hydrate.ts +68 -61
- package/src/internal/indexRefCounter.ts +63 -2
- package/src/internal/module-augmentation.ts +0 -4
- package/src/internal/parser.ts +92 -19
- package/src/internal/parts.ts +158 -73
- package/src/internal/render.ts +701 -89
- package/src/internal/server.ts +5 -3
- package/dist/cjs/Token.js +0 -270
- package/dist/cjs/Token.js.map +0 -1
- package/dist/cjs/Tokenizer.js +0 -18
- package/dist/cjs/Tokenizer.js.map +0 -1
- package/dist/cjs/internal/readAttribute.js +0 -34
- package/dist/cjs/internal/readAttribute.js.map +0 -1
- package/dist/cjs/internal/tokenizer.js +0 -264
- package/dist/cjs/internal/tokenizer.js.map +0 -1
- package/dist/dts/Token.d.ts +0 -202
- package/dist/dts/Token.d.ts.map +0 -1
- package/dist/dts/Tokenizer.d.ts +0 -6
- package/dist/dts/Tokenizer.d.ts.map +0 -1
- package/dist/dts/internal/readAttribute.d.ts +0 -9
- package/dist/dts/internal/readAttribute.d.ts.map +0 -1
- package/dist/dts/internal/tokenizer.d.ts +0 -3
- package/dist/dts/internal/tokenizer.d.ts.map +0 -1
- package/dist/esm/Token.js +0 -264
- package/dist/esm/Token.js.map +0 -1
- package/dist/esm/Tokenizer.js +0 -9
- package/dist/esm/Tokenizer.js.map +0 -1
- package/dist/esm/internal/readAttribute.js +0 -24
- package/dist/esm/internal/readAttribute.js.map +0 -1
- package/dist/esm/internal/tokenizer.js +0 -296
- package/dist/esm/internal/tokenizer.js.map +0 -1
- package/src/Token.ts +0 -269
- package/src/Tokenizer.ts +0 -10
- package/src/internal/readAttribute.ts +0 -28
- 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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
*/
|
package/src/Placeholder.ts
CHANGED
|
@@ -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
|
|
10
|
-
import
|
|
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("
|
|
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
|
-
|
|
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
|
}
|