@typed/template 0.14.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 -224
- 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 -385
- 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 -246
- 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 -65
- 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 -343
- 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 -79
- 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 -246
- 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 -42
- 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 -338
- 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 -148
- package/src/ElementSource.ts +0 -510
- 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 -70
- 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
package/dist/Parser.js
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-syntax */
|
|
2
|
+
import { tokenize } from "html5parser";
|
|
3
|
+
import { keyToPartType } from "./internal/keyToPartType.js";
|
|
4
|
+
import { PART_STRING } from "./internal/meta.js";
|
|
5
|
+
import { PathStack } from "./internal/PathStack.js";
|
|
6
|
+
import { templateHash } from "./internal/templateHash.js";
|
|
7
|
+
import * as Template from "./Template.js";
|
|
8
|
+
let parser;
|
|
9
|
+
/**
|
|
10
|
+
* Parses a template string array (from a tagged template literal) into a reusable `Template` object.
|
|
11
|
+
*
|
|
12
|
+
* This parser handles:
|
|
13
|
+
* - Standard HTML structure (elements, attributes, text, comments).
|
|
14
|
+
* - Custom part syntax for interpolation (e.g., `${value}`).
|
|
15
|
+
* - Special attributes like `.property`, `@event`, `?boolean`.
|
|
16
|
+
* - Self-closing tags and text-only elements (script, style).
|
|
17
|
+
*
|
|
18
|
+
* The result is a cached `Template` instance that contains the static AST and dynamic part locations.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { parse } from "@typed/template/Parser"
|
|
23
|
+
* import * as Template from "@typed/template/Template"
|
|
24
|
+
*
|
|
25
|
+
* // Parse a template
|
|
26
|
+
* const template = parse`<div id=${"my-id"} class="container">
|
|
27
|
+
* <p>Hello, ${"world"}!</p>
|
|
28
|
+
* </div>`
|
|
29
|
+
*
|
|
30
|
+
* // Access parsed structure
|
|
31
|
+
* console.log(template.nodes) // Array of parsed nodes
|
|
32
|
+
* console.log(template.parts) // Array of dynamic interpolation points
|
|
33
|
+
* console.log(template.hash) // Unique hash for the template
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param template - The template strings array from a tagged template literal.
|
|
37
|
+
* @returns A `Template` object representing the parsed structure.
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
* @category parsing
|
|
40
|
+
*/
|
|
41
|
+
export function parse(template) {
|
|
42
|
+
parser ??= new Parser();
|
|
43
|
+
return parser.parse(template);
|
|
44
|
+
}
|
|
45
|
+
class Parser {
|
|
46
|
+
html;
|
|
47
|
+
tokens;
|
|
48
|
+
index;
|
|
49
|
+
parts;
|
|
50
|
+
path;
|
|
51
|
+
parse(templateStrings) {
|
|
52
|
+
this.init(templateStrings);
|
|
53
|
+
return new Template.Template(this.parseNodes(), templateHash(templateStrings), this.parts);
|
|
54
|
+
}
|
|
55
|
+
init(templateStrings) {
|
|
56
|
+
this.html = templateWithParts(templateStrings);
|
|
57
|
+
this.tokens = tokenize(this.html);
|
|
58
|
+
this.index = 0;
|
|
59
|
+
this.parts = [];
|
|
60
|
+
this.path = new PathStack();
|
|
61
|
+
}
|
|
62
|
+
peek() {
|
|
63
|
+
return this.tokens[this.index];
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
66
|
+
consumeNextTokenOfKind(kind) {
|
|
67
|
+
const token = this.tokens[this.index];
|
|
68
|
+
if (token.type !== kind) {
|
|
69
|
+
throw new Error(`Expected ${TokenKindToName[kind]} but got ${TokenKindToName[token.type]}`);
|
|
70
|
+
}
|
|
71
|
+
this.index++;
|
|
72
|
+
return token;
|
|
73
|
+
}
|
|
74
|
+
consumeWhitespace() {
|
|
75
|
+
while (this.tokens[this.index]?.type === TokenKind.Whitespace) {
|
|
76
|
+
this.index++;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
80
|
+
consumeNextTokenOfKinds(...kinds) {
|
|
81
|
+
const token = this.tokens[this.index];
|
|
82
|
+
if (!kinds.includes(token.type)) {
|
|
83
|
+
throw new Error(`Expected ${kinds.map((kind) => TokenKindToName[kind]).join(" or ")} but got ${TokenKindToName[token.type]}`);
|
|
84
|
+
}
|
|
85
|
+
this.index++;
|
|
86
|
+
return token;
|
|
87
|
+
}
|
|
88
|
+
parseNodes() {
|
|
89
|
+
const nodes = [];
|
|
90
|
+
while (this.index < this.tokens.length) {
|
|
91
|
+
const token = this.consumeNextTokenOfKinds(TokenKind.Literal, TokenKind.OpenTag, TokenKind.CloseTag, TokenKind.Whitespace);
|
|
92
|
+
if (token.type === TokenKind.Literal) {
|
|
93
|
+
nodes.push(...this.parseNodeParts(token));
|
|
94
|
+
}
|
|
95
|
+
else if (token.type === TokenKind.OpenTag) {
|
|
96
|
+
nodes.push(this.parseOpenTag(token));
|
|
97
|
+
this.path.inc();
|
|
98
|
+
}
|
|
99
|
+
else if (token.type === TokenKind.CloseTag) {
|
|
100
|
+
this.consumeWhitespace();
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
else if (nodes.length > 0) {
|
|
104
|
+
nodes.push(new Template.TextNode(token.value));
|
|
105
|
+
this.path.inc();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return nodes;
|
|
109
|
+
}
|
|
110
|
+
parseNodeParts(literal) {
|
|
111
|
+
return parseTextAndParts(literal.value, (index) => this.addPartWithPrevious(new Template.NodePart(index)), () => this.path.inc());
|
|
112
|
+
}
|
|
113
|
+
parseOpenTag({ value }) {
|
|
114
|
+
if (value === "!--")
|
|
115
|
+
return this.parseCommentNode();
|
|
116
|
+
if (value === "!doctype")
|
|
117
|
+
return this.parseDocTypeNode();
|
|
118
|
+
if (SELF_CLOSING_TAGS.has(value))
|
|
119
|
+
return this.parseSelfClosingElementNode(value);
|
|
120
|
+
if (TEXT_ONLY_NODES_REGEX.has(value))
|
|
121
|
+
return this.parseTextOnlyElementNode(value);
|
|
122
|
+
// All other elements
|
|
123
|
+
const { attributes, wasSelfClosed } = this.parseAttributes();
|
|
124
|
+
const children = wasSelfClosed ? [] : this.parseChildren();
|
|
125
|
+
return new Template.ElementNode(value, attributes, children);
|
|
126
|
+
}
|
|
127
|
+
parseChildren() {
|
|
128
|
+
this.path.push();
|
|
129
|
+
const children = this.parseNodes();
|
|
130
|
+
this.path.pop();
|
|
131
|
+
return children;
|
|
132
|
+
}
|
|
133
|
+
parseCommentNode() {
|
|
134
|
+
const { value } = this.consumeNextTokenOfKind(TokenKind.Literal);
|
|
135
|
+
this.consumeNextTokenOfKind(TokenKind.OpenTagEnd);
|
|
136
|
+
return this.parseMultipleParts(value, (index) => new Template.CommentPartNode(index), (text) => new Template.CommentNode(text.value), (parts) => new Template.SparseCommentNode(parts));
|
|
137
|
+
}
|
|
138
|
+
parseDocTypeNode() {
|
|
139
|
+
this.consumeWhitespace();
|
|
140
|
+
// Try to parse the name
|
|
141
|
+
const parsedName = this.parseLiteralLike();
|
|
142
|
+
if (parsedName.closed)
|
|
143
|
+
return new Template.DocType("html");
|
|
144
|
+
const name = parsedName.value ?? "html";
|
|
145
|
+
const { closed, publicId, systemId } = this.parseDocTypeIds();
|
|
146
|
+
if (!closed) {
|
|
147
|
+
this.consumeWhitespace();
|
|
148
|
+
this.consumeNextTokenOfKind(TokenKind.OpenTagEnd);
|
|
149
|
+
}
|
|
150
|
+
return new Template.DocType(name, publicId, systemId);
|
|
151
|
+
}
|
|
152
|
+
parseDocTypeIds() {
|
|
153
|
+
const firstIdType = this.parseDocTypeId();
|
|
154
|
+
if (firstIdType.closed)
|
|
155
|
+
return firstIdType;
|
|
156
|
+
const secondIdType = this.parseDocTypeId();
|
|
157
|
+
return {
|
|
158
|
+
closed: secondIdType.closed,
|
|
159
|
+
publicId: secondIdType.publicId ?? firstIdType.publicId,
|
|
160
|
+
systemId: secondIdType.systemId ?? firstIdType.systemId,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
parseDocTypeId() {
|
|
164
|
+
const parsedIdType = this.parseLiteralLike();
|
|
165
|
+
if (parsedIdType.closed || parsedIdType.value === null) {
|
|
166
|
+
return { closed: parsedIdType.closed, publicId: undefined, systemId: undefined };
|
|
167
|
+
}
|
|
168
|
+
const value = parsedIdType.value.toLowerCase();
|
|
169
|
+
if (value === "public" || value === "system") {
|
|
170
|
+
const parsedLiteral = this.parseLiteralLike();
|
|
171
|
+
if (parsedLiteral.closed || parsedLiteral.value === null) {
|
|
172
|
+
return { closed: parsedLiteral.closed, publicId: undefined, systemId: undefined };
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
closed: false,
|
|
176
|
+
publicId: value === "public" ? parsedLiteral.value : undefined,
|
|
177
|
+
systemId: value === "system" ? parsedLiteral.value : undefined,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return { closed: false, publicId: undefined, systemId: undefined };
|
|
181
|
+
}
|
|
182
|
+
parseLiteralLike() {
|
|
183
|
+
this.consumeWhitespace();
|
|
184
|
+
const { type, value } = this.consumeNextTokenOfKinds(TokenKind.Literal, TokenKind.AttrValueNq, TokenKind.AttrValueDq, TokenKind.AttrValueSq, TokenKind.OpenTagEnd);
|
|
185
|
+
if (type === TokenKind.OpenTagEnd)
|
|
186
|
+
return { closed: true, value: null };
|
|
187
|
+
if (type === TokenKind.Literal || type === TokenKind.AttrValueNq)
|
|
188
|
+
return { closed: false, value };
|
|
189
|
+
if (type === TokenKind.AttrValueDq || type === TokenKind.AttrValueSq) {
|
|
190
|
+
return { closed: false, value: value.slice(1, -1) };
|
|
191
|
+
}
|
|
192
|
+
throw new Error(`Unexpected token ${TokenKindToName[type]} in place of literal`);
|
|
193
|
+
}
|
|
194
|
+
parseSelfClosingElementNode(name) {
|
|
195
|
+
const { attributes } = this.parseAttributes();
|
|
196
|
+
return new Template.SelfClosingElementNode(name, attributes);
|
|
197
|
+
}
|
|
198
|
+
parseTextOnlyElementNode(name) {
|
|
199
|
+
const { attributes, wasSelfClosed } = this.parseAttributes();
|
|
200
|
+
const textContent = wasSelfClosed ? null : this.parseTextOnlyChildren();
|
|
201
|
+
return new Template.TextOnlyElement(name, attributes, textContent);
|
|
202
|
+
}
|
|
203
|
+
parseAttributes() {
|
|
204
|
+
let wasSelfClosed = false;
|
|
205
|
+
const attributes = [];
|
|
206
|
+
this.consumeWhitespace();
|
|
207
|
+
while (this.index < this.tokens.length) {
|
|
208
|
+
const token = this.peek();
|
|
209
|
+
if (token.type === TokenKind.OpenTagEnd) {
|
|
210
|
+
this.index++;
|
|
211
|
+
wasSelfClosed = token.value === "/";
|
|
212
|
+
this.consumeWhitespace();
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
if (token.type === TokenKind.Whitespace) {
|
|
216
|
+
this.index++;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const { attribute, isSelfClosed, shouldContinue } = this.parseAttribute();
|
|
220
|
+
attributes.push(attribute);
|
|
221
|
+
wasSelfClosed ||= isSelfClosed;
|
|
222
|
+
if (!shouldContinue) {
|
|
223
|
+
this.consumeWhitespace();
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
attributes,
|
|
229
|
+
wasSelfClosed,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
parseAttribute() {
|
|
233
|
+
const { value: name } = this.consumeNextTokenOfKind(TokenKind.AttrValueNq);
|
|
234
|
+
if (isSpreadAttribute(name)) {
|
|
235
|
+
return {
|
|
236
|
+
shouldContinue: true,
|
|
237
|
+
isSelfClosed: false,
|
|
238
|
+
attribute: this.parsePropertiesAttribute(name.slice(3)),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const next = this.consumeNextTokenOfKinds(TokenKind.AttrValueEq, TokenKind.Whitespace, TokenKind.OpenTagEnd);
|
|
242
|
+
if (next.type === TokenKind.AttrValueEq) {
|
|
243
|
+
const { type, value } = this.consumeNextTokenOfKinds(TokenKind.AttrValueDq, TokenKind.AttrValueSq, TokenKind.AttrValueNq);
|
|
244
|
+
return {
|
|
245
|
+
shouldContinue: true,
|
|
246
|
+
isSelfClosed: false,
|
|
247
|
+
attribute: this.parseAttributeWithValue(name, type === TokenKind.AttrValueNq ? value : value.slice(1, -1)),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
else if (next.type === TokenKind.Whitespace) {
|
|
251
|
+
return {
|
|
252
|
+
shouldContinue: true,
|
|
253
|
+
isSelfClosed: false,
|
|
254
|
+
attribute: new Template.BooleanNode(name),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
else if (next.type === TokenKind.OpenTagEnd) {
|
|
258
|
+
this.consumeWhitespace();
|
|
259
|
+
return {
|
|
260
|
+
shouldContinue: false,
|
|
261
|
+
isSelfClosed: next.value === "/",
|
|
262
|
+
attribute: new Template.BooleanNode(name),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
throw new Error(`Unexpected token ${TokenKindToName[next.type]} in place of attribute`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
parseAttributeWithValue(rawName, value) {
|
|
270
|
+
const [match, name] = keyToPartType(rawName);
|
|
271
|
+
switch (match) {
|
|
272
|
+
case "attr":
|
|
273
|
+
return this.parseAttributePart(value, name);
|
|
274
|
+
case "boolean":
|
|
275
|
+
return this.parseBooleanAttribute(value, name);
|
|
276
|
+
case "class":
|
|
277
|
+
return this.parseClassNameAttribute(value);
|
|
278
|
+
case "data":
|
|
279
|
+
return this.parseDataAttribute(value);
|
|
280
|
+
case "event":
|
|
281
|
+
return this.parseEventAttribute(value, name);
|
|
282
|
+
case "properties":
|
|
283
|
+
return this.parsePropertiesAttribute(value);
|
|
284
|
+
case "property":
|
|
285
|
+
return this.parsePropertyAttribute(value, name);
|
|
286
|
+
case "ref":
|
|
287
|
+
return this.parseRefAttribute(value);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
parseAttributePart(value, name) {
|
|
291
|
+
return this.parseMultipleParts(value, (index) => new Template.AttrPartNode(name, index), (text) => new Template.AttributeNode(name, text.value), (parts) => new Template.SparseAttrNode(name, parts));
|
|
292
|
+
}
|
|
293
|
+
parseBooleanAttribute(value, name) {
|
|
294
|
+
return this.parseMultipleParts(value, (index) => new Template.BooleanPartNode(name, index), () => new Template.BooleanNode(name), () => {
|
|
295
|
+
throw new Error("Boolean attributes cannot have multiple parts");
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
parseClassNameAttribute(value) {
|
|
299
|
+
return this.parseMultipleParts(value, (index) => new Template.ClassNamePartNode(index), (text) => new Template.AttributeNode("class", text.value.trim()), (parts) => new Template.SparseClassNameNode(parts));
|
|
300
|
+
}
|
|
301
|
+
parseDataAttribute(value) {
|
|
302
|
+
return this.addPart(new Template.DataPartNode(unsafeParsePartIndex(value)));
|
|
303
|
+
}
|
|
304
|
+
parseEventAttribute(value, name) {
|
|
305
|
+
return this.addPart(new Template.EventPartNode(name, unsafeParsePartIndex(value)));
|
|
306
|
+
}
|
|
307
|
+
parsePropertyAttribute(value, name) {
|
|
308
|
+
return this.addPart(new Template.PropertyPartNode(name, unsafeParsePartIndex(value)));
|
|
309
|
+
}
|
|
310
|
+
parsePropertiesAttribute(value) {
|
|
311
|
+
return this.addPart(new Template.PropertiesPartNode(unsafeParsePartIndex(value)));
|
|
312
|
+
}
|
|
313
|
+
parseRefAttribute(value) {
|
|
314
|
+
return this.addPart(new Template.RefPartNode(unsafeParsePartIndex(value)));
|
|
315
|
+
}
|
|
316
|
+
parseTextOnlyChildren() {
|
|
317
|
+
const { type, value } = this.consumeNextTokenOfKinds(TokenKind.Literal, TokenKind.CloseTag);
|
|
318
|
+
if (type === TokenKind.Literal) {
|
|
319
|
+
this.consumeNextTokenOfKind(TokenKind.CloseTag);
|
|
320
|
+
return this.parseMultipleParts(value, (index) => new Template.TextPartNode(index), (text) => text, (parts) => new Template.SparseTextNode(parts));
|
|
321
|
+
}
|
|
322
|
+
this.consumeWhitespace();
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
parseMultipleParts(value, createPart, onSingleTextNode, onMultiParts) {
|
|
326
|
+
const parts = parseTextAndParts(value, createPart);
|
|
327
|
+
if (parts.length === 1) {
|
|
328
|
+
if (parts[0]._tag === "text")
|
|
329
|
+
return onSingleTextNode(parts[0]);
|
|
330
|
+
return this.addPart(parts[0]);
|
|
331
|
+
}
|
|
332
|
+
return this.addPart(onMultiParts(parts));
|
|
333
|
+
}
|
|
334
|
+
addPart(part) {
|
|
335
|
+
this.parts.push([part, this.path.toChunk()]);
|
|
336
|
+
return part;
|
|
337
|
+
}
|
|
338
|
+
addPartWithPrevious(part) {
|
|
339
|
+
this.parts.push([part, this.path.previousChunk()]);
|
|
340
|
+
this.path.inc(); // Nodes will be inserted as a comment
|
|
341
|
+
return part;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const TEXT_ONLY_NODES_REGEX = new Set(["textarea", "script", "style", "title", "plaintext", "xmp"]);
|
|
345
|
+
const SELF_CLOSING_TAGS = new Set([
|
|
346
|
+
"area",
|
|
347
|
+
"base",
|
|
348
|
+
"br",
|
|
349
|
+
"col",
|
|
350
|
+
"command",
|
|
351
|
+
"embed",
|
|
352
|
+
"hr",
|
|
353
|
+
"img",
|
|
354
|
+
"input",
|
|
355
|
+
"keygen",
|
|
356
|
+
"link",
|
|
357
|
+
"meta",
|
|
358
|
+
"param",
|
|
359
|
+
"source",
|
|
360
|
+
"track",
|
|
361
|
+
"wbr",
|
|
362
|
+
]);
|
|
363
|
+
const TokenKind = {
|
|
364
|
+
/* eslint-disable @typescript-eslint/consistent-type-imports */
|
|
365
|
+
Literal: 0,
|
|
366
|
+
OpenTag: 1,
|
|
367
|
+
OpenTagEnd: 2,
|
|
368
|
+
CloseTag: 3,
|
|
369
|
+
Whitespace: 4,
|
|
370
|
+
AttrValueEq: 5,
|
|
371
|
+
AttrValueNq: 6,
|
|
372
|
+
AttrValueSq: 7,
|
|
373
|
+
AttrValueDq: 8,
|
|
374
|
+
/* eslint-enable @typescript-eslint/consistent-type-imports */
|
|
375
|
+
};
|
|
376
|
+
const TokenKindToName = {
|
|
377
|
+
[TokenKind.Literal]: "Literal",
|
|
378
|
+
[TokenKind.OpenTag]: "OpenTag",
|
|
379
|
+
[TokenKind.OpenTagEnd]: "OpenTagEnd",
|
|
380
|
+
[TokenKind.CloseTag]: "CloseTag",
|
|
381
|
+
[TokenKind.Whitespace]: "Whitespace",
|
|
382
|
+
[TokenKind.AttrValueEq]: "AttrValueEq",
|
|
383
|
+
[TokenKind.AttrValueNq]: "AttrValueNq",
|
|
384
|
+
[TokenKind.AttrValueSq]: "AttrValueSq",
|
|
385
|
+
[TokenKind.AttrValueDq]: "AttrValueDq",
|
|
386
|
+
};
|
|
387
|
+
function templateWithParts(template) {
|
|
388
|
+
const length = template.length;
|
|
389
|
+
if (length === 0)
|
|
390
|
+
return "";
|
|
391
|
+
// oxlint-disable-next-line no-new-array
|
|
392
|
+
const parts = new Array(length + length - 1);
|
|
393
|
+
let j = 0;
|
|
394
|
+
for (let i = 0; i < length; i++) {
|
|
395
|
+
parts[j++] = template[i];
|
|
396
|
+
if (i !== length - 1) {
|
|
397
|
+
parts[j++] = PART_STRING(i);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return parts.join("");
|
|
401
|
+
}
|
|
402
|
+
function parseTextAndParts(s, createPartFromIndex, onTextNodeInserted) {
|
|
403
|
+
const out = [];
|
|
404
|
+
let pos = 0;
|
|
405
|
+
let foundAny = false;
|
|
406
|
+
while (true) {
|
|
407
|
+
const start = s.indexOf("{{", pos);
|
|
408
|
+
if (start === -1)
|
|
409
|
+
break;
|
|
410
|
+
const end = s.indexOf("}}", start + 2);
|
|
411
|
+
if (end === -1)
|
|
412
|
+
break;
|
|
413
|
+
const before = s.slice(pos, start);
|
|
414
|
+
pos = end + 2;
|
|
415
|
+
// Before first part: skip whitespace-only. Between parts: only skip empty.
|
|
416
|
+
if (before !== "" && (foundAny || /\S/.test(before))) {
|
|
417
|
+
out.push(new Template.TextNode(before));
|
|
418
|
+
onTextNodeInserted?.();
|
|
419
|
+
}
|
|
420
|
+
foundAny = true;
|
|
421
|
+
out.push(createPartFromIndex(+s.slice(start + 2, end)));
|
|
422
|
+
}
|
|
423
|
+
const after = s.slice(pos);
|
|
424
|
+
// After last part (or entire string if no parts): skip whitespace-only
|
|
425
|
+
if (after !== "" && /\S/.test(after)) {
|
|
426
|
+
out.push(new Template.TextNode(after));
|
|
427
|
+
onTextNodeInserted?.();
|
|
428
|
+
}
|
|
429
|
+
return out;
|
|
430
|
+
}
|
|
431
|
+
// Only to be utilized when parsing positions which MUST be a single part.
|
|
432
|
+
function unsafeParsePartIndex(text) {
|
|
433
|
+
return parseInt(text.slice(2, -2), 10);
|
|
434
|
+
}
|
|
435
|
+
function isSpreadAttribute(rawName) {
|
|
436
|
+
return rawName[0] === "." && rawName[1] === "." && rawName[2] === ".";
|
|
437
|
+
}
|
package/dist/Render.d.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as Cause from "effect/Cause";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import * as Scope from "effect/Scope";
|
|
5
|
+
import * as ServiceMap from "effect/ServiceMap";
|
|
6
|
+
import { Fx } from "@typed/fx";
|
|
7
|
+
import { type EventSource } from "./EventSource.js";
|
|
8
|
+
import { HydrateContext } from "./HydrateContext.js";
|
|
9
|
+
import type { HydrationTemplate } from "./internal/hydration.js";
|
|
10
|
+
import { type IndexRefCounter } from "./internal/IndexRefCounter.js";
|
|
11
|
+
import type { Renderable } from "./Renderable.js";
|
|
12
|
+
import { type RenderEvent } from "./RenderEvent.js";
|
|
13
|
+
import * as RQ from "./RenderQueue.js";
|
|
14
|
+
import { RenderTemplate } from "./RenderTemplate.js";
|
|
15
|
+
import { type Rendered } from "./Wire.js";
|
|
16
|
+
/**
|
|
17
|
+
* A service that provides the `Document` interface for rendering.
|
|
18
|
+
*
|
|
19
|
+
* Defaults to the global `document` object. This can be overridden for testing
|
|
20
|
+
* or environments where the global document is not available or desired.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { CurrentRenderDocument } from "@typed/template/Render"
|
|
25
|
+
* import { Layer } from "effect"
|
|
26
|
+
*
|
|
27
|
+
* // Override document for testing
|
|
28
|
+
* const testDocument = new Document()
|
|
29
|
+
* const testLayer = Layer.succeed(CurrentRenderDocument, testDocument)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @since 1.0.0
|
|
33
|
+
* @category services
|
|
34
|
+
*/
|
|
35
|
+
export declare const CurrentRenderDocument: ServiceMap.Reference<Document>;
|
|
36
|
+
/**
|
|
37
|
+
* A service that manages the queue of DOM updates.
|
|
38
|
+
*
|
|
39
|
+
* It ensures that DOM updates are batched and executed efficiently, often coordinating
|
|
40
|
+
* with browser painting cycles (e.g., via `requestAnimationFrame`).
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { CurrentRenderQueue } from "@typed/template/Render"
|
|
45
|
+
* import { MixedRenderQueue } from "@typed/template/RenderQueue"
|
|
46
|
+
* import { Layer } from "effect"
|
|
47
|
+
*
|
|
48
|
+
* // Use a custom render queue
|
|
49
|
+
* const customQueue = new MixedRenderQueue()
|
|
50
|
+
* const queueLayer = Layer.succeed(CurrentRenderQueue, customQueue)
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @since 1.0.0
|
|
54
|
+
* @category services
|
|
55
|
+
*/
|
|
56
|
+
export declare const CurrentRenderQueue: ServiceMap.Reference<RQ.RenderQueue>;
|
|
57
|
+
/**
|
|
58
|
+
* A service that provides the default priority for rendering tasks.
|
|
59
|
+
*
|
|
60
|
+
* The default value is `RenderPriority.Raf(10)`, which typically schedules updates
|
|
61
|
+
* to occur before the next repaint.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { CurrentRenderPriority } from "@typed/template/Render"
|
|
66
|
+
* import { RenderPriority } from "@typed/template/RenderQueue"
|
|
67
|
+
* import { Layer } from "effect"
|
|
68
|
+
*
|
|
69
|
+
* // Use synchronous priority for immediate updates
|
|
70
|
+
* const syncLayer = Layer.succeed(CurrentRenderPriority, RenderPriority.Sync)
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
* @category services
|
|
75
|
+
*/
|
|
76
|
+
export declare const CurrentRenderPriority: ServiceMap.Reference<number>;
|
|
77
|
+
/**
|
|
78
|
+
* A Layer that provides the `RenderTemplate` service implemented for DOM rendering.
|
|
79
|
+
*
|
|
80
|
+
* This layer enables templates to be rendered as actual DOM nodes. It handles:
|
|
81
|
+
* - Parsing templates into DOM fragments.
|
|
82
|
+
* - Caching parsed templates.
|
|
83
|
+
* - Hydrating from existing DOM (if applicable).
|
|
84
|
+
* - Setting up event listeners.
|
|
85
|
+
* - Managing fine-grained updates to DOM nodes via `Fx` streams.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { Effect, Layer } from "effect"
|
|
90
|
+
* import { html } from "@typed/template"
|
|
91
|
+
* import { DomRenderTemplate, render } from "@typed/template/Render"
|
|
92
|
+
* import { Fx } from "@typed/fx"
|
|
93
|
+
*
|
|
94
|
+
* const program = Effect.gen(function* () {
|
|
95
|
+
* const template = html`<div>Hello, world!</div>`
|
|
96
|
+
*
|
|
97
|
+
* yield* render(template, document.body).pipe(
|
|
98
|
+
* Fx.drainLayer,
|
|
99
|
+
* Layer.provide(DomRenderTemplate),
|
|
100
|
+
* Layer.launch
|
|
101
|
+
* )
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @since 1.0.0
|
|
106
|
+
* @category layers
|
|
107
|
+
*/
|
|
108
|
+
export declare const DomRenderTemplate: Layer.Layer<RenderTemplate, never, never> & {
|
|
109
|
+
readonly using: (document: Document) => Layer.Layer<RenderTemplate, never, never>;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* A helper type to determine the rendered output type.
|
|
113
|
+
*/
|
|
114
|
+
export type ToRendered<T extends RenderEvent | null> = Rendered | (T extends null ? null : never);
|
|
115
|
+
/**
|
|
116
|
+
* Mounts a reactive `Fx` stream of `RenderEvent`s to a specific DOM element.
|
|
117
|
+
*
|
|
118
|
+
* This function takes a stream of render events (usually from a template) and keeps
|
|
119
|
+
* the target DOM element updated. It handles:
|
|
120
|
+
* - Mounting the initial content.
|
|
121
|
+
* - Updating the content as new events are emitted.
|
|
122
|
+
* - Hydrating the content if hydration context is provided.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { Effect, Layer } from "effect"
|
|
127
|
+
* import { html } from "@typed/template"
|
|
128
|
+
* import { DomRenderTemplate, render } from "@typed/template/Render"
|
|
129
|
+
* import { Fx } from "@typed/fx"
|
|
130
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
131
|
+
*
|
|
132
|
+
* const program = Effect.gen(function* () {
|
|
133
|
+
* const count = yield* RefSubject.make(0)
|
|
134
|
+
*
|
|
135
|
+
* const template = html`<div>
|
|
136
|
+
* <p>Count: ${count}</p>
|
|
137
|
+
* <button onclick=${RefSubject.increment(count)}>Increment</button>
|
|
138
|
+
* </div>`
|
|
139
|
+
*
|
|
140
|
+
* // Render to document.body
|
|
141
|
+
* yield* render(template, document.body).pipe(
|
|
142
|
+
* Fx.drainLayer,
|
|
143
|
+
* Layer.provide(DomRenderTemplate),
|
|
144
|
+
* Layer.launch
|
|
145
|
+
* )
|
|
146
|
+
* })
|
|
147
|
+
*
|
|
148
|
+
* // Can also use pipe syntax
|
|
149
|
+
* const program2 = Effect.gen(function* () {
|
|
150
|
+
* const template = html`<div>Hello</div>`
|
|
151
|
+
*
|
|
152
|
+
* yield* template.pipe(
|
|
153
|
+
* render(document.body),
|
|
154
|
+
* Fx.drainLayer,
|
|
155
|
+
* Layer.provide(DomRenderTemplate),
|
|
156
|
+
* Layer.launch
|
|
157
|
+
* )
|
|
158
|
+
* })
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* @param fx - The `Fx` stream of content to render.
|
|
162
|
+
* @param where - The target DOM element to render into.
|
|
163
|
+
* @returns An `Fx` that emits the currently rendered DOM nodes.
|
|
164
|
+
* @since 1.0.0
|
|
165
|
+
* @category rendering
|
|
166
|
+
*/
|
|
167
|
+
export declare const render: {
|
|
168
|
+
(where: HTMLElement): <A extends RenderEvent | null, E, R>(fx: Fx.Fx<A, E, R>) => Fx.Fx<ToRendered<A>, E, R>;
|
|
169
|
+
<A extends RenderEvent | null, E, R>(fx: Fx.Fx<A, E, R>, where: HTMLElement): Fx.Fx<ToRendered<A>, E, R>;
|
|
170
|
+
};
|
|
171
|
+
export type TemplateContext<R = never> = {
|
|
172
|
+
readonly document: Document;
|
|
173
|
+
readonly renderQueue: RQ.RenderQueue;
|
|
174
|
+
readonly disposables: Set<Disposable>;
|
|
175
|
+
readonly eventSource: EventSource;
|
|
176
|
+
readonly refCounter: IndexRefCounter;
|
|
177
|
+
readonly scope: Scope.Closeable;
|
|
178
|
+
readonly values: ArrayLike<Renderable<unknown, any, any>>;
|
|
179
|
+
readonly services: ServiceMap.ServiceMap<R | Scope.Scope>;
|
|
180
|
+
readonly onCause: (cause: Cause.Cause<any>) => Effect.Effect<unknown>;
|
|
181
|
+
/**
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
expected: number;
|
|
185
|
+
/**
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
dynamicIndex: number;
|
|
189
|
+
readonly hydrateContext: HydrateContext | undefined;
|
|
190
|
+
};
|
|
191
|
+
export declare function attemptHydration(ctx: TemplateContext, hash: string): {
|
|
192
|
+
readonly where: HydrationTemplate;
|
|
193
|
+
readonly hydrateCtx: HydrateContext;
|
|
194
|
+
} | undefined;
|
|
195
|
+
//# sourceMappingURL=Render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Render.d.ts","sourceRoot":"","sources":["../src/Render.ts"],"names":[],"mappings":"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"}
|