@typed/template 0.13.0 → 1.0.0-beta.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/README.md +108 -2
- package/dist/EventHandler.d.ts +273 -0
- package/dist/EventHandler.d.ts.map +1 -0
- package/dist/EventHandler.js +261 -0
- package/dist/EventSource.d.ts +82 -0
- package/dist/EventSource.d.ts.map +1 -0
- package/dist/EventSource.js +127 -0
- package/dist/Html.d.ts +122 -0
- package/dist/Html.d.ts.map +1 -0
- package/dist/Html.js +250 -0
- package/dist/HtmlChunk.d.ts +118 -0
- package/dist/HtmlChunk.d.ts.map +1 -0
- package/dist/HtmlChunk.js +211 -0
- package/dist/HydrateContext.d.ts +28 -0
- package/dist/HydrateContext.d.ts.map +1 -0
- package/dist/HydrateContext.js +25 -0
- package/dist/Parser.d.ts +35 -0
- package/dist/Parser.d.ts.map +1 -0
- package/dist/Parser.js +437 -0
- package/dist/Render.d.ts +195 -0
- package/dist/Render.d.ts.map +1 -0
- package/dist/Render.js +609 -0
- package/dist/RenderEvent.d.ts +179 -0
- package/dist/RenderEvent.d.ts.map +1 -0
- package/dist/RenderEvent.js +102 -0
- package/dist/RenderQueue.d.ts +167 -0
- package/dist/RenderQueue.d.ts.map +1 -0
- package/dist/RenderQueue.js +297 -0
- package/dist/RenderTemplate.d.ts +90 -0
- package/dist/RenderTemplate.d.ts.map +1 -0
- package/dist/RenderTemplate.js +87 -0
- package/dist/Renderable.d.ts +88 -0
- package/dist/Renderable.d.ts.map +1 -0
- package/dist/Renderable.js +3 -0
- package/dist/{dts/Template.d.ts → Template.d.ts} +109 -74
- package/dist/Template.d.ts.map +1 -0
- package/dist/{esm/Template.js → Template.js} +96 -56
- package/dist/Wire.d.ts +169 -0
- package/dist/Wire.d.ts.map +1 -0
- package/dist/Wire.js +217 -0
- package/dist/errors.d.ts +145 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +159 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/internal/IndexRefCounter.d.ts +11 -0
- package/dist/internal/IndexRefCounter.d.ts.map +1 -0
- package/dist/internal/IndexRefCounter.js +42 -0
- package/dist/internal/ParentChildNodes.d.ts +6 -0
- package/dist/internal/ParentChildNodes.d.ts.map +1 -0
- package/dist/internal/ParentChildNodes.js +1 -0
- package/dist/internal/PathStack.d.ts +9 -0
- package/dist/internal/PathStack.d.ts.map +1 -0
- package/dist/internal/PathStack.js +18 -0
- package/dist/internal/buildTemplateFragement.d.ts +3 -0
- package/dist/internal/buildTemplateFragement.d.ts.map +1 -0
- package/dist/internal/buildTemplateFragement.js +61 -0
- package/dist/internal/diff.d.ts +2 -0
- package/dist/internal/diff.d.ts.map +1 -0
- package/dist/internal/diff.js +119 -0
- package/dist/internal/dom.d.ts +45 -0
- package/dist/internal/dom.d.ts.map +1 -0
- package/dist/internal/dom.js +304 -0
- package/dist/internal/encoding.d.ts +7 -0
- package/dist/internal/encoding.d.ts.map +1 -0
- package/dist/internal/encoding.js +134 -0
- package/dist/{dts/internal/v2/hydration-template.d.ts → internal/hydration.d.ts} +10 -7
- package/dist/internal/hydration.d.ts.map +1 -0
- package/dist/{esm/internal/v2/hydration-template.js → internal/hydration.js} +80 -26
- package/dist/internal/keyToPartType.d.ts +2 -0
- package/dist/internal/keyToPartType.d.ts.map +1 -0
- package/dist/internal/keyToPartType.js +110 -0
- package/dist/internal/meta.d.ts +17 -0
- package/dist/internal/meta.d.ts.map +1 -0
- package/dist/internal/meta.js +14 -0
- package/dist/internal/takeOneIfNotRenderEvent.d.ts +4 -0
- package/dist/internal/takeOneIfNotRenderEvent.d.ts.map +1 -0
- package/dist/internal/takeOneIfNotRenderEvent.js +10 -0
- package/dist/internal/templateHash.d.ts +2 -0
- package/dist/internal/templateHash.d.ts.map +1 -0
- package/dist/internal/templateHash.js +14 -0
- package/dist/many.d.ts +68 -0
- package/dist/many.d.ts.map +1 -0
- package/dist/many.js +107 -0
- package/package.json +22 -223
- package/src/EventHandler.ts +318 -86
- package/src/EventSource.ts +202 -0
- package/src/Html.test.ts +490 -0
- package/src/Html.ts +292 -333
- package/src/HtmlChunk.ts +290 -332
- package/src/HydrateContext.ts +40 -0
- package/src/Hydration.test.ts +409 -0
- package/src/Parser.test.ts +924 -0
- package/src/Parser.ts +598 -10
- package/src/Render.test.ts +338 -0
- package/src/Render.ts +878 -63
- package/src/RenderEvent.ts +169 -40
- package/src/RenderQueue.ts +290 -383
- package/src/RenderTemplate.ts +98 -31
- package/src/Renderable.ts +122 -24
- package/src/Template.ts +246 -145
- package/src/Wire.ts +309 -0
- package/src/errors.ts +173 -0
- package/src/index.ts +14 -66
- package/src/internal/IndexRefCounter.ts +53 -0
- package/src/internal/ParentChildNodes.ts +7 -0
- package/src/internal/PathStack.ts +23 -0
- package/src/internal/buildTemplateFragement.ts +82 -0
- package/src/internal/diff.ts +127 -0
- package/src/internal/dom.ts +357 -0
- package/src/internal/encoding.ts +147 -0
- package/src/internal/hydration.ts +406 -0
- package/src/internal/keyToPartType.ts +113 -0
- package/src/internal/meta.ts +25 -0
- package/src/internal/takeOneIfNotRenderEvent.ts +19 -0
- package/src/internal/templateHash.ts +18 -0
- package/src/many.ts +148 -0
- package/tsconfig.json +6 -0
- package/Directive/package.json +0 -6
- package/ElementRef/package.json +0 -6
- package/ElementSource/package.json +0 -6
- package/Entry/package.json +0 -6
- package/EventHandler/package.json +0 -6
- package/Html/package.json +0 -6
- package/HtmlChunk/package.json +0 -6
- package/Hydrate/package.json +0 -6
- package/LICENSE +0 -21
- package/Many/package.json +0 -6
- package/Meta/package.json +0 -6
- package/Parser/package.json +0 -6
- package/Part/package.json +0 -6
- package/Placeholder/package.json +0 -6
- package/Platform/package.json +0 -6
- package/Render/package.json +0 -6
- package/RenderContext/package.json +0 -6
- package/RenderEvent/package.json +0 -6
- package/RenderQueue/package.json +0 -6
- package/RenderTemplate/package.json +0 -6
- package/Renderable/package.json +0 -6
- package/Template/package.json +0 -6
- package/Test/package.json +0 -6
- package/Vitest/package.json +0 -6
- package/compiler-tools/package.json +0 -6
- package/dist/cjs/Directive.js +0 -76
- package/dist/cjs/Directive.js.map +0 -1
- package/dist/cjs/ElementRef.js +0 -92
- package/dist/cjs/ElementRef.js.map +0 -1
- package/dist/cjs/ElementSource.js +0 -242
- package/dist/cjs/ElementSource.js.map +0 -1
- package/dist/cjs/Entry.js +0 -6
- package/dist/cjs/Entry.js.map +0 -1
- package/dist/cjs/EventHandler.js +0 -76
- package/dist/cjs/EventHandler.js.map +0 -1
- package/dist/cjs/Html.js +0 -224
- package/dist/cjs/Html.js.map +0 -1
- package/dist/cjs/HtmlChunk.js +0 -306
- package/dist/cjs/HtmlChunk.js.map +0 -1
- package/dist/cjs/Hydrate.js +0 -43
- package/dist/cjs/Hydrate.js.map +0 -1
- package/dist/cjs/Many.js +0 -66
- package/dist/cjs/Many.js.map +0 -1
- package/dist/cjs/Meta.js +0 -50
- package/dist/cjs/Meta.js.map +0 -1
- package/dist/cjs/Parser.js +0 -19
- package/dist/cjs/Parser.js.map +0 -1
- package/dist/cjs/Part.js +0 -6
- package/dist/cjs/Part.js.map +0 -1
- package/dist/cjs/Placeholder.js +0 -34
- package/dist/cjs/Placeholder.js.map +0 -1
- package/dist/cjs/Platform.js +0 -66
- package/dist/cjs/Platform.js.map +0 -1
- package/dist/cjs/Render.js +0 -50
- package/dist/cjs/Render.js.map +0 -1
- package/dist/cjs/RenderContext.js +0 -67
- package/dist/cjs/RenderContext.js.map +0 -1
- package/dist/cjs/RenderEvent.js +0 -52
- package/dist/cjs/RenderEvent.js.map +0 -1
- package/dist/cjs/RenderQueue.js +0 -341
- package/dist/cjs/RenderQueue.js.map +0 -1
- package/dist/cjs/RenderTemplate.js +0 -26
- package/dist/cjs/RenderTemplate.js.map +0 -1
- package/dist/cjs/Renderable.js +0 -6
- package/dist/cjs/Renderable.js.map +0 -1
- package/dist/cjs/Template.js +0 -305
- package/dist/cjs/Template.js.map +0 -1
- package/dist/cjs/Test.js +0 -184
- package/dist/cjs/Test.js.map +0 -1
- package/dist/cjs/Vitest.js +0 -52
- package/dist/cjs/Vitest.js.map +0 -1
- package/dist/cjs/compiler-tools.js +0 -100
- package/dist/cjs/compiler-tools.js.map +0 -1
- package/dist/cjs/index.js +0 -138
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/internal/EventSource.js +0 -129
- package/dist/cjs/internal/EventSource.js.map +0 -1
- package/dist/cjs/internal/HydrateContext.js +0 -13
- package/dist/cjs/internal/HydrateContext.js.map +0 -1
- package/dist/cjs/internal/browser.js +0 -110
- package/dist/cjs/internal/browser.js.map +0 -1
- package/dist/cjs/internal/character-entities.js +0 -2141
- package/dist/cjs/internal/character-entities.js.map +0 -1
- package/dist/cjs/internal/chunks.js +0 -68
- package/dist/cjs/internal/chunks.js.map +0 -1
- package/dist/cjs/internal/errors.js +0 -52
- package/dist/cjs/internal/errors.js.map +0 -1
- package/dist/cjs/internal/indexRefCounter.js +0 -52
- package/dist/cjs/internal/indexRefCounter.js.map +0 -1
- package/dist/cjs/internal/module-augmentation.js +0 -6
- package/dist/cjs/internal/module-augmentation.js.map +0 -1
- package/dist/cjs/internal/parser.js +0 -568
- package/dist/cjs/internal/parser.js.map +0 -1
- package/dist/cjs/internal/parser2.js +0 -382
- package/dist/cjs/internal/parser2.js.map +0 -1
- package/dist/cjs/internal/server-parts.js +0 -124
- package/dist/cjs/internal/server-parts.js.map +0 -1
- package/dist/cjs/internal/server.js +0 -48
- package/dist/cjs/internal/server.js.map +0 -1
- package/dist/cjs/internal/utils.js +0 -136
- package/dist/cjs/internal/utils.js.map +0 -1
- package/dist/cjs/internal/v2/SyncPart.js +0 -6
- package/dist/cjs/internal/v2/SyncPart.js.map +0 -1
- package/dist/cjs/internal/v2/helpers.js +0 -15
- package/dist/cjs/internal/v2/helpers.js.map +0 -1
- package/dist/cjs/internal/v2/hydration-template.js +0 -269
- package/dist/cjs/internal/v2/hydration-template.js.map +0 -1
- package/dist/cjs/internal/v2/parts.js +0 -169
- package/dist/cjs/internal/v2/parts.js.map +0 -1
- package/dist/cjs/internal/v2/render-entry.js +0 -110
- package/dist/cjs/internal/v2/render-entry.js.map +0 -1
- package/dist/cjs/internal/v2/render-sync-parts.js +0 -318
- package/dist/cjs/internal/v2/render-sync-parts.js.map +0 -1
- package/dist/cjs/internal/v2/render.js +0 -592
- package/dist/cjs/internal/v2/render.js.map +0 -1
- package/dist/cjs/internal/v2/sync-parts.js +0 -115
- package/dist/cjs/internal/v2/sync-parts.js.map +0 -1
- package/dist/dts/Directive.d.ts +0 -70
- package/dist/dts/Directive.d.ts.map +0 -1
- package/dist/dts/ElementRef.d.ts +0 -42
- package/dist/dts/ElementRef.d.ts.map +0 -1
- package/dist/dts/ElementSource.d.ts +0 -77
- package/dist/dts/ElementSource.d.ts.map +0 -1
- package/dist/dts/Entry.d.ts +0 -26
- package/dist/dts/Entry.d.ts.map +0 -1
- package/dist/dts/EventHandler.d.ts +0 -73
- package/dist/dts/EventHandler.d.ts.map +0 -1
- package/dist/dts/Html.d.ts +0 -35
- package/dist/dts/Html.d.ts.map +0 -1
- package/dist/dts/HtmlChunk.d.ts +0 -56
- package/dist/dts/HtmlChunk.d.ts.map +0 -1
- package/dist/dts/Hydrate.d.ts +0 -19
- package/dist/dts/Hydrate.d.ts.map +0 -1
- package/dist/dts/Many.d.ts +0 -32
- package/dist/dts/Many.d.ts.map +0 -1
- package/dist/dts/Meta.d.ts +0 -33
- package/dist/dts/Meta.d.ts.map +0 -1
- package/dist/dts/Parser.d.ts +0 -13
- package/dist/dts/Parser.d.ts.map +0 -1
- package/dist/dts/Part.d.ts +0 -121
- package/dist/dts/Part.d.ts.map +0 -1
- package/dist/dts/Placeholder.d.ts +0 -48
- package/dist/dts/Placeholder.d.ts.map +0 -1
- package/dist/dts/Platform.d.ts +0 -21
- package/dist/dts/Platform.d.ts.map +0 -1
- package/dist/dts/Render.d.ts +0 -31
- package/dist/dts/Render.d.ts.map +0 -1
- package/dist/dts/RenderContext.d.ts +0 -70
- package/dist/dts/RenderContext.d.ts.map +0 -1
- package/dist/dts/RenderEvent.d.ts +0 -42
- package/dist/dts/RenderEvent.d.ts.map +0 -1
- package/dist/dts/RenderQueue.d.ts +0 -103
- package/dist/dts/RenderQueue.d.ts.map +0 -1
- package/dist/dts/RenderTemplate.d.ts +0 -25
- package/dist/dts/RenderTemplate.d.ts.map +0 -1
- package/dist/dts/Renderable.d.ts +0 -28
- package/dist/dts/Renderable.d.ts.map +0 -1
- package/dist/dts/Template.d.ts.map +0 -1
- package/dist/dts/Test.d.ts +0 -85
- package/dist/dts/Test.d.ts.map +0 -1
- package/dist/dts/Vitest.d.ts +0 -43
- package/dist/dts/Vitest.d.ts.map +0 -1
- package/dist/dts/compiler-tools.d.ts +0 -143
- package/dist/dts/compiler-tools.d.ts.map +0 -1
- package/dist/dts/index.d.ts +0 -65
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/dts/internal/EventSource.d.ts +0 -13
- package/dist/dts/internal/EventSource.d.ts.map +0 -1
- package/dist/dts/internal/HydrateContext.d.ts +0 -2
- package/dist/dts/internal/HydrateContext.d.ts.map +0 -1
- package/dist/dts/internal/browser.d.ts +0 -8
- package/dist/dts/internal/browser.d.ts.map +0 -1
- package/dist/dts/internal/character-entities.d.ts +0 -2133
- package/dist/dts/internal/character-entities.d.ts.map +0 -1
- package/dist/dts/internal/chunks.d.ts +0 -23
- package/dist/dts/internal/chunks.d.ts.map +0 -1
- package/dist/dts/internal/errors.d.ts +0 -22
- package/dist/dts/internal/errors.d.ts.map +0 -1
- package/dist/dts/internal/indexRefCounter.d.ts +0 -7
- package/dist/dts/internal/indexRefCounter.d.ts.map +0 -1
- package/dist/dts/internal/module-augmentation.d.ts +0 -32
- package/dist/dts/internal/module-augmentation.d.ts.map +0 -1
- package/dist/dts/internal/parser.d.ts +0 -33
- package/dist/dts/internal/parser.d.ts.map +0 -1
- package/dist/dts/internal/parser2.d.ts +0 -12
- package/dist/dts/internal/parser2.d.ts.map +0 -1
- package/dist/dts/internal/server-parts.d.ts +0 -223
- package/dist/dts/internal/server-parts.d.ts.map +0 -1
- package/dist/dts/internal/server.d.ts +0 -5
- package/dist/dts/internal/server.d.ts.map +0 -1
- package/dist/dts/internal/utils.d.ts +0 -19
- package/dist/dts/internal/utils.d.ts.map +0 -1
- package/dist/dts/internal/v2/SyncPart.d.ts +0 -87
- package/dist/dts/internal/v2/SyncPart.d.ts.map +0 -1
- package/dist/dts/internal/v2/helpers.d.ts +0 -3
- package/dist/dts/internal/v2/helpers.d.ts.map +0 -1
- package/dist/dts/internal/v2/hydration-template.d.ts.map +0 -1
- package/dist/dts/internal/v2/parts.d.ts +0 -245
- package/dist/dts/internal/v2/parts.d.ts.map +0 -1
- package/dist/dts/internal/v2/render-entry.d.ts +0 -6
- package/dist/dts/internal/v2/render-entry.d.ts.map +0 -1
- package/dist/dts/internal/v2/render-sync-parts.d.ts +0 -22
- package/dist/dts/internal/v2/render-sync-parts.d.ts.map +0 -1
- package/dist/dts/internal/v2/render.d.ts +0 -83
- package/dist/dts/internal/v2/render.d.ts.map +0 -1
- package/dist/dts/internal/v2/sync-parts.d.ts +0 -129
- package/dist/dts/internal/v2/sync-parts.d.ts.map +0 -1
- package/dist/esm/Directive.js +0 -64
- package/dist/esm/Directive.js.map +0 -1
- package/dist/esm/ElementRef.js +0 -76
- package/dist/esm/ElementRef.js.map +0 -1
- package/dist/esm/ElementSource.js +0 -240
- package/dist/esm/ElementSource.js.map +0 -1
- package/dist/esm/Entry.js +0 -2
- package/dist/esm/Entry.js.map +0 -1
- package/dist/esm/EventHandler.js +0 -68
- package/dist/esm/EventHandler.js.map +0 -1
- package/dist/esm/Html.js +0 -230
- package/dist/esm/Html.js.map +0 -1
- package/dist/esm/HtmlChunk.js +0 -330
- package/dist/esm/HtmlChunk.js.map +0 -1
- package/dist/esm/Hydrate.js +0 -31
- package/dist/esm/Hydrate.js.map +0 -1
- package/dist/esm/Many.js +0 -54
- package/dist/esm/Many.js.map +0 -1
- package/dist/esm/Meta.js +0 -40
- package/dist/esm/Meta.js.map +0 -1
- package/dist/esm/Parser.js +0 -13
- package/dist/esm/Parser.js.map +0 -1
- package/dist/esm/Part.js +0 -5
- package/dist/esm/Part.js.map +0 -1
- package/dist/esm/Placeholder.js +0 -26
- package/dist/esm/Placeholder.js.map +0 -1
- package/dist/esm/Platform.js +0 -43
- package/dist/esm/Platform.js.map +0 -1
- package/dist/esm/Render.js +0 -36
- package/dist/esm/Render.js.map +0 -1
- package/dist/esm/RenderContext.js +0 -54
- package/dist/esm/RenderContext.js.map +0 -1
- package/dist/esm/RenderEvent.js +0 -43
- package/dist/esm/RenderEvent.js.map +0 -1
- package/dist/esm/RenderQueue.js +0 -336
- package/dist/esm/RenderQueue.js.map +0 -1
- package/dist/esm/RenderTemplate.js +0 -16
- package/dist/esm/RenderTemplate.js.map +0 -1
- package/dist/esm/Renderable.js +0 -2
- package/dist/esm/Renderable.js.map +0 -1
- package/dist/esm/Template.js.map +0 -1
- package/dist/esm/Test.js +0 -167
- package/dist/esm/Test.js.map +0 -1
- package/dist/esm/Vitest.js +0 -44
- package/dist/esm/Vitest.js.map +0 -1
- package/dist/esm/compiler-tools.js +0 -91
- package/dist/esm/compiler-tools.js.map +0 -1
- package/dist/esm/index.js +0 -65
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/internal/EventSource.js +0 -126
- package/dist/esm/internal/EventSource.js.map +0 -1
- package/dist/esm/internal/HydrateContext.js +0 -7
- package/dist/esm/internal/HydrateContext.js.map +0 -1
- package/dist/esm/internal/browser.js +0 -103
- package/dist/esm/internal/browser.js.map +0 -1
- package/dist/esm/internal/character-entities.js +0 -2134
- package/dist/esm/internal/character-entities.js.map +0 -1
- package/dist/esm/internal/chunks.js +0 -60
- package/dist/esm/internal/chunks.js.map +0 -1
- package/dist/esm/internal/errors.js +0 -46
- package/dist/esm/internal/errors.js.map +0 -1
- package/dist/esm/internal/indexRefCounter.js +0 -47
- package/dist/esm/internal/indexRefCounter.js.map +0 -1
- package/dist/esm/internal/module-augmentation.js +0 -2
- package/dist/esm/internal/module-augmentation.js.map +0 -1
- package/dist/esm/internal/parser.js +0 -596
- package/dist/esm/internal/parser.js.map +0 -1
- package/dist/esm/internal/parser2.js +0 -393
- package/dist/esm/internal/parser2.js.map +0 -1
- package/dist/esm/internal/server-parts.js +0 -109
- package/dist/esm/internal/server-parts.js.map +0 -1
- package/dist/esm/internal/server.js +0 -22
- package/dist/esm/internal/server.js.map +0 -1
- package/dist/esm/internal/utils.js +0 -119
- package/dist/esm/internal/utils.js.map +0 -1
- package/dist/esm/internal/v2/SyncPart.js +0 -5
- package/dist/esm/internal/v2/SyncPart.js.map +0 -1
- package/dist/esm/internal/v2/helpers.js +0 -12
- package/dist/esm/internal/v2/helpers.js.map +0 -1
- package/dist/esm/internal/v2/hydration-template.js.map +0 -1
- package/dist/esm/internal/v2/parts.js +0 -150
- package/dist/esm/internal/v2/parts.js.map +0 -1
- package/dist/esm/internal/v2/render-entry.js +0 -102
- package/dist/esm/internal/v2/render-entry.js.map +0 -1
- package/dist/esm/internal/v2/render-sync-parts.js +0 -265
- package/dist/esm/internal/v2/render-sync-parts.js.map +0 -1
- package/dist/esm/internal/v2/render.js +0 -521
- package/dist/esm/internal/v2/render.js.map +0 -1
- package/dist/esm/internal/v2/sync-parts.js +0 -102
- package/dist/esm/internal/v2/sync-parts.js.map +0 -1
- package/dist/esm/package.json +0 -4
- package/src/Directive.ts +0 -114
- package/src/ElementRef.ts +0 -126
- package/src/ElementSource.ts +0 -432
- package/src/Entry.ts +0 -28
- package/src/Hydrate.ts +0 -51
- package/src/Many.ts +0 -161
- package/src/Meta.ts +0 -45
- package/src/Part.ts +0 -154
- package/src/Placeholder.ts +0 -78
- package/src/Platform.ts +0 -71
- package/src/RenderContext.ts +0 -121
- package/src/Test.ts +0 -354
- package/src/Vitest.ts +0 -141
- package/src/compiler-tools.ts +0 -250
- package/src/internal/EventSource.ts +0 -188
- package/src/internal/HydrateContext.ts +0 -22
- package/src/internal/browser.ts +0 -138
- package/src/internal/character-entities.ts +0 -2136
- package/src/internal/chunks.ts +0 -89
- package/src/internal/errors.ts +0 -49
- package/src/internal/external.d.ts +0 -11
- package/src/internal/indexRefCounter.ts +0 -54
- package/src/internal/module-augmentation.ts +0 -44
- package/src/internal/parser.ts +0 -757
- package/src/internal/parser2.ts +0 -468
- package/src/internal/server-parts.ts +0 -161
- package/src/internal/server.ts +0 -37
- package/src/internal/utils.ts +0 -153
- package/src/internal/v2/SyncPart.ts +0 -112
- package/src/internal/v2/helpers.ts +0 -13
- package/src/internal/v2/hydration-template.ts +0 -308
- package/src/internal/v2/parts.ts +0 -254
- package/src/internal/v2/render-entry.ts +0 -131
- package/src/internal/v2/render-sync-parts.ts +0 -440
- package/src/internal/v2/render.ts +0 -813
- package/src/internal/v2/sync-parts.ts +0 -133
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Scope from "effect/Scope";
|
|
3
|
+
import type { EventHandler } from "./EventHandler.js";
|
|
4
|
+
import { type Rendered } from "./Wire.js";
|
|
5
|
+
type EventName = string;
|
|
6
|
+
type Handler<Ev extends Event> = EventHandler<Ev>;
|
|
7
|
+
/**
|
|
8
|
+
* An interface for managing event listeners on DOM nodes.
|
|
9
|
+
*
|
|
10
|
+
* It abstracts the process of adding and removing event listeners, ensuring that they are
|
|
11
|
+
* properly cleaned up when the scope is closed or the element is removed.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { Effect } from "effect"
|
|
16
|
+
* import { makeEventSource } from "@typed/template/EventSource"
|
|
17
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
18
|
+
* import { Scope } from "effect"
|
|
19
|
+
*
|
|
20
|
+
* const program = Effect.gen(function* () {
|
|
21
|
+
* const eventSource = makeEventSource()
|
|
22
|
+
* const button = document.createElement("button")
|
|
23
|
+
*
|
|
24
|
+
* // Add event listener
|
|
25
|
+
* const handler = EventHandler.make((event: MouseEvent) => {
|
|
26
|
+
* console.log("Button clicked")
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* const disposable = eventSource.addEventListener(button, "click", handler)
|
|
30
|
+
*
|
|
31
|
+
* // Setup listeners for rendered content
|
|
32
|
+
* yield* eventSource.setup(button, yield* Scope.make())
|
|
33
|
+
*
|
|
34
|
+
* // Cleanup
|
|
35
|
+
* disposable[Symbol.dispose]()
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @since 1.0.0
|
|
40
|
+
* @category models
|
|
41
|
+
*/
|
|
42
|
+
export interface EventSource {
|
|
43
|
+
/**
|
|
44
|
+
* Adds an event listener to a target.
|
|
45
|
+
*/
|
|
46
|
+
readonly addEventListener: <Ev extends Event>(element: EventTarget, event: EventName, handler: Handler<Ev>) => Disposable;
|
|
47
|
+
/**
|
|
48
|
+
* Sets up event listeners for a rendered template within a scope.
|
|
49
|
+
*/
|
|
50
|
+
readonly setup: (rendered: Rendered, scope: Scope.Scope) => Effect.Effect<void>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a new `EventSource`.
|
|
54
|
+
*
|
|
55
|
+
* The created `EventSource` can efficiently manage multiple event listeners,
|
|
56
|
+
* grouping them by event type and handling setup/teardown lifecycles.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { Effect } from "effect"
|
|
61
|
+
* import { makeEventSource } from "@typed/template/EventSource"
|
|
62
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
63
|
+
*
|
|
64
|
+
* const program = Effect.gen(function* () {
|
|
65
|
+
* const eventSource = makeEventSource()
|
|
66
|
+
* const element = document.createElement("div")
|
|
67
|
+
*
|
|
68
|
+
* // Add multiple event listeners
|
|
69
|
+
* eventSource.addEventListener(element, "click", EventHandler.make(() => console.log("clicked")))
|
|
70
|
+
* eventSource.addEventListener(element, "mouseover", EventHandler.make(() => console.log("hovered")))
|
|
71
|
+
*
|
|
72
|
+
* // Setup all listeners
|
|
73
|
+
* yield* eventSource.setup(element, yield* Scope.make())
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
* @category constructors
|
|
79
|
+
*/
|
|
80
|
+
export declare function makeEventSource(): EventSource;
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=EventSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventSource.d.ts","sourceRoot":"","sources":["../src/EventSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEvD,KAAK,SAAS,GAAG,MAAM,CAAC;AAExB,KAAK,OAAO,CAAC,EAAE,SAAS,KAAK,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,gBAAgB,EAAE,CAAC,EAAE,SAAS,KAAK,EAC1C,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,KACjB,UAAU,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACjF;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAoF7C"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Fiber from "effect/Fiber";
|
|
3
|
+
import * as Scope from "effect/Scope";
|
|
4
|
+
import { getElements } from "./Wire.js";
|
|
5
|
+
const disposable = (f) => ({ [Symbol.dispose]: f });
|
|
6
|
+
const dispose = (d) => d[Symbol.dispose]();
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new `EventSource`.
|
|
9
|
+
*
|
|
10
|
+
* The created `EventSource` can efficiently manage multiple event listeners,
|
|
11
|
+
* grouping them by event type and handling setup/teardown lifecycles.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { Effect } from "effect"
|
|
16
|
+
* import { makeEventSource } from "@typed/template/EventSource"
|
|
17
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
18
|
+
*
|
|
19
|
+
* const program = Effect.gen(function* () {
|
|
20
|
+
* const eventSource = makeEventSource()
|
|
21
|
+
* const element = document.createElement("div")
|
|
22
|
+
*
|
|
23
|
+
* // Add multiple event listeners
|
|
24
|
+
* eventSource.addEventListener(element, "click", EventHandler.make(() => console.log("clicked")))
|
|
25
|
+
* eventSource.addEventListener(element, "mouseover", EventHandler.make(() => console.log("hovered")))
|
|
26
|
+
*
|
|
27
|
+
* // Setup all listeners
|
|
28
|
+
* yield* eventSource.setup(element, yield* Scope.make())
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @since 1.0.0
|
|
33
|
+
* @category constructors
|
|
34
|
+
*/
|
|
35
|
+
export function makeEventSource() {
|
|
36
|
+
const listeners = new Map();
|
|
37
|
+
function addEventListener(element, event, handler) {
|
|
38
|
+
const sets = listeners.get(event);
|
|
39
|
+
const entry = [element, handler];
|
|
40
|
+
const isOnce = handler.options?.once === true;
|
|
41
|
+
const normal = sets?.[0] ?? new Set();
|
|
42
|
+
const once = sets?.[1] ?? new Set();
|
|
43
|
+
if (sets === undefined) {
|
|
44
|
+
listeners.set(event, [normal, once]);
|
|
45
|
+
}
|
|
46
|
+
if (isOnce) {
|
|
47
|
+
once.add(entry);
|
|
48
|
+
return disposable(() => once.delete(entry));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
normal.add(entry);
|
|
52
|
+
return disposable(() => normal.delete(entry));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function setupListeners(element, run) {
|
|
56
|
+
const disposables = [];
|
|
57
|
+
for (const [event, sets] of listeners) {
|
|
58
|
+
for (const handlers of sets) {
|
|
59
|
+
if (handlers.size === 0)
|
|
60
|
+
continue;
|
|
61
|
+
const listener = (ev) => run(Effect.forEach(handlers, ([el, { handler }]) => {
|
|
62
|
+
const match = ev.target === el || el.contains(ev.target);
|
|
63
|
+
return match ? handler(proxyCurrentTarget(ev, el)) : Effect.void;
|
|
64
|
+
}));
|
|
65
|
+
element.addEventListener(event, listener, getDerivedAddEventListenerOptions(handlers));
|
|
66
|
+
disposables.push(disposable(() => element.removeEventListener(event, listener)));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return disposables;
|
|
70
|
+
}
|
|
71
|
+
function setup(rendered, scope) {
|
|
72
|
+
if (listeners.size === 0)
|
|
73
|
+
return Effect.void;
|
|
74
|
+
const elements = getElements(rendered);
|
|
75
|
+
if (elements.length === 0)
|
|
76
|
+
return Effect.void;
|
|
77
|
+
const disposables = [];
|
|
78
|
+
const fibers = new Map();
|
|
79
|
+
const run = (effect) => {
|
|
80
|
+
const id = Symbol();
|
|
81
|
+
const fiber = Effect.runFork(Effect.onExit(effect, () => Effect.sync(() => fibers.delete(id))));
|
|
82
|
+
fibers.set(id, fiber);
|
|
83
|
+
return fiber;
|
|
84
|
+
};
|
|
85
|
+
if (listeners.size > 0) {
|
|
86
|
+
for (const element of elements) {
|
|
87
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
88
|
+
disposables.push(...setupListeners(element, run));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return Scope.addFinalizer(scope, Effect.suspend(() => {
|
|
92
|
+
disposables.forEach(dispose);
|
|
93
|
+
if (fibers.size === 0)
|
|
94
|
+
return Effect.void;
|
|
95
|
+
return Fiber.interruptAll(fibers.values());
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
addEventListener,
|
|
100
|
+
setup,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function proxyCurrentTarget(event, currentTarget) {
|
|
104
|
+
return new Proxy(event, {
|
|
105
|
+
get(target, property) {
|
|
106
|
+
if (property === "currentTarget")
|
|
107
|
+
return currentTarget;
|
|
108
|
+
const value = target[property];
|
|
109
|
+
if (typeof value === "function")
|
|
110
|
+
return value.bind(event);
|
|
111
|
+
return value;
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function getDerivedAddEventListenerOptions(entries) {
|
|
116
|
+
let once = true;
|
|
117
|
+
let passive = true;
|
|
118
|
+
for (const h of entries) {
|
|
119
|
+
if (h[1].options?.once !== true)
|
|
120
|
+
once = false;
|
|
121
|
+
if (h[1].options?.passive !== true)
|
|
122
|
+
passive = false;
|
|
123
|
+
if (!once && !passive)
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
return { once, passive };
|
|
127
|
+
}
|
package/dist/Html.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Layer from "effect/Layer";
|
|
3
|
+
import * as ServiceMap from "effect/ServiceMap";
|
|
4
|
+
import { Fx } from "@typed/fx";
|
|
5
|
+
import { type RenderEvent } from "./RenderEvent.js";
|
|
6
|
+
import { RenderTemplate } from "./RenderTemplate.js";
|
|
7
|
+
/**
|
|
8
|
+
* Renders a stream of `RenderEvent`s into a stream of HTML strings.
|
|
9
|
+
*
|
|
10
|
+
* This function transforms the output of a template rendering process (which produces `RenderEvent`s)
|
|
11
|
+
* into a stream of strings suitable for HTML output (e.g., for Server-Side Rendering).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { Effect } from "effect"
|
|
16
|
+
* import { html } from "@typed/template"
|
|
17
|
+
* import { renderToHtml, HtmlRenderTemplate } from "@typed/template/Html"
|
|
18
|
+
* import { Fx } from "@typed/fx"
|
|
19
|
+
* import { Layer } from "effect"
|
|
20
|
+
*
|
|
21
|
+
* const program = Effect.gen(function* () {
|
|
22
|
+
* const template = html`<div>Hello, ${"world"}!</div>`
|
|
23
|
+
*
|
|
24
|
+
* // Render to HTML string stream
|
|
25
|
+
* const htmlStream = renderToHtml(template).pipe(
|
|
26
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
27
|
+
* )
|
|
28
|
+
*
|
|
29
|
+
* // Collect all HTML chunks
|
|
30
|
+
* const chunks = yield* Fx.collectAll(htmlStream)
|
|
31
|
+
* console.log(chunks.join("")) // "<div>Hello, world!</div>"
|
|
32
|
+
* })
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @param fx - The `Fx` stream of `RenderEvent`s to render.
|
|
36
|
+
* @returns An `Fx` stream of HTML strings.
|
|
37
|
+
* @since 1.0.0
|
|
38
|
+
* @category rendering
|
|
39
|
+
*/
|
|
40
|
+
export declare function renderToHtml<E, R>(fx: Fx.Fx<RenderEvent | null | undefined, E, R>): Fx.Fx<string, E, R>;
|
|
41
|
+
/**
|
|
42
|
+
* Renders a stream of `RenderEvent`s into a single HTML string.
|
|
43
|
+
*
|
|
44
|
+
* This is a convenience function that collects all events from `renderToHtml` and joins them
|
|
45
|
+
* into a single string. It is an Effect that resolves when the stream completes.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { Effect } from "effect"
|
|
50
|
+
* import { html } from "@typed/template"
|
|
51
|
+
* import { renderToHtmlString, HtmlRenderTemplate } from "@typed/template/Html"
|
|
52
|
+
* import { Fx } from "@typed/fx"
|
|
53
|
+
* import { Layer } from "effect"
|
|
54
|
+
*
|
|
55
|
+
* const program = Effect.gen(function* () {
|
|
56
|
+
* const template = html`<div>
|
|
57
|
+
* <h1>Hello</h1>
|
|
58
|
+
* <p>World</p>
|
|
59
|
+
* </div>`
|
|
60
|
+
*
|
|
61
|
+
* // Render to single HTML string
|
|
62
|
+
* const htmlString = yield* renderToHtmlString(template).pipe(
|
|
63
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
64
|
+
* )
|
|
65
|
+
*
|
|
66
|
+
* console.log(htmlString)
|
|
67
|
+
* // "<div><h1>Hello</h1><p>World</p></div>"
|
|
68
|
+
* })
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @param fx - The `Fx` stream of `RenderEvent`s to render.
|
|
72
|
+
* @returns An `Effect` that resolves to the full HTML string.
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
* @category rendering
|
|
75
|
+
*/
|
|
76
|
+
export declare function renderToHtmlString<E, R>(fx: Fx.Fx<RenderEvent | null | undefined, E, R>): Effect.Effect<string, E, R>;
|
|
77
|
+
/**
|
|
78
|
+
* A boolean service that indicates whether the current rendering context is static.
|
|
79
|
+
*
|
|
80
|
+
* If `true`, the HTML renderer will optimize for static output, potentially skipping
|
|
81
|
+
* dynamic placeholder generation or other interactive features not needed for static HTML.
|
|
82
|
+
*/
|
|
83
|
+
export declare const StaticRendering: ServiceMap.Reference<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* A Layer that provides the `RenderTemplate` service implemented for HTML string generation.
|
|
86
|
+
*
|
|
87
|
+
* Using this layer enables templates to be rendered as HTML strings (e.g., for SSR)
|
|
88
|
+
* rather than DOM nodes. It sets the `RefSubject.CurrentComputedBehavior` to `"one"`, indicating
|
|
89
|
+
* a single-pass render approach typical for HTML generation.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* import { Effect } from "effect"
|
|
94
|
+
* import { html } from "@typed/template"
|
|
95
|
+
* import { renderToHtmlString, HtmlRenderTemplate } from "@typed/template/Html"
|
|
96
|
+
* import { Fx } from "@typed/fx"
|
|
97
|
+
* import { Layer } from "effect"
|
|
98
|
+
*
|
|
99
|
+
* const program = Effect.gen(function* () {
|
|
100
|
+
* const template = html`<div>Hello, ${"world"}!</div>`
|
|
101
|
+
*
|
|
102
|
+
* const htmlString = yield* renderToHtmlString(template).pipe(
|
|
103
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
104
|
+
* )
|
|
105
|
+
*
|
|
106
|
+
* // Use for SSR
|
|
107
|
+
* return htmlString
|
|
108
|
+
* })
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @since 1.0.0
|
|
112
|
+
* @category layers
|
|
113
|
+
*/
|
|
114
|
+
export declare const HtmlRenderTemplate: Layer.Layer<RenderTemplate, never, never>;
|
|
115
|
+
/**
|
|
116
|
+
* A variant of `HtmlRenderTemplate` that enables static rendering optimizations.
|
|
117
|
+
*
|
|
118
|
+
* This layer provides the `RenderTemplate` service for HTML generation but also
|
|
119
|
+
* sets `StaticRendering` to `true`, enabling optimizations for static content.
|
|
120
|
+
*/
|
|
121
|
+
export declare const StaticHtmlRenderTemplate: Layer.Layer<RenderTemplate, never, never>;
|
|
122
|
+
//# sourceMappingURL=Html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Html.d.ts","sourceRoot":"","sources":["../src/Html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAc,MAAM,WAAW,CAAC;AAa3C,OAAO,EAAsC,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AASrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAC/B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,GAC9C,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAErB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EACrC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,GAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAM7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,+BAK3B,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,kBAAkB,2CA+BqD,CAAC;AAErF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,2CAEpC,CAAC"}
|
package/dist/Html.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Layer from "effect/Layer";
|
|
3
|
+
import { none, some } from "effect/Option";
|
|
4
|
+
import { isNullish, isObject } from "effect/Predicate";
|
|
5
|
+
import { map as mapRecord } from "effect/Record";
|
|
6
|
+
import * as ServiceMap from "effect/ServiceMap";
|
|
7
|
+
import { Fx, RefSubject } from "@typed/fx";
|
|
8
|
+
import { addTemplateHash, templateToHtmlChunks, } from "./HtmlChunk.js";
|
|
9
|
+
import { renderToString } from "./internal/encoding.js";
|
|
10
|
+
import { TEXT_START, TYPED_NODE_END, TYPED_NODE_START } from "./internal/meta.js";
|
|
11
|
+
import { takeOneIfNotRenderEvent } from "./internal/takeOneIfNotRenderEvent.js";
|
|
12
|
+
import { parse } from "./Parser.js";
|
|
13
|
+
import { HtmlRenderEvent, isHtmlRenderEvent } from "./RenderEvent.js";
|
|
14
|
+
import { RenderTemplate } from "./RenderTemplate.js";
|
|
15
|
+
const toHtmlString = (event) => {
|
|
16
|
+
if (event === null || event === undefined)
|
|
17
|
+
return none();
|
|
18
|
+
const s = event.toString();
|
|
19
|
+
if (s === "")
|
|
20
|
+
return none();
|
|
21
|
+
return some(s);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Renders a stream of `RenderEvent`s into a stream of HTML strings.
|
|
25
|
+
*
|
|
26
|
+
* This function transforms the output of a template rendering process (which produces `RenderEvent`s)
|
|
27
|
+
* into a stream of strings suitable for HTML output (e.g., for Server-Side Rendering).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { Effect } from "effect"
|
|
32
|
+
* import { html } from "@typed/template"
|
|
33
|
+
* import { renderToHtml, HtmlRenderTemplate } from "@typed/template/Html"
|
|
34
|
+
* import { Fx } from "@typed/fx"
|
|
35
|
+
* import { Layer } from "effect"
|
|
36
|
+
*
|
|
37
|
+
* const program = Effect.gen(function* () {
|
|
38
|
+
* const template = html`<div>Hello, ${"world"}!</div>`
|
|
39
|
+
*
|
|
40
|
+
* // Render to HTML string stream
|
|
41
|
+
* const htmlStream = renderToHtml(template).pipe(
|
|
42
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
43
|
+
* )
|
|
44
|
+
*
|
|
45
|
+
* // Collect all HTML chunks
|
|
46
|
+
* const chunks = yield* Fx.collectAll(htmlStream)
|
|
47
|
+
* console.log(chunks.join("")) // "<div>Hello, world!</div>"
|
|
48
|
+
* })
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @param fx - The `Fx` stream of `RenderEvent`s to render.
|
|
52
|
+
* @returns An `Fx` stream of HTML strings.
|
|
53
|
+
* @since 1.0.0
|
|
54
|
+
* @category rendering
|
|
55
|
+
*/
|
|
56
|
+
export function renderToHtml(fx) {
|
|
57
|
+
return Fx.filterMap(fx, toHtmlString);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Renders a stream of `RenderEvent`s into a single HTML string.
|
|
61
|
+
*
|
|
62
|
+
* This is a convenience function that collects all events from `renderToHtml` and joins them
|
|
63
|
+
* into a single string. It is an Effect that resolves when the stream completes.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { Effect } from "effect"
|
|
68
|
+
* import { html } from "@typed/template"
|
|
69
|
+
* import { renderToHtmlString, HtmlRenderTemplate } from "@typed/template/Html"
|
|
70
|
+
* import { Fx } from "@typed/fx"
|
|
71
|
+
* import { Layer } from "effect"
|
|
72
|
+
*
|
|
73
|
+
* const program = Effect.gen(function* () {
|
|
74
|
+
* const template = html`<div>
|
|
75
|
+
* <h1>Hello</h1>
|
|
76
|
+
* <p>World</p>
|
|
77
|
+
* </div>`
|
|
78
|
+
*
|
|
79
|
+
* // Render to single HTML string
|
|
80
|
+
* const htmlString = yield* renderToHtmlString(template).pipe(
|
|
81
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
82
|
+
* )
|
|
83
|
+
*
|
|
84
|
+
* console.log(htmlString)
|
|
85
|
+
* // "<div><h1>Hello</h1><p>World</p></div>"
|
|
86
|
+
* })
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @param fx - The `Fx` stream of `RenderEvent`s to render.
|
|
90
|
+
* @returns An `Effect` that resolves to the full HTML string.
|
|
91
|
+
* @since 1.0.0
|
|
92
|
+
* @category rendering
|
|
93
|
+
*/
|
|
94
|
+
export function renderToHtmlString(fx) {
|
|
95
|
+
return fx.pipe(renderToHtml, Fx.collectAll, Effect.map((events) => events.join("")));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A boolean service that indicates whether the current rendering context is static.
|
|
99
|
+
*
|
|
100
|
+
* If `true`, the HTML renderer will optimize for static output, potentially skipping
|
|
101
|
+
* dynamic placeholder generation or other interactive features not needed for static HTML.
|
|
102
|
+
*/
|
|
103
|
+
export const StaticRendering = ServiceMap.Reference("@typed/template/Html/StaticRendering", {
|
|
104
|
+
defaultValue: () => false,
|
|
105
|
+
});
|
|
106
|
+
/**
|
|
107
|
+
* A Layer that provides the `RenderTemplate` service implemented for HTML string generation.
|
|
108
|
+
*
|
|
109
|
+
* Using this layer enables templates to be rendered as HTML strings (e.g., for SSR)
|
|
110
|
+
* rather than DOM nodes. It sets the `RefSubject.CurrentComputedBehavior` to `"one"`, indicating
|
|
111
|
+
* a single-pass render approach typical for HTML generation.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* import { Effect } from "effect"
|
|
116
|
+
* import { html } from "@typed/template"
|
|
117
|
+
* import { renderToHtmlString, HtmlRenderTemplate } from "@typed/template/Html"
|
|
118
|
+
* import { Fx } from "@typed/fx"
|
|
119
|
+
* import { Layer } from "effect"
|
|
120
|
+
*
|
|
121
|
+
* const program = Effect.gen(function* () {
|
|
122
|
+
* const template = html`<div>Hello, ${"world"}!</div>`
|
|
123
|
+
*
|
|
124
|
+
* const htmlString = yield* renderToHtmlString(template).pipe(
|
|
125
|
+
* Fx.provide(HtmlRenderTemplate)
|
|
126
|
+
* )
|
|
127
|
+
*
|
|
128
|
+
* // Use for SSR
|
|
129
|
+
* return htmlString
|
|
130
|
+
* })
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @since 1.0.0
|
|
134
|
+
* @category layers
|
|
135
|
+
*/
|
|
136
|
+
export const HtmlRenderTemplate = Layer.effect(RenderTemplate, Effect.gen(function* () {
|
|
137
|
+
const isStatic = yield* StaticRendering;
|
|
138
|
+
const entries = new WeakMap();
|
|
139
|
+
const getChunks = (templateStrings) => {
|
|
140
|
+
let entry = entries.get(templateStrings);
|
|
141
|
+
if (entry === undefined) {
|
|
142
|
+
const template = parse(templateStrings);
|
|
143
|
+
const chunks = templateToHtmlChunks(template);
|
|
144
|
+
entry = isStatic ? chunks : addTemplateHash(chunks, template);
|
|
145
|
+
entries.set(templateStrings, entry);
|
|
146
|
+
}
|
|
147
|
+
return entry;
|
|
148
|
+
};
|
|
149
|
+
return (template, values) => Fx.mergeOrdered(...getChunks(template).map((chunk, i, chunks) => renderChunk(chunk, values, isStatic, i === chunks.length - 1)));
|
|
150
|
+
})).pipe(Layer.provideMerge(Layer.succeed(RefSubject.CurrentComputedBehavior, "one")));
|
|
151
|
+
/**
|
|
152
|
+
* A variant of `HtmlRenderTemplate` that enables static rendering optimizations.
|
|
153
|
+
*
|
|
154
|
+
* This layer provides the `RenderTemplate` service for HTML generation but also
|
|
155
|
+
* sets `StaticRendering` to `true`, enabling optimizations for static content.
|
|
156
|
+
*/
|
|
157
|
+
export const StaticHtmlRenderTemplate = HtmlRenderTemplate.pipe(Layer.provideMerge(Layer.succeed(StaticRendering, true)));
|
|
158
|
+
function renderChunk(chunk, values, isStatic, last) {
|
|
159
|
+
if (chunk._tag === "text") {
|
|
160
|
+
return Fx.succeed(HtmlRenderEvent(chunk.text, last));
|
|
161
|
+
}
|
|
162
|
+
if (chunk._tag === "part") {
|
|
163
|
+
return renderPart(chunk, values, isStatic, last);
|
|
164
|
+
}
|
|
165
|
+
return renderSparsePart(chunk, values, isStatic, last);
|
|
166
|
+
}
|
|
167
|
+
function renderPart(chunk, values, isStatic, last) {
|
|
168
|
+
const { node, render } = chunk;
|
|
169
|
+
const renderable = values[node.index];
|
|
170
|
+
// We don't render ref and event nodes via HTML
|
|
171
|
+
if (node._tag === "ref" || node._tag === "event")
|
|
172
|
+
return Fx.empty;
|
|
173
|
+
// Node need to handle all possible value types including arrays
|
|
174
|
+
if (node._tag === "node") {
|
|
175
|
+
return renderNode(renderable, node.index, isStatic, last);
|
|
176
|
+
}
|
|
177
|
+
// Properties is entirely recursive
|
|
178
|
+
if (node._tag === "properties") {
|
|
179
|
+
const setup = (props) => setupProperties(props, isStatic, last, render);
|
|
180
|
+
if (isObject(renderable))
|
|
181
|
+
return setup(renderable);
|
|
182
|
+
return Fx.switchMap(liftRenderableToFx(renderable, isStatic), (props) => {
|
|
183
|
+
if (isObject(props))
|
|
184
|
+
return setup(props);
|
|
185
|
+
return Fx.empty;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// Otherwise we're going to coerce to a string
|
|
189
|
+
return Fx.filterMap(liftRenderableToFx(renderable, isStatic), (value) => {
|
|
190
|
+
const s = render(value);
|
|
191
|
+
return s ? some(HtmlRenderEvent(s, last)) : none();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function setupProperties(renderable, isStatic, last, render) {
|
|
195
|
+
const entries = Object.entries(renderable);
|
|
196
|
+
const length = entries.length;
|
|
197
|
+
const lastIndex = length - 1;
|
|
198
|
+
// Order here doesn't matter ??
|
|
199
|
+
return Fx.mergeAll(...entries.map(([key, renderable], i) => {
|
|
200
|
+
return Fx.filterMap(liftRenderableToFx(renderable, isStatic), (value) => {
|
|
201
|
+
const s = render({ [key]: value });
|
|
202
|
+
return s ? some(HtmlRenderEvent(s, last && i === lastIndex)) : none();
|
|
203
|
+
});
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
function renderNode(renderable, index, isStatic, last) {
|
|
207
|
+
let node = liftRenderableToFx(renderable, isStatic).pipe(Fx.map((x) => (isHtmlRenderEvent(x) ? x : HtmlRenderEvent(renderToString(x, ""), last))));
|
|
208
|
+
if (!isStatic) {
|
|
209
|
+
node = addNodePlaceholders(node, index);
|
|
210
|
+
}
|
|
211
|
+
return node.pipe(Fx.map((x) => HtmlRenderEvent(x.html, x.last && last)));
|
|
212
|
+
}
|
|
213
|
+
function addNodePlaceholders(fx, index) {
|
|
214
|
+
return fx.pipe(Fx.map((event) => (isHtmlRenderEvent(event) ? HtmlRenderEvent(event.html, false) : event)), Fx.delimit(HtmlRenderEvent(TYPED_NODE_START(index), false), HtmlRenderEvent(TYPED_NODE_END(index), true)));
|
|
215
|
+
}
|
|
216
|
+
function renderSparsePart(chunk, values, isStatic, last) {
|
|
217
|
+
const { node, render } = chunk;
|
|
218
|
+
return Fx.tuple(...node.nodes.map((node) => {
|
|
219
|
+
if (node._tag === "text")
|
|
220
|
+
return Fx.succeed(node.value);
|
|
221
|
+
return liftRenderableToFx(values[node.index], isStatic);
|
|
222
|
+
})).pipe(Fx.take(1), Fx.map((value) => HtmlRenderEvent(render(value), last)));
|
|
223
|
+
}
|
|
224
|
+
function liftRenderableToFx(renderable, isStatic) {
|
|
225
|
+
switch (typeof renderable) {
|
|
226
|
+
case "undefined":
|
|
227
|
+
case "function":
|
|
228
|
+
case "object": {
|
|
229
|
+
if (isNullish(renderable)) {
|
|
230
|
+
return isStatic ? Fx.empty : Fx.succeed(HtmlRenderEvent(TEXT_START, true));
|
|
231
|
+
}
|
|
232
|
+
else if (Array.isArray(renderable)) {
|
|
233
|
+
return Fx.mergeOrdered(...renderable.map((r) => liftRenderableToFx(r, isStatic)));
|
|
234
|
+
}
|
|
235
|
+
else if (Fx.isFx(renderable)) {
|
|
236
|
+
return takeOneIfNotRenderEvent(renderable);
|
|
237
|
+
}
|
|
238
|
+
else if (Effect.isEffect(renderable)) {
|
|
239
|
+
return Fx.unwrap(Effect.map(renderable, (r) => liftRenderableToFx(r, isStatic)));
|
|
240
|
+
}
|
|
241
|
+
else if (isHtmlRenderEvent(renderable)) {
|
|
242
|
+
return Fx.succeed(renderable);
|
|
243
|
+
}
|
|
244
|
+
else
|
|
245
|
+
return Fx.take(Fx.struct(mapRecord(renderable, (_) => liftRenderableToFx(_, isStatic))), 1);
|
|
246
|
+
}
|
|
247
|
+
default:
|
|
248
|
+
return Fx.succeed(renderable);
|
|
249
|
+
}
|
|
250
|
+
}
|