@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/Html.ts
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import * as Fx from "@typed/fx/Fx"
|
|
6
|
-
import
|
|
6
|
+
import * as Sink from "@typed/fx/Sink"
|
|
7
7
|
import { TypeId } from "@typed/fx/TypeId"
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import * as Effect from "effect/Effect"
|
|
9
|
+
import * as Option from "effect/Option"
|
|
10
10
|
import { join } from "effect/ReadonlyArray"
|
|
11
11
|
import type * as Scope from "effect/Scope"
|
|
12
12
|
import { isDirective } from "./Directive.js"
|
|
13
|
-
import * as ElementRef from "./ElementRef.js"
|
|
14
13
|
import type { ServerEntry } from "./Entry.js"
|
|
15
14
|
import type { HtmlChunk, PartChunk, SparsePartChunk, TextChunk } from "./HtmlChunk.js"
|
|
16
15
|
import { templateToHtmlChunks } from "./HtmlChunk.js"
|
|
@@ -23,10 +22,11 @@ import { RenderContext } from "./RenderContext.js"
|
|
|
23
22
|
import { HtmlRenderEvent, isRenderEvent } from "./RenderEvent.js"
|
|
24
23
|
import type { RenderEvent } from "./RenderEvent.js"
|
|
25
24
|
import { RenderTemplate } from "./RenderTemplate.js"
|
|
26
|
-
import { TemplateInstance } from "./TemplateInstance.js"
|
|
27
25
|
|
|
28
26
|
const toHtml = (r: RenderEvent) => (r as HtmlRenderEvent).html
|
|
29
27
|
|
|
28
|
+
const [padStart, padEnd] = [[TYPED_START], [TYPED_END]] as const
|
|
29
|
+
|
|
30
30
|
/**
|
|
31
31
|
* @since 1.0.0
|
|
32
32
|
*/
|
|
@@ -38,8 +38,7 @@ export function renderToHtml<R, E>(
|
|
|
38
38
|
fx.pipe(
|
|
39
39
|
Fx.provide(RenderTemplate.layer(renderHtml(ctx))),
|
|
40
40
|
Fx.map(toHtml),
|
|
41
|
-
Fx.
|
|
42
|
-
Fx.endWith(TYPED_END)
|
|
41
|
+
Fx.padWith(padStart, padEnd)
|
|
43
42
|
)
|
|
44
43
|
)
|
|
45
44
|
)
|
|
@@ -55,41 +54,30 @@ export function renderToHtmlString<R, E>(
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
function renderHtml(ctx: RenderContext) {
|
|
58
|
-
return <Values extends ReadonlyArray<Renderable<any, any
|
|
57
|
+
return <Values extends ReadonlyArray<Renderable<any, any>>>(
|
|
59
58
|
templateStrings: TemplateStringsArray,
|
|
60
|
-
values: Values
|
|
61
|
-
|
|
62
|
-
): Effect.Effect<
|
|
59
|
+
values: Values
|
|
60
|
+
): Fx.Fx<
|
|
63
61
|
Scope.Scope | Placeholder.Context<readonly [] extends Values ? never : Values[number]>,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
Placeholder.Error<Values[number]>,
|
|
67
|
-
T
|
|
68
|
-
>
|
|
62
|
+
Placeholder.Error<Values[number]>,
|
|
63
|
+
RenderEvent
|
|
69
64
|
> => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
),
|
|
87
|
-
(x) => (x.valueOf() as string).length > 0
|
|
88
|
-
) as any,
|
|
89
|
-
ref as any
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
})
|
|
65
|
+
const entry = getServerEntry(templateStrings, ctx.templateCache)
|
|
66
|
+
if (values.length === 0) {
|
|
67
|
+
return Fx.succeed(HtmlRenderEvent((entry.chunks[0] as TextChunk).value))
|
|
68
|
+
} else {
|
|
69
|
+
return Fx.filter(
|
|
70
|
+
Fx.mergeOrdered(
|
|
71
|
+
entry.chunks.map((chunk) =>
|
|
72
|
+
renderChunk<
|
|
73
|
+
Placeholder.Context<readonly [] extends Values ? never : Values[number]>,
|
|
74
|
+
Placeholder.Error<Values[number]>
|
|
75
|
+
>(chunk, values)
|
|
76
|
+
)
|
|
77
|
+
),
|
|
78
|
+
(x) => (x.valueOf() as string).length > 0
|
|
79
|
+
)
|
|
80
|
+
}
|
|
93
81
|
}
|
|
94
82
|
}
|
|
95
83
|
|
|
@@ -125,7 +113,7 @@ function renderObject<R, E>(renderable: object | null | undefined) {
|
|
|
125
113
|
if (renderable === null || renderable === undefined) {
|
|
126
114
|
return Fx.succeed(HtmlRenderEvent(TEXT_START))
|
|
127
115
|
} else if (Array.isArray(renderable)) {
|
|
128
|
-
return Fx.
|
|
116
|
+
return Fx.mergeOrdered(renderable.map(renderNode)) as any
|
|
129
117
|
} else if (Fx.isFx<R, E, Renderable>(renderable)) {
|
|
130
118
|
return Fx.concatMap(takeOneIfNotRenderEvent(renderable), renderNode as any)
|
|
131
119
|
} else if (Effect.isEffect(renderable)) {
|
|
@@ -146,7 +134,7 @@ function renderPart<R, E>(
|
|
|
146
134
|
|
|
147
135
|
// Refs and events are not rendered into HTML
|
|
148
136
|
if (isDirective<R, E>(renderable)) {
|
|
149
|
-
return Fx.
|
|
137
|
+
return Fx.make((sink: Sink.Sink<never, E, RenderEvent>) => {
|
|
150
138
|
const part = partNodeToPart(
|
|
151
139
|
node,
|
|
152
140
|
(value) => sink.onSuccess(HtmlRenderEvent(render(value)))
|
|
@@ -155,8 +143,21 @@ function renderPart<R, E>(
|
|
|
155
143
|
return Effect.catchAllCause(renderable(part), sink.onFailure)
|
|
156
144
|
})
|
|
157
145
|
} else if (node._tag === "node") {
|
|
158
|
-
return Fx.
|
|
146
|
+
return Fx.append(renderNode<R, E>(renderable), HtmlRenderEvent(TYPED_HOLE(node.index)))
|
|
147
|
+
} else if (node._tag === "properties") {
|
|
148
|
+
if (renderable == null) return Fx.empty
|
|
149
|
+
return Fx.map(
|
|
150
|
+
Fx.take(
|
|
151
|
+
Fx.struct(
|
|
152
|
+
Object.fromEntries(Object.entries(renderable).map(([k, v]) => [k, unwrapRenderable(v)] as const))
|
|
153
|
+
),
|
|
154
|
+
1
|
|
155
|
+
),
|
|
156
|
+
render
|
|
157
|
+
) as any
|
|
159
158
|
} else {
|
|
159
|
+
if (renderable === null) return Fx.succeed(HtmlRenderEvent(render(renderable)))
|
|
160
|
+
|
|
160
161
|
const html = Fx.filterMap(Fx.take(unwrapRenderable<R, E>(renderable), 1), (value) => {
|
|
161
162
|
const s = render(value)
|
|
162
163
|
|
|
@@ -164,7 +165,7 @@ function renderPart<R, E>(
|
|
|
164
165
|
})
|
|
165
166
|
|
|
166
167
|
if (node._tag === "text-part") {
|
|
167
|
-
return Fx.
|
|
168
|
+
return Fx.append(Fx.prepend(html, HtmlRenderEvent(TEXT_START)), HtmlRenderEvent(TYPED_HOLE(node.index)))
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
return html
|
|
@@ -179,14 +180,14 @@ function renderSparsePart<R, E>(
|
|
|
179
180
|
|
|
180
181
|
return Fx.map(
|
|
181
182
|
Fx.take(
|
|
182
|
-
Fx.
|
|
183
|
+
Fx.tuple(
|
|
183
184
|
node.nodes.map((node) => {
|
|
184
185
|
if (node._tag === "text") return Fx.succeed(node.value)
|
|
185
186
|
|
|
186
187
|
const renderable: Renderable<any, any> = (values as any)[node.index]
|
|
187
188
|
|
|
188
189
|
if (isDirective<R, E>(renderable)) {
|
|
189
|
-
return Fx.
|
|
190
|
+
return Fx.make<R, E, unknown>((sink: Sink.Sink<never, E, unknown>) =>
|
|
190
191
|
Effect.catchAllCause(
|
|
191
192
|
renderable(partNodeToPart(node, (value) => sink.onSuccess(value))),
|
|
192
193
|
sink.onFailure
|
|
@@ -204,17 +205,15 @@ function renderSparsePart<R, E>(
|
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
function takeOneIfNotRenderEvent<R, E, A>(fx: Fx.Fx<R, E, A>): Fx.Fx<R, E, A> {
|
|
207
|
-
return Fx.
|
|
208
|
-
|
|
209
|
-
fx
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Effect.fromFiberEffect
|
|
217
|
-
)
|
|
208
|
+
return Fx.make<R, E, A>((sink) =>
|
|
209
|
+
Sink.withEarlyExit(sink, (sink) =>
|
|
210
|
+
fx.run(
|
|
211
|
+
Sink.make(
|
|
212
|
+
sink.onFailure,
|
|
213
|
+
(event) =>
|
|
214
|
+
isRenderEvent(event) ? sink.onSuccess(event) : Effect.zipRight(sink.onSuccess(event), sink.earlyExit)
|
|
215
|
+
)
|
|
216
|
+
))
|
|
218
217
|
)
|
|
219
218
|
}
|
|
220
219
|
|
|
@@ -233,6 +232,8 @@ function getServerEntry(
|
|
|
233
232
|
chunks: templateToHtmlChunks(template)
|
|
234
233
|
}
|
|
235
234
|
|
|
235
|
+
templateCache.set(templateStrings, entry)
|
|
236
|
+
|
|
236
237
|
return entry
|
|
237
238
|
} else {
|
|
238
239
|
return cached
|
|
@@ -245,7 +246,7 @@ function unwrapRenderable<R, E>(renderable: Renderable<any, any>): Fx.Fx<R, E, a
|
|
|
245
246
|
case "object": {
|
|
246
247
|
if (renderable === null || renderable === undefined) return Fx.succeed(null)
|
|
247
248
|
else if (Array.isArray(renderable)) {
|
|
248
|
-
return Fx.
|
|
249
|
+
return Fx.tuple(renderable.map(unwrapRenderable)) as any
|
|
249
250
|
} else if (TypeId in renderable) {
|
|
250
251
|
return renderable as any
|
|
251
252
|
} else if (Effect.EffectTypeId in renderable) {
|
package/src/HtmlChunk.ts
CHANGED
|
@@ -64,7 +64,9 @@ export type AttrValue = string | null | undefined | ReadonlyArray<AttrValue>
|
|
|
64
64
|
* @since 1.0.0
|
|
65
65
|
*/
|
|
66
66
|
export function templateToHtmlChunks({ hash, nodes }: Template) {
|
|
67
|
-
|
|
67
|
+
const chunks = fuseTextChunks(nodes.flatMap((node) => nodeToHtmlChunk(node, hash)))
|
|
68
|
+
|
|
69
|
+
return chunks
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
function fuseTextChunks(chunks: Array<HtmlChunk>): ReadonlyArray<HtmlChunk> {
|
|
@@ -94,6 +96,7 @@ type NodeMap = {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
const nodeMap: NodeMap = {
|
|
99
|
+
doctype: (node) => [new TextChunk(`<!DOCTYPE ${node.name}>`)],
|
|
97
100
|
element: elementToHtmlChunks,
|
|
98
101
|
node: (node) => [new PartChunk(node, String)],
|
|
99
102
|
"self-closing-element": selfClosingElementToHtmlChunks,
|
|
@@ -201,6 +204,17 @@ const attrMap: AttrMap = {
|
|
|
201
204
|
new PartChunk(attr, (value) => value == null ? `` : datasetToString(value as Readonly<Record<string, string>>)),
|
|
202
205
|
event: () => new TextChunk(""),
|
|
203
206
|
property: (attr) => new PartChunk(attr, (value) => (value == null ? `` : ` ${attr.name}="${escape(value)}"`)),
|
|
207
|
+
properties: (attr) =>
|
|
208
|
+
new PartChunk(
|
|
209
|
+
attr,
|
|
210
|
+
(
|
|
211
|
+
value
|
|
212
|
+
) => (value == null
|
|
213
|
+
? ``
|
|
214
|
+
: " " + Object.entries(value).map(([key, value]) =>
|
|
215
|
+
value === true ? key : value === false ? "" : `${key}="${escape(value)}"`
|
|
216
|
+
).join(" "))
|
|
217
|
+
),
|
|
204
218
|
ref: () => new TextChunk(""),
|
|
205
219
|
"sparse-attr": (attr) =>
|
|
206
220
|
new SparsePartChunk(attr, (values) => {
|
package/src/Hydrate.ts
CHANGED
|
@@ -49,5 +49,5 @@ export function hydrate<R, E, T extends RenderEvent | null>(
|
|
|
49
49
|
export function hydrateLayer<R, E, T extends RenderEvent | null>(
|
|
50
50
|
rendered: Fx.Fx<R, E, T>
|
|
51
51
|
) {
|
|
52
|
-
return Fx.drainLayer(Fx.switchMapCause(hydrate(rendered), Effect.logError))
|
|
52
|
+
return Fx.drainLayer(Fx.switchMapCause(hydrate(rendered), (cause) => Fx.fromEffect(Effect.logError(cause))))
|
|
53
53
|
}
|
package/src/Many.ts
CHANGED
|
@@ -2,44 +2,54 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import type * as AsyncData from "@typed/async-data/AsyncData"
|
|
5
|
-
import
|
|
5
|
+
import * as RefAsyncData from "@typed/fx/AsyncData"
|
|
6
6
|
import * as Fx from "@typed/fx/Fx"
|
|
7
|
-
import * as RefAsyncData from "@typed/fx/RefAsyncData"
|
|
8
7
|
import * as RefSubject from "@typed/fx/RefSubject"
|
|
9
|
-
import {
|
|
8
|
+
import type { Scope } from "effect"
|
|
10
9
|
import * as Effect from "effect/Effect"
|
|
11
10
|
import { dual } from "effect/Function"
|
|
11
|
+
import type { NoInfer } from "effect/Types"
|
|
12
12
|
import { RenderContext } from "./RenderContext.js"
|
|
13
13
|
import { type RenderEvent } from "./RenderEvent.js"
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @since 1.0.0
|
|
17
17
|
*/
|
|
18
|
-
export function many<R, E, A, B, R2, E2>(
|
|
18
|
+
export function many<R, E, A, B extends PropertyKey, R2, E2>(
|
|
19
19
|
values: Fx.Fx<R, E, ReadonlyArray<A>>,
|
|
20
|
-
getKey: (a: A) => B,
|
|
21
|
-
f: (a: RefSubject.RefSubject<never, never, A
|
|
22
|
-
): Fx.Fx<R | R2 | RenderContext, E | E2, RenderEvent | ReadonlyArray<RenderEvent>> {
|
|
20
|
+
getKey: (a: NoInfer<A>) => B,
|
|
21
|
+
f: (a: RefSubject.RefSubject<never, never, NoInfer<A>>, key: B) => Fx.Fx<R2, E2, RenderEvent>
|
|
22
|
+
): Fx.Fx<R | R2 | Scope.Scope | RenderContext, E | E2, RenderEvent | ReadonlyArray<RenderEvent>> {
|
|
23
23
|
return Fx.fromFxEffect(
|
|
24
|
-
RenderContext.with(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
RenderContext.with(
|
|
25
|
+
(ctx): Fx.Fx<R | R2 | RenderContext | Scope.Scope, E | E2, RenderEvent | ReadonlyArray<RenderEvent>> => {
|
|
26
|
+
// When rendering HTML, we want to ensure that we order our HTML events in the same order
|
|
27
|
+
// as the templates are defined which is why we use mergeOrdered. We also want to ensure that
|
|
28
|
+
// our templates end, so we take only the first of our source values and also ensure that a subscription
|
|
29
|
+
// to our RefSubjects only include its first event.
|
|
30
|
+
if (ctx.environment === "server" || ctx.environment === "static") {
|
|
31
|
+
return Fx.fromFxEffect(
|
|
32
|
+
Effect.map(Fx.first(values), (values) =>
|
|
33
|
+
Fx.mergeOrdered(
|
|
34
|
+
values.map((value) =>
|
|
35
|
+
Fx.fromFxEffect(Effect.map(RefSubject.of(value), (ref) => f(RefSubject.take(ref, 1), getKey(value))))
|
|
36
|
+
)
|
|
37
|
+
))
|
|
38
|
+
)
|
|
39
|
+
}
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
// In other environments we just used Fx.keyed to allow indefinite subscriptions to RefSubjects
|
|
42
|
+
return Fx.keyed(values, {
|
|
43
|
+
getKey,
|
|
44
|
+
onValue: f
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
)
|
|
40
48
|
)
|
|
41
49
|
}
|
|
42
50
|
|
|
51
|
+
type TODO = any
|
|
52
|
+
|
|
43
53
|
/**
|
|
44
54
|
* @since 1.0.0
|
|
45
55
|
*/
|
|
@@ -47,18 +57,18 @@ export const manyAsyncData: {
|
|
|
47
57
|
<
|
|
48
58
|
E1,
|
|
49
59
|
A,
|
|
50
|
-
B,
|
|
51
|
-
NoData extends Fx.
|
|
52
|
-
Loading extends Fx.
|
|
53
|
-
Failure extends Fx.
|
|
54
|
-
Success extends Fx.
|
|
60
|
+
B extends PropertyKey,
|
|
61
|
+
NoData extends Fx.Fx<any, any, any>,
|
|
62
|
+
Loading extends Fx.Fx<any, any, any>,
|
|
63
|
+
Failure extends Fx.Fx<any, any, any>,
|
|
64
|
+
Success extends Fx.Fx<any, any, any>
|
|
55
65
|
>(
|
|
56
66
|
getKey: (a: A) => B,
|
|
57
67
|
matchers: {
|
|
58
68
|
NoData: () => NoData
|
|
59
|
-
Loading: (
|
|
60
|
-
Failure: (data:
|
|
61
|
-
Success: (value:
|
|
69
|
+
Loading: (todo: TODO) => Loading
|
|
70
|
+
Failure: (data: RefSubject.Computed<never, never, E1>, computed: TODO) => Failure
|
|
71
|
+
Success: (value: RefSubject.Computed<never, never, A>, computed: TODO) => Success
|
|
62
72
|
}
|
|
63
73
|
): <R, E>(
|
|
64
74
|
fx: Fx.Fx<R, E, AsyncData.AsyncData<E1, ReadonlyArray<A>>>
|
|
@@ -73,7 +83,7 @@ export const manyAsyncData: {
|
|
|
73
83
|
E,
|
|
74
84
|
E1,
|
|
75
85
|
A,
|
|
76
|
-
B,
|
|
86
|
+
B extends PropertyKey,
|
|
77
87
|
NoData extends Fx.Fx<any, any, any>,
|
|
78
88
|
Loading extends Fx.Fx<any, any, any>,
|
|
79
89
|
Failure extends Fx.Fx<any, any, any>,
|
|
@@ -83,9 +93,9 @@ export const manyAsyncData: {
|
|
|
83
93
|
getKey: (a: A) => B,
|
|
84
94
|
matchers: {
|
|
85
95
|
NoData: () => NoData
|
|
86
|
-
Loading: (data:
|
|
87
|
-
Failure: (data:
|
|
88
|
-
Success: (value:
|
|
96
|
+
Loading: (data: TODO) => Loading
|
|
97
|
+
Failure: (data: RefSubject.Computed<never, never, E1>, computed: TODO) => Failure
|
|
98
|
+
Success: (value: RefSubject.Computed<never, never, A>, computed: TODO) => Success
|
|
89
99
|
}
|
|
90
100
|
): Fx.Fx<
|
|
91
101
|
R | Fx.Fx.Context<NoData | Loading | Failure | Success>,
|
|
@@ -99,26 +109,26 @@ export const manyAsyncData: {
|
|
|
99
109
|
E,
|
|
100
110
|
E1,
|
|
101
111
|
A,
|
|
112
|
+
B extends PropertyKey,
|
|
102
113
|
NoData extends Fx.Fx<any, any, RenderEvent>,
|
|
103
114
|
Loading extends Fx.Fx<any, any, RenderEvent>,
|
|
104
115
|
Failure extends Fx.Fx<any, any, RenderEvent>,
|
|
105
|
-
Success extends Fx.Fx<any, any, RenderEvent
|
|
106
|
-
B
|
|
116
|
+
Success extends Fx.Fx<any, any, RenderEvent>
|
|
107
117
|
>(
|
|
108
118
|
fx: Fx.Fx<R, E, AsyncData.AsyncData<E1, ReadonlyArray<A>>>,
|
|
119
|
+
getKey: (a: A) => B,
|
|
109
120
|
matchers: {
|
|
110
|
-
NoData:
|
|
111
|
-
Loading: (data:
|
|
112
|
-
Failure: (data:
|
|
113
|
-
Success: (value:
|
|
114
|
-
}
|
|
115
|
-
getKey: (a: A) => B
|
|
121
|
+
NoData: NoData
|
|
122
|
+
Loading: (data: TODO) => Loading
|
|
123
|
+
Failure: (data: RefSubject.Computed<never, never, E1>, computed: TODO) => Failure
|
|
124
|
+
Success: (value: RefSubject.Computed<never, never, A>, computed: TODO) => Success
|
|
125
|
+
}
|
|
116
126
|
): Fx.Fx<
|
|
117
127
|
R | Fx.Fx.Context<NoData | Loading | Failure | Success>,
|
|
118
128
|
E | Fx.Fx.Error<NoData | Loading | Failure | Success>,
|
|
119
129
|
Fx.Fx.Success<NoData | Loading | Failure | Success>
|
|
120
130
|
> => {
|
|
121
|
-
return RefAsyncData.
|
|
131
|
+
return RefAsyncData.matchAsyncData(fx, {
|
|
122
132
|
NoData: matchers.NoData,
|
|
123
133
|
Loading: matchers.Loading,
|
|
124
134
|
Failure: matchers.Failure,
|