sygnal 5.3.7 → 6.0.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/CHANGELOG.md +646 -0
- package/README.md +77 -47
- package/dist/astro/client.cjs.js +33 -8114
- package/dist/astro/client.cjs.js.map +1 -0
- package/dist/astro/client.mjs +33 -8114
- package/dist/astro/client.mjs.map +1 -0
- package/dist/astro/index.cjs.js +1039 -9
- package/dist/astro/index.cjs.js.map +1 -0
- package/dist/astro/index.mjs +1038 -9
- package/dist/astro/index.mjs.map +1 -0
- package/dist/astro/server.cjs.js +3400 -166
- package/dist/astro/server.cjs.js.map +1 -0
- package/dist/astro/server.mjs +3400 -166
- package/dist/astro/server.mjs.map +1 -0
- package/dist/devtools.cjs.js +1431 -0
- package/dist/devtools.cjs.js.map +1 -0
- package/dist/devtools.esm.js +1419 -0
- package/dist/devtools.esm.js.map +1 -0
- package/dist/diagnostics.cjs.js +4033 -0
- package/dist/diagnostics.cjs.js.map +1 -0
- package/dist/diagnostics.esm.js +4003 -0
- package/dist/diagnostics.esm.js.map +1 -0
- package/dist/element.cjs.js +230 -0
- package/dist/element.cjs.js.map +1 -0
- package/dist/element.esm.js +228 -0
- package/dist/element.esm.js.map +1 -0
- package/dist/guide/accessibility.md +257 -0
- package/dist/guide/adapters.md +221 -0
- package/dist/guide/behaviors.md +312 -0
- package/dist/guide/browser-sources.md +203 -0
- package/dist/guide/drag-and-drop.md +342 -0
- package/dist/guide/element-commands.md +306 -0
- package/dist/guide/error-boundaries.md +169 -0
- package/dist/guide/forms-reference.md +381 -0
- package/dist/guide/forms.md +250 -0
- package/dist/guide/http.md +299 -0
- package/dist/guide/inputs.md +173 -0
- package/dist/guide/persistence.md +245 -0
- package/dist/guide/recipes/carousel.md +155 -0
- package/dist/guide/recipes/charts.md +177 -0
- package/dist/guide/recipes/code-editor.md +135 -0
- package/dist/guide/recipes/data-grid.md +155 -0
- package/dist/guide/recipes/data-table.md +196 -0
- package/dist/guide/recipes/i18n.md +222 -0
- package/dist/guide/recipes/icons.md +115 -0
- package/dist/guide/recipes/overview.md +33 -0
- package/dist/guide/recipes/rich-text.md +154 -0
- package/dist/guide/resources.md +471 -0
- package/dist/guide/ssr.md +255 -0
- package/dist/guide/timers.md +178 -0
- package/dist/guide/ui/accordion.md +93 -0
- package/dist/guide/ui/combobox.md +144 -0
- package/dist/guide/ui/dialog.md +124 -0
- package/dist/guide/ui/disclosure.md +60 -0
- package/dist/guide/ui/menu.md +125 -0
- package/dist/guide/ui/overview.md +166 -0
- package/dist/guide/ui/popover.md +101 -0
- package/dist/guide/ui/select.md +114 -0
- package/dist/guide/ui/tabs.md +161 -0
- package/dist/guide/ui/toaster.md +152 -0
- package/dist/guide/ui/tooltip.md +103 -0
- package/dist/guide/undo.md +178 -0
- package/dist/guide/virtual-collections.md +183 -0
- package/dist/guide/web-components.md +179 -0
- package/dist/guide/widgets.md +217 -0
- package/dist/index.cjs.js +15283 -6279
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +3739 -370
- package/dist/index.esm.js +15230 -6274
- package/dist/index.esm.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs.js +27 -329
- package/dist/jsx-dev-runtime.cjs.js.map +1 -0
- package/dist/jsx-dev-runtime.esm.js +20 -322
- package/dist/jsx-dev-runtime.esm.js.map +1 -0
- package/dist/jsx-runtime.cjs.js +27 -329
- package/dist/jsx-runtime.cjs.js.map +1 -0
- package/dist/jsx-runtime.esm.js +20 -322
- package/dist/jsx-runtime.esm.js.map +1 -0
- package/dist/jsx.cjs.js +11 -309
- package/dist/jsx.cjs.js.map +1 -0
- package/dist/jsx.esm.js +9 -310
- package/dist/jsx.esm.js.map +1 -0
- package/dist/react.cjs.js +117 -0
- package/dist/react.cjs.js.map +1 -0
- package/dist/react.esm.js +115 -0
- package/dist/react.esm.js.map +1 -0
- package/dist/shims/globalthis.cjs +20 -0
- package/dist/sygnal.min.js +2 -1
- package/dist/sygnal.min.js.map +1 -0
- package/dist/ui-combobox.cjs.js +169 -0
- package/dist/ui-combobox.cjs.js.map +1 -0
- package/dist/ui-combobox.esm.js +148 -0
- package/dist/ui-combobox.esm.js.map +1 -0
- package/dist/ui-menu.cjs.js +87 -0
- package/dist/ui-menu.cjs.js.map +1 -0
- package/dist/ui-menu.esm.js +66 -0
- package/dist/ui-menu.esm.js.map +1 -0
- package/dist/ui-select.cjs.js +104 -0
- package/dist/ui-select.cjs.js.map +1 -0
- package/dist/ui-select.esm.js +83 -0
- package/dist/ui-select.esm.js.map +1 -0
- package/dist/ui.cjs.js +738 -0
- package/dist/ui.cjs.js.map +1 -0
- package/dist/ui.esm.js +727 -0
- package/dist/ui.esm.js.map +1 -0
- package/dist/vike/ClientOnly.cjs.js +5 -14
- package/dist/vike/ClientOnly.cjs.js.map +1 -0
- package/dist/vike/ClientOnly.mjs +5 -14
- package/dist/vike/ClientOnly.mjs.map +1 -0
- package/dist/vike/{+config.js → config/+config.js} +10 -1
- package/dist/vike/config/+config.js.map +1 -0
- package/dist/vike/config/package.json +6 -0
- package/dist/vike/onRenderClient.cjs.js +166 -95
- package/dist/vike/onRenderClient.cjs.js.map +1 -0
- package/dist/vike/onRenderClient.mjs +166 -95
- package/dist/vike/onRenderClient.mjs.map +1 -0
- package/dist/vike/onRenderHtml.cjs.js +60 -24
- package/dist/vike/onRenderHtml.cjs.js.map +1 -0
- package/dist/vike/onRenderHtml.mjs +61 -25
- package/dist/vike/onRenderHtml.mjs.map +1 -0
- package/dist/vite/plugin.cjs.js +926 -65
- package/dist/vite/plugin.cjs.js.map +1 -0
- package/dist/vite/plugin.mjs +925 -65
- package/dist/vite/plugin.mjs.map +1 -0
- package/dist/zag.cjs.js +408 -0
- package/dist/zag.cjs.js.map +1 -0
- package/dist/zag.esm.js +405 -0
- package/dist/zag.esm.js.map +1 -0
- package/llms.txt +313 -0
- package/package.json +109 -16
- package/src/astro/client.ts +40 -18
- package/src/astro/index.d.ts +48 -1
- package/src/astro/index.ts +106 -9
- package/src/astro/server.ts +11 -3
- package/src/collection.ts +6 -90
- package/src/core/actions.ts +134 -0
- package/src/core/cell.ts +202 -0
- package/src/core/debug.ts +23 -0
- package/src/core/define.ts +242 -0
- package/src/core/hooks.ts +314 -0
- package/src/core/hosts/collection.ts +325 -0
- package/src/core/hosts/switchable.ts +146 -0
- package/src/core/instance.ts +592 -0
- package/src/core/markers/clientonly.ts +13 -0
- package/src/core/markers/lazy.ts +40 -0
- package/src/core/markers/portal.ts +96 -0
- package/src/core/markers/suspense.ts +41 -0
- package/src/core/markers/transition.ts +70 -0
- package/src/core/registry.ts +25 -0
- package/src/core/runtime.ts +573 -0
- package/src/core/statics.ts +104 -0
- package/src/core/teardown.ts +60 -0
- package/src/core/view.ts +37 -0
- package/src/cycle/dom/DocumentDOMSource.ts +13 -8
- package/src/cycle/dom/ElementFinder.ts +7 -9
- package/src/cycle/dom/EventDelegator.ts +174 -223
- package/src/cycle/dom/IsolateModule.ts +65 -35
- package/src/cycle/dom/MainDOMSource.ts +13 -2
- package/src/cycle/dom/PriorityQueue.ts +4 -2
- package/src/cycle/dom/SymbolTree.ts +18 -47
- package/src/cycle/dom/classNameModule.ts +76 -0
- package/src/cycle/dom/controlledInputModule.ts +50 -0
- package/src/cycle/dom/enrichEventStream.ts +29 -45
- package/src/cycle/dom/fragment.ts +7 -0
- package/src/cycle/dom/isolate.ts +30 -27
- package/src/cycle/dom/makeDOMDriver.ts +115 -57
- package/src/cycle/dom/mockDOMSource.ts +83 -9
- package/src/cycle/dom/modules.ts +21 -4
- package/src/cycle/dom/propsModule.ts +65 -0
- package/src/cycle/dom/selectModule.ts +22 -17
- package/src/cycle/dom/snabbdom.ts +1 -6
- package/src/cycle/dom/thunk.ts +3 -0
- package/src/cycle/dom/utils.ts +98 -0
- package/src/cycle/dom/viewTransition.ts +43 -0
- package/src/cycle/state/StateSource.ts +20 -4
- package/src/cycle/state/objIsEqual.ts +50 -0
- package/src/cycle/state/types.ts +0 -10
- package/src/defineComponent.ts +34 -0
- package/src/devtools.d.ts +151 -0
- package/src/devtools.ts +34 -0
- package/src/element.d.ts +59 -0
- package/src/element.ts +235 -0
- package/src/extra/backoff.ts +9 -0
- package/src/extra/behaviors.ts +169 -0
- package/src/extra/browserSignals.ts +23 -0
- package/src/extra/browserSources.ts +326 -0
- package/src/extra/command.ts +3 -3
- package/src/extra/controls.ts +47 -0
- package/src/extra/copyAsTest.ts +286 -0
- package/src/extra/devtools.ts +109 -31
- package/src/extra/devtoolsActions.ts +379 -0
- package/src/extra/devtoolsHook.ts +9 -0
- package/src/extra/devtoolsNext.ts +83 -0
- package/src/extra/diagnostics/checks/actionLog.ts +108 -0
- package/src/extra/diagnostics/checks/behaviors.ts +49 -0
- package/src/extra/diagnostics/checks/browserSources.ts +96 -0
- package/src/extra/diagnostics/checks/collections.ts +67 -0
- package/src/extra/diagnostics/checks/controls.ts +148 -0
- package/src/extra/diagnostics/checks/dataset.ts +57 -0
- package/src/extra/diagnostics/checks/dom.ts +250 -0
- package/src/extra/diagnostics/checks/elementCommands.ts +175 -0
- package/src/extra/diagnostics/checks/events.ts +83 -0
- package/src/extra/diagnostics/checks/fetch.ts +135 -0
- package/src/extra/diagnostics/checks/forms.ts +163 -0
- package/src/extra/diagnostics/checks/index.ts +202 -0
- package/src/extra/diagnostics/checks/inspect.ts +427 -0
- package/src/extra/diagnostics/checks/next.ts +417 -0
- package/src/extra/diagnostics/checks/persist.ts +54 -0
- package/src/extra/diagnostics/checks/props.ts +56 -0
- package/src/extra/diagnostics/checks/public.d.ts +302 -0
- package/src/extra/diagnostics/checks/replies.ts +128 -0
- package/src/extra/diagnostics/checks/router.ts +100 -0
- package/src/extra/diagnostics/checks/rxjsHints.ts +88 -0
- package/src/extra/diagnostics/checks/shared.ts +203 -0
- package/src/extra/diagnostics/checks/shorthand.ts +115 -0
- package/src/extra/diagnostics/checks/sortable.ts +129 -0
- package/src/extra/diagnostics/checks/state.ts +148 -0
- package/src/extra/diagnostics/checks/statics.ts +48 -0
- package/src/extra/diagnostics/checks/strict.ts +55 -0
- package/src/extra/diagnostics/checks/timers.ts +80 -0
- package/src/extra/diagnostics/checks/viewTransitions.ts +47 -0
- package/src/extra/diagnostics/checks/virtual.ts +73 -0
- package/src/extra/diagnostics/checks/widgets.ts +109 -0
- package/src/extra/diagnostics/checks/wiring.ts +121 -0
- package/src/extra/diagnostics/codes.ts +477 -0
- package/src/extra/diagnostics/index.ts +353 -0
- package/src/extra/diagnostics/legacy.ts +76 -0
- package/src/extra/driverFactories.ts +172 -60
- package/src/extra/elementCommands.ts +53 -0
- package/src/extra/eventDriver.ts +4 -0
- package/src/extra/fetchDriver.ts +519 -0
- package/src/extra/flatten.ts +75 -0
- package/src/extra/focusWithin.ts +27 -0
- package/src/extra/form.ts +268 -0
- package/src/extra/formHelpers.ts +139 -0
- package/src/extra/head.ts +106 -0
- package/src/extra/hmr.ts +2 -3
- package/src/extra/owned.ts +24 -0
- package/src/extra/pager.ts +50 -0
- package/src/extra/persist.ts +133 -0
- package/src/extra/pwa.ts +1 -1
- package/src/extra/queryCache.ts +107 -0
- package/src/extra/reducers.ts +13 -6
- package/src/extra/reduxDevtools.ts +92 -0
- package/src/extra/replies.ts +54 -0
- package/src/extra/router.ts +323 -0
- package/src/extra/run.ts +94 -210
- package/src/extra/selection.ts +76 -0
- package/src/extra/socketDriver.ts +265 -0
- package/src/extra/sortable.ts +377 -0
- package/src/extra/ssr.ts +427 -160
- package/src/extra/standardSchema.ts +27 -0
- package/src/extra/testing.ts +3158 -190
- package/src/extra/timers.ts +95 -0
- package/src/extra/undo.ts +261 -0
- package/src/extra/viewTransitions.ts +38 -0
- package/src/extra/virtual.ts +513 -0
- package/src/extra/widget.ts +201 -0
- package/src/extra/xstreamExtras.ts +269 -0
- package/src/index.d.ts +3012 -87
- package/src/index.ts +32 -10
- package/src/jsx-runtime.ts +15 -1
- package/src/jsx.ts +2 -1
- package/src/lazy.ts +50 -7
- package/src/portal.ts +3 -1
- package/src/pragma/index.ts +262 -134
- package/src/react-peers.d.ts +5 -0
- package/src/react.d.ts +43 -0
- package/src/react.ts +110 -0
- package/src/shared.ts +48 -0
- package/src/slot.ts +1 -1
- package/src/suspense.ts +3 -1
- package/src/switchable.ts +6 -119
- package/src/transition.ts +3 -1
- package/src/ui/accordion.ts +64 -0
- package/src/ui/dialog.ts +129 -0
- package/src/ui/disclosure.ts +35 -0
- package/src/ui/popover.ts +45 -0
- package/src/ui/shared.ts +94 -0
- package/src/ui/tabs.ts +82 -0
- package/src/ui/toaster.ts +198 -0
- package/src/ui/tooltip.ts +70 -0
- package/src/ui/zag/combobox.ts +115 -0
- package/src/ui/zag/menu.ts +40 -0
- package/src/ui/zag/select.ts +54 -0
- package/src/ui/zag/shared.ts +43 -0
- package/src/ui-combobox.d.ts +20 -0
- package/src/ui-combobox.ts +6 -0
- package/src/ui-menu.d.ts +30 -0
- package/src/ui-menu.ts +6 -0
- package/src/ui-select.d.ts +17 -0
- package/src/ui-select.ts +6 -0
- package/src/ui-zag-types.d.ts +42 -0
- package/src/ui.d.ts +208 -0
- package/src/ui.ts +15 -0
- package/src/vike/+config.ts +9 -1
- package/src/vike/ClientOnly.ts +1 -1
- package/src/vike/onRenderClient.ts +144 -96
- package/src/vike/onRenderHtml.ts +69 -26
- package/src/vike/types.ts +27 -4
- package/src/vite/globalthis-shim.ts +18 -0
- package/src/vite/globalthis.ts +56 -0
- package/src/vite/plugin.d.ts +114 -2
- package/src/vite/plugin.ts +920 -56
- package/src/zag.d.ts +64 -0
- package/src/zag.ts +238 -0
- package/dist/astro/astro/client.d.ts +0 -5
- package/dist/astro/astro/index.d.ts +0 -16
- package/dist/astro/astro/server.d.ts +0 -12
- package/dist/astro/client.d.ts +0 -5
- package/dist/astro/client.esm.js +0 -4665
- package/dist/astro/collection.d.ts +0 -12
- package/dist/astro/component.d.ts +0 -22
- package/dist/astro/cycle/dom/BodyDOMSource.d.ts +0 -10
- package/dist/astro/cycle/dom/DOMSource.d.ts +0 -11
- package/dist/astro/cycle/dom/DocumentDOMSource.d.ts +0 -12
- package/dist/astro/cycle/dom/ElementFinder.d.ts +0 -8
- package/dist/astro/cycle/dom/EventDelegator.d.ts +0 -34
- package/dist/astro/cycle/dom/IsolateModule.d.ts +0 -23
- package/dist/astro/cycle/dom/MainDOMSource.d.ts +0 -32
- package/dist/astro/cycle/dom/PriorityQueue.d.ts +0 -7
- package/dist/astro/cycle/dom/ScopeChecker.d.ts +0 -9
- package/dist/astro/cycle/dom/SymbolTree.d.ts +0 -9
- package/dist/astro/cycle/dom/VNodeWrapper.d.ts +0 -8
- package/dist/astro/cycle/dom/enrichEventStream.d.ts +0 -24
- package/dist/astro/cycle/dom/fromEvent.d.ts +0 -6
- package/dist/astro/cycle/dom/index.d.ts +0 -8
- package/dist/astro/cycle/dom/isolate.d.ts +0 -9
- package/dist/astro/cycle/dom/makeDOMDriver.d.ts +0 -11
- package/dist/astro/cycle/dom/mockDOMSource.d.ts +0 -17
- package/dist/astro/cycle/dom/modules.d.ts +0 -5
- package/dist/astro/cycle/dom/snabbdom.d.ts +0 -22
- package/dist/astro/cycle/dom/styleModule.d.ts +0 -13
- package/dist/astro/cycle/dom/thunk.d.ts +0 -11
- package/dist/astro/cycle/dom/utils.d.ts +0 -8
- package/dist/astro/cycle/isolate/index.d.ts +0 -42
- package/dist/astro/cycle/run/adapt.d.ts +0 -6
- package/dist/astro/cycle/run/index.d.ts +0 -36
- package/dist/astro/cycle/run/internals.d.ts +0 -8
- package/dist/astro/cycle/run/types.d.ts +0 -49
- package/dist/astro/cycle/state/Collection.d.ts +0 -29
- package/dist/astro/cycle/state/StateSource.d.ts +0 -20
- package/dist/astro/cycle/state/index.d.ts +0 -5
- package/dist/astro/cycle/state/pickCombine.d.ts +0 -3
- package/dist/astro/cycle/state/pickMerge.d.ts +0 -3
- package/dist/astro/cycle/state/types.d.ts +0 -18
- package/dist/astro/cycle/state/withState.d.ts +0 -17
- package/dist/astro/extra/classes.d.ts +0 -7
- package/dist/astro/extra/devtools.d.ts +0 -78
- package/dist/astro/extra/dragDriver.d.ts +0 -20
- package/dist/astro/extra/driverFactories.d.ts +0 -12
- package/dist/astro/extra/eventDriver.d.ts +0 -9
- package/dist/astro/extra/exactState.d.ts +0 -1
- package/dist/astro/extra/hmr.d.ts +0 -17
- package/dist/astro/extra/logDriver.d.ts +0 -2
- package/dist/astro/extra/processDrag.d.ts +0 -19
- package/dist/astro/extra/processForm.d.ts +0 -15
- package/dist/astro/extra/run.d.ts +0 -13
- package/dist/astro/extra/xstreamCompat.d.ts +0 -5
- package/dist/astro/index.d.ts +0 -19
- package/dist/astro/index.esm.js +0 -27
- package/dist/astro/jsx-dev-runtime.d.ts +0 -1
- package/dist/astro/jsx-runtime.d.ts +0 -4
- package/dist/astro/jsx.d.ts +0 -2
- package/dist/astro/pragma/fn.d.ts +0 -7
- package/dist/astro/pragma/index.d.ts +0 -7
- package/dist/astro/pragma/is.d.ts +0 -10
- package/dist/astro/server.d.ts +0 -12
- package/dist/astro/server.esm.js +0 -25
- package/dist/astro/switchable.d.ts +0 -7
- package/dist/collection.d.ts +0 -12
- package/dist/component.d.ts +0 -22
- package/dist/cycle/dom/BodyDOMSource.d.ts +0 -10
- package/dist/cycle/dom/DOMSource.d.ts +0 -11
- package/dist/cycle/dom/DocumentDOMSource.d.ts +0 -12
- package/dist/cycle/dom/ElementFinder.d.ts +0 -8
- package/dist/cycle/dom/EventDelegator.d.ts +0 -34
- package/dist/cycle/dom/IsolateModule.d.ts +0 -23
- package/dist/cycle/dom/MainDOMSource.d.ts +0 -32
- package/dist/cycle/dom/PriorityQueue.d.ts +0 -7
- package/dist/cycle/dom/ScopeChecker.d.ts +0 -9
- package/dist/cycle/dom/SymbolTree.d.ts +0 -9
- package/dist/cycle/dom/VNodeWrapper.d.ts +0 -8
- package/dist/cycle/dom/enrichEventStream.d.ts +0 -24
- package/dist/cycle/dom/fromEvent.d.ts +0 -6
- package/dist/cycle/dom/index.d.ts +0 -8
- package/dist/cycle/dom/isolate.d.ts +0 -9
- package/dist/cycle/dom/makeDOMDriver.d.ts +0 -11
- package/dist/cycle/dom/mockDOMSource.d.ts +0 -17
- package/dist/cycle/dom/modules.d.ts +0 -5
- package/dist/cycle/dom/snabbdom.d.ts +0 -22
- package/dist/cycle/dom/styleModule.d.ts +0 -13
- package/dist/cycle/dom/thunk.d.ts +0 -11
- package/dist/cycle/dom/utils.d.ts +0 -8
- package/dist/cycle/isolate/index.d.ts +0 -42
- package/dist/cycle/run/adapt.d.ts +0 -6
- package/dist/cycle/run/index.d.ts +0 -36
- package/dist/cycle/run/internals.d.ts +0 -8
- package/dist/cycle/run/types.d.ts +0 -49
- package/dist/cycle/state/Collection.d.ts +0 -29
- package/dist/cycle/state/StateSource.d.ts +0 -20
- package/dist/cycle/state/index.d.ts +0 -5
- package/dist/cycle/state/pickCombine.d.ts +0 -3
- package/dist/cycle/state/pickMerge.d.ts +0 -3
- package/dist/cycle/state/types.d.ts +0 -18
- package/dist/cycle/state/withState.d.ts +0 -17
- package/dist/extra/classes.d.ts +0 -7
- package/dist/extra/devtools.d.ts +0 -78
- package/dist/extra/dragDriver.d.ts +0 -20
- package/dist/extra/driverFactories.d.ts +0 -12
- package/dist/extra/eventDriver.d.ts +0 -9
- package/dist/extra/exactState.d.ts +0 -1
- package/dist/extra/hmr.d.ts +0 -17
- package/dist/extra/logDriver.d.ts +0 -2
- package/dist/extra/processDrag.d.ts +0 -19
- package/dist/extra/processForm.d.ts +0 -15
- package/dist/extra/run.d.ts +0 -13
- package/dist/extra/xstreamCompat.d.ts +0 -5
- package/dist/jsx-dev-runtime.d.ts +0 -1
- package/dist/jsx-dev-runtime.js +0 -224
- package/dist/jsx-runtime.d.ts +0 -4
- package/dist/jsx-runtime.js +0 -224
- package/dist/jsx.d.ts +0 -2
- package/dist/pragma/fn.d.ts +0 -7
- package/dist/pragma/index.d.ts +0 -7
- package/dist/pragma/is.d.ts +0 -10
- package/dist/switchable.d.ts +0 -7
- package/dist/vike/+config.cjs.js +0 -65
- package/src/component.ts +0 -2256
- package/src/cycle/isolate/index.ts +0 -196
- package/src/cycle/run/index.ts +0 -151
- package/src/cycle/run/internals.ts +0 -143
- package/src/cycle/state/Collection.ts +0 -174
- package/src/cycle/state/index.ts +0 -5
- package/src/cycle/state/pickCombine.ts +0 -167
- package/src/cycle/state/pickMerge.ts +0 -122
- package/src/cycle/state/withState.ts +0 -47
- package/src/pragma/fn.ts +0 -55
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// Import from the package entry so rollup externalizes it
|
|
19
19
|
// @ts-ignore — resolved at runtime via package exports
|
|
20
20
|
import { run } from 'sygnal'
|
|
21
|
+
import { owned } from '../extra/owned'
|
|
21
22
|
|
|
22
23
|
declare global {
|
|
23
24
|
interface Window {
|
|
@@ -31,12 +32,16 @@ interface PageContext {
|
|
|
31
32
|
routeParams?: Record<string, string>
|
|
32
33
|
urlPathname?: string
|
|
33
34
|
isHydration?: boolean
|
|
35
|
+
/** PLAN-3 5-5 (H-7): the queryCache() snapshot a loader seeded (see onRenderHtml) */
|
|
36
|
+
queryCache?: any
|
|
34
37
|
config: {
|
|
35
38
|
Layout?: any | any[]
|
|
36
39
|
Wrapper?: any | any[]
|
|
37
40
|
title?: string
|
|
38
41
|
ssr?: boolean
|
|
39
42
|
drivers?: Record<string, (sink: any) => any>
|
|
43
|
+
// PLAN-4 GS-11: the app-level error hook (not Vike's own onError)
|
|
44
|
+
sygnalOnError?: (error: any, info: any) => void
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
|
|
@@ -54,40 +59,53 @@ let currentRouteParams: any = {}
|
|
|
54
59
|
let currentUrlPathname: string = ''
|
|
55
60
|
let pageNavCounter: number = 0
|
|
56
61
|
|
|
62
|
+
/**
|
|
63
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page: wrapper_0 → 'w0',
|
|
64
|
+
* layout_1 → 'l1', page → 'p'. Given as the nested vnode's `id` prop, so the Page's uid is
|
|
65
|
+
* 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the same root
|
|
66
|
+
* (renderToString's `uid`), so server and client ids match. (Same helper in onRenderHtml.ts.)
|
|
67
|
+
*/
|
|
68
|
+
function uidPart(key: string): string {
|
|
69
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* PLAN-4.6 R4 (04 §3.11): the core instantiates a component from the vnode's `data.c`, a
|
|
74
|
+
* component function, and reads its statics there (no options object). A shell component or a
|
|
75
|
+
* Page is wrapped once (a per-app / per-navigation function) with the statics the options
|
|
76
|
+
* gave the 5.x core: isolatedState, and the initial state.
|
|
77
|
+
*/
|
|
78
|
+
const shellFns = new WeakMap<any, any>()
|
|
79
|
+
function shellFn(comp: any, initialState: any, cache = true): any {
|
|
80
|
+
let f = cache ? shellFns.get(comp) : undefined
|
|
81
|
+
if (!f) {
|
|
82
|
+
f = Object.assign((p: any) => comp(p), comp, { isolatedState: true, initialState })
|
|
83
|
+
try { Object.defineProperty(f, 'name', { value: comp.name, configurable: true }) } catch (_) {}
|
|
84
|
+
if (cache) shellFns.set(comp, f)
|
|
85
|
+
}
|
|
86
|
+
return f
|
|
87
|
+
}
|
|
88
|
+
let pageFn: any, pageFnNav = -1
|
|
89
|
+
|
|
57
90
|
/**
|
|
58
91
|
* Build a component vnode that matches what the JSX pragma produces.
|
|
59
92
|
*/
|
|
60
|
-
function componentVNode(comp: any,
|
|
93
|
+
function componentVNode(comp: any, key: string, stateField: any, children: any[], compInitialState?: any): any {
|
|
61
94
|
const name = comp.componentName || comp.name || 'FUNCTION_COMPONENT'
|
|
62
95
|
return {
|
|
63
96
|
sel: name,
|
|
64
97
|
data: {
|
|
98
|
+
c: shellFn(comp, owned(comp.initialState)),
|
|
65
99
|
props: {
|
|
66
100
|
state: stateField,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
view: comp,
|
|
70
|
-
model: comp.model,
|
|
71
|
-
intent: comp.intent,
|
|
72
|
-
hmrActions: comp.hmrActions,
|
|
73
|
-
context: comp.context,
|
|
74
|
-
peers: comp.peers,
|
|
75
|
-
components: comp.components,
|
|
76
|
-
initialState: compInitialState,
|
|
77
|
-
isolatedState: true,
|
|
78
|
-
calculated: comp.calculated,
|
|
79
|
-
storeCalculatedInState: comp.storeCalculatedInState,
|
|
80
|
-
DOMSourceName: comp.DOMSourceName,
|
|
81
|
-
stateSourceName: comp.stateSourceName,
|
|
82
|
-
onError: comp.onError,
|
|
83
|
-
debug: comp.debug,
|
|
84
|
-
},
|
|
101
|
+
// G-207: the uid() base, as onRenderHtml gives this shell component (see uidPart)
|
|
102
|
+
id: uidPart(key),
|
|
85
103
|
},
|
|
86
104
|
},
|
|
87
105
|
children,
|
|
88
106
|
text: undefined,
|
|
89
107
|
elm: undefined,
|
|
90
|
-
key: '__vike_' +
|
|
108
|
+
key: '__vike_' + key + '__',
|
|
91
109
|
}
|
|
92
110
|
}
|
|
93
111
|
|
|
@@ -96,33 +114,19 @@ function componentVNode(comp: any, stateField: string, children: any[], compInit
|
|
|
96
114
|
* Reads from mutable `currentPage` / `currentPageName` so the wrapper
|
|
97
115
|
* view picks up the new Page component on navigation without being recreated.
|
|
98
116
|
*/
|
|
99
|
-
function pageChildVNode(pageState: any): any {
|
|
100
|
-
//
|
|
101
|
-
//
|
|
117
|
+
function pageChildVNode(pageState: any, stateField: any = 'page'): any {
|
|
118
|
+
// a new function per navigation, so the Page is made again even when both pages are the same
|
|
119
|
+
// function (e.g. 'Page'); the nav counter in `sel` keeps the vnodes apart
|
|
102
120
|
const sel = currentPageName + '__nav' + pageNavCounter
|
|
121
|
+
if (pageFnNav !== pageNavCounter) { pageFnNav = pageNavCounter; pageFn = shellFn(currentPage, undefined, false) }
|
|
103
122
|
return {
|
|
104
123
|
sel,
|
|
105
124
|
data: {
|
|
125
|
+
c: pageFn,
|
|
106
126
|
props: {
|
|
107
|
-
state:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
view: currentPage,
|
|
111
|
-
model: currentPage.model,
|
|
112
|
-
intent: currentPage.intent,
|
|
113
|
-
hmrActions: currentPage.hmrActions,
|
|
114
|
-
context: currentPage.context,
|
|
115
|
-
peers: currentPage.peers,
|
|
116
|
-
components: currentPage.components,
|
|
117
|
-
initialState: pageState,
|
|
118
|
-
isolatedState: true,
|
|
119
|
-
calculated: currentPage.calculated,
|
|
120
|
-
storeCalculatedInState: currentPage.storeCalculatedInState,
|
|
121
|
-
DOMSourceName: currentPage.DOMSourceName,
|
|
122
|
-
stateSourceName: currentPage.stateSourceName,
|
|
123
|
-
onError: currentPage.onError,
|
|
124
|
-
debug: currentPage.debug,
|
|
125
|
-
},
|
|
127
|
+
state: stateField,
|
|
128
|
+
// G-207: the Page's uid() base, as onRenderHtml gives it (the same across navigations)
|
|
129
|
+
id: uidPart('page'),
|
|
126
130
|
},
|
|
127
131
|
},
|
|
128
132
|
children: [],
|
|
@@ -146,13 +150,37 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
|
|
|
146
150
|
currentPage = Page
|
|
147
151
|
currentPageName = Page.componentName || Page.name || 'VikePageComponent'
|
|
148
152
|
|
|
149
|
-
// Combined shell = wrappers (outermost) + layouts (innermost around Page)
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
// Combined shell = wrappers (outermost) + layouts (innermost around Page).
|
|
154
|
+
// D50: the root state holds every slice as a sibling, as in 5.4.0 but with the Page at the
|
|
155
|
+
// root too: { wrapper_0, ..., layout_0, ..., page }. A component's `state` prop selects from
|
|
156
|
+
// its parent component's state, and the shell components are nested in each other, so each
|
|
157
|
+
// one (and the Page) gets a { get, set } lens onto its own ROOT slice: an outer component's
|
|
158
|
+
// reducer replacing its state can't wipe the inner slices (R2-2), and no view sees another
|
|
159
|
+
// component's slice.
|
|
160
|
+
const keys = shellKeys(wrappers, layouts)
|
|
161
|
+
const shell = [...wrappers, ...layouts].map((comp: any, i: number) => ({ comp, key: keys[i] }))
|
|
162
|
+
|
|
163
|
+
// The latest root state. Only the outermost lens gets the root itself; the nested lenses get
|
|
164
|
+
// their parent shell component's state. In both directions the outermost lens runs first and
|
|
165
|
+
// synchronously (state: root -> outer get -> inner get; a reducer: outer get, inner get, inner
|
|
166
|
+
// set, outer set), so the nested lenses read and write through `root`.
|
|
167
|
+
let root: any = {}
|
|
168
|
+
const rootLens = (key: string, outermost: boolean, fresh: boolean) => ({
|
|
169
|
+
get: (state: any) => {
|
|
170
|
+
if (outermost) root = state || {}
|
|
171
|
+
const slice = root[key]
|
|
172
|
+
// a shell slice is a new object on every root state, so the components nested in the
|
|
173
|
+
// shell component see every change (their state stream drops repeated objects)
|
|
174
|
+
return fresh && slice && typeof slice === 'object' && !Array.isArray(slice) ? { ...slice } : slice
|
|
175
|
+
},
|
|
176
|
+
set: (state: any, slice: any) => {
|
|
177
|
+
root = { ...root, [key]: slice }
|
|
178
|
+
// a nested lens returns a changed parent state, so the parent's lens writes `root` back
|
|
179
|
+
return outermost ? root : { ...state }
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
const lenses = keys.map((key, i) => rootLens(key, i === 0, true))
|
|
183
|
+
const pageLens = rootLens('page', false, false)
|
|
156
184
|
|
|
157
185
|
function LayoutWrapperView({ state }: any) {
|
|
158
186
|
if (shell.length === 0) {
|
|
@@ -161,17 +189,17 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
|
|
|
161
189
|
}
|
|
162
190
|
|
|
163
191
|
const lastIdx = shell.length - 1
|
|
164
|
-
const innermostState = state[shell[lastIdx].key] || {}
|
|
165
192
|
let inner: any = componentVNode(
|
|
166
193
|
shell[lastIdx].comp,
|
|
167
194
|
shell[lastIdx].key,
|
|
168
|
-
[
|
|
169
|
-
|
|
195
|
+
lenses[lastIdx],
|
|
196
|
+
[pageChildVNode(state.page, pageLens)],
|
|
197
|
+
state[shell[lastIdx].key]
|
|
170
198
|
)
|
|
171
199
|
|
|
172
200
|
// Wrap with outer shell components
|
|
173
201
|
for (let i = lastIdx - 1; i >= 0; i--) {
|
|
174
|
-
inner = componentVNode(shell[i].comp, shell[i].key, [inner], state[shell[i].key])
|
|
202
|
+
inner = componentVNode(shell[i].comp, shell[i].key, lenses[i], [inner], state[shell[i].key])
|
|
175
203
|
}
|
|
176
204
|
|
|
177
205
|
// Wrap in a plain div so the view returns a regular DOM vnode.
|
|
@@ -188,19 +216,16 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
|
|
|
188
216
|
}
|
|
189
217
|
|
|
190
218
|
LayoutWrapperView.componentName = 'VikeLayoutWrapper'
|
|
219
|
+
// run() names the root by `name` first
|
|
220
|
+
try { Object.defineProperty(LayoutWrapperView, 'name', { value: 'VikeLayoutWrapper', configurable: true }) } catch (_) {}
|
|
191
221
|
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
const
|
|
195
|
-
shell.forEach(({ comp, key }: any
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
wrapperInitialState[key] = sliceState
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
LayoutWrapperView.initialState = wrapperInitialState
|
|
222
|
+
// The wrapper's initial state: a sibling slice for each shell component and the Page.
|
|
223
|
+
// Must match onRenderHtml's serialized state.
|
|
224
|
+
const initialState: any = {}
|
|
225
|
+
shell.forEach(({ comp, key }: any) => { initialState[key] = { ...(comp.initialState || {}) } })
|
|
226
|
+
initialState.page = Page.initialState || {}
|
|
227
|
+
// G-275: owned (built from the hydrated state and pageContext.data: never frozen in dev)
|
|
228
|
+
LayoutWrapperView.initialState = root = owned(initialState)
|
|
204
229
|
|
|
205
230
|
// Context uses mutable references so navigation updates are picked up.
|
|
206
231
|
// Wrapper and Layout contexts are merged once; page-level context
|
|
@@ -224,6 +249,14 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
|
|
|
224
249
|
return LayoutWrapperView
|
|
225
250
|
}
|
|
226
251
|
|
|
252
|
+
/** State keys of the shell components, outermost first: wrapper_0, ..., layout_0, ... */
|
|
253
|
+
function shellKeys(wrappers: any[], layouts: any[]): string[] {
|
|
254
|
+
return [
|
|
255
|
+
...wrappers.map((_: any, i: number) => 'wrapper_' + i),
|
|
256
|
+
...layouts.map((_: any, i: number) => 'layout_' + i),
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
|
|
227
260
|
/**
|
|
228
261
|
* Normalize a cumulative config value into an array of functions.
|
|
229
262
|
*/
|
|
@@ -240,37 +273,41 @@ export function onRenderClient(pageContext: PageContext) {
|
|
|
240
273
|
const layouts = toComponentArray(config.Layout)
|
|
241
274
|
const hasShell = wrappers.length > 0 || layouts.length > 0
|
|
242
275
|
|
|
243
|
-
// The shell is wrappers (outermost) + layouts
|
|
244
|
-
//
|
|
245
|
-
const shell =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
276
|
+
// The shell is wrappers (outermost) + layouts; their state slices and the Page's are
|
|
277
|
+
// siblings at the root (D50).
|
|
278
|
+
const shell = shellKeys(wrappers, layouts)
|
|
279
|
+
|
|
280
|
+
// PLAN-3 5-5 (H-7): seed the caches of the fetch drivers (makeFetchDriver({ cache: queryCache() })
|
|
281
|
+
// exposes it as driver.cache) before the page renders, so its resources start at 'success'
|
|
282
|
+
if (pageContext.queryCache) {
|
|
283
|
+
for (const d of Object.values(config.drivers || {})) (d as any)?.cache?.hydrate?.(pageContext.queryCache)
|
|
284
|
+
}
|
|
250
285
|
|
|
251
286
|
// Update mutable context references (used by the wrapper's context functions)
|
|
252
287
|
currentPageData = data
|
|
253
288
|
currentRouteParams = pageContext.routeParams || {}
|
|
254
|
-
|
|
289
|
+
// urlPathname is built in on the client with Client Routing (G-046: it is
|
|
290
|
+
// not in passToClient); fall back to the location with Server Routing.
|
|
291
|
+
currentUrlPathname = pageContext.urlPathname
|
|
292
|
+
|| (typeof window !== 'undefined' && window.location ? window.location.pathname : '')
|
|
255
293
|
|
|
256
294
|
// --- Shell path: hot-swap Page, keep Layout/Wrapper alive ---
|
|
257
295
|
if (hasShell) {
|
|
258
296
|
if (currentApp) {
|
|
259
297
|
// Client-side navigation: swap the Page without disposing the shell.
|
|
298
|
+
// PLAN-3 5-4b: a router given Vike's navigate() (makeRouter({ routes, navigate })) re-reads
|
|
299
|
+
// the route on this event; sent before the swap, so the new Page declares after it
|
|
300
|
+
if (typeof window !== 'undefined') window.dispatchEvent?.(new Event('sygnal:navigate'))
|
|
260
301
|
currentPage = Page
|
|
261
302
|
currentPageName = Page.componentName || Page.name || 'VikePageComponent'
|
|
262
303
|
pageNavCounter++
|
|
263
304
|
|
|
264
305
|
const newPageState = { ...(Page.initialState || {}), ...data }
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
[innermostKey!]: { ...shellState, page: newPageState },
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
}
|
|
306
|
+
// replace the page slice, keeping every shell slice (G-106, D50)
|
|
307
|
+
const swapPage = (state: any) => ({ ...state, page: newPageState })
|
|
308
|
+
// (PLAN-4.6 core: through the runtime API, 04 §3.11)
|
|
309
|
+
const rt = (currentApp as any).__runtime
|
|
310
|
+
rt?.setState('root', swapPage)
|
|
274
311
|
} else {
|
|
275
312
|
// First load: read hydrated state or build from initialState
|
|
276
313
|
let initialState: any
|
|
@@ -281,23 +318,25 @@ export function onRenderClient(pageContext: PageContext) {
|
|
|
281
318
|
initialState = null
|
|
282
319
|
}
|
|
283
320
|
|
|
284
|
-
if (initialState &&
|
|
285
|
-
// Hydrated
|
|
321
|
+
if (initialState && initialState[shell[shell.length - 1]] !== undefined) {
|
|
322
|
+
// Hydrated shell state: sibling slices (D50), or the 5.4.0 shape with the Page state
|
|
323
|
+
// under the innermost shell slice (R2-9) — distribute the slices to each component
|
|
286
324
|
const allShellComps = [...wrappers, ...layouts]
|
|
325
|
+
let pageState = initialState.page
|
|
287
326
|
shell.forEach((key: string, i: number) => {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
allShellComps[i].initialState = initialState[key]
|
|
295
|
-
}
|
|
327
|
+
let slice = initialState[key]
|
|
328
|
+
if (slice === undefined) return
|
|
329
|
+
if (i === shell.length - 1 && slice && 'page' in slice) {
|
|
330
|
+
const { page, ...rest } = slice
|
|
331
|
+
if (pageState === undefined) pageState = page
|
|
332
|
+
slice = rest
|
|
296
333
|
}
|
|
334
|
+
allShellComps[i].initialState = owned(slice)
|
|
297
335
|
})
|
|
336
|
+
Page.initialState = owned(pageState || { ...(Page.initialState || {}), ...data })
|
|
298
337
|
} else {
|
|
299
338
|
// SPA mode or client-side first navigation
|
|
300
|
-
Page.initialState = { ...(Page.initialState || {}), ...data }
|
|
339
|
+
Page.initialState = owned({ ...(Page.initialState || {}), ...data })
|
|
301
340
|
}
|
|
302
341
|
|
|
303
342
|
// Inject page-level context into Page (for SSR renderToString compat)
|
|
@@ -311,7 +350,9 @@ export function onRenderClient(pageContext: PageContext) {
|
|
|
311
350
|
const Component = createLayoutWrapper(wrappers, layouts, Page)
|
|
312
351
|
|
|
313
352
|
try {
|
|
314
|
-
|
|
353
|
+
// 3-B2: `__vike` marks the shell's components (Page, Layouts, Wrappers: sub-components of
|
|
354
|
+
// the shell root) for the dev entry, whose SYG224 then says persist() isn't supported there
|
|
355
|
+
currentApp = run(Component, { ...config.drivers, __vike: () => 1 }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any
|
|
315
356
|
} catch (err: any) {
|
|
316
357
|
console.error('[sygnal/vike] Client render error:', err)
|
|
317
358
|
const container = document.getElementById('page-view')
|
|
@@ -332,14 +373,17 @@ export function onRenderClient(pageContext: PageContext) {
|
|
|
332
373
|
}
|
|
333
374
|
|
|
334
375
|
let initialState: any
|
|
376
|
+
// 3-B2: the server's state is here when the page hydrates its HTML
|
|
377
|
+
let serverState = false
|
|
335
378
|
if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {
|
|
336
379
|
initialState = window.__VIKE_SYGNAL_STATE__
|
|
337
380
|
delete window.__VIKE_SYGNAL_STATE__
|
|
381
|
+
serverState = true
|
|
338
382
|
} else {
|
|
339
383
|
initialState = { ...(Page.initialState || {}), ...data }
|
|
340
384
|
}
|
|
341
385
|
|
|
342
|
-
Page.initialState = initialState
|
|
386
|
+
Page.initialState = owned(initialState)
|
|
343
387
|
Page.context = {
|
|
344
388
|
...Page.context,
|
|
345
389
|
pageData: () => currentPageData,
|
|
@@ -348,7 +392,11 @@ export function onRenderClient(pageContext: PageContext) {
|
|
|
348
392
|
}
|
|
349
393
|
|
|
350
394
|
try {
|
|
351
|
-
|
|
395
|
+
// 3-B2: the Page is the root, so its persist() restores after the first render when this
|
|
396
|
+
// is a hydration (`__hydrate`), keeping that render equal to the server's HTML. A client-side
|
|
397
|
+
// navigation isn't one, though the previous page's markup is still in #page-view
|
|
398
|
+
const hydrating = pageContext.isHydration ?? serverState
|
|
399
|
+
currentApp = run(Page, { ...config.drivers, __hydrate: () => hydrating }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any
|
|
352
400
|
} catch (err: any) {
|
|
353
401
|
console.error('[sygnal/vike] Client render error:', err)
|
|
354
402
|
const container = document.getElementById('page-view')
|
package/src/vike/onRenderHtml.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
// @ts-ignore — resolved at runtime via package exports
|
|
18
|
-
import { renderToString } from 'sygnal'
|
|
18
|
+
import { renderToString, renderHead, queryCache } from 'sygnal'
|
|
19
19
|
|
|
20
20
|
interface PageContext {
|
|
21
21
|
Page: any
|
|
@@ -31,8 +31,16 @@ interface PageContext {
|
|
|
31
31
|
favicon?: string
|
|
32
32
|
lang?: string
|
|
33
33
|
ssr?: boolean
|
|
34
|
+
// PLAN-4 GS-11: the app-level error hook (not Vike's own onError)
|
|
35
|
+
sygnalOnError?: (error: any, info: any) => void
|
|
34
36
|
}
|
|
35
37
|
is404?: boolean
|
|
38
|
+
/**
|
|
39
|
+
* PLAN-3 5-5 (H-7): a queryCache() snapshot a loader (+data) seeded:
|
|
40
|
+
* `pageContext.queryCache = cache.dehydrate()`. Resources render from it here, and Vike passes
|
|
41
|
+
* it to the client (passToClient), where onRenderClient hydrates the drivers' caches with it
|
|
42
|
+
*/
|
|
43
|
+
queryCache?: any
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -46,6 +54,16 @@ function esc(str: string): string {
|
|
|
46
54
|
.replace(/"/g, '"')
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
/**
|
|
58
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',
|
|
59
|
+
* layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each
|
|
60
|
+
* one renders here as its own root, so its root is 'u' plus the parts of the shell around it and
|
|
61
|
+
* its own: the same uids as the client's nested instances.
|
|
62
|
+
*/
|
|
63
|
+
function uidPart(key: string): string {
|
|
64
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)
|
|
65
|
+
}
|
|
66
|
+
|
|
49
67
|
export function onRenderHtml(pageContext: PageContext) {
|
|
50
68
|
const { Page, config } = pageContext
|
|
51
69
|
const data = pageContext.data || {}
|
|
@@ -107,6 +125,9 @@ export function onRenderHtml(pageContext: PageContext) {
|
|
|
107
125
|
urlPathname: () => pageContext.urlPathname || '',
|
|
108
126
|
}
|
|
109
127
|
|
|
128
|
+
// PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
|
|
129
|
+
const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined
|
|
130
|
+
|
|
110
131
|
// Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape
|
|
111
132
|
const wrapperArray = config.Wrapper
|
|
112
133
|
? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])
|
|
@@ -117,15 +138,32 @@ export function onRenderHtml(pageContext: PageContext) {
|
|
|
117
138
|
.filter((L: any) => typeof L === 'function')
|
|
118
139
|
: []
|
|
119
140
|
const hasShell = wrapperArray.length > 0 || layoutArray.length > 0
|
|
141
|
+
// Combined shell: wrappers (outermost) + layouts (innermost around Page)
|
|
142
|
+
// Must match the order used in onRenderClient's createLayoutWrapper.
|
|
143
|
+
const shell = [
|
|
144
|
+
...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),
|
|
145
|
+
...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),
|
|
146
|
+
]
|
|
147
|
+
// G-207: with a shell, the client nests each shell component and the Page in the one outside it
|
|
148
|
+
// with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
|
|
149
|
+
const uidRoot = (i: number) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-')
|
|
150
|
+
const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined
|
|
120
151
|
|
|
121
152
|
// Render the page component to HTML, with error boundary.
|
|
122
153
|
// When layouts are present, the hydration state is serialized separately
|
|
123
154
|
// as the wrapper's combined state (with page + layout slices).
|
|
155
|
+
// PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)
|
|
156
|
+
const pageHeads: any[] = [], shellHeads: any[] = []
|
|
124
157
|
let pageHtml: string
|
|
125
158
|
try {
|
|
126
159
|
pageHtml = renderToString(Page, {
|
|
127
160
|
state: initialState,
|
|
161
|
+
onError: config.sygnalOnError,
|
|
162
|
+
// G-207: the client's uid base and `id` prop for the nested Page
|
|
163
|
+
...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),
|
|
128
164
|
hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',
|
|
165
|
+
head: pageHeads,
|
|
166
|
+
cache,
|
|
129
167
|
})
|
|
130
168
|
} catch (err: any) {
|
|
131
169
|
// If the component has an onError boundary, try rendering its fallback
|
|
@@ -152,27 +190,33 @@ export function onRenderHtml(pageContext: PageContext) {
|
|
|
152
190
|
// If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.
|
|
153
191
|
// HTML is rendered INSIDE #page-view so the structure matches the client-side
|
|
154
192
|
// wrapper component. Nesting order: Wrapper > Layout > Page.
|
|
155
|
-
// Each shell component receives page content
|
|
193
|
+
// Each shell component receives the page content as a placeholder. G-464: a placeholder element
|
|
194
|
+
// as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written
|
|
195
|
+
// for the server only, the `innerHTML` prop.
|
|
156
196
|
let pageViewContent = pageHtml
|
|
157
197
|
if (hasShell) {
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),
|
|
163
|
-
]
|
|
164
|
-
|
|
198
|
+
// G-491: with attributes too (a shell whose root, or fragment's first element, is the slot
|
|
199
|
+
// carries the SSR root stamp: data-sygnal-ssr="")
|
|
200
|
+
const SLOT = /<sygnal-page-slot(?:\s[^>]*)?><\/sygnal-page-slot>/
|
|
201
|
+
const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'
|
|
165
202
|
// Wrap from innermost to outermost (reverse order)
|
|
166
203
|
for (let i = shell.length - 1; i >= 0; i--) {
|
|
167
|
-
const { comp } = shell[i]
|
|
168
|
-
const
|
|
204
|
+
const { comp, key } = shell[i]
|
|
205
|
+
const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined }
|
|
169
206
|
const compHtml = renderToString(comp, {
|
|
170
207
|
state: comp.initialState || {},
|
|
171
|
-
|
|
208
|
+
// G-207: the uid root and `id` prop the client's nested instance has
|
|
209
|
+
uid: uidRoot(i),
|
|
210
|
+
props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },
|
|
211
|
+
head: shellHeads,
|
|
212
|
+
cache,
|
|
213
|
+
onError: config.sygnalOnError,
|
|
172
214
|
})
|
|
173
|
-
const
|
|
215
|
+
const m = SLOT.exec(compHtml)
|
|
216
|
+
let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0
|
|
217
|
+
if (splitIdx === -1) splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length
|
|
174
218
|
if (splitIdx !== -1) {
|
|
175
|
-
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx +
|
|
219
|
+
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len)
|
|
176
220
|
} else {
|
|
177
221
|
// Fallback: component didn't use children/innerHTML, wrap content after it
|
|
178
222
|
pageViewContent = compHtml + pageViewContent
|
|
@@ -181,17 +225,12 @@ export function onRenderHtml(pageContext: PageContext) {
|
|
|
181
225
|
// Wrap in a shell div matching the client-side wrapper's root element
|
|
182
226
|
pageViewContent = `<div id="vike-shell">${pageViewContent}</div>`
|
|
183
227
|
|
|
184
|
-
// Serialize the wrapper's combined state for hydration.
|
|
185
|
-
//
|
|
186
|
-
// { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState }
|
|
228
|
+
// Serialize the wrapper's combined state for hydration. Must match the state shape
|
|
229
|
+
// from createLayoutWrapper (D50: sibling slices at the root):
|
|
230
|
+
// { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }
|
|
187
231
|
const wrapperState: any = {}
|
|
188
|
-
shell.forEach(({ comp, key }: any
|
|
189
|
-
|
|
190
|
-
if (i === shell.length - 1) {
|
|
191
|
-
compState.page = initialState
|
|
192
|
-
}
|
|
193
|
-
wrapperState[key] = compState
|
|
194
|
-
})
|
|
232
|
+
shell.forEach(({ comp, key }: any) => { wrapperState[key] = { ...(comp.initialState || {}) } })
|
|
233
|
+
wrapperState.page = initialState
|
|
195
234
|
pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`
|
|
196
235
|
}
|
|
197
236
|
|
|
@@ -210,8 +249,12 @@ export function onRenderHtml(pageContext: PageContext) {
|
|
|
210
249
|
const favicon = config.favicon || ''
|
|
211
250
|
const lang = config.lang || 'en'
|
|
212
251
|
|
|
213
|
-
const
|
|
214
|
-
|
|
252
|
+
const heads = [...shellHeads, ...pageHeads].filter(Boolean)
|
|
253
|
+
// with `head` statics, config.title / description are the defaults they override
|
|
254
|
+
const titleTag = heads.length
|
|
255
|
+
? renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])
|
|
256
|
+
: title ? `<title>${esc(title)}</title>` : ''
|
|
257
|
+
const descTag = description && !heads.length
|
|
215
258
|
? `<meta name="description" content="${esc(description)}">`
|
|
216
259
|
: ''
|
|
217
260
|
const faviconTag = favicon
|
package/src/vike/types.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TypeScript declarations for
|
|
2
|
+
* TypeScript declarations for 'sygnal/config' (also 'sygnal/vike' and
|
|
3
|
+
* 'sygnal/vike/config'): the Vike extension config (default export), and the
|
|
4
|
+
* custom config settings, which augment Vike's Config interface so users get
|
|
5
|
+
* autocomplete and type checking in their +config.ts files.
|
|
3
6
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
7
|
+
* import vikeSygnal from 'sygnal/config'
|
|
8
|
+
* export default { extends: [vikeSygnal] }
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
declare global {
|
|
@@ -24,10 +27,30 @@ declare global {
|
|
|
24
27
|
lang?: string
|
|
25
28
|
/** Additional Cycle.js drivers to pass to run() (e.g. WebSocket, HTTP). Client-only. */
|
|
26
29
|
drivers?: Record<string, (sink: any) => any>
|
|
30
|
+
/**
|
|
31
|
+
* App-level error hook (PLAN-4 GS-11), passed to run() on the client and to renderToString
|
|
32
|
+
* on the server: called after a component's onError boundary, reporting only. (Vike's own
|
|
33
|
+
* `onError` is a different, server-only hook)
|
|
34
|
+
*/
|
|
35
|
+
sygnalOnError?: (error: any, info: { componentName?: string; action?: string; phase: 'view' | 'reducer' | 'effect' | 'intent' | 'context' | 'declaration' | 'driver' | 'instantiate' | 'dispose' | 'widget'; driver?: string }) => void
|
|
27
36
|
/** Enable/disable SSR for this page (default: true). Set false for SPA mode. */
|
|
28
37
|
ssr?: boolean
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
40
|
}
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The Sygnal extension for Vike: put it in `extends` of your root +config.
|
|
44
|
+
* (Declared here; the value is the package's dist/vike/config/+config.js entry.)
|
|
45
|
+
*/
|
|
46
|
+
declare const vikeSygnal: {
|
|
47
|
+
name: 'sygnal'
|
|
48
|
+
clientRouting: boolean
|
|
49
|
+
hydrationCanBeAborted: boolean
|
|
50
|
+
onRenderHtml: string
|
|
51
|
+
onRenderClient: string
|
|
52
|
+
passToClient: string[]
|
|
53
|
+
meta: Record<string, any>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default vikeSygnal
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stand-in for the `globalthis` npm package (built to dist/shims/globalthis.cjs).
|
|
3
|
+
*
|
|
4
|
+
* xstream does `require('globalthis').getPolyfill()`, which pulls a polyfill
|
|
5
|
+
* chain (define-properties, get-intrinsic, object-keys, has-symbols, ...) into
|
|
6
|
+
* every app bundle (~4 KB gzip). Every browser and Node version Sygnal supports
|
|
7
|
+
* has a native `globalThis`, so `sygnal/vite` aliases `globalthis` to this
|
|
8
|
+
* module (opt out with `sygnal({ nativeGlobalThis: false })`).
|
|
9
|
+
*
|
|
10
|
+
* Same shape as the package's main export (the es-shim API): a function that
|
|
11
|
+
* returns the global object, with `getPolyfill`, `implementation` and `shim`.
|
|
12
|
+
*/
|
|
13
|
+
const getGlobal: any = () => globalThis
|
|
14
|
+
getGlobal.getPolyfill = getGlobal
|
|
15
|
+
getGlobal.implementation = globalThis
|
|
16
|
+
getGlobal.shim = getGlobal
|
|
17
|
+
|
|
18
|
+
export default getGlobal
|