@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/src/EventHandler.ts
CHANGED
|
@@ -1,142 +1,374 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
import { type
|
|
5
|
-
import
|
|
6
|
-
import type
|
|
1
|
+
import type * as Cause from "effect/Cause";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import { dual } from "effect/Function";
|
|
4
|
+
import { type Pipeable, pipeArguments } from "effect/Pipeable";
|
|
5
|
+
import { hasProperty } from "effect/Predicate";
|
|
6
|
+
import type * as ServiceMap from "effect/ServiceMap";
|
|
7
|
+
|
|
8
|
+
export const EventHandlerTypeId = Symbol.for("@typed/template/EventHandler");
|
|
9
|
+
export type EventHandlerTypeId = typeof EventHandlerTypeId;
|
|
7
10
|
|
|
8
11
|
/**
|
|
12
|
+
* Represents a DOM event handler that returns an Effect.
|
|
13
|
+
*
|
|
14
|
+
* It encapsulates the event handler logic and any options (like `preventDefault`, `once`, etc.)
|
|
15
|
+
* that should be applied when the event is triggered.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { Effect } from "effect"
|
|
20
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
21
|
+
* import { html } from "@typed/template"
|
|
22
|
+
*
|
|
23
|
+
* // Simple event handler
|
|
24
|
+
* const handleClick = EventHandler.make((event: MouseEvent) => {
|
|
25
|
+
* console.log("Clicked!", event)
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* // Event handler with Effect
|
|
29
|
+
* const handleSubmit = EventHandler.make((event: SubmitEvent) =>
|
|
30
|
+
* Effect.gen(function* () {
|
|
31
|
+
* event.preventDefault()
|
|
32
|
+
* yield* Effect.sync(() => console.log("Form submitted"))
|
|
33
|
+
* })
|
|
34
|
+
* )
|
|
35
|
+
*
|
|
36
|
+
* // Use in template
|
|
37
|
+
* const template = html`<button onclick=${handleClick}>Click me</button>`
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
9
40
|
* @since 1.0.0
|
|
41
|
+
* @category models
|
|
10
42
|
*/
|
|
11
|
-
export
|
|
43
|
+
export interface EventHandler<Ev extends Event = Event, E = never, R = never> extends Pipeable {
|
|
44
|
+
readonly [EventHandlerTypeId]: EventHandlerTypeId;
|
|
45
|
+
readonly handler: (event: Ev) => Effect.Effect<unknown, E, R>;
|
|
46
|
+
readonly options: (AddEventListenerOptions & EventOptions) | undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type Context<T> = T extends EventHandler<infer _Ev, infer _E, infer R> ? R : never;
|
|
50
|
+
export type Error<T> = T extends EventHandler<infer _Ev, infer E, infer _R> ? E : never;
|
|
51
|
+
export type EventOf<T> = T extends EventHandler<infer Ev, infer _E, infer _R> ? Ev : never;
|
|
52
|
+
|
|
12
53
|
/**
|
|
13
|
-
*
|
|
54
|
+
* Options for configuring event handling behavior.
|
|
14
55
|
*/
|
|
15
|
-
export type
|
|
56
|
+
export type EventOptions = {
|
|
57
|
+
readonly preventDefault?: boolean;
|
|
58
|
+
readonly stopPropagation?: boolean;
|
|
59
|
+
readonly stopImmediatePropagation?: boolean;
|
|
60
|
+
};
|
|
16
61
|
|
|
17
62
|
/**
|
|
63
|
+
* Creates a new `EventHandler`.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { Effect } from "effect"
|
|
68
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
69
|
+
* import { html } from "@typed/template"
|
|
70
|
+
*
|
|
71
|
+
* // Simple handler
|
|
72
|
+
* const clickHandler = EventHandler.make((event) => {
|
|
73
|
+
* console.log("Button clicked")
|
|
74
|
+
* })
|
|
75
|
+
*
|
|
76
|
+
* // Handler with Effect
|
|
77
|
+
* const submitHandler = EventHandler.make((event) =>
|
|
78
|
+
* Effect.gen(function* () {
|
|
79
|
+
* const form = event.target as HTMLFormElement
|
|
80
|
+
* const data = new FormData(form)
|
|
81
|
+
* yield* Effect.sync(() => console.log("Submitting:", data))
|
|
82
|
+
* })
|
|
83
|
+
* )
|
|
84
|
+
*
|
|
85
|
+
* // Handler with options
|
|
86
|
+
* const preventDefaultHandler = EventHandler.make(
|
|
87
|
+
* (event) => console.log("Prevented default"),
|
|
88
|
+
* { preventDefault: true }
|
|
89
|
+
* )
|
|
90
|
+
*
|
|
91
|
+
* const template = html`<button onclick=${clickHandler}>Click</button>`
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @param handler - The function to execute when the event occurs. Can return void or an Effect.
|
|
95
|
+
* @param options - Optional configuration for the event listener.
|
|
18
96
|
* @since 1.0.0
|
|
97
|
+
* @category constructors
|
|
19
98
|
*/
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
99
|
+
export function make<Ev extends Event, E = never, R = never>(
|
|
100
|
+
handler: (event: Ev) => void | Effect.Effect<unknown, E, R>,
|
|
101
|
+
options?: AddEventListenerOptions & EventOptions,
|
|
102
|
+
): EventHandler<Ev, E, R> {
|
|
103
|
+
return {
|
|
104
|
+
[EventHandlerTypeId]: EventHandlerTypeId,
|
|
105
|
+
handler: (ev: Ev) => {
|
|
106
|
+
if (options) handleEventOptions(options, ev);
|
|
107
|
+
const result = handler(ev);
|
|
108
|
+
if (Effect.isEffect(result)) return result;
|
|
109
|
+
return Effect.void;
|
|
110
|
+
},
|
|
111
|
+
options,
|
|
112
|
+
pipe(this: EventHandler<Ev, E, R>) {
|
|
113
|
+
return pipeArguments(this, arguments);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
24
116
|
}
|
|
25
117
|
|
|
26
118
|
/**
|
|
119
|
+
* Provides services to the `EventHandler`.
|
|
120
|
+
*
|
|
121
|
+
* This allows you to inject dependencies into the effect returned by the event handler.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* import { Effect, Context } from "effect"
|
|
126
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
127
|
+
*
|
|
128
|
+
* interface Database {
|
|
129
|
+
* readonly save: (data: string) => Effect.Effect<void>
|
|
130
|
+
* }
|
|
131
|
+
* const Database = Context.GenericTag<Database>("Database")
|
|
132
|
+
*
|
|
133
|
+
* const handler = EventHandler.make((event) =>
|
|
134
|
+
* Effect.flatMap(Database, (db) => db.save("data"))
|
|
135
|
+
* )
|
|
136
|
+
*
|
|
137
|
+
* // Provide services
|
|
138
|
+
* const provided = EventHandler.provide(handler, Database.of({ save: (d) => Effect.sync(() => console.log(d)) }))
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
27
141
|
* @since 1.0.0
|
|
142
|
+
* @category combinators
|
|
28
143
|
*/
|
|
29
|
-
export
|
|
144
|
+
export const provide: {
|
|
145
|
+
<R2 = never>(
|
|
146
|
+
services: ServiceMap.ServiceMap<R2>,
|
|
147
|
+
): <Ev extends Event, E = never, R = never>(
|
|
148
|
+
handler: EventHandler<Ev, E, R>,
|
|
149
|
+
) => EventHandler<Ev, E, Exclude<R, R2>>;
|
|
150
|
+
|
|
151
|
+
<Ev extends Event, E = never, R = never, R2 = never>(
|
|
152
|
+
handler: EventHandler<Ev, E, R>,
|
|
153
|
+
services: ServiceMap.ServiceMap<R2>,
|
|
154
|
+
): EventHandler<Ev, E, Exclude<R, R2>>;
|
|
155
|
+
} = dual(
|
|
156
|
+
2,
|
|
157
|
+
<Ev extends Event, E = never, R = never, R2 = never>(
|
|
158
|
+
handler: EventHandler<Ev, E, R>,
|
|
159
|
+
services: ServiceMap.ServiceMap<R2>,
|
|
160
|
+
): EventHandler<Ev, E, Exclude<R, R2>> => {
|
|
161
|
+
return make(
|
|
162
|
+
(ev) => handler.handler(ev).pipe(Effect.provideServices(services)),
|
|
163
|
+
handler.options,
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
|
|
30
168
|
/**
|
|
169
|
+
* Recovers from errors in the `EventHandler`.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* import { Effect } from "effect"
|
|
174
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
175
|
+
*
|
|
176
|
+
* const handler = EventHandler.make((event) =>
|
|
177
|
+
* Effect.fail("Something went wrong")
|
|
178
|
+
* )
|
|
179
|
+
*
|
|
180
|
+
* // Recover from errors
|
|
181
|
+
* const recovered = EventHandler.catchCause(handler, (cause) =>
|
|
182
|
+
* Effect.sync(() => console.error("Error:", cause))
|
|
183
|
+
* )
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
31
186
|
* @since 1.0.0
|
|
187
|
+
* @category combinators
|
|
32
188
|
*/
|
|
33
|
-
export
|
|
189
|
+
export const catchCause: {
|
|
190
|
+
<E, E2 = never, R2 = never>(
|
|
191
|
+
f: (cause: Cause.Cause<E>) => Effect.Effect<unknown, E2, R2>,
|
|
192
|
+
): <Ev extends Event, R = never>(handler: EventHandler<Ev, E, R>) => EventHandler<Ev, E2, R | R2>;
|
|
193
|
+
|
|
194
|
+
<Ev extends Event, E = never, R = never, E2 = never, R2 = never>(
|
|
195
|
+
handler: EventHandler<Ev, E, R>,
|
|
196
|
+
f: (cause: Cause.Cause<E>) => Effect.Effect<unknown, E2, R2>,
|
|
197
|
+
): EventHandler<Ev, E2, R | R2>;
|
|
198
|
+
} = dual(
|
|
199
|
+
2,
|
|
200
|
+
<Ev extends Event, E = never, R = never, E2 = never, R2 = never>(
|
|
201
|
+
handler: EventHandler<Ev, E, R>,
|
|
202
|
+
f: (cause: Cause.Cause<E>) => Effect.Effect<unknown, E2, R2>,
|
|
203
|
+
): EventHandler<Ev, E2, R | R2> => {
|
|
204
|
+
return make((ev) => handler.handler(ev).pipe(Effect.catchCause(f)), handler.options);
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
|
|
34
208
|
/**
|
|
35
|
-
*
|
|
209
|
+
* Helper to ensure a value is an `EventHandler`.
|
|
210
|
+
*
|
|
211
|
+
* If the input is already an `EventHandler`, it is returned as is.
|
|
212
|
+
* If it is an `Effect`, it is wrapped in an `EventHandler` that ignores the event argument.
|
|
36
213
|
*/
|
|
37
|
-
export
|
|
214
|
+
export function fromEffectOrEventHandler<Ev extends Event, E = never, R = never>(
|
|
215
|
+
handler: Effect.Effect<unknown, E, R> | EventHandler<Ev, E, R>,
|
|
216
|
+
): EventHandler<Ev, E, R> {
|
|
217
|
+
if (isEventHandler(handler)) return handler;
|
|
218
|
+
return make(() => handler as Effect.Effect<unknown, E, R>);
|
|
219
|
+
}
|
|
38
220
|
|
|
39
221
|
/**
|
|
222
|
+
* Checks if a value is an `EventHandler`.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```ts
|
|
226
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
227
|
+
*
|
|
228
|
+
* const handler = EventHandler.make((event) => console.log("Click"))
|
|
229
|
+
* const isHandler = EventHandler.isEventHandler(handler)
|
|
230
|
+
* console.log(isHandler) // true
|
|
231
|
+
*
|
|
232
|
+
* const notHandler = (event: Event) => console.log("Click")
|
|
233
|
+
* const isNotHandler = EventHandler.isEventHandler(notHandler)
|
|
234
|
+
* console.log(isNotHandler) // false
|
|
235
|
+
* ```
|
|
236
|
+
*
|
|
40
237
|
* @since 1.0.0
|
|
238
|
+
* @category guards
|
|
41
239
|
*/
|
|
42
|
-
export function
|
|
43
|
-
handler:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
[EventHandlerTypeId]: EventHandlerTypeId,
|
|
48
|
-
handler,
|
|
49
|
-
options
|
|
50
|
-
} as any
|
|
240
|
+
export function isEventHandler<Ev extends Event, E = never, R = never>(
|
|
241
|
+
handler: unknown,
|
|
242
|
+
): handler is EventHandler<Ev, E, R> {
|
|
243
|
+
return hasProperty(handler, EventHandlerTypeId);
|
|
51
244
|
}
|
|
52
245
|
|
|
53
246
|
/**
|
|
54
|
-
*
|
|
247
|
+
* Applies event options to a native DOM event.
|
|
55
248
|
*/
|
|
56
|
-
export function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
|
|
249
|
+
export function handleEventOptions<Ev extends Event>(eventOptions: EventOptions, ev: Ev): boolean {
|
|
250
|
+
if (eventOptions.preventDefault) ev.preventDefault();
|
|
251
|
+
if (eventOptions.stopPropagation) ev.stopPropagation();
|
|
252
|
+
if (eventOptions.stopImmediatePropagation) ev.stopImmediatePropagation();
|
|
253
|
+
|
|
254
|
+
return true;
|
|
61
255
|
}
|
|
62
256
|
|
|
63
257
|
/**
|
|
258
|
+
* Modifies an `EventHandler` to call `preventDefault()` on the event.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
263
|
+
* import { html } from "@typed/template"
|
|
264
|
+
*
|
|
265
|
+
* const handler = EventHandler.make((event) => {
|
|
266
|
+
* console.log("Form submit prevented")
|
|
267
|
+
* })
|
|
268
|
+
*
|
|
269
|
+
* const preventDefaultHandler = EventHandler.preventDefault(handler)
|
|
270
|
+
*
|
|
271
|
+
* const template = html`<form onsubmit=${preventDefaultHandler}>...</form>`
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
64
274
|
* @since 1.0.0
|
|
275
|
+
* @category combinators
|
|
65
276
|
*/
|
|
66
|
-
export function
|
|
67
|
-
handler:
|
|
68
|
-
options?: AddEventListenerOptions
|
|
277
|
+
export function preventDefault<Ev extends Event, E = never, R = never>(
|
|
278
|
+
handler: EventHandler<Ev, E, R>,
|
|
69
279
|
): EventHandler<Ev, E, R> {
|
|
70
|
-
return make(
|
|
280
|
+
return make(handler.handler, { ...handler.options, preventDefault: true });
|
|
71
281
|
}
|
|
72
282
|
|
|
73
283
|
/**
|
|
284
|
+
* Modifies an `EventHandler` to call `stopPropagation()` on the event.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
289
|
+
*
|
|
290
|
+
* const handler = EventHandler.make((event) => {
|
|
291
|
+
* console.log("Event stopped")
|
|
292
|
+
* })
|
|
293
|
+
*
|
|
294
|
+
* const stopPropHandler = EventHandler.stopPropagation(handler)
|
|
295
|
+
* ```
|
|
296
|
+
*
|
|
74
297
|
* @since 1.0.0
|
|
298
|
+
* @category combinators
|
|
75
299
|
*/
|
|
76
|
-
export function
|
|
77
|
-
handler:
|
|
78
|
-
options?: AddEventListenerOptions
|
|
300
|
+
export function stopPropagation<Ev extends Event, E = never, R = never>(
|
|
301
|
+
handler: EventHandler<Ev, E, R>,
|
|
79
302
|
): EventHandler<Ev, E, R> {
|
|
80
|
-
return make(
|
|
303
|
+
return make(handler.handler, { ...handler.options, stopPropagation: true });
|
|
81
304
|
}
|
|
82
305
|
|
|
83
306
|
/**
|
|
307
|
+
* Modifies an `EventHandler` to call `stopImmediatePropagation()` on the event.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```ts
|
|
311
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
312
|
+
*
|
|
313
|
+
* const handler = EventHandler.make((event) => {
|
|
314
|
+
* console.log("Immediate propagation stopped")
|
|
315
|
+
* })
|
|
316
|
+
*
|
|
317
|
+
* const stopImmediateHandler = EventHandler.stopImmediatePropagation(handler)
|
|
318
|
+
* ```
|
|
319
|
+
*
|
|
84
320
|
* @since 1.0.0
|
|
321
|
+
* @category combinators
|
|
85
322
|
*/
|
|
86
|
-
export
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function handleEventOptions<Ev extends Event>(
|
|
93
|
-
eventOptions: EventOptions,
|
|
94
|
-
ev: Ev
|
|
95
|
-
): boolean {
|
|
96
|
-
if (eventOptions.preventDefault) ev.preventDefault()
|
|
97
|
-
if (eventOptions.stopPropagation) ev.stopPropagation()
|
|
98
|
-
if (eventOptions.stopImmediatePropagation) ev.stopImmediatePropagation()
|
|
99
|
-
|
|
100
|
-
return true
|
|
323
|
+
export function stopImmediatePropagation<Ev extends Event, E = never, R = never>(
|
|
324
|
+
handler: EventHandler<Ev, E, R>,
|
|
325
|
+
): EventHandler<Ev, E, R> {
|
|
326
|
+
return make(handler.handler, { ...handler.options, stopImmediatePropagation: true });
|
|
101
327
|
}
|
|
102
328
|
|
|
103
329
|
/**
|
|
330
|
+
* Modifies an `EventHandler` to run only once.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```ts
|
|
334
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
335
|
+
*
|
|
336
|
+
* const handler = EventHandler.make((event) => {
|
|
337
|
+
* console.log("This will only run once")
|
|
338
|
+
* })
|
|
339
|
+
*
|
|
340
|
+
* const onceHandler = EventHandler.once(handler)
|
|
341
|
+
* ```
|
|
342
|
+
*
|
|
104
343
|
* @since 1.0.0
|
|
344
|
+
* @category combinators
|
|
105
345
|
*/
|
|
106
|
-
export function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}) {
|
|
111
|
-
return <R, E, Ev extends Event>(
|
|
112
|
-
handler: (event: EventWithTarget<T, Ev>) => Effect.Effect<unknown, E, R>,
|
|
113
|
-
options?: AddEventListenerOptions
|
|
114
|
-
): EventHandler<EventWithTarget<T, Ev>, E, R> => {
|
|
115
|
-
return make(
|
|
116
|
-
eventOptions ?
|
|
117
|
-
(ev) => {
|
|
118
|
-
handleEventOptions(eventOptions, ev)
|
|
119
|
-
return handler(ev)
|
|
120
|
-
} :
|
|
121
|
-
handler,
|
|
122
|
-
options
|
|
123
|
-
)
|
|
124
|
-
}
|
|
346
|
+
export function once<Ev extends Event, E = never, R = never>(
|
|
347
|
+
handler: EventHandler<Ev, E, R>,
|
|
348
|
+
): EventHandler<Ev, E, R> {
|
|
349
|
+
return make(handler.handler, { ...handler.options, once: true, passive: false });
|
|
125
350
|
}
|
|
126
351
|
|
|
127
352
|
/**
|
|
353
|
+
* Modifies an `EventHandler` to be passive (improves scrolling performance).
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```ts
|
|
357
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
358
|
+
*
|
|
359
|
+
* const handler = EventHandler.make((event) => {
|
|
360
|
+
* // Passive handlers can't call preventDefault
|
|
361
|
+
* console.log("Scroll event")
|
|
362
|
+
* })
|
|
363
|
+
*
|
|
364
|
+
* const passiveHandler = EventHandler.passive(handler)
|
|
365
|
+
* ```
|
|
366
|
+
*
|
|
128
367
|
* @since 1.0.0
|
|
368
|
+
* @category combinators
|
|
129
369
|
*/
|
|
130
|
-
export function
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
): EventHandler<KeyboardEvent, E, R> =>
|
|
135
|
-
make(
|
|
136
|
-
(ev: KeyboardEvent) =>
|
|
137
|
-
!isUsingKeyModifier(ev) && keys.includes(ev.key)
|
|
138
|
-
? (options && handleEventOptions(options, ev), handler(ev as any))
|
|
139
|
-
: Effect.void,
|
|
140
|
-
options
|
|
141
|
-
)
|
|
370
|
+
export function passive<Ev extends Event, E = never, R = never>(
|
|
371
|
+
handler: EventHandler<Ev, E, R>,
|
|
372
|
+
): EventHandler<Ev, E, R> {
|
|
373
|
+
return make(handler.handler, { ...handler.options, passive: true, once: false });
|
|
142
374
|
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Fiber from "effect/Fiber";
|
|
3
|
+
import * as Scope from "effect/Scope";
|
|
4
|
+
import type { EventHandler } from "./EventHandler.js";
|
|
5
|
+
import { getElements, type Rendered } from "./Wire.js";
|
|
6
|
+
|
|
7
|
+
type EventName = string;
|
|
8
|
+
|
|
9
|
+
type Handler<Ev extends Event> = EventHandler<Ev>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An interface for managing event listeners on DOM nodes.
|
|
13
|
+
*
|
|
14
|
+
* It abstracts the process of adding and removing event listeners, ensuring that they are
|
|
15
|
+
* properly cleaned up when the scope is closed or the element is removed.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { Effect } from "effect"
|
|
20
|
+
* import { makeEventSource } from "@typed/template/EventSource"
|
|
21
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
22
|
+
* import { Scope } from "effect"
|
|
23
|
+
*
|
|
24
|
+
* const program = Effect.gen(function* () {
|
|
25
|
+
* const eventSource = makeEventSource()
|
|
26
|
+
* const button = document.createElement("button")
|
|
27
|
+
*
|
|
28
|
+
* // Add event listener
|
|
29
|
+
* const handler = EventHandler.make((event: MouseEvent) => {
|
|
30
|
+
* console.log("Button clicked")
|
|
31
|
+
* })
|
|
32
|
+
*
|
|
33
|
+
* const disposable = eventSource.addEventListener(button, "click", handler)
|
|
34
|
+
*
|
|
35
|
+
* // Setup listeners for rendered content
|
|
36
|
+
* yield* eventSource.setup(button, yield* Scope.make())
|
|
37
|
+
*
|
|
38
|
+
* // Cleanup
|
|
39
|
+
* disposable[Symbol.dispose]()
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @since 1.0.0
|
|
44
|
+
* @category models
|
|
45
|
+
*/
|
|
46
|
+
export interface EventSource {
|
|
47
|
+
/**
|
|
48
|
+
* Adds an event listener to a target.
|
|
49
|
+
*/
|
|
50
|
+
readonly addEventListener: <Ev extends Event>(
|
|
51
|
+
element: EventTarget,
|
|
52
|
+
event: EventName,
|
|
53
|
+
handler: Handler<Ev>,
|
|
54
|
+
) => Disposable;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Sets up event listeners for a rendered template within a scope.
|
|
58
|
+
*/
|
|
59
|
+
readonly setup: (rendered: Rendered, scope: Scope.Scope) => Effect.Effect<void>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
type Entry = readonly [Element, Handler<any>];
|
|
63
|
+
type Run = <E, A>(effect: Effect.Effect<A, E>) => Fiber.Fiber<A, E>;
|
|
64
|
+
|
|
65
|
+
const disposable = (f: () => void): Disposable => ({ [Symbol.dispose]: f });
|
|
66
|
+
const dispose = (d: Disposable): void => d[Symbol.dispose]();
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new `EventSource`.
|
|
70
|
+
*
|
|
71
|
+
* The created `EventSource` can efficiently manage multiple event listeners,
|
|
72
|
+
* grouping them by event type and handling setup/teardown lifecycles.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import { Effect } from "effect"
|
|
77
|
+
* import { makeEventSource } from "@typed/template/EventSource"
|
|
78
|
+
* import * as EventHandler from "@typed/template/EventHandler"
|
|
79
|
+
*
|
|
80
|
+
* const program = Effect.gen(function* () {
|
|
81
|
+
* const eventSource = makeEventSource()
|
|
82
|
+
* const element = document.createElement("div")
|
|
83
|
+
*
|
|
84
|
+
* // Add multiple event listeners
|
|
85
|
+
* eventSource.addEventListener(element, "click", EventHandler.make(() => console.log("clicked")))
|
|
86
|
+
* eventSource.addEventListener(element, "mouseover", EventHandler.make(() => console.log("hovered")))
|
|
87
|
+
*
|
|
88
|
+
* // Setup all listeners
|
|
89
|
+
* yield* eventSource.setup(element, yield* Scope.make())
|
|
90
|
+
* })
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @since 1.0.0
|
|
94
|
+
* @category constructors
|
|
95
|
+
*/
|
|
96
|
+
export function makeEventSource(): EventSource {
|
|
97
|
+
const listeners = new Map<EventName, readonly [normal: Set<Entry>, once: Set<Entry>]>();
|
|
98
|
+
|
|
99
|
+
function addEventListener(
|
|
100
|
+
element: EventTarget,
|
|
101
|
+
event: EventName,
|
|
102
|
+
handler: Handler<any>,
|
|
103
|
+
): Disposable {
|
|
104
|
+
const sets = listeners.get(event);
|
|
105
|
+
const entry: Entry = [element as Element, handler];
|
|
106
|
+
const isOnce = handler.options?.once === true;
|
|
107
|
+
const normal: Set<Entry> = sets?.[0] ?? new Set<Entry>();
|
|
108
|
+
const once: Set<Entry> = sets?.[1] ?? new Set<Entry>();
|
|
109
|
+
if (sets === undefined) {
|
|
110
|
+
listeners.set(event, [normal, once]);
|
|
111
|
+
}
|
|
112
|
+
if (isOnce) {
|
|
113
|
+
once.add(entry);
|
|
114
|
+
return disposable(() => once.delete(entry));
|
|
115
|
+
} else {
|
|
116
|
+
normal.add(entry);
|
|
117
|
+
return disposable(() => normal.delete(entry));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function setupListeners(element: Element, run: Run) {
|
|
122
|
+
const disposables: Array<Disposable> = [];
|
|
123
|
+
|
|
124
|
+
for (const [event, sets] of listeners) {
|
|
125
|
+
for (const handlers of sets) {
|
|
126
|
+
if (handlers.size === 0) continue;
|
|
127
|
+
const listener = (ev: Event) =>
|
|
128
|
+
run(
|
|
129
|
+
Effect.forEach(handlers, ([el, { handler }]) => {
|
|
130
|
+
const match = ev.target === el || el.contains(ev.target as Node);
|
|
131
|
+
return match ? handler(proxyCurrentTarget(ev, el)) : Effect.void;
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
element.addEventListener(event, listener, getDerivedAddEventListenerOptions(handlers));
|
|
135
|
+
disposables.push(disposable(() => element.removeEventListener(event, listener)));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return disposables;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function setup(rendered: Rendered, scope: Scope.Scope) {
|
|
143
|
+
if (listeners.size === 0) return Effect.void;
|
|
144
|
+
|
|
145
|
+
const elements = getElements(rendered);
|
|
146
|
+
if (elements.length === 0) return Effect.void;
|
|
147
|
+
|
|
148
|
+
const disposables: Array<Disposable> = [];
|
|
149
|
+
const fibers = new Map<symbol, Fiber.Fiber<any, any>>();
|
|
150
|
+
const run: Run = <E, A>(effect: Effect.Effect<A, E>) => {
|
|
151
|
+
const id = Symbol();
|
|
152
|
+
const fiber = Effect.runFork(
|
|
153
|
+
Effect.onExit(effect, () => Effect.sync(() => fibers.delete(id))),
|
|
154
|
+
);
|
|
155
|
+
fibers.set(id, fiber);
|
|
156
|
+
return fiber;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
if (listeners.size > 0) {
|
|
160
|
+
for (const element of elements) {
|
|
161
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
162
|
+
disposables.push(...setupListeners(element, run));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return Scope.addFinalizer(
|
|
167
|
+
scope,
|
|
168
|
+
Effect.suspend(() => {
|
|
169
|
+
disposables.forEach(dispose);
|
|
170
|
+
if (fibers.size === 0) return Effect.void;
|
|
171
|
+
return Fiber.interruptAll(fibers.values());
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
addEventListener,
|
|
178
|
+
setup,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function proxyCurrentTarget<E extends Event>(event: E, currentTarget: Element): E {
|
|
183
|
+
return new Proxy(event, {
|
|
184
|
+
get(target: E, property: string | symbol) {
|
|
185
|
+
if (property === "currentTarget") return currentTarget;
|
|
186
|
+
const value = target[property as keyof E];
|
|
187
|
+
if (typeof value === "function") return value.bind(event);
|
|
188
|
+
return value;
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function getDerivedAddEventListenerOptions(entries: Set<Entry>): AddEventListenerOptions {
|
|
194
|
+
let once = true;
|
|
195
|
+
let passive = true;
|
|
196
|
+
for (const h of entries) {
|
|
197
|
+
if (h[1].options?.once !== true) once = false;
|
|
198
|
+
if (h[1].options?.passive !== true) passive = false;
|
|
199
|
+
if (!once && !passive) break;
|
|
200
|
+
}
|
|
201
|
+
return { once, passive };
|
|
202
|
+
}
|