@typed/template 0.9.5 → 0.10.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/RenderQueue/package.json +6 -0
- package/dist/cjs/Directive.js +1 -1
- package/dist/cjs/Directive.js.map +1 -1
- package/dist/cjs/ElementRef.js +1 -1
- package/dist/cjs/ElementRef.js.map +1 -1
- package/dist/cjs/ElementSource.js +1 -1
- package/dist/cjs/ElementSource.js.map +1 -1
- package/dist/cjs/EventHandler.js +11 -4
- package/dist/cjs/EventHandler.js.map +1 -1
- package/dist/cjs/Html.js +84 -44
- package/dist/cjs/Html.js.map +1 -1
- package/dist/cjs/HtmlChunk.js +67 -21
- package/dist/cjs/HtmlChunk.js.map +1 -1
- package/dist/cjs/Hydrate.js +6 -6
- package/dist/cjs/Hydrate.js.map +1 -1
- package/dist/cjs/Many.js +4 -4
- package/dist/cjs/Many.js.map +1 -1
- package/dist/cjs/Meta.js +10 -3
- package/dist/cjs/Meta.js.map +1 -1
- package/dist/cjs/Parser.js +1 -1
- package/dist/cjs/Placeholder.js +5 -9
- package/dist/cjs/Placeholder.js.map +1 -1
- package/dist/cjs/Platform.js +7 -5
- package/dist/cjs/Platform.js.map +1 -1
- package/dist/cjs/Render.js +8 -7
- package/dist/cjs/Render.js.map +1 -1
- package/dist/cjs/RenderContext.js +8 -92
- package/dist/cjs/RenderContext.js.map +1 -1
- package/dist/cjs/RenderEvent.js +9 -1
- package/dist/cjs/RenderEvent.js.map +1 -1
- package/dist/cjs/RenderQueue.js +341 -0
- package/dist/cjs/RenderQueue.js.map +1 -0
- package/dist/cjs/RenderTemplate.js +1 -1
- package/dist/cjs/RenderTemplate.js.map +1 -1
- package/dist/cjs/Template.js +12 -0
- package/dist/cjs/Template.js.map +1 -1
- package/dist/cjs/Test.js +64 -33
- package/dist/cjs/Test.js.map +1 -1
- package/dist/cjs/Vitest.js +12 -20
- package/dist/cjs/Vitest.js.map +1 -1
- package/dist/cjs/index.js +6 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/EventSource.js +16 -9
- package/dist/cjs/internal/EventSource.js.map +1 -1
- package/dist/cjs/internal/HydrateContext.js.map +1 -1
- package/dist/cjs/internal/browser.js +11 -10
- package/dist/cjs/internal/browser.js.map +1 -1
- package/dist/cjs/internal/character-entities.js +2141 -0
- package/dist/cjs/internal/character-entities.js.map +1 -0
- package/dist/cjs/internal/errors.js +19 -2
- package/dist/cjs/internal/errors.js.map +1 -1
- package/dist/cjs/internal/indexRefCounter.js +36 -63
- package/dist/cjs/internal/indexRefCounter.js.map +1 -1
- package/dist/cjs/internal/parser.js +18 -17
- package/dist/cjs/internal/parser.js.map +1 -1
- package/dist/cjs/internal/parser2.js +382 -0
- package/dist/cjs/internal/parser2.js.map +1 -0
- package/dist/cjs/internal/server-parts.js +124 -0
- package/dist/cjs/internal/server-parts.js.map +1 -0
- package/dist/cjs/internal/server.js +15 -185
- package/dist/cjs/internal/server.js.map +1 -1
- package/dist/cjs/internal/utils.js +73 -9
- package/dist/cjs/internal/utils.js.map +1 -1
- package/dist/cjs/internal/v2/SyncPart.js +6 -0
- package/dist/cjs/internal/v2/SyncPart.js.map +1 -0
- package/dist/cjs/internal/v2/helpers.js +15 -0
- package/dist/cjs/internal/v2/helpers.js.map +1 -0
- package/dist/cjs/internal/v2/hydrate.js +202 -0
- package/dist/cjs/internal/v2/hydrate.js.map +1 -0
- package/dist/cjs/internal/v2/hydration-template.js +269 -0
- package/dist/cjs/internal/v2/hydration-template.js.map +1 -0
- package/dist/cjs/internal/v2/parts.js +169 -0
- package/dist/cjs/internal/v2/parts.js.map +1 -0
- package/dist/cjs/internal/v2/render-entry.js +110 -0
- package/dist/cjs/internal/v2/render-entry.js.map +1 -0
- package/dist/cjs/internal/v2/render-sync-parts.js +318 -0
- package/dist/cjs/internal/v2/render-sync-parts.js.map +1 -0
- package/dist/cjs/internal/v2/render.js +417 -0
- package/dist/cjs/internal/v2/render.js.map +1 -0
- package/dist/cjs/internal/v2/sync-parts.js +115 -0
- package/dist/cjs/internal/v2/sync-parts.js.map +1 -0
- package/dist/dts/ElementRef.d.ts +1 -1
- package/dist/dts/ElementRef.d.ts.map +1 -1
- package/dist/dts/ElementSource.d.ts +1 -1
- package/dist/dts/ElementSource.d.ts.map +1 -1
- package/dist/dts/EventHandler.d.ts +12 -8
- package/dist/dts/EventHandler.d.ts.map +1 -1
- package/dist/dts/Html.d.ts +6 -5
- package/dist/dts/Html.d.ts.map +1 -1
- package/dist/dts/HtmlChunk.d.ts.map +1 -1
- package/dist/dts/Hydrate.d.ts +1 -3
- package/dist/dts/Hydrate.d.ts.map +1 -1
- package/dist/dts/Many.d.ts +9 -11
- package/dist/dts/Many.d.ts.map +1 -1
- package/dist/dts/Meta.d.ts +5 -1
- package/dist/dts/Meta.d.ts.map +1 -1
- package/dist/dts/Parser.d.ts +1 -1
- package/dist/dts/Parser.d.ts.map +1 -1
- package/dist/dts/Part.d.ts +20 -56
- package/dist/dts/Part.d.ts.map +1 -1
- package/dist/dts/Placeholder.d.ts +6 -10
- package/dist/dts/Placeholder.d.ts.map +1 -1
- package/dist/dts/Platform.d.ts +2 -4
- package/dist/dts/Platform.d.ts.map +1 -1
- package/dist/dts/Render.d.ts +4 -8
- package/dist/dts/Render.d.ts.map +1 -1
- package/dist/dts/RenderContext.d.ts +3 -22
- package/dist/dts/RenderContext.d.ts.map +1 -1
- package/dist/dts/RenderEvent.d.ts +6 -1
- package/dist/dts/RenderEvent.d.ts.map +1 -1
- package/dist/dts/RenderQueue.d.ts +103 -0
- package/dist/dts/RenderQueue.d.ts.map +1 -0
- package/dist/dts/RenderTemplate.d.ts +3 -2
- package/dist/dts/RenderTemplate.d.ts.map +1 -1
- package/dist/dts/Renderable.d.ts +1 -1
- package/dist/dts/Template.d.ts +14 -1
- package/dist/dts/Template.d.ts.map +1 -1
- package/dist/dts/Test.d.ts +14 -1
- package/dist/dts/Test.d.ts.map +1 -1
- package/dist/dts/Vitest.d.ts +11 -8
- package/dist/dts/Vitest.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/EventSource.d.ts +2 -1
- package/dist/dts/internal/EventSource.d.ts.map +1 -1
- package/dist/dts/internal/browser.d.ts +3 -3
- package/dist/dts/internal/browser.d.ts.map +1 -1
- package/dist/dts/internal/character-entities.d.ts +2133 -0
- package/dist/dts/internal/character-entities.d.ts.map +1 -0
- package/dist/dts/internal/errors.d.ts +9 -1
- package/dist/dts/internal/errors.d.ts.map +1 -1
- package/dist/dts/internal/indexRefCounter.d.ts +0 -4
- package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
- package/dist/dts/internal/parser.d.ts +13 -0
- package/dist/dts/internal/parser.d.ts.map +1 -1
- package/dist/dts/internal/parser2.d.ts +12 -0
- package/dist/dts/internal/parser2.d.ts.map +1 -0
- package/dist/dts/internal/server-parts.d.ts +223 -0
- package/dist/dts/internal/server-parts.d.ts.map +1 -0
- package/dist/dts/internal/server.d.ts +2 -28
- package/dist/dts/internal/server.d.ts.map +1 -1
- package/dist/dts/internal/utils.d.ts +4 -1
- package/dist/dts/internal/utils.d.ts.map +1 -1
- package/dist/dts/internal/v2/SyncPart.d.ts +87 -0
- package/dist/dts/internal/v2/SyncPart.d.ts.map +1 -0
- package/dist/dts/internal/v2/helpers.d.ts +3 -0
- package/dist/dts/internal/v2/helpers.d.ts.map +1 -0
- package/dist/dts/internal/v2/hydrate.d.ts +7 -0
- package/dist/dts/internal/v2/hydrate.d.ts.map +1 -0
- package/dist/dts/internal/v2/hydration-template.d.ts +54 -0
- package/dist/dts/internal/v2/hydration-template.d.ts.map +1 -0
- package/dist/dts/internal/v2/parts.d.ts +245 -0
- package/dist/dts/internal/v2/parts.d.ts.map +1 -0
- package/dist/dts/internal/v2/render-entry.d.ts +6 -0
- package/dist/dts/internal/v2/render-entry.d.ts.map +1 -0
- package/dist/dts/internal/v2/render-sync-parts.d.ts +22 -0
- package/dist/dts/internal/v2/render-sync-parts.d.ts.map +1 -0
- package/dist/dts/internal/v2/render.d.ts +62 -0
- package/dist/dts/internal/v2/render.d.ts.map +1 -0
- package/dist/dts/internal/v2/sync-parts.d.ts +129 -0
- package/dist/dts/internal/v2/sync-parts.d.ts.map +1 -0
- package/dist/esm/ElementRef.js.map +1 -1
- package/dist/esm/EventHandler.js +14 -4
- package/dist/esm/EventHandler.js.map +1 -1
- package/dist/esm/Html.js +91 -50
- package/dist/esm/Html.js.map +1 -1
- package/dist/esm/HtmlChunk.js +75 -24
- package/dist/esm/HtmlChunk.js.map +1 -1
- package/dist/esm/Hydrate.js +5 -5
- package/dist/esm/Hydrate.js.map +1 -1
- package/dist/esm/Many.js +3 -3
- package/dist/esm/Many.js.map +1 -1
- package/dist/esm/Meta.js +7 -1
- package/dist/esm/Meta.js.map +1 -1
- package/dist/esm/Parser.js +1 -1
- package/dist/esm/Parser.js.map +1 -1
- package/dist/esm/Placeholder.js +4 -8
- package/dist/esm/Placeholder.js.map +1 -1
- package/dist/esm/Platform.js +3 -1
- package/dist/esm/Platform.js.map +1 -1
- package/dist/esm/Render.js +6 -5
- package/dist/esm/Render.js.map +1 -1
- package/dist/esm/RenderContext.js +5 -85
- package/dist/esm/RenderContext.js.map +1 -1
- package/dist/esm/RenderEvent.js +8 -1
- package/dist/esm/RenderEvent.js.map +1 -1
- package/dist/esm/RenderQueue.js +336 -0
- package/dist/esm/RenderQueue.js.map +1 -0
- package/dist/esm/RenderTemplate.js.map +1 -1
- package/dist/esm/Template.js +12 -0
- package/dist/esm/Template.js.map +1 -1
- package/dist/esm/Test.js +71 -30
- package/dist/esm/Test.js.map +1 -1
- package/dist/esm/Vitest.js +11 -8
- package/dist/esm/Vitest.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/EventSource.js +12 -7
- package/dist/esm/internal/EventSource.js.map +1 -1
- package/dist/esm/internal/HydrateContext.js.map +1 -1
- package/dist/esm/internal/browser.js +10 -9
- package/dist/esm/internal/browser.js.map +1 -1
- package/dist/esm/internal/character-entities.js +2134 -0
- package/dist/esm/internal/character-entities.js.map +1 -0
- package/dist/esm/internal/errors.js +22 -2
- package/dist/esm/internal/errors.js.map +1 -1
- package/dist/esm/internal/indexRefCounter.js +36 -61
- package/dist/esm/internal/indexRefCounter.js.map +1 -1
- package/dist/esm/internal/parser.js +18 -18
- package/dist/esm/internal/parser.js.map +1 -1
- package/dist/esm/internal/parser2.js +393 -0
- package/dist/esm/internal/parser2.js.map +1 -0
- package/dist/esm/internal/server-parts.js +109 -0
- package/dist/esm/internal/server-parts.js.map +1 -0
- package/dist/esm/internal/server.js +12 -161
- package/dist/esm/internal/server.js.map +1 -1
- package/dist/esm/internal/utils.js +71 -7
- package/dist/esm/internal/utils.js.map +1 -1
- package/dist/esm/internal/v2/SyncPart.js +5 -0
- package/dist/esm/internal/v2/SyncPart.js.map +1 -0
- package/dist/esm/internal/v2/helpers.js +12 -0
- package/dist/esm/internal/v2/helpers.js.map +1 -0
- package/dist/esm/internal/v2/hydrate.js +195 -0
- package/dist/esm/internal/v2/hydrate.js.map +1 -0
- package/dist/esm/internal/v2/hydration-template.js +265 -0
- package/dist/esm/internal/v2/hydration-template.js.map +1 -0
- package/dist/esm/internal/v2/parts.js +150 -0
- package/dist/esm/internal/v2/parts.js.map +1 -0
- package/dist/esm/internal/v2/render-entry.js +102 -0
- package/dist/esm/internal/v2/render-entry.js.map +1 -0
- package/dist/esm/internal/v2/render-sync-parts.js +265 -0
- package/dist/esm/internal/v2/render-sync-parts.js.map +1 -0
- package/dist/esm/internal/v2/render.js +353 -0
- package/dist/esm/internal/v2/render.js.map +1 -0
- package/dist/esm/internal/v2/sync-parts.js +102 -0
- package/dist/esm/internal/v2/sync-parts.js.map +1 -0
- package/package.json +20 -13
- package/src/ElementRef.ts +1 -1
- package/src/ElementSource.ts +1 -1
- package/src/EventHandler.ts +29 -11
- package/src/Html.ts +199 -90
- package/src/HtmlChunk.ts +77 -30
- package/src/Hydrate.ts +20 -14
- package/src/Many.ts +17 -14
- package/src/Meta.ts +8 -1
- package/src/Parser.ts +1 -1
- package/src/Part.ts +22 -66
- package/src/Placeholder.ts +17 -15
- package/src/Platform.ts +5 -5
- package/src/Render.ts +23 -26
- package/src/RenderContext.ts +14 -142
- package/src/RenderEvent.ts +10 -1
- package/src/RenderQueue.ts +445 -0
- package/src/RenderTemplate.ts +7 -2
- package/src/Renderable.ts +1 -1
- package/src/Template.ts +15 -1
- package/src/Test.ts +122 -38
- package/src/Vitest.ts +20 -10
- package/src/index.ts +4 -0
- package/src/internal/EventSource.ts +14 -8
- package/src/internal/HydrateContext.ts +3 -4
- package/src/internal/browser.ts +26 -21
- package/src/internal/character-entities.ts +2136 -0
- package/src/internal/errors.ts +30 -3
- package/src/internal/indexRefCounter.ts +38 -70
- package/src/internal/parser.ts +19 -19
- package/src/internal/parser2.ts +468 -0
- package/src/internal/server-parts.ts +161 -0
- package/src/internal/server.ts +16 -272
- package/src/internal/utils.ts +83 -7
- package/src/internal/v2/SyncPart.ts +112 -0
- package/src/internal/v2/helpers.ts +13 -0
- package/src/internal/v2/hydrate.ts +289 -0
- package/src/internal/v2/hydration-template.ts +308 -0
- package/src/internal/v2/parts.ts +254 -0
- package/src/internal/v2/render-entry.ts +131 -0
- package/src/internal/v2/render-sync-parts.ts +440 -0
- package/src/internal/v2/render.ts +588 -0
- package/src/internal/v2/sync-parts.ts +133 -0
- package/dist/cjs/internal/hydrate.js +0 -274
- package/dist/cjs/internal/hydrate.js.map +0 -1
- package/dist/cjs/internal/parts.js +0 -451
- package/dist/cjs/internal/parts.js.map +0 -1
- package/dist/cjs/internal/render.js +0 -704
- package/dist/cjs/internal/render.js.map +0 -1
- package/dist/dts/internal/hydrate.d.ts +0 -33
- package/dist/dts/internal/hydrate.d.ts.map +0 -1
- package/dist/dts/internal/parts.d.ts +0 -314
- package/dist/dts/internal/parts.d.ts.map +0 -1
- package/dist/dts/internal/render.d.ts +0 -16
- package/dist/dts/internal/render.d.ts.map +0 -1
- package/dist/esm/internal/hydrate.js +0 -239
- package/dist/esm/internal/hydrate.js.map +0 -1
- package/dist/esm/internal/parts.js +0 -373
- package/dist/esm/internal/parts.js.map +0 -1
- package/dist/esm/internal/render.js +0 -689
- package/dist/esm/internal/render.js.map +0 -1
- package/src/internal/hydrate.ts +0 -366
- package/src/internal/parts.ts +0 -609
- package/src/internal/render.ts +0 -971
package/src/internal/server.ts
CHANGED
|
@@ -1,112 +1,7 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect"
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
ClassNamePart,
|
|
6
|
-
CommentPart,
|
|
7
|
-
Part,
|
|
8
|
-
SparseAttributePart,
|
|
9
|
-
SparseClassNamePart,
|
|
10
|
-
SparseCommentPart,
|
|
11
|
-
SparsePart,
|
|
12
|
-
StaticText
|
|
13
|
-
} from "../Part.js"
|
|
14
|
-
import type { Renderable } from "../Renderable.js"
|
|
15
|
-
import type { PartNode, SparseAttrNode, SparseClassNameNode, SparseCommentNode, SparsePartNode } from "../Template.js"
|
|
16
|
-
import {
|
|
17
|
-
AttributePartImpl,
|
|
18
|
-
BooleanPartImpl,
|
|
19
|
-
ClassNamePartImpl,
|
|
20
|
-
CommentPartImpl,
|
|
21
|
-
DataPartImpl,
|
|
22
|
-
NodePartImpl,
|
|
23
|
-
PropertiesPartImpl,
|
|
24
|
-
PropertyPartImpl,
|
|
25
|
-
SparseAttributePartImpl,
|
|
26
|
-
SparseClassNamePartImpl,
|
|
27
|
-
SparseCommentPartImpl,
|
|
28
|
-
StaticTextImpl,
|
|
29
|
-
TextPartImpl
|
|
30
|
-
} from "./parts.js"
|
|
31
|
-
|
|
32
|
-
export type RenderChunk<R, E> =
|
|
33
|
-
| TextRenderChunk
|
|
34
|
-
| PartRenderChunk<R, E>
|
|
35
|
-
| SparsePartRenderChunk<R, E>
|
|
36
|
-
|
|
37
|
-
export class TextRenderChunk {
|
|
38
|
-
readonly type = "text"
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
readonly index: number,
|
|
42
|
-
readonly value: string
|
|
43
|
-
) {}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export class PartRenderChunk<R, E> {
|
|
47
|
-
readonly type = "part"
|
|
48
|
-
|
|
49
|
-
constructor(
|
|
50
|
-
readonly index: number,
|
|
51
|
-
readonly chunk: PartChunk,
|
|
52
|
-
readonly part: Part,
|
|
53
|
-
readonly renderable: Renderable<R, E>
|
|
54
|
-
) {}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export class SparsePartRenderChunk<R, E> {
|
|
58
|
-
readonly type = "sparse-part"
|
|
59
|
-
|
|
60
|
-
constructor(
|
|
61
|
-
readonly index: number,
|
|
62
|
-
readonly chunk: SparsePartChunk,
|
|
63
|
-
readonly part: SparsePart,
|
|
64
|
-
readonly renderables: Array<Renderable<R, E>>
|
|
65
|
-
) {}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type RenderChunkMap = {
|
|
69
|
-
readonly [K in HtmlChunk["_tag"]]: <R, E>(
|
|
70
|
-
chunk: Extract<HtmlChunk, { _tag: K }>,
|
|
71
|
-
index: number,
|
|
72
|
-
values: ReadonlyArray<Renderable<any, any>>,
|
|
73
|
-
onChunk: (index: number, value: string) => Effect.Effect<void>
|
|
74
|
-
) => RenderChunk<R, E>
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const renderChunkMap: RenderChunkMap = {
|
|
78
|
-
text: (chunk, index) => new TextRenderChunk(index, chunk.value),
|
|
79
|
-
part: (chunk, index, values, onChunk) =>
|
|
80
|
-
new PartRenderChunk(
|
|
81
|
-
index,
|
|
82
|
-
chunk,
|
|
83
|
-
partNodeToPart(chunk.node, (v) => onChunk(index, chunk.render(v))),
|
|
84
|
-
values[chunk.node.index]
|
|
85
|
-
),
|
|
86
|
-
"sparse-part": (chunk, index, values, onChunk) =>
|
|
87
|
-
new SparsePartRenderChunk(
|
|
88
|
-
index,
|
|
89
|
-
chunk,
|
|
90
|
-
sparsePartNodeToPart(chunk.node, (v) => onChunk(index, chunk.render(v))),
|
|
91
|
-
// @ts-ignore Type Instantiation is excessively deep and possibly infinite
|
|
92
|
-
chunk.node.nodes.map((n) => (n._tag === "text" ? n.value : values[n.index]))
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function htmlChunksToRenderChunks<R, E>(
|
|
97
|
-
chunks: ReadonlyArray<HtmlChunk>,
|
|
98
|
-
values: ReadonlyArray<Renderable<R, E>>,
|
|
99
|
-
onChunk: (index: number, value: string) => Effect.Effect<void>
|
|
100
|
-
) {
|
|
101
|
-
const output: Array<RenderChunk<R, E>> = Array(chunks.length)
|
|
102
|
-
|
|
103
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
104
|
-
// @ts-ignore Type Instantiation is excessively deep and possibly infinite
|
|
105
|
-
output[i] = renderChunkMap[chunks[i]._tag](chunks[i] as any, i, values, onChunk)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return output
|
|
109
|
-
}
|
|
1
|
+
import type * as Effect from "effect/Effect"
|
|
2
|
+
import type { Part } from "../Part.js"
|
|
3
|
+
import type { PartNode } from "../Template.js"
|
|
4
|
+
import * as impls from "./server-parts.js"
|
|
110
5
|
|
|
111
6
|
type PartNodeMap = {
|
|
112
7
|
readonly [K in PartNode["_tag"]]: (
|
|
@@ -116,21 +11,22 @@ type PartNodeMap = {
|
|
|
116
11
|
}
|
|
117
12
|
|
|
118
13
|
const partNodeMap: PartNodeMap = {
|
|
119
|
-
attr: (node, onChunk) => new AttributePartImpl(node.name, node.index, ({ value }) => onChunk(value), null),
|
|
120
|
-
"boolean-part": (node, onChunk) =>
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
|
|
14
|
+
attr: (node, onChunk) => new impls.AttributePartImpl(node.name, node.index, ({ value }) => onChunk(value), null),
|
|
15
|
+
"boolean-part": (node, onChunk) =>
|
|
16
|
+
new impls.BooleanPartImpl(node.name, node.index, ({ value }) => onChunk(value), null),
|
|
17
|
+
"className-part": (node, onChunk) => new impls.ClassNamePartImpl(node.index, ({ value }) => onChunk(value), []),
|
|
18
|
+
"comment-part": (node, onChunk) => new impls.CommentPartImpl(node.index, ({ value }) => onChunk(value), null),
|
|
19
|
+
data: (node, onChunk) => new impls.DataPartImpl(node.index, ({ value }) => onChunk(value), null),
|
|
20
|
+
event: () => {
|
|
125
21
|
throw new Error("Events are not utilized on the server")
|
|
126
22
|
},
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
23
|
+
node: (node, onChunk) => new impls.NodePartImpl(node.index, ({ value }) => onChunk(value), null),
|
|
24
|
+
property: (node, onChunk) => new impls.PropertyPartImpl(node.name, node.index, ({ value }) => onChunk(value), null),
|
|
25
|
+
ref: () => {
|
|
130
26
|
throw new Error("Refs are not utilized on the server")
|
|
131
27
|
},
|
|
132
|
-
"text-part": (node, onChunk) => new TextPartImpl(node.index, ({ value }) => onChunk(value), null),
|
|
133
|
-
|
|
28
|
+
"text-part": (node, onChunk) => new impls.TextPartImpl(node.index, ({ value }) => onChunk(value), null),
|
|
29
|
+
properties: (node, onChunk) => new impls.PropertiesPartImpl(node.index, ({ value }) => onChunk(value), [])
|
|
134
30
|
}
|
|
135
31
|
|
|
136
32
|
export function partNodeToPart(
|
|
@@ -139,155 +35,3 @@ export function partNodeToPart(
|
|
|
139
35
|
): Part {
|
|
140
36
|
return partNodeMap[node._tag](node as any, onChunk)
|
|
141
37
|
}
|
|
142
|
-
|
|
143
|
-
function sparsePartNodeToPart(
|
|
144
|
-
node: SparsePartNode,
|
|
145
|
-
onChunk: (value: string | null) => Effect.Effect<void>
|
|
146
|
-
) {
|
|
147
|
-
if (node._tag === "sparse-attr") {
|
|
148
|
-
return renderSparseAttr(node, onChunk)
|
|
149
|
-
} else if (node._tag === "sparse-class-name") {
|
|
150
|
-
return renderSparseClassName(node, onChunk)
|
|
151
|
-
} else {
|
|
152
|
-
return renderSparseComment(node, onChunk)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function renderSparseAttr(
|
|
157
|
-
attrNode: SparseAttrNode,
|
|
158
|
-
setAttribute: (value: string | null) => Effect.Effect<void>
|
|
159
|
-
): SparseAttributePart {
|
|
160
|
-
const { nodes } = attrNode
|
|
161
|
-
const values: Map<number, string | null> = new Map()
|
|
162
|
-
|
|
163
|
-
function getValue() {
|
|
164
|
-
return (part.value = Array.from({ length: nodes.length }, (_, i) => values.get(i) || ""))
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function setValue(value: string | null, index: number) {
|
|
168
|
-
return Effect.suspend(() => {
|
|
169
|
-
values.set(index, value)
|
|
170
|
-
|
|
171
|
-
if (values.size === nodes.length) return setAttribute(getValue().join(""))
|
|
172
|
-
|
|
173
|
-
return Effect.unit
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const parts: Array<StaticText | AttributePart> = []
|
|
178
|
-
|
|
179
|
-
let partIndex = 0
|
|
180
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
181
|
-
const node = nodes[i]
|
|
182
|
-
|
|
183
|
-
if (node._tag === "text") {
|
|
184
|
-
values.set(i, node.value)
|
|
185
|
-
parts.push(new StaticTextImpl(node.value))
|
|
186
|
-
} else {
|
|
187
|
-
parts.push(
|
|
188
|
-
new AttributePartImpl(
|
|
189
|
-
node.name,
|
|
190
|
-
partIndex++,
|
|
191
|
-
({ value }) => setValue(value || "", i),
|
|
192
|
-
null
|
|
193
|
-
)
|
|
194
|
-
)
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const part = new SparseAttributePartImpl(attrNode.name, parts, ({ value }) => setAttribute(value.join("")))
|
|
199
|
-
|
|
200
|
-
return part
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function renderSparseClassName(
|
|
204
|
-
classNameNode: SparseClassNameNode,
|
|
205
|
-
setClassName: (value: string | null) => Effect.Effect<void>
|
|
206
|
-
): SparseClassNamePart {
|
|
207
|
-
const { nodes } = classNameNode
|
|
208
|
-
const values: Map<number, string | null> = new Map()
|
|
209
|
-
|
|
210
|
-
function getValue() {
|
|
211
|
-
return (part.value = Array.from({ length: nodes.length }, (_, i) => values.get(i) || ""))
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function setValue(value: string | null, index: number) {
|
|
215
|
-
return Effect.suspend(() => {
|
|
216
|
-
values.set(index, value)
|
|
217
|
-
|
|
218
|
-
if (values.size === nodes.length) return setClassName(getValue().join(""))
|
|
219
|
-
|
|
220
|
-
return Effect.unit
|
|
221
|
-
})
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const parts: Array<StaticText | ClassNamePart> = []
|
|
225
|
-
|
|
226
|
-
let partIndex = 0
|
|
227
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
228
|
-
const node = nodes[i]
|
|
229
|
-
|
|
230
|
-
if (node._tag === "text") {
|
|
231
|
-
values.set(i, node.value)
|
|
232
|
-
parts.push(new StaticTextImpl(node.value))
|
|
233
|
-
} else {
|
|
234
|
-
parts.push(
|
|
235
|
-
new ClassNamePartImpl(
|
|
236
|
-
partIndex++,
|
|
237
|
-
({ value }) => setValue(value?.join(" ") || null, i),
|
|
238
|
-
null
|
|
239
|
-
)
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const part = new SparseClassNamePartImpl(parts, ({ value }) => setClassName(value.join("")), [])
|
|
245
|
-
|
|
246
|
-
return part
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function renderSparseComment(
|
|
250
|
-
commentNode: SparseCommentNode,
|
|
251
|
-
setComment: (value: string | null) => Effect.Effect<void>
|
|
252
|
-
): SparseCommentPart {
|
|
253
|
-
const { nodes } = commentNode
|
|
254
|
-
const values: Map<number, string | null | undefined> = new Map()
|
|
255
|
-
|
|
256
|
-
function getValue(): ReadonlyArray<string> {
|
|
257
|
-
return (part.value = Array.from({ length: nodes.length }, (_, i) => values.get(i) || ""))
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function setValue(value: string | null | undefined, index: number) {
|
|
261
|
-
return Effect.suspend(() => {
|
|
262
|
-
values.set(index, value)
|
|
263
|
-
|
|
264
|
-
if (values.size === nodes.length) return setComment(getValue().join(""))
|
|
265
|
-
|
|
266
|
-
return Effect.unit
|
|
267
|
-
})
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const parts: Array<StaticText | CommentPart> = []
|
|
271
|
-
|
|
272
|
-
let partIndex = 0
|
|
273
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
274
|
-
const node = nodes[i]
|
|
275
|
-
|
|
276
|
-
if (node._tag === "text") {
|
|
277
|
-
values.set(i, node.value)
|
|
278
|
-
parts.push(new StaticTextImpl(node.value))
|
|
279
|
-
} else {
|
|
280
|
-
parts.push(
|
|
281
|
-
new CommentPartImpl(
|
|
282
|
-
partIndex++,
|
|
283
|
-
({ value }) => setValue(value, i),
|
|
284
|
-
null
|
|
285
|
-
)
|
|
286
|
-
)
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const part = new SparseCommentPartImpl(parts, ({ value }) => setComment(value.join("")), [])
|
|
291
|
-
|
|
292
|
-
return part
|
|
293
|
-
}
|
package/src/internal/utils.ts
CHANGED
|
@@ -3,8 +3,11 @@ import * as Chunk from "effect/Chunk"
|
|
|
3
3
|
import type * as Duration from "effect/Duration"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
5
|
import { isSome } from "effect/Option"
|
|
6
|
+
import { uncapitalize } from "effect/String"
|
|
6
7
|
import { TestClock } from "effect/TestClock"
|
|
7
8
|
import { TEXT_START, TYPED_START } from "../Meta.js"
|
|
9
|
+
import { CouldNotFindCommentError } from "./errors.js"
|
|
10
|
+
import { getNodesExcludingStartComment, type HydrationNode } from "./v2/hydration-template.js"
|
|
8
11
|
|
|
9
12
|
export function isComment(node: Node): node is Comment {
|
|
10
13
|
return node.nodeType === node.COMMENT_NODE
|
|
@@ -33,19 +36,31 @@ export function findHoleComment(parent: Element, index: number) {
|
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
throw new
|
|
39
|
+
throw new CouldNotFindCommentError(index)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
const previousComments = new Set([TEXT_START, TYPED_START])
|
|
40
43
|
|
|
41
|
-
export function getPreviousNodes(comment: Node, index: number) {
|
|
44
|
+
export function getPreviousNodes(comment: Node, index: number, hash?: string) {
|
|
42
45
|
const nodes: Array<Node> = []
|
|
43
46
|
let node = comment.previousSibling
|
|
44
47
|
const previousHole = `hole${index - 1}`
|
|
48
|
+
const typedHash = hash ? `typed-${hash}` : ""
|
|
45
49
|
|
|
46
50
|
previousComments.add(previousHole)
|
|
47
51
|
|
|
48
|
-
while (node
|
|
52
|
+
while (node) {
|
|
53
|
+
if (isComment(node)) {
|
|
54
|
+
if (previousComments.has(node.data)) {
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (node.data === typedHash) {
|
|
59
|
+
nodes.unshift(node)
|
|
60
|
+
break
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
49
64
|
nodes.unshift(node)
|
|
50
65
|
node = node.previousSibling
|
|
51
66
|
}
|
|
@@ -58,20 +73,81 @@ export function getPreviousNodes(comment: Node, index: number) {
|
|
|
58
73
|
export const findPath = (node: ParentChildNodes, path: Chunk.Chunk<number>): Node =>
|
|
59
74
|
Chunk.reduce(path, node, ({ childNodes }, index) => childNodes[index]) as Node
|
|
60
75
|
|
|
76
|
+
export const findHydratePath = (
|
|
77
|
+
node: HydrationNode,
|
|
78
|
+
path: Chunk.Chunk<number>
|
|
79
|
+
): Node => {
|
|
80
|
+
if (Chunk.isEmpty(path)) {
|
|
81
|
+
return getNodesExcludingStartComment(node)[0]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const [first, ...rest] = path
|
|
85
|
+
|
|
86
|
+
// Hydration adds an extra starting comment node which should not be included in the path
|
|
87
|
+
let current: Node = getNodesExcludingStartComment(node)[first]
|
|
88
|
+
for (const index of rest) {
|
|
89
|
+
current = Array.from(current.childNodes).filter(isNotStartComment)[index]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return current
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isNotStartComment(node: Node) {
|
|
96
|
+
return !isComment(node) || !node.data.startsWith("hole")
|
|
97
|
+
}
|
|
98
|
+
|
|
61
99
|
export interface ParentChildNodes {
|
|
62
100
|
readonly parentNode: Node | null
|
|
63
101
|
readonly childNodes: ArrayLike<Node>
|
|
64
102
|
}
|
|
65
103
|
|
|
66
104
|
export function adjustTime(input?: Duration.DurationInput) {
|
|
67
|
-
return Effect.gen(function*(
|
|
68
|
-
const ctx = yield*
|
|
105
|
+
return Effect.gen(function*() {
|
|
106
|
+
const ctx = yield* Effect.context<never>()
|
|
69
107
|
const testClock = getOption(ctx, TestClock)
|
|
70
108
|
|
|
71
109
|
if (isSome(testClock)) {
|
|
72
|
-
yield*
|
|
110
|
+
yield* testClock.value.adjust(input ?? 1)
|
|
73
111
|
} else if (input) {
|
|
74
|
-
yield*
|
|
112
|
+
yield* Effect.sleep(input)
|
|
75
113
|
}
|
|
76
114
|
})
|
|
77
115
|
}
|
|
116
|
+
|
|
117
|
+
export function keyToPartType(key: string) {
|
|
118
|
+
switch (key[0]) {
|
|
119
|
+
case "?":
|
|
120
|
+
return ["boolean", key.slice(1)] as const
|
|
121
|
+
case ".": {
|
|
122
|
+
const propertyName = key.slice(1)
|
|
123
|
+
|
|
124
|
+
if (propertyName === "data") {
|
|
125
|
+
return ["data"] as const
|
|
126
|
+
} else if (
|
|
127
|
+
propertyName === "props" || propertyName === "properties"
|
|
128
|
+
) {
|
|
129
|
+
return ["properties"] as const
|
|
130
|
+
} else {
|
|
131
|
+
return ["property", propertyName] as const
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
case "@":
|
|
135
|
+
return ["event", uncapitalize(key.slice(1))] as const
|
|
136
|
+
case "o": {
|
|
137
|
+
if (key[1] === "n") {
|
|
138
|
+
const name = uncapitalize(key.slice(2))
|
|
139
|
+
return ["event", name] as const
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const lower = key.toLowerCase()
|
|
145
|
+
|
|
146
|
+
if (lower === "ref") {
|
|
147
|
+
return ["ref"] as const
|
|
148
|
+
} else if (lower === "class" || lower === "classname") {
|
|
149
|
+
return ["class"] as const
|
|
150
|
+
} else {
|
|
151
|
+
return ["attr", key] as const
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @since 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
export type SyncPart =
|
|
9
|
+
| AttributeSyncPart
|
|
10
|
+
| BooleanSyncPart
|
|
11
|
+
| ClassNameSyncPart
|
|
12
|
+
| CommentSyncPart
|
|
13
|
+
| DataSyncPart
|
|
14
|
+
| NodeSyncPart
|
|
15
|
+
| PropertySyncPart
|
|
16
|
+
| TextSyncPart
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @since 1.0.0
|
|
20
|
+
*/
|
|
21
|
+
export interface AttributeSyncPart {
|
|
22
|
+
readonly _tag: "attribute"
|
|
23
|
+
readonly name: string
|
|
24
|
+
readonly value: string | null | undefined
|
|
25
|
+
readonly index: number
|
|
26
|
+
|
|
27
|
+
readonly update: (value: this["value"]) => boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @since 1.0.0
|
|
32
|
+
*/
|
|
33
|
+
export interface BooleanSyncPart {
|
|
34
|
+
readonly _tag: "boolean"
|
|
35
|
+
readonly name: string
|
|
36
|
+
readonly value: boolean | null | undefined
|
|
37
|
+
readonly index: number
|
|
38
|
+
|
|
39
|
+
readonly update: (value: this["value"]) => boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @since 1.0.0
|
|
44
|
+
*/
|
|
45
|
+
export interface ClassNameSyncPart {
|
|
46
|
+
readonly _tag: "className"
|
|
47
|
+
readonly value: ReadonlyArray<string>
|
|
48
|
+
readonly index: number
|
|
49
|
+
|
|
50
|
+
readonly update: (value: this["value"]) => boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @since 1.0.0
|
|
55
|
+
*/
|
|
56
|
+
export interface DataSyncPart {
|
|
57
|
+
readonly _tag: "data"
|
|
58
|
+
readonly value: Readonly<Record<string, string | undefined>> | null | undefined
|
|
59
|
+
readonly index: number
|
|
60
|
+
|
|
61
|
+
readonly update: (value: this["value"]) => boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @since 1.0.0
|
|
66
|
+
*/
|
|
67
|
+
export interface PropertySyncPart {
|
|
68
|
+
readonly _tag: "property"
|
|
69
|
+
readonly name: string
|
|
70
|
+
readonly value: unknown
|
|
71
|
+
readonly index: number
|
|
72
|
+
|
|
73
|
+
readonly update: (value: this["value"]) => boolean
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
*/
|
|
79
|
+
export interface CommentSyncPart {
|
|
80
|
+
readonly _tag: "comment"
|
|
81
|
+
readonly value: string | null | undefined
|
|
82
|
+
readonly index: number
|
|
83
|
+
|
|
84
|
+
readonly update: (value: this["value"]) => boolean
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @since 1.0.0
|
|
89
|
+
*/
|
|
90
|
+
export interface TextSyncPart {
|
|
91
|
+
readonly _tag: "text"
|
|
92
|
+
readonly value: string | null | undefined
|
|
93
|
+
readonly index: number
|
|
94
|
+
|
|
95
|
+
readonly update: (value: this["value"]) => boolean
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @since 1.0.0
|
|
100
|
+
*/
|
|
101
|
+
export interface NodeSyncPart {
|
|
102
|
+
readonly _tag: "node"
|
|
103
|
+
readonly value: unknown
|
|
104
|
+
readonly index: number
|
|
105
|
+
|
|
106
|
+
readonly update: (value: this["value"]) => boolean
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @since 1.0.0
|
|
111
|
+
*/
|
|
112
|
+
export type SyncParts = ReadonlyArray<SyncPart>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { hasProperty } from "effect/Predicate"
|
|
2
|
+
|
|
3
|
+
export function isNullOrUndefined<T>(value: T | null | undefined): value is null | undefined {
|
|
4
|
+
return value === null || value === undefined
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function renderToString(value: unknown): string {
|
|
8
|
+
return isNullOrUndefined(value)
|
|
9
|
+
? ""
|
|
10
|
+
: hasProperty(value, "toString") && typeof value.toString === "function"
|
|
11
|
+
? value.toString()
|
|
12
|
+
: String(value)
|
|
13
|
+
}
|