@saolabs/client 1.0.0 → 1.0.2
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 +52 -195
- package/dist/index.d.ts +20 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +2 -2
- package/dist/plugins.js +2 -2
- package/dist/src/core/app/Application.d.ts +17 -15
- package/dist/src/core/app/Application.d.ts.map +1 -1
- package/dist/src/core/app/Application.js +41 -18
- package/dist/src/core/app/Application.js.map +1 -1
- package/dist/src/core/bootstrap/app.d.ts +1 -1
- package/dist/src/core/bootstrap/app.d.ts.map +1 -1
- package/dist/src/core/bootstrap/app.js +74 -4
- package/dist/src/core/bootstrap/app.js.map +1 -1
- package/dist/src/core/bootstrap/bundle.d.ts +41 -0
- package/dist/src/core/bootstrap/bundle.d.ts.map +1 -0
- package/dist/src/core/bootstrap/bundle.js +98 -0
- package/dist/src/core/bootstrap/bundle.js.map +1 -0
- package/dist/src/core/bootstrap/providers/ApiServiceProvider.d.ts +1 -1
- package/dist/src/core/bootstrap/providers/ApiServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/ApiServiceProvider.js +3 -3
- package/dist/src/core/bootstrap/providers/ApiServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/CoreServiceProvider.d.ts +1 -1
- package/dist/src/core/bootstrap/providers/CoreServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/CoreServiceProvider.js +11 -8
- package/dist/src/core/bootstrap/providers/CoreServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/HelperServiceProvider.d.ts +3 -1
- package/dist/src/core/bootstrap/providers/HelperServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/HelperServiceProvider.js +8 -3
- package/dist/src/core/bootstrap/providers/HelperServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/RouteServiceProvider.d.ts +2 -1
- package/dist/src/core/bootstrap/providers/RouteServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/RouteServiceProvider.js +14 -4
- package/dist/src/core/bootstrap/providers/RouteServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/ServiceProvider.d.ts +4 -4
- package/dist/src/core/bootstrap/providers/ServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/ServiceProvider.js +5 -5
- package/dist/src/core/bootstrap/providers/ServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/ViewServiceProvider.d.ts +1 -1
- package/dist/src/core/bootstrap/providers/ViewServiceProvider.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/ViewServiceProvider.js +3 -3
- package/dist/src/core/bootstrap/providers/ViewServiceProvider.js.map +1 -1
- package/dist/src/core/bootstrap/providers/default-providers.d.ts +1 -1
- package/dist/src/core/bootstrap/providers/default-providers.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/default-providers.js +44 -11
- package/dist/src/core/bootstrap/providers/default-providers.js.map +1 -1
- package/dist/src/core/bootstrap/providers/index.d.ts +9 -9
- package/dist/src/core/bootstrap/providers/index.d.ts.map +1 -1
- package/dist/src/core/bootstrap/providers/index.js +8 -8
- package/dist/src/core/bootstrap/providers/index.js.map +1 -1
- package/dist/src/core/bootstrap/providers/provider-order.d.ts +1 -1
- package/dist/src/core/bootstrap/providers/provider-order.d.ts.map +1 -1
- package/dist/src/core/bootstrap/ssr.d.ts +47 -0
- package/dist/src/core/bootstrap/ssr.d.ts.map +1 -0
- package/dist/src/core/bootstrap/ssr.js +125 -0
- package/dist/src/core/bootstrap/ssr.js.map +1 -0
- package/dist/src/core/cache/ViewCache.d.ts +1 -1
- package/dist/src/core/cache/ViewCache.d.ts.map +1 -1
- package/dist/src/core/cache/index.d.ts +1 -1
- package/dist/src/core/cache/index.d.ts.map +1 -1
- package/dist/src/core/cache/index.js +1 -1
- package/dist/src/core/cache/index.js.map +1 -1
- package/dist/src/core/contracts/ApplicationInterface.d.ts +13 -11
- package/dist/src/core/contracts/ApplicationInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/BlockInterface.d.ts +10 -10
- package/dist/src/core/contracts/BlockInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/BundleInterface.d.ts +38 -0
- package/dist/src/core/contracts/BundleInterface.d.ts.map +1 -0
- package/dist/src/core/contracts/BundleInterface.js +2 -0
- package/dist/src/core/contracts/BundleInterface.js.map +1 -0
- package/dist/src/core/contracts/ComponentInterface.d.ts +7 -6
- package/dist/src/core/contracts/ComponentInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ElementInterface.d.ts +91 -27
- package/dist/src/core/contracts/ElementInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/HeadServiceInterface.d.ts +37 -0
- package/dist/src/core/contracts/HeadServiceInterface.d.ts.map +1 -0
- package/dist/src/core/contracts/HeadServiceInterface.js +3 -0
- package/dist/src/core/contracts/HeadServiceInterface.js.map +1 -0
- package/dist/src/core/contracts/HelperInterface.d.ts +9 -1
- package/dist/src/core/contracts/HelperInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/HttpServiceInterface.d.ts +3 -0
- package/dist/src/core/contracts/HttpServiceInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/MarkerInterface.d.ts +29 -44
- package/dist/src/core/contracts/MarkerInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ReactiveInterface.d.ts +9 -9
- package/dist/src/core/contracts/ReactiveInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/RouterInterface.d.ts +5 -2
- package/dist/src/core/contracts/RouterInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/SectionInterface.d.ts +48 -0
- package/dist/src/core/contracts/SectionInterface.d.ts.map +1 -0
- package/dist/src/core/contracts/SectionInterface.js +2 -0
- package/dist/src/core/contracts/SectionInterface.js.map +1 -0
- package/dist/src/core/contracts/ServiceProviderInterface.d.ts +3 -3
- package/dist/src/core/contracts/ServiceProviderInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ViewControllerInterface.d.ts +116 -15
- package/dist/src/core/contracts/ViewControllerInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ViewInterface.d.ts +31 -5
- package/dist/src/core/contracts/ViewInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ViewManagerInterface.d.ts +47 -5
- package/dist/src/core/contracts/ViewManagerInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/ViewStateInterface.d.ts +39 -2
- package/dist/src/core/contracts/ViewStateInterface.d.ts.map +1 -1
- package/dist/src/core/contracts/common.d.ts +3 -3
- package/dist/src/core/contracts/common.js +3 -3
- package/dist/src/core/contracts/utils.d.ts +19 -19
- package/dist/src/core/contracts/utils.d.ts.map +1 -1
- package/dist/src/core/contracts/views.d.ts +1 -22
- package/dist/src/core/contracts/views.d.ts.map +1 -1
- package/dist/src/core/devtools/hook.d.ts +66 -0
- package/dist/src/core/devtools/hook.d.ts.map +1 -0
- package/dist/src/core/devtools/hook.js +114 -0
- package/dist/src/core/devtools/hook.js.map +1 -0
- package/dist/src/core/devtools/index.d.ts +34 -0
- package/dist/src/core/devtools/index.d.ts.map +1 -0
- package/dist/src/core/devtools/index.js +33 -0
- package/dist/src/core/devtools/index.js.map +1 -0
- package/dist/src/core/devtools/inspector.d.ts +31 -0
- package/dist/src/core/devtools/inspector.d.ts.map +1 -0
- package/dist/src/core/devtools/inspector.js +249 -0
- package/dist/src/core/devtools/inspector.js.map +1 -0
- package/dist/src/core/elements/Block.d.ts +9 -7
- package/dist/src/core/elements/Block.d.ts.map +1 -1
- package/dist/src/core/elements/Block.js +33 -9
- package/dist/src/core/elements/Block.js.map +1 -1
- package/dist/src/core/elements/BlockOutlet.d.ts +19 -8
- package/dist/src/core/elements/BlockOutlet.d.ts.map +1 -1
- package/dist/src/core/elements/BlockOutlet.js +57 -13
- package/dist/src/core/elements/BlockOutlet.js.map +1 -1
- package/dist/src/core/elements/Component.d.ts +83 -11
- package/dist/src/core/elements/Component.d.ts.map +1 -1
- package/dist/src/core/elements/Component.js +334 -13
- package/dist/src/core/elements/Component.js.map +1 -1
- package/dist/src/core/elements/ForeachSlotCache.d.ts +95 -0
- package/dist/src/core/elements/ForeachSlotCache.d.ts.map +1 -0
- package/dist/src/core/elements/ForeachSlotCache.js +149 -0
- package/dist/src/core/elements/ForeachSlotCache.js.map +1 -0
- package/dist/src/core/elements/Fragment.d.ts +19 -13
- package/dist/src/core/elements/Fragment.d.ts.map +1 -1
- package/dist/src/core/elements/Fragment.js +43 -20
- package/dist/src/core/elements/Fragment.js.map +1 -1
- package/dist/src/core/elements/Html.d.ts +89 -12
- package/dist/src/core/elements/Html.d.ts.map +1 -1
- package/dist/src/core/elements/Html.js +707 -106
- package/dist/src/core/elements/Html.js.map +1 -1
- package/dist/src/core/elements/Output.d.ts +34 -10
- package/dist/src/core/elements/Output.d.ts.map +1 -1
- package/dist/src/core/elements/Output.js +141 -26
- package/dist/src/core/elements/Output.js.map +1 -1
- package/dist/src/core/elements/Reactive.d.ts +85 -14
- package/dist/src/core/elements/Reactive.d.ts.map +1 -1
- package/dist/src/core/elements/Reactive.js +315 -41
- package/dist/src/core/elements/Reactive.js.map +1 -1
- package/dist/src/core/elements/TextElement.d.ts +11 -7
- package/dist/src/core/elements/TextElement.d.ts.map +1 -1
- package/dist/src/core/elements/TextElement.js +18 -11
- package/dist/src/core/elements/TextElement.js.map +1 -1
- package/dist/src/core/elements/Wrapper.d.ts +24 -13
- package/dist/src/core/elements/Wrapper.d.ts.map +1 -1
- package/dist/src/core/elements/Wrapper.js +65 -8
- package/dist/src/core/elements/Wrapper.js.map +1 -1
- package/dist/src/core/elements/Yield.d.ts +10 -9
- package/dist/src/core/elements/Yield.d.ts.map +1 -1
- package/dist/src/core/elements/Yield.js +31 -19
- package/dist/src/core/elements/Yield.js.map +1 -1
- package/dist/src/core/elements/helpers.d.ts +7 -7
- package/dist/src/core/elements/helpers.d.ts.map +1 -1
- package/dist/src/core/elements/helpers.js +4 -4
- package/dist/src/core/elements/index.d.ts +12 -11
- package/dist/src/core/elements/index.d.ts.map +1 -1
- package/dist/src/core/elements/index.js +12 -11
- package/dist/src/core/elements/index.js.map +1 -1
- package/dist/src/core/elements/reconcileChildren.d.ts +7 -0
- package/dist/src/core/elements/reconcileChildren.d.ts.map +1 -0
- package/dist/src/core/elements/reconcileChildren.js +74 -0
- package/dist/src/core/elements/reconcileChildren.js.map +1 -0
- package/dist/src/core/hellpers/utils.d.ts +2 -2
- package/dist/src/core/hellpers/utils.js +4 -4
- package/dist/src/core/helpers/ApiClient.d.ts +58 -0
- package/dist/src/core/helpers/ApiClient.d.ts.map +1 -0
- package/dist/src/core/helpers/ApiClient.js +131 -0
- package/dist/src/core/helpers/ApiClient.js.map +1 -0
- package/dist/src/core/helpers/app.d.ts +3 -0
- package/dist/src/core/helpers/app.d.ts.map +1 -0
- package/dist/src/core/helpers/app.js +63 -0
- package/dist/src/core/helpers/app.js.map +1 -0
- package/dist/src/core/helpers/transition.d.ts +34 -0
- package/dist/src/core/helpers/transition.d.ts.map +1 -0
- package/dist/src/core/helpers/transition.js +118 -0
- package/dist/src/core/helpers/transition.js.map +1 -0
- package/dist/src/core/helpers/utils.d.ts +26 -0
- package/dist/src/core/helpers/utils.d.ts.map +1 -0
- package/dist/src/core/helpers/utils.js +96 -0
- package/dist/src/core/helpers/utils.js.map +1 -0
- package/dist/src/core/helpers/view.d.ts +39 -0
- package/dist/src/core/helpers/view.d.ts.map +1 -0
- package/dist/src/core/helpers/view.js +286 -0
- package/dist/src/core/helpers/view.js.map +1 -0
- package/dist/src/core/routers/Router.d.ts +108 -7
- package/dist/src/core/routers/Router.d.ts.map +1 -1
- package/dist/src/core/routers/Router.js +444 -68
- package/dist/src/core/routers/Router.js.map +1 -1
- package/dist/src/core/routers/index.d.ts +2 -2
- package/dist/src/core/routers/index.d.ts.map +1 -1
- package/dist/src/core/routers/index.js +1 -1
- package/dist/src/core/routers/index.js.map +1 -1
- package/dist/src/core/services/AssetManager.d.ts +112 -0
- package/dist/src/core/services/AssetManager.d.ts.map +1 -0
- package/dist/src/core/services/AssetManager.js +361 -0
- package/dist/src/core/services/AssetManager.js.map +1 -0
- package/dist/src/core/services/BlockManager.d.ts +73 -2
- package/dist/src/core/services/BlockManager.d.ts.map +1 -1
- package/dist/src/core/services/BlockManager.js +270 -48
- package/dist/src/core/services/BlockManager.js.map +1 -1
- package/dist/src/core/services/DomService.js +3 -3
- package/dist/src/core/services/DomService.js.map +1 -1
- package/dist/src/core/services/HeadService.d.ts +24 -0
- package/dist/src/core/services/HeadService.d.ts.map +1 -0
- package/dist/src/core/services/HeadService.js +120 -0
- package/dist/src/core/services/HeadService.js.map +1 -0
- package/dist/src/core/services/HelperService.d.ts +14 -3
- package/dist/src/core/services/HelperService.d.ts.map +1 -1
- package/dist/src/core/services/HelperService.js +32 -2
- package/dist/src/core/services/HelperService.js.map +1 -1
- package/dist/src/core/services/HttpService.d.ts +8 -0
- package/dist/src/core/services/HttpService.d.ts.map +1 -1
- package/dist/src/core/services/HttpService.js +121 -47
- package/dist/src/core/services/HttpService.js.map +1 -1
- package/dist/src/core/services/MarkerRegistry.d.ts +51 -8
- package/dist/src/core/services/MarkerRegistry.d.ts.map +1 -1
- package/dist/src/core/services/MarkerRegistry.js +135 -14
- package/dist/src/core/services/MarkerRegistry.js.map +1 -1
- package/dist/src/core/services/PageCache.d.ts +101 -0
- package/dist/src/core/services/PageCache.d.ts.map +1 -0
- package/dist/src/core/services/PageCache.js +184 -0
- package/dist/src/core/services/PageCache.js.map +1 -0
- package/dist/src/core/services/SectionManager.d.ts +100 -0
- package/dist/src/core/services/SectionManager.d.ts.map +1 -0
- package/dist/src/core/services/SectionManager.js +408 -0
- package/dist/src/core/services/SectionManager.js.map +1 -0
- package/dist/src/core/services/StorageService.js +1 -1
- package/dist/src/core/services/TranslationService.d.ts +21 -0
- package/dist/src/core/services/TranslationService.d.ts.map +1 -0
- package/dist/src/core/services/TranslationService.js +95 -0
- package/dist/src/core/services/TranslationService.js.map +1 -0
- package/dist/src/core/services/index.d.ts +11 -8
- package/dist/src/core/services/index.d.ts.map +1 -1
- package/dist/src/core/services/index.js +11 -8
- package/dist/src/core/services/index.js.map +1 -1
- package/dist/src/core/types/utils.d.ts +8 -8
- package/dist/src/core/types/utils.d.ts.map +1 -1
- package/dist/src/core/view/LoopContext.d.ts +21 -1
- package/dist/src/core/view/LoopContext.d.ts.map +1 -1
- package/dist/src/core/view/LoopContext.js +36 -0
- package/dist/src/core/view/LoopContext.js.map +1 -1
- package/dist/src/core/view/ResourceScope.d.ts +38 -0
- package/dist/src/core/view/ResourceScope.d.ts.map +1 -0
- package/dist/src/core/view/ResourceScope.js +167 -0
- package/dist/src/core/view/ResourceScope.js.map +1 -0
- package/dist/src/core/view/Section.d.ts +17 -32
- package/dist/src/core/view/Section.d.ts.map +1 -1
- package/dist/src/core/view/Section.js +14 -55
- package/dist/src/core/view/Section.js.map +1 -1
- package/dist/src/core/view/View.d.ts +43 -7
- package/dist/src/core/view/View.d.ts.map +1 -1
- package/dist/src/core/view/View.js +22 -4
- package/dist/src/core/view/View.js.map +1 -1
- package/dist/src/core/view/ViewController.d.ts +313 -40
- package/dist/src/core/view/ViewController.d.ts.map +1 -1
- package/dist/src/core/view/ViewController.js +1002 -147
- package/dist/src/core/view/ViewController.js.map +1 -1
- package/dist/src/core/view/ViewManager.d.ts +318 -27
- package/dist/src/core/view/ViewManager.d.ts.map +1 -1
- package/dist/src/core/view/ViewManager.js +1199 -258
- package/dist/src/core/view/ViewManager.js.map +1 -1
- package/dist/src/core/view/ViewState.d.ts +185 -6
- package/dist/src/core/view/ViewState.d.ts.map +1 -1
- package/dist/src/core/view/ViewState.js +851 -123
- package/dist/src/core/view/ViewState.js.map +1 -1
- package/dist/src/core/view/index.d.ts +5 -5
- package/dist/src/core/view/index.d.ts.map +1 -1
- package/dist/src/core/view/index.js +5 -5
- package/dist/src/core/view/index.js.map +1 -1
- package/dist/src/testing/index.d.ts +69 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +140 -0
- package/dist/src/testing/index.js.map +1 -0
- package/index.ts +29 -5
- package/package.json +30 -21
- package/plugins.ts +2 -2
- package/src/core/app/Application.ts +58 -31
- package/src/core/bootstrap/app.ts +80 -6
- package/src/core/bootstrap/bundle.ts +101 -0
- package/src/core/bootstrap/providers/ApiServiceProvider.ts +4 -4
- package/src/core/bootstrap/providers/CoreServiceProvider.ts +14 -8
- package/src/core/bootstrap/providers/HelperServiceProvider.ts +8 -3
- package/src/core/bootstrap/providers/RouteServiceProvider.ts +15 -4
- package/src/core/bootstrap/providers/ServiceProvider.ts +8 -8
- package/src/core/bootstrap/providers/ViewServiceProvider.ts +3 -3
- package/src/core/bootstrap/providers/default-providers.ts +51 -16
- package/src/core/bootstrap/providers/index.ts +9 -9
- package/src/core/bootstrap/providers/provider-order.test.ts +16 -27
- package/src/core/bootstrap/providers/provider-order.ts +1 -1
- package/src/core/bootstrap/ssr.ts +136 -0
- package/src/core/cache/ViewCache.ts +1 -1
- package/src/core/cache/index.ts +1 -1
- package/src/core/contracts/ApplicationInterface.ts +13 -11
- package/src/core/contracts/BlockInterface.ts +18 -18
- package/src/core/contracts/BundleInterface.ts +40 -0
- package/src/core/contracts/ComponentInterface.ts +7 -6
- package/src/core/contracts/ElementInterface.ts +95 -27
- package/src/core/contracts/HeadServiceInterface.ts +41 -0
- package/src/core/contracts/HelperInterface.ts +9 -1
- package/src/core/contracts/HttpServiceInterface.ts +3 -0
- package/src/core/contracts/MarkerInterface.ts +22 -49
- package/src/core/contracts/ReactiveInterface.ts +9 -9
- package/src/core/contracts/RouterInterface.ts +5 -2
- package/src/core/contracts/SectionInterface.ts +49 -0
- package/src/core/contracts/ServiceProviderInterface.ts +3 -3
- package/src/core/contracts/ViewControllerInterface.ts +124 -16
- package/src/core/contracts/ViewInterface.ts +34 -5
- package/src/core/contracts/ViewManagerInterface.ts +40 -5
- package/src/core/contracts/ViewStateInterface.ts +39 -2
- package/src/core/contracts/common.ts +3 -3
- package/src/core/contracts/utils.ts +19 -19
- package/src/core/contracts/views.ts +2 -22
- package/src/core/devtools/hook.ts +142 -0
- package/src/core/devtools/index.ts +38 -0
- package/src/core/devtools/inspector.ts +270 -0
- package/src/core/elements/Block.ts +43 -21
- package/src/core/elements/BlockOutlet.ts +61 -21
- package/src/core/elements/Component.ts +352 -18
- package/src/core/elements/ElementManager.ts +9 -9
- package/src/core/elements/ForeachSlotCache.ts +170 -0
- package/src/core/elements/Fragment.ts +50 -32
- package/src/core/elements/Html.ts +696 -117
- package/src/core/elements/Output.ts +147 -30
- package/src/core/elements/Reactive.ts +329 -52
- package/src/core/elements/TextElement.ts +25 -16
- package/src/core/elements/Wrapper.ts +84 -18
- package/src/core/elements/Yield.ts +35 -24
- package/src/core/elements/helpers.ts +12 -12
- package/src/core/elements/index.ts +25 -24
- package/src/core/elements/reconcileChildren.ts +70 -0
- package/src/core/{hellpers → helpers}/ApiClient.ts +8 -1
- package/src/core/{hellpers → helpers}/app.ts +13 -2
- package/src/core/helpers/transition.ts +127 -0
- package/src/core/{hellpers → helpers}/utils.ts +4 -4
- package/src/core/helpers/view.ts +283 -0
- package/src/core/routers/Router.ts +458 -64
- package/src/core/routers/index.ts +2 -2
- package/src/core/services/AssetManager.ts +387 -0
- package/src/core/services/BlockManager.ts +272 -50
- package/src/core/services/DomService.ts +3 -3
- package/src/core/services/HeadService.ts +124 -0
- package/src/core/services/HelperService.ts +34 -4
- package/src/core/services/HttpService.ts +116 -55
- package/src/core/services/MarkerRegistry.ts +142 -16
- package/src/core/services/PageCache.ts +239 -0
- package/src/core/services/SectionManager.ts +387 -0
- package/src/core/services/StorageService.ts +1 -1
- package/src/core/services/TranslationService.ts +91 -0
- package/src/core/services/index.ts +11 -8
- package/src/core/types/utils.ts +8 -8
- package/src/core/view/LoopContext.ts +38 -1
- package/src/core/view/ResourceScope.ts +174 -0
- package/src/core/view/Section.ts +21 -68
- package/src/core/view/View.ts +57 -8
- package/src/core/view/ViewController.ts +1070 -186
- package/src/core/view/ViewManager.ts +1346 -272
- package/src/core/view/ViewState.ts +834 -116
- package/src/core/view/index.ts +5 -5
- package/src/testing/index.ts +184 -0
- package/dist/src/core/services/MarkerService.d.ts +0 -299
- package/dist/src/core/services/MarkerService.d.ts.map +0 -1
- package/dist/src/core/services/MarkerService.js +0 -723
- package/dist/src/core/services/MarkerService.js.map +0 -1
- package/src/core/services/MarkerService.ts +0 -923
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { describe, it } from "node:test";
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
3
2
|
import { NamedServiceProvider, resolveProviderOrder, PROVIDER_NAMES } from "./provider-order";
|
|
4
3
|
|
|
5
4
|
function provider(name: string, dependsOn: string[] = []): NamedServiceProvider {
|
|
6
5
|
return {
|
|
7
6
|
name,
|
|
8
7
|
dependsOn,
|
|
9
|
-
register() {
|
|
10
|
-
// noop for ordering test
|
|
11
|
-
}
|
|
8
|
+
register() {},
|
|
12
9
|
};
|
|
13
10
|
}
|
|
14
11
|
|
|
@@ -22,7 +19,7 @@ describe("resolveProviderOrder", () => {
|
|
|
22
19
|
]);
|
|
23
20
|
|
|
24
21
|
const names = ordered.map((item) => item.name);
|
|
25
|
-
|
|
22
|
+
expect(names).toEqual(["core", "view", "router", "api"]);
|
|
26
23
|
});
|
|
27
24
|
|
|
28
25
|
it("works with PROVIDER_NAMES constants", () => {
|
|
@@ -33,35 +30,27 @@ describe("resolveProviderOrder", () => {
|
|
|
33
30
|
]);
|
|
34
31
|
|
|
35
32
|
const names = ordered.map((p) => p.name);
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
expect(names.indexOf(PROVIDER_NAMES.CORE)).toBe(0);
|
|
34
|
+
expect(names.indexOf(PROVIDER_NAMES.VIEW)).toBeLessThan(names.indexOf(PROVIDER_NAMES.ROUTER));
|
|
38
35
|
});
|
|
39
36
|
|
|
40
37
|
it("throws for missing dependency", () => {
|
|
41
|
-
|
|
42
|
-
(
|
|
43
|
-
/Missing provider dependency/
|
|
44
|
-
);
|
|
38
|
+
expect(() => resolveProviderOrder([provider("view", ["core"])]))
|
|
39
|
+
.toThrow(/Missing provider dependency/);
|
|
45
40
|
});
|
|
46
41
|
|
|
47
42
|
it("throws for circular dependency", () => {
|
|
48
|
-
|
|
49
|
-
(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
]),
|
|
54
|
-
/Circular service provider dependency/
|
|
55
|
-
);
|
|
43
|
+
expect(() => resolveProviderOrder([
|
|
44
|
+
provider("a", ["b"]),
|
|
45
|
+
provider("b", ["c"]),
|
|
46
|
+
provider("c", ["a"])
|
|
47
|
+
])).toThrow(/Circular service provider dependency/);
|
|
56
48
|
});
|
|
57
49
|
|
|
58
50
|
it("throws for duplicate provider names", () => {
|
|
59
|
-
|
|
60
|
-
()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]),
|
|
64
|
-
/Duplicate provider name/
|
|
65
|
-
);
|
|
51
|
+
expect(() => resolveProviderOrder([
|
|
52
|
+
provider("core"),
|
|
53
|
+
provider("core")
|
|
54
|
+
])).toThrow(/Duplicate provider name/);
|
|
66
55
|
});
|
|
67
56
|
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR boot detection — đọc thông tin server nhúng để hydrate route đầu tiên.
|
|
3
|
+
* Tham chiếu: RUNTIME_CONTRACT.md §6 (Hydration boot).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Thông tin boot server nhúng cho trang server-rendered. */
|
|
7
|
+
export interface SSRBootInfo {
|
|
8
|
+
/** Registry path của page entry (vd 'web.modules.home'). */
|
|
9
|
+
view: string;
|
|
10
|
+
/** viewId server đã dùng prefix markers/classes của page. */
|
|
11
|
+
viewId: string;
|
|
12
|
+
/** CSS selector container chứa SSR HTML (mặc định '#app-root'). */
|
|
13
|
+
container?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Đọc SSR boot info từ DOM:
|
|
18
|
+
*
|
|
19
|
+
* <script type="application/json" data-ref="saola-ssr">
|
|
20
|
+
* { "container": "#app-root", "view": "web.modules.home", "viewId": "v_abc" }
|
|
21
|
+
* </script>
|
|
22
|
+
*
|
|
23
|
+
* viewId của layout chain được đọc từ APP_CONFIGS.view.ssrData khi server có
|
|
24
|
+
* cung cấp; DOM marker chỉ là fallback tương thích cho output cũ.
|
|
25
|
+
* Trả null nếu không phải trang server-rendered → CSR boot bình thường.
|
|
26
|
+
*/
|
|
27
|
+
export function readSSRBoot(): SSRBootInfo | null {
|
|
28
|
+
if (typeof document === 'undefined') return null;
|
|
29
|
+
const el = document.querySelector('script[type="application/json"][data-ref="saola-ssr"]');
|
|
30
|
+
if (!el || !el.textContent) return null;
|
|
31
|
+
try {
|
|
32
|
+
const info = JSON.parse(el.textContent);
|
|
33
|
+
if (info && typeof info.view === 'string' && typeof info.viewId === 'string') {
|
|
34
|
+
return {
|
|
35
|
+
view: info.view,
|
|
36
|
+
viewId: info.viewId,
|
|
37
|
+
container: typeof info.container === 'string' ? info.container : undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.warn('[Bootstrap] SSR boot JSON không hợp lệ:', e);
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Đọc boot config server nhúng qua `window.APP_CONFIGS` (contract server hiện tại)
|
|
48
|
+
* và map về shape config của client (`{ view, router, api }`).
|
|
49
|
+
*
|
|
50
|
+
* Server (`_system/page/end.blade.php`) đã emit:
|
|
51
|
+
* window.APP_CONFIGS = {
|
|
52
|
+
* container: '#app-root',
|
|
53
|
+
* router: { mode, base, allRoutes: [{name,path,params,component}], ... },
|
|
54
|
+
* ...
|
|
55
|
+
* }
|
|
56
|
+
* `allRoutes` đã đúng shape `Router.addRoutes` cần ({path, component}).
|
|
57
|
+
*
|
|
58
|
+
* Trả null nếu không có APP_CONFIGS (→ app tự truyền config cho App.start).
|
|
59
|
+
*/
|
|
60
|
+
export function readBootConfig(): Record<string, any> | null {
|
|
61
|
+
if (typeof window === 'undefined') return null;
|
|
62
|
+
const cfg = (window as any).APP_CONFIGS;
|
|
63
|
+
if (!cfg || typeof cfg !== 'object') return null;
|
|
64
|
+
|
|
65
|
+
const out: Record<string, any> = {};
|
|
66
|
+
if (cfg.i18n && typeof cfg.i18n === "object") out.i18n = cfg.i18n;
|
|
67
|
+
|
|
68
|
+
// view.systemData (server: __layout__/__base__/__page__/...) PHẢI tới được
|
|
69
|
+
// ViewManager: compiled factory destructure `__layout__` từ systemData để
|
|
70
|
+
// resolve superView (`${__layout__+"base"}`). Thiếu → 'undefinedbase' →
|
|
71
|
+
// "View not found in registry" + page render() trả rỗng.
|
|
72
|
+
const view: Record<string, any> = {};
|
|
73
|
+
if (typeof cfg.container === 'string') {
|
|
74
|
+
view.container = cfg.container;
|
|
75
|
+
}
|
|
76
|
+
if (typeof cfg.view?.dataEndpoint === 'string') view.dataEndpoint = cfg.view.dataEndpoint;
|
|
77
|
+
if (cfg.view?.fetchOptions && typeof cfg.view.fetchOptions === 'object') view.fetchOptions = cfg.view.fetchOptions;
|
|
78
|
+
if (cfg.api && typeof cfg.api === 'object') out.api = cfg.api;
|
|
79
|
+
|
|
80
|
+
if (cfg.view?.systemData && typeof cfg.view.systemData === 'object') {
|
|
81
|
+
view.systemData = cfg.view.systemData;
|
|
82
|
+
}
|
|
83
|
+
if (typeof cfg.view?.revision === 'string') {
|
|
84
|
+
view.revision = cfg.view.revision;
|
|
85
|
+
}
|
|
86
|
+
if (typeof cfg.view?.contextViews === 'string') {
|
|
87
|
+
view.contextViews = cfg.view.contextViews;
|
|
88
|
+
}
|
|
89
|
+
if (cfg.view?.ssrData && typeof cfg.view.ssrData === 'object') {
|
|
90
|
+
view.ssrData = cfg.view.ssrData;
|
|
91
|
+
}
|
|
92
|
+
if (Object.keys(view).length > 0) {
|
|
93
|
+
out.view = view;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Danh sách bundle nạp rời (theme…) — server là chỗ DUY NHẤT biết theme nào
|
|
97
|
+
// đang bật, nên client không đoán đường dẫn. Xem EXTENSION_ARCHITECTURE §8.
|
|
98
|
+
if (Array.isArray(cfg.bundles)) {
|
|
99
|
+
out.bundles = cfg.bundles.filter((u: unknown) => typeof u === 'string' && u !== '');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const routes = cfg.router?.allRoutes ?? cfg.router?.routes;
|
|
103
|
+
if (Array.isArray(routes)) {
|
|
104
|
+
out.router = {
|
|
105
|
+
mode: cfg.router?.mode ?? 'history',
|
|
106
|
+
base: cfg.router?.base,
|
|
107
|
+
defaultRoute: cfg.router?.defaultRoute,
|
|
108
|
+
routes,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Merge nông 2 tầng config boot (base) với config app truyền (override).
|
|
117
|
+
* Per top-level key (view/router/api): nếu cả hai là object thì merge nông,
|
|
118
|
+
* ngược lại override thắng. Dùng để config app truyền có ưu tiên hơn boot.
|
|
119
|
+
*/
|
|
120
|
+
export function mergeBootConfig(
|
|
121
|
+
base: Record<string, any>,
|
|
122
|
+
override: Record<string, any>
|
|
123
|
+
): Record<string, any> {
|
|
124
|
+
const out: Record<string, any> = { ...base };
|
|
125
|
+
for (const key of Object.keys(override)) {
|
|
126
|
+
const b = out[key];
|
|
127
|
+
const o = override[key];
|
|
128
|
+
if (b && o && typeof b === 'object' && typeof o === 'object'
|
|
129
|
+
&& !Array.isArray(b) && !Array.isArray(o)) {
|
|
130
|
+
out[key] = { ...b, ...o };
|
|
131
|
+
} else {
|
|
132
|
+
out[key] = o;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
}
|
package/src/core/cache/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { ViewCache } from './ViewCache';
|
|
1
|
+
export { ViewCache } from './ViewCache.js';
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// ─── Application Interface ───────────────────────────────────────
|
|
2
2
|
|
|
3
|
-
import { RouterInterface, ViewManagerInterface } from "./utils";
|
|
4
|
-
import type { HelperInterface } from "./HelperInterface";
|
|
5
|
-
import type { EventServiceInterface } from "./EventServiceInterface";
|
|
6
|
-
import type { HttpServiceInterface } from "./HttpServiceInterface";
|
|
7
|
-
import type { StoreServiceInterface } from "./StoreServiceInterface";
|
|
8
|
-
import type { StorageServiceInterface } from "./StorageServiceInterface";
|
|
9
|
-
import type { LoggerServiceInterface } from "./LoggerServiceInterface";
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
3
|
+
import { RouterInterface, ViewManagerInterface } from "./utils.js";
|
|
4
|
+
import type { HelperInterface } from "./HelperInterface.js";
|
|
5
|
+
import type { EventServiceInterface } from "./EventServiceInterface.js";
|
|
6
|
+
import type { HttpServiceInterface } from "./HttpServiceInterface.js";
|
|
7
|
+
import type { StoreServiceInterface } from "./StoreServiceInterface.js";
|
|
8
|
+
import type { StorageServiceInterface } from "./StorageServiceInterface.js";
|
|
9
|
+
import type { LoggerServiceInterface } from "./LoggerServiceInterface.js";
|
|
10
|
+
import type { HeadServiceInterface } from "./HeadServiceInterface.js";
|
|
11
|
+
import { APIClientInterface } from "./ApiInterface.js";
|
|
12
|
+
import type { ServiceProviderInterface } from "./ServiceProviderInterface.js";
|
|
13
|
+
import { SaoObjectType } from "../types/utils.js";
|
|
13
14
|
|
|
14
15
|
export interface ApplicationInterface {
|
|
15
16
|
[key: string]: any;
|
|
@@ -30,7 +31,7 @@ export interface ApplicationInterface {
|
|
|
30
31
|
setMethod(name: string, method: Function, isOne?: boolean): void;
|
|
31
32
|
get<T = any>(name: string): T;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
saoType?: SaoObjectType;
|
|
34
35
|
|
|
35
36
|
// Service properties — set during bootstrap via App.set()
|
|
36
37
|
isInitialized: boolean;
|
|
@@ -44,6 +45,7 @@ export interface ApplicationInterface {
|
|
|
44
45
|
Store: StoreServiceInterface;
|
|
45
46
|
Storage: StorageServiceInterface;
|
|
46
47
|
Logger: LoggerServiceInterface;
|
|
48
|
+
Head: HeadServiceInterface;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
// ─── App Factory (helper function type) ─────────────────────────
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ViewControllerInterface } from "./ViewControllerInterface";
|
|
3
|
-
import type { HtmlInterface, FragmentInterface,
|
|
4
|
-
import { InitMode } from "./common";
|
|
1
|
+
import type { SaoObjectType } from "../types/utils.js";
|
|
2
|
+
import type { ViewControllerInterface } from "./ViewControllerInterface.js";
|
|
3
|
+
import type { HtmlInterface, FragmentInterface, SaoChildrenFactoryOutput, SaoNodeInterface } from "./ElementInterface.js";
|
|
4
|
+
import { InitMode } from "./common.js";
|
|
5
5
|
|
|
6
6
|
// ─── Block / Layout Interfaces ───────────────────────────────────
|
|
7
7
|
export type BlockConstructorParams = {
|
|
@@ -13,7 +13,7 @@ export type BlockConstructorParams = {
|
|
|
13
13
|
initMode?: InitMode;
|
|
14
14
|
};
|
|
15
15
|
export interface BlockInterface {
|
|
16
|
-
|
|
16
|
+
saoType: SaoObjectType;
|
|
17
17
|
/** Unique block slot name (e.g. 'content', 'sidebar') */
|
|
18
18
|
name: string;
|
|
19
19
|
id: string;
|
|
@@ -24,30 +24,30 @@ export interface BlockInterface {
|
|
|
24
24
|
fragment: FragmentInterface | null;
|
|
25
25
|
parentElement: HtmlInterface | null;
|
|
26
26
|
domChildren: Node[];
|
|
27
|
-
|
|
27
|
+
isSaoElement: boolean;
|
|
28
28
|
isOneBlock: boolean;
|
|
29
29
|
initMode?: InitMode;
|
|
30
|
-
|
|
30
|
+
/** Initialize the block (e.g. during hydration) */
|
|
31
31
|
init(): void;
|
|
32
|
-
|
|
32
|
+
/** Render the block's content into the parent element */
|
|
33
33
|
render(): void;
|
|
34
|
-
|
|
34
|
+
/** Mount the block's content into the DOM, finding matching outlets */
|
|
35
35
|
mount(mountCtx: ViewControllerInterface, parentElement: HtmlInterface): any;
|
|
36
|
-
|
|
36
|
+
/** Unmount the block's content from the DOM */
|
|
37
37
|
unmount(): void;
|
|
38
|
-
|
|
38
|
+
/** Destroy the block and clean up resources */
|
|
39
39
|
destroy(): void;
|
|
40
|
-
|
|
40
|
+
/** Update the block's content (e.g. on state change) */
|
|
41
41
|
update(): void;
|
|
42
|
-
|
|
42
|
+
/** Set the block's parent element (used for mounting) */
|
|
43
43
|
setParentElement(parentElement: HtmlInterface | null): void;
|
|
44
44
|
|
|
45
45
|
contentRenderFactory: BlockRenderFactory | null;
|
|
46
46
|
// new(params: BlockConstructorParams, ...args: any[]): BlockInterface;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export interface BlockOutletInterface extends
|
|
50
|
-
|
|
49
|
+
export interface BlockOutletInterface extends SaoNodeInterface {
|
|
50
|
+
saoType: SaoObjectType;
|
|
51
51
|
id: string;
|
|
52
52
|
name: string;
|
|
53
53
|
parent: HtmlInterface | null;
|
|
@@ -56,9 +56,9 @@ export interface BlockOutletInterface extends OneNodeInterface {
|
|
|
56
56
|
parentElement: HtmlInterface | null;
|
|
57
57
|
ctx: ViewControllerInterface;
|
|
58
58
|
initMode: InitMode;
|
|
59
|
-
|
|
59
|
+
isSaoElement: boolean;
|
|
60
60
|
isOneBlockOutlet: boolean;
|
|
61
|
-
|
|
61
|
+
/** Render the outlet's markers into the parent element */
|
|
62
62
|
render(): any;
|
|
63
63
|
hydrate(): any;
|
|
64
64
|
destroy(): any;
|
|
@@ -73,4 +73,4 @@ export interface BlockManagerInterface {
|
|
|
73
73
|
|
|
74
74
|
// ─── Block Types ────────────────────────────────────────────────
|
|
75
75
|
|
|
76
|
-
export type BlockRenderFactory = (parentElement: HtmlInterface) =>
|
|
76
|
+
export type BlockRenderFactory = (parentElement: HtmlInterface) => SaoChildrenFactoryOutput;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ApplicationInterface } from "./ApplicationInterface.js";
|
|
2
|
+
import type { ServiceProviderInterface } from "./ServiceProviderInterface.js";
|
|
3
|
+
|
|
4
|
+
/** Factory view mà registry nhận: đồng bộ, hoặc lazy trả Promise<module>. */
|
|
5
|
+
export type ViewFactory = ((...args: any[]) => any) | (() => Promise<any>);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Manifest của một bundle nạp rời (theme, gói mở rộng).
|
|
9
|
+
*
|
|
10
|
+
* Cùng MỘT hình dạng cho mọi loại bundle: file chỉ có view thì điền `views`,
|
|
11
|
+
* file chỉ có code thì điền `providers`/`services`. Hai shape khác nhau = hai
|
|
12
|
+
* nhánh loader = hai chỗ để lệch.
|
|
13
|
+
*/
|
|
14
|
+
export interface SaolaBundle {
|
|
15
|
+
/** Định danh, dùng để báo lỗi và bắt trùng tên. */
|
|
16
|
+
name?: string;
|
|
17
|
+
/** Provider của bundle — class hoặc instance, đưa thẳng vào resolveProviderOrder. */
|
|
18
|
+
providers?: any[];
|
|
19
|
+
/** { Tên: Class | instance | object } → App.set(tên, …). */
|
|
20
|
+
services?: Record<string, any>;
|
|
21
|
+
/** { tên: fn } → gộp vào App.Helper. */
|
|
22
|
+
helpers?: Record<string, any>;
|
|
23
|
+
/** { 'dot.path': factory } → View.setViewRegistry(). Nạp sau ĐÈ nạp trước. */
|
|
24
|
+
views?: Record<string, ViewFactory>;
|
|
25
|
+
/** Chạy sau khi mọi bundle đã merge và App đã init. */
|
|
26
|
+
boot?(app: ApplicationInterface): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Kết quả gộp nhiều bundle, theo đúng thứ tự mảng URL. */
|
|
30
|
+
export interface MergedBundles {
|
|
31
|
+
providers: (ServiceProviderInterface | any)[];
|
|
32
|
+
services: Record<string, any>;
|
|
33
|
+
helpers: Record<string, any>;
|
|
34
|
+
views: Record<string, ViewFactory>;
|
|
35
|
+
boots: Array<(app: ApplicationInterface) => void>;
|
|
36
|
+
/** Tên (hoặc URL) của bundle đã nạp được. */
|
|
37
|
+
loaded: string[];
|
|
38
|
+
/** [url, thông điệp lỗi] — nạp hỏng thì bỏ qua, KHÔNG làm sập boot. */
|
|
39
|
+
failed: Array<[string, string]>;
|
|
40
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ViewControllerInterface } from "./ViewControllerInterface";
|
|
3
|
-
import type { ViewInterface } from "./ViewInterface";
|
|
4
|
-
import type { HtmlInterface } from "./ElementInterface";
|
|
1
|
+
import type { SaoObjectType } from "../types/utils.js";
|
|
2
|
+
import type { ViewControllerInterface } from "./ViewControllerInterface.js";
|
|
3
|
+
import type { ViewInterface } from "./ViewInterface.js";
|
|
4
|
+
import type { HtmlInterface } from "./ElementInterface.js";
|
|
5
5
|
|
|
6
6
|
// ─── Component Interface ─────────────────────────────────────────
|
|
7
7
|
|
|
8
8
|
export interface ComponentInterface {
|
|
9
|
-
|
|
9
|
+
saoType: SaoObjectType;
|
|
10
10
|
id: string;
|
|
11
11
|
ctx: ViewControllerInterface;
|
|
12
12
|
viewRef: ViewInterface | null;
|
|
@@ -15,12 +15,13 @@ export interface ComponentInterface {
|
|
|
15
15
|
openTag: Comment;
|
|
16
16
|
closeTag: Comment;
|
|
17
17
|
stateKeys: string[];
|
|
18
|
+
listeners: Record<string, (...args: any[]) => any>;
|
|
18
19
|
subscribeFn: () => void;
|
|
19
20
|
unsubscribeFn: () => void;
|
|
20
21
|
render(): void;
|
|
21
22
|
destroy(): void;
|
|
22
23
|
setParent(parent: HtmlInterface | null): void;
|
|
23
|
-
|
|
24
|
+
isSaoElement: boolean;
|
|
24
25
|
isOneComponent: boolean;
|
|
25
26
|
[key: string]: any;
|
|
26
27
|
}
|
|
@@ -1,39 +1,45 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ViewControllerInterface } from "./ViewControllerInterface";
|
|
3
|
-
import type { ReactiveInterface } from "./ReactiveInterface";
|
|
1
|
+
import type { SaoObjectType } from "../types/utils.js";
|
|
2
|
+
import type { ViewControllerInterface } from "./ViewControllerInterface.js";
|
|
3
|
+
import type { ReactiveInterface } from "./ReactiveInterface.js";
|
|
4
4
|
|
|
5
5
|
// ─── Element Interfaces ──────────────────────────────────────────
|
|
6
6
|
|
|
7
7
|
/** Base for any renderable node in the tree */
|
|
8
|
-
export interface
|
|
9
|
-
|
|
8
|
+
export interface SaoNodeInterface {
|
|
9
|
+
saoType: SaoObjectType;
|
|
10
10
|
parent: HtmlInterface | null;
|
|
11
11
|
render(): void;
|
|
12
12
|
destroy(): void;
|
|
13
|
-
|
|
13
|
+
isSaoElement: boolean;
|
|
14
14
|
setParentElement(parent: HtmlInterface | null): void;
|
|
15
15
|
[key: string]: any;
|
|
16
16
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/** Native HTML element wrapper */
|
|
20
|
-
export interface HtmlInterface extends
|
|
20
|
+
export interface HtmlInterface extends SaoNodeInterface {
|
|
21
21
|
element: HTMLElement;
|
|
22
22
|
domChildren: Node[];
|
|
23
23
|
[key: string]: any;
|
|
24
|
+
clearHTML(): void;
|
|
25
|
+
appendElement(element: HTMLElement | Comment | Text): void;
|
|
26
|
+
getElement(): HTMLElement;
|
|
27
|
+
renderChildren(): SaoElementChildren;
|
|
28
|
+
render(): HTMLElement;
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
/** Text node wrapper */
|
|
27
|
-
export interface TextInterface extends
|
|
32
|
+
export interface TextInterface extends SaoNodeInterface {
|
|
28
33
|
element: Text;
|
|
29
34
|
text: string;
|
|
30
35
|
|
|
31
36
|
|
|
32
37
|
domChildren: Node[];
|
|
33
38
|
update(newText: string): void;
|
|
39
|
+
render(): HTMLElement | Text | Comment;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
export interface OutputInterface extends
|
|
42
|
+
export interface OutputInterface extends SaoNodeInterface {
|
|
37
43
|
ctx: ViewControllerInterface;
|
|
38
44
|
parent: HtmlInterface | null;
|
|
39
45
|
stateKeys: string[];
|
|
@@ -43,12 +49,11 @@ export interface OutputInterface extends OneNodeInterface {
|
|
|
43
49
|
[key: string]: any;
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
export interface YieldInterface extends
|
|
52
|
+
export interface YieldInterface extends SaoNodeInterface {
|
|
47
53
|
ctx: ViewControllerInterface;
|
|
48
54
|
parent: HtmlInterface | null;
|
|
49
55
|
name: string;
|
|
50
|
-
|
|
51
|
-
setContentFactory(factory: () => OneChildrenFactoryOutput): void;
|
|
56
|
+
defaultValue: string;
|
|
52
57
|
openTag: Comment;
|
|
53
58
|
closeTag: Comment;
|
|
54
59
|
domChildren: Node[];
|
|
@@ -56,40 +61,84 @@ export interface YieldInterface extends OneNodeInterface {
|
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
/** Fragment — renders multiple root nodes into a parent without a wrapping tag */
|
|
59
|
-
export interface FragmentInterface extends
|
|
64
|
+
export interface FragmentInterface extends SaoNodeInterface {
|
|
60
65
|
nodes: Node[];
|
|
61
66
|
domChildren: Node[];
|
|
62
67
|
[key: string]: any;
|
|
63
68
|
|
|
64
69
|
}
|
|
65
70
|
/** Wrapper — renders multiple root nodes into a parent without a wrapping tag */
|
|
66
|
-
export interface WrapperInterface extends
|
|
71
|
+
export interface WrapperInterface extends SaoNodeInterface {
|
|
67
72
|
nodes: Node[];
|
|
68
73
|
domChildren: Node[];
|
|
69
74
|
[key: string]: any;
|
|
75
|
+
/** Render — chạy childrenFactory, trả về danh sách children đã tạo. */
|
|
76
|
+
render(): SaoElementChildren;
|
|
77
|
+
appendTo(parent: HtmlInterface): void;
|
|
78
|
+
mountTo(parent: HtmlInterface): void;
|
|
79
|
+
clear(): void;
|
|
80
|
+
setChildrenFactory(factory: SaoChildrenFactory): void;
|
|
81
|
+
children: SaoElementChildren;
|
|
82
|
+
openTag: Comment;
|
|
83
|
+
closeTag: Comment;
|
|
84
|
+
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
// ─── Element Config Types ────────────────────────────────────────
|
|
73
88
|
|
|
74
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Contract chuẩn (RUNTIME_CONTRACT.md §1.1): type = 'static' | 'binding'.
|
|
91
|
+
* 'value' giữ làm legacy alias của 'static' đến v0.2.
|
|
92
|
+
*/
|
|
93
|
+
export type BindingConfigType = 'static' | 'binding' | 'value';
|
|
94
|
+
|
|
95
|
+
export type SaoElementConfig = {
|
|
96
|
+
/** Marker-free content for HTML RCDATA elements (textarea/title). */
|
|
97
|
+
content?: {
|
|
98
|
+
factory: () => any;
|
|
99
|
+
stateKeys?: string[];
|
|
100
|
+
},
|
|
75
101
|
attrs?: {
|
|
76
102
|
[key: string]: {
|
|
77
|
-
type:
|
|
103
|
+
type: BindingConfigType;
|
|
78
104
|
value?: any;
|
|
79
105
|
stateKeys?: string[];
|
|
80
106
|
factory?: () => any;
|
|
107
|
+
/** `@yield(name, ...)` used as the whole attribute value — no static stateKeys
|
|
108
|
+
* (the section it resolves to is only known at runtime), so Html subscribes to
|
|
109
|
+
* SectionManager by name instead. */
|
|
110
|
+
yieldName?: string;
|
|
81
111
|
}
|
|
82
112
|
},
|
|
83
113
|
props?: {
|
|
84
114
|
[key: string]: {
|
|
85
|
-
type:
|
|
115
|
+
type: BindingConfigType;
|
|
86
116
|
value?: any;
|
|
87
117
|
stateKeys?: string[];
|
|
88
118
|
factory?: () => any;
|
|
89
119
|
}
|
|
90
120
|
},
|
|
91
121
|
events?: {
|
|
92
|
-
[key: string]:
|
|
122
|
+
[key: string]: SaoElementEventHandler;
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* `@click.prevent.stop(...)` — bucket RIÊNG cạnh `events` để shape
|
|
126
|
+
* `events: {click: [...]}` (contract sẵn có) không đổi; view compile trước
|
|
127
|
+
* khi có modifier không có key này và chạy y nguyên.
|
|
128
|
+
*/
|
|
129
|
+
eventModifiers?: {
|
|
130
|
+
[key: string]: EventModifier[];
|
|
131
|
+
},
|
|
132
|
+
/** `@bind(key)`/`@val(key)` — two-way binding, own bucket (sibling of attrs/props/events). */
|
|
133
|
+
bind?: {
|
|
134
|
+
key: string;
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
* `@transition('fade')` — tiền tố class enter/leave (`fade-enter-from`, ...).
|
|
138
|
+
* Bucket riêng như `bind`/`eventModifiers`; vắng mặt = hành vi cũ y nguyên.
|
|
139
|
+
*/
|
|
140
|
+
transition?: {
|
|
141
|
+
name: string;
|
|
93
142
|
},
|
|
94
143
|
classes?: {
|
|
95
144
|
[className: string]: {
|
|
@@ -99,14 +148,15 @@ export type OneElementConfig = {
|
|
|
99
148
|
factory?: () => boolean;
|
|
100
149
|
}
|
|
101
150
|
} | Array<{
|
|
102
|
-
|
|
151
|
+
/** 'dynamic' = factory trả về TÊN class (`class="language-{{ lang }}"`), không có `value`. */
|
|
152
|
+
type: 'static' | 'binding' | 'dynamic';
|
|
103
153
|
value?: string;
|
|
104
154
|
stateKeys?: string[];
|
|
105
|
-
factory?: () => boolean;
|
|
155
|
+
factory?: () => boolean | string;
|
|
106
156
|
}>,
|
|
107
157
|
styles?: {
|
|
108
158
|
[prop: string]: {
|
|
109
|
-
type:
|
|
159
|
+
type: BindingConfigType;
|
|
110
160
|
value?: string;
|
|
111
161
|
stateKeys?: string[];
|
|
112
162
|
factory?: () => string;
|
|
@@ -115,7 +165,7 @@ export type OneElementConfig = {
|
|
|
115
165
|
[key: string]: any;
|
|
116
166
|
}
|
|
117
167
|
|
|
118
|
-
export type HtmlElementConfig =
|
|
168
|
+
export type HtmlElementConfig = SaoElementConfig & {
|
|
119
169
|
ctx: ViewControllerInterface;
|
|
120
170
|
parentElement?: HtmlInterface | null;
|
|
121
171
|
parent?: HtmlInterface | null;
|
|
@@ -123,18 +173,36 @@ export type HtmlElementConfig = OneElementConfig & {
|
|
|
123
173
|
|
|
124
174
|
// ─── Event Handler ──────────────────────────────────────────────
|
|
125
175
|
|
|
126
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Modifier của `@click.prevent.stop(...)`. Phải khớp `EVENT_MODIFIERS` trong
|
|
178
|
+
* `compiler/src/sao2js/template_ast.py` — compiler chỉ emit tên trong tập đó.
|
|
179
|
+
*/
|
|
180
|
+
export type EventModifier = 'prevent' | 'stop' | 'self' | 'once';
|
|
181
|
+
|
|
182
|
+
export type SaoElementEventHandler = Array<{
|
|
127
183
|
handler: string | ((event: Event) => any);
|
|
128
184
|
params?: (any | ((event: Event) => any[]))[];
|
|
129
185
|
} | ((event: Event) => any)>;
|
|
130
186
|
|
|
187
|
+
export type SaoElement = WrapperInterface | HtmlInterface | ReactiveInterface | TextInterface | FragmentInterface;
|
|
188
|
+
export type DOMElement = HTMLElement | SVGElement | DocumentFragment | Text | Comment;
|
|
131
189
|
// ─── Children Types ─────────────────────────────────────────────
|
|
132
190
|
|
|
133
191
|
/** All possible rendered child node types */
|
|
134
|
-
export type
|
|
192
|
+
export type SaoElementChildren = Array<SaoElement | SaoNodeInterface | DOMElement>;
|
|
135
193
|
|
|
136
|
-
/** What a children factory can return (before mounting)
|
|
137
|
-
|
|
194
|
+
/** What a children factory can return (before mounting).
|
|
195
|
+
* SaoNodeInterface bao phủ các marker-based element (Output, Component, Block...)
|
|
196
|
+
* mà compiled output vẫn trả về trong children factories. */
|
|
197
|
+
export type SaoChildrenFactoryOutput = Array<SaoElement | SaoNodeInterface | DOMElement | string | number | null | undefined>;
|
|
138
198
|
|
|
139
199
|
/** Factory function that produces children given parent element */
|
|
140
|
-
export type
|
|
200
|
+
export type SaoChildrenFactory = (parentElement: HtmlInterface | null) => SaoChildrenFactoryOutput;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Lazy payload passed from a parent component to one ChildrenNode placeholder.
|
|
204
|
+
* A factory is deliberately not executed while component data is resolved; the
|
|
205
|
+
* child view invokes it only when its render traversal reaches the placeholder.
|
|
206
|
+
*/
|
|
207
|
+
export type SaoChildrenSlotFactory = SaoChildrenFactory;
|
|
208
|
+
export type SaoChildrenSlotContent = SaoChildrenSlotFactory | string | number | null | undefined;
|