sygnal 5.4.0 → 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 +24 -9
- package/dist/astro/client.cjs.js +16 -9
- package/dist/astro/client.cjs.js.map +1 -1
- package/dist/astro/client.mjs +16 -9
- package/dist/astro/client.mjs.map +1 -1
- package/dist/astro/index.cjs.js +362 -91
- package/dist/astro/index.cjs.js.map +1 -1
- package/dist/astro/index.mjs +362 -92
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/server.cjs.js +3396 -165
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs +3396 -165
- package/dist/astro/server.mjs.map +1 -1
- 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 +3032 -296
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +3032 -296
- package/dist/diagnostics.esm.js.map +1 -1
- 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 +13178 -5769
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2908 -276
- package/dist/index.esm.js +13149 -5779
- package/dist/index.esm.js.map +1 -1
- package/dist/jsx-dev-runtime.cjs.js +26 -334
- package/dist/jsx-dev-runtime.cjs.js.map +1 -1
- package/dist/jsx-dev-runtime.esm.js +19 -327
- package/dist/jsx-dev-runtime.esm.js.map +1 -1
- package/dist/jsx-runtime.cjs.js +26 -334
- package/dist/jsx-runtime.cjs.js.map +1 -1
- package/dist/jsx-runtime.esm.js +19 -327
- package/dist/jsx-runtime.esm.js.map +1 -1
- package/dist/jsx.cjs.js +10 -314
- package/dist/jsx.cjs.js.map +1 -1
- package/dist/jsx.esm.js +8 -315
- package/dist/jsx.esm.js.map +1 -1
- 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 +1 -1
- package/dist/sygnal.min.js.map +1 -1
- 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 +4 -14
- package/dist/vike/ClientOnly.cjs.js.map +1 -1
- package/dist/vike/ClientOnly.mjs +4 -14
- package/dist/vike/ClientOnly.mjs.map +1 -1
- package/dist/vike/{+config.js → config/+config.js} +9 -1
- package/dist/vike/config/+config.js.map +1 -0
- package/dist/vike/config/package.json +6 -0
- package/dist/vike/onRenderClient.cjs.js +165 -95
- package/dist/vike/onRenderClient.cjs.js.map +1 -1
- package/dist/vike/onRenderClient.mjs +165 -95
- package/dist/vike/onRenderClient.mjs.map +1 -1
- package/dist/vike/onRenderHtml.cjs.js +59 -24
- package/dist/vike/onRenderHtml.cjs.js.map +1 -1
- package/dist/vike/onRenderHtml.mjs +60 -25
- package/dist/vike/onRenderHtml.mjs.map +1 -1
- package/dist/vite/plugin.cjs.js +323 -88
- package/dist/vite/plugin.cjs.js.map +1 -1
- package/dist/vite/plugin.mjs +323 -89
- package/dist/vite/plugin.mjs.map +1 -1
- 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 +166 -103
- package/package.json +98 -14
- package/src/astro/client.ts +27 -16
- package/src/astro/index.d.ts +24 -0
- package/src/astro/index.ts +69 -3
- package/src/astro/server.ts +8 -2
- package/src/collection.ts +6 -93
- 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 +9 -2
- package/src/cycle/dom/PriorityQueue.ts +4 -2
- package/src/cycle/dom/SymbolTree.ts +18 -47
- package/src/cycle/dom/classNameModule.ts +9 -7
- package/src/cycle/dom/controlledInputModule.ts +23 -6
- package/src/cycle/dom/enrichEventStream.ts +25 -47
- package/src/cycle/dom/fragment.ts +7 -0
- package/src/cycle/dom/isolate.ts +30 -27
- package/src/cycle/dom/makeDOMDriver.ts +115 -56
- package/src/cycle/dom/mockDOMSource.ts +21 -1
- package/src/cycle/dom/modules.ts +16 -3
- 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 +19 -3
- 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 +101 -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 +1 -1
- 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 +20 -11
- package/src/extra/diagnostics/checks/elementCommands.ts +175 -0
- package/src/extra/diagnostics/checks/events.ts +17 -2
- 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 +97 -4
- package/src/extra/diagnostics/checks/inspect.ts +140 -32
- 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 +10 -5
- package/src/extra/diagnostics/checks/public.d.ts +98 -7
- 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 +1 -1
- package/src/extra/diagnostics/checks/shared.ts +86 -2
- 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 +100 -7
- package/src/extra/diagnostics/checks/statics.ts +48 -0
- package/src/extra/diagnostics/checks/strict.ts +10 -67
- 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 +66 -10
- package/src/extra/diagnostics/codes.ts +268 -23
- package/src/extra/diagnostics/index.ts +34 -9
- package/src/extra/diagnostics/legacy.ts +17 -0
- package/src/extra/driverFactories.ts +83 -19
- package/src/extra/elementCommands.ts +53 -0
- package/src/extra/fetchDriver.ts +519 -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 +1 -1
- 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 +90 -217
- 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 +2433 -175
- 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/index.d.ts +2631 -117
- package/src/index.ts +25 -4
- 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 +256 -133
- 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 -121
- 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 +7 -1
- package/src/vite/globalthis-shim.ts +18 -0
- package/src/vite/globalthis.ts +56 -0
- package/src/vite/plugin.d.ts +22 -3
- package/src/vite/plugin.ts +222 -24
- package/src/zag.d.ts +64 -0
- package/src/zag.ts +238 -0
- package/dist/vike/+config.cjs.js +0 -66
- package/dist/vike/+config.cjs.js.map +0 -1
- package/dist/vike/+config.js.map +0 -1
- package/src/component.ts +0 -2301
- 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 -184
- package/src/cycle/state/index.ts +0 -5
- package/src/cycle/state/pickCombine.ts +0 -201
- package/src/cycle/state/pickMerge.ts +0 -122
- package/src/cycle/state/withState.ts +0 -47
- package/src/pragma/fn.ts +0 -55
|
@@ -28,6 +28,15 @@ function esc(str) {
|
|
|
28
28
|
.replace(/>/g, '>')
|
|
29
29
|
.replace(/"/g, '"');
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',
|
|
33
|
+
* layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each
|
|
34
|
+
* one renders here as its own root, so its root is 'u' plus the parts of the shell around it and
|
|
35
|
+
* its own: the same uids as the client's nested instances.
|
|
36
|
+
*/
|
|
37
|
+
function uidPart(key) {
|
|
38
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1);
|
|
39
|
+
}
|
|
31
40
|
function onRenderHtml(pageContext) {
|
|
32
41
|
const { Page, config } = pageContext;
|
|
33
42
|
const data = pageContext.data || {};
|
|
@@ -84,6 +93,8 @@ function onRenderHtml(pageContext) {
|
|
|
84
93
|
routeParams: () => pageContext.routeParams || {},
|
|
85
94
|
urlPathname: () => pageContext.urlPathname || '',
|
|
86
95
|
};
|
|
96
|
+
// PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
|
|
97
|
+
const cache = pageContext.queryCache ? sygnal.queryCache({ initial: pageContext.queryCache }) : undefined;
|
|
87
98
|
// Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape
|
|
88
99
|
const wrapperArray = config.Wrapper
|
|
89
100
|
? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])
|
|
@@ -94,14 +105,31 @@ function onRenderHtml(pageContext) {
|
|
|
94
105
|
.filter((L) => typeof L === 'function')
|
|
95
106
|
: [];
|
|
96
107
|
const hasShell = wrapperArray.length > 0 || layoutArray.length > 0;
|
|
108
|
+
// Combined shell: wrappers (outermost) + layouts (innermost around Page)
|
|
109
|
+
// Must match the order used in onRenderClient's createLayoutWrapper.
|
|
110
|
+
const shell = [
|
|
111
|
+
...wrapperArray.map((w, i) => ({ comp: w, key: 'wrapper_' + i })),
|
|
112
|
+
...layoutArray.map((l, i) => ({ comp: l, key: 'layout_' + i })),
|
|
113
|
+
];
|
|
114
|
+
// G-207: with a shell, the client nests each shell component and the Page in the one outside it
|
|
115
|
+
// with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
|
|
116
|
+
const uidRoot = (i) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-');
|
|
117
|
+
const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined;
|
|
97
118
|
// Render the page component to HTML, with error boundary.
|
|
98
119
|
// When layouts are present, the hydration state is serialized separately
|
|
99
120
|
// as the wrapper's combined state (with page + layout slices).
|
|
121
|
+
// PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)
|
|
122
|
+
const pageHeads = [], shellHeads = [];
|
|
100
123
|
let pageHtml;
|
|
101
124
|
try {
|
|
102
125
|
pageHtml = sygnal.renderToString(Page, {
|
|
103
126
|
state: initialState,
|
|
127
|
+
onError: config.sygnalOnError,
|
|
128
|
+
// G-207: the client's uid base and `id` prop for the nested Page
|
|
129
|
+
...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),
|
|
104
130
|
hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',
|
|
131
|
+
head: pageHeads,
|
|
132
|
+
cache,
|
|
105
133
|
});
|
|
106
134
|
}
|
|
107
135
|
catch (err) {
|
|
@@ -131,26 +159,34 @@ function onRenderHtml(pageContext) {
|
|
|
131
159
|
// If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.
|
|
132
160
|
// HTML is rendered INSIDE #page-view so the structure matches the client-side
|
|
133
161
|
// wrapper component. Nesting order: Wrapper > Layout > Page.
|
|
134
|
-
// Each shell component receives page content
|
|
162
|
+
// Each shell component receives the page content as a placeholder. G-464: a placeholder element
|
|
163
|
+
// as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written
|
|
164
|
+
// for the server only, the `innerHTML` prop.
|
|
135
165
|
let pageViewContent = pageHtml;
|
|
136
166
|
if (hasShell) {
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
...layoutArray.map((l, i) => ({ comp: l, key: 'layout_' + i })),
|
|
142
|
-
];
|
|
167
|
+
// G-491: with attributes too (a shell whose root, or fragment's first element, is the slot
|
|
168
|
+
// carries the SSR root stamp: data-sygnal-ssr="")
|
|
169
|
+
const SLOT = /<sygnal-page-slot(?:\s[^>]*)?><\/sygnal-page-slot>/;
|
|
170
|
+
const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->';
|
|
143
171
|
// Wrap from innermost to outermost (reverse order)
|
|
144
172
|
for (let i = shell.length - 1; i >= 0; i--) {
|
|
145
|
-
const { comp } = shell[i];
|
|
146
|
-
const
|
|
173
|
+
const { comp, key } = shell[i];
|
|
174
|
+
const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined };
|
|
147
175
|
const compHtml = sygnal.renderToString(comp, {
|
|
148
176
|
state: comp.initialState || {},
|
|
149
|
-
|
|
177
|
+
// G-207: the uid root and `id` prop the client's nested instance has
|
|
178
|
+
uid: uidRoot(i),
|
|
179
|
+
props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },
|
|
180
|
+
head: shellHeads,
|
|
181
|
+
cache,
|
|
182
|
+
onError: config.sygnalOnError,
|
|
150
183
|
});
|
|
151
|
-
const
|
|
184
|
+
const m = SLOT.exec(compHtml);
|
|
185
|
+
let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0;
|
|
186
|
+
if (splitIdx === -1)
|
|
187
|
+
splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length;
|
|
152
188
|
if (splitIdx !== -1) {
|
|
153
|
-
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx +
|
|
189
|
+
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len);
|
|
154
190
|
}
|
|
155
191
|
else {
|
|
156
192
|
// Fallback: component didn't use children/innerHTML, wrap content after it
|
|
@@ -159,17 +195,12 @@ function onRenderHtml(pageContext) {
|
|
|
159
195
|
}
|
|
160
196
|
// Wrap in a shell div matching the client-side wrapper's root element
|
|
161
197
|
pageViewContent = `<div id="vike-shell">${pageViewContent}</div>`;
|
|
162
|
-
// Serialize the wrapper's combined state for hydration.
|
|
163
|
-
//
|
|
164
|
-
// { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState }
|
|
198
|
+
// Serialize the wrapper's combined state for hydration. Must match the state shape
|
|
199
|
+
// from createLayoutWrapper (D50: sibling slices at the root):
|
|
200
|
+
// { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }
|
|
165
201
|
const wrapperState = {};
|
|
166
|
-
shell.forEach(({ comp, key }
|
|
167
|
-
|
|
168
|
-
if (i === shell.length - 1) {
|
|
169
|
-
compState.page = initialState;
|
|
170
|
-
}
|
|
171
|
-
wrapperState[key] = compState;
|
|
172
|
-
});
|
|
202
|
+
shell.forEach(({ comp, key }) => { wrapperState[key] = { ...(comp.initialState || {}) }; });
|
|
203
|
+
wrapperState.page = initialState;
|
|
173
204
|
pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`;
|
|
174
205
|
}
|
|
175
206
|
// Render Head component for <head> tags
|
|
@@ -186,8 +217,12 @@ function onRenderHtml(pageContext) {
|
|
|
186
217
|
const description = config.description || '';
|
|
187
218
|
const favicon = config.favicon || '';
|
|
188
219
|
const lang = config.lang || 'en';
|
|
189
|
-
const
|
|
190
|
-
|
|
220
|
+
const heads = [...shellHeads, ...pageHeads].filter(Boolean);
|
|
221
|
+
// with `head` statics, config.title / description are the defaults they override
|
|
222
|
+
const titleTag = heads.length
|
|
223
|
+
? sygnal.renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])
|
|
224
|
+
: title ? `<title>${esc(title)}</title>` : '';
|
|
225
|
+
const descTag = description && !heads.length
|
|
191
226
|
? `<meta name="description" content="${esc(description)}">`
|
|
192
227
|
: '';
|
|
193
228
|
const faviconTag = favicon
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onRenderHtml.cjs.js","sources":["../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * Vike server-side render hook for Sygnal.\n *\n * Renders the Page component to HTML using Sygnal's renderToString,\n * wraps it in a full HTML document, and embeds serialized state for\n * client hydration.\n *\n * When a Layout is configured, the Layout HTML wraps the Page HTML\n * inside #page-view so the structure matches the client-side wrapper\n * component (see onRenderClient.ts).\n *\n * Returns a plain HTML string. Vike wraps it with dangerouslySkipEscape\n * automatically. We avoid importing from vike/server because our bundled\n * output lives in node_modules/sygnal/ where vike isn't resolvable.\n */\n\n// @ts-ignore — resolved at runtime via package exports\nimport { renderToString } from 'sygnal'\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n Head?: any\n title?: string\n description?: string\n favicon?: string\n lang?: string\n ssr?: boolean\n }\n is404?: boolean\n}\n\n/**\n * Escape a string for use in HTML attributes/text.\n */\nfunction esc(str: string): string {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\nexport function onRenderHtml(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n // SPA mode: return empty shell, let the client render everything.\n // Head component and meta tags are still included — they're static\n // metadata that should be present regardless of SSR being disabled.\n if (config.ssr === false) {\n const lang = config.lang || 'en'\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: {} })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const spaHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\"></div>\n </body>\n</html>`\n return { documentHtml: { _escaped: spaHtml } }\n }\n\n // Merge fetched data into the component's initial state\n const initialState = {\n ...(Page.initialState || {}),\n ...data,\n }\n\n // Inject page data, route params, and URL into the component's context\n // so sub-components can access them without prop drilling during SSR.\n Page.context = {\n ...Page.context,\n pageData: () => data,\n routeParams: () => pageContext.routeParams || {},\n urlPathname: () => pageContext.urlPathname || '',\n }\n\n // Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape\n const wrapperArray = config.Wrapper\n ? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])\n .filter((W: any) => typeof W === 'function')\n : []\n const layoutArray = config.Layout\n ? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])\n .filter((L: any) => typeof L === 'function')\n : []\n const hasShell = wrapperArray.length > 0 || layoutArray.length > 0\n\n // Render the page component to HTML, with error boundary.\n // When layouts are present, the hydration state is serialized separately\n // as the wrapper's combined state (with page + layout slices).\n let pageHtml: string\n try {\n pageHtml = renderToString(Page, {\n state: initialState,\n hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',\n })\n } catch (err: any) {\n // If the component has an onError boundary, try rendering its fallback\n if (Page.onError) {\n try {\n const fallbackVNode = Page.onError(err, { componentName: Page.name || 'Page' })\n if (fallbackVNode) {\n pageHtml = renderToString(() => fallbackVNode, { state: {} })\n if (!hasShell) {\n pageHtml += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(initialState)}</script>`\n }\n } else {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } catch (_) {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } else {\n console.error('[sygnal/vike] SSR render error:', err)\n pageHtml = `<div data-sygnal-error><!-- SSR render error: ${esc(String(err.message || err))} --></div>`\n }\n }\n\n // If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.\n // HTML is rendered INSIDE #page-view so the structure matches the client-side\n // wrapper component. Nesting order: Wrapper > Layout > Page.\n // Each shell component receives page content via a placeholder in its children slot.\n let pageViewContent = pageHtml\n if (hasShell) {\n // Combined shell: wrappers (outermost) + layouts (innermost around Page)\n // Must match the order used in onRenderClient's createLayoutWrapper.\n const shell = [\n ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),\n ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),\n ]\n\n // Wrap from innermost to outermost (reverse order)\n for (let i = shell.length - 1; i >= 0; i--) {\n const { comp } = shell[i]\n const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'\n const compHtml = renderToString(comp, {\n state: comp.initialState || {},\n props: { innerHTML: PLACEHOLDER },\n })\n const splitIdx = compHtml.indexOf(PLACEHOLDER)\n if (splitIdx !== -1) {\n pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + PLACEHOLDER.length)\n } else {\n // Fallback: component didn't use children/innerHTML, wrap content after it\n pageViewContent = compHtml + pageViewContent\n }\n }\n // Wrap in a shell div matching the client-side wrapper's root element\n pageViewContent = `<div id=\"vike-shell\">${pageViewContent}</div>`\n\n // Serialize the wrapper's combined state for hydration.\n // Must match the state shape from createLayoutWrapper:\n // { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState } }\n const wrapperState: any = {}\n shell.forEach(({ comp, key }: any, i: number) => {\n const compState: any = { ...(comp.initialState || {}) }\n if (i === shell.length - 1) {\n compState.page = initialState\n }\n wrapperState[key] = compState\n })\n pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`\n }\n\n // Render Head component for <head> tags\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: initialState })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const lang = config.lang || 'en'\n\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n const documentHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\">${pageViewContent}</div>\n </body>\n</html>`\n\n // Produce the shape Vike's isDocumentHtml() recognizes: { _escaped: string }\n // This is equivalent to dangerouslySkipEscape(html) from vike/server,\n // but avoids importing vike/server (which isn't resolvable from within\n // node_modules/sygnal/ in Vite's module runner).\n return { documentHtml: { _escaped: documentHtml } }\n}\n"],"names":["renderToString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onRenderHtml.cjs.js","sources":["../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * Vike server-side render hook for Sygnal.\n *\n * Renders the Page component to HTML using Sygnal's renderToString,\n * wraps it in a full HTML document, and embeds serialized state for\n * client hydration.\n *\n * When a Layout is configured, the Layout HTML wraps the Page HTML\n * inside #page-view so the structure matches the client-side wrapper\n * component (see onRenderClient.ts).\n *\n * Returns a plain HTML string. Vike wraps it with dangerouslySkipEscape\n * automatically. We avoid importing from vike/server because our bundled\n * output lives in node_modules/sygnal/ where vike isn't resolvable.\n */\n\n// @ts-ignore — resolved at runtime via package exports\nimport { renderToString, renderHead, queryCache } from 'sygnal'\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n Head?: any\n title?: string\n description?: string\n favicon?: string\n lang?: string\n ssr?: boolean\n // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)\n sygnalOnError?: (error: any, info: any) => void\n }\n is404?: boolean\n /**\n * PLAN-3 5-5 (H-7): a queryCache() snapshot a loader (+data) seeded:\n * `pageContext.queryCache = cache.dehydrate()`. Resources render from it here, and Vike passes\n * it to the client (passToClient), where onRenderClient hydrates the drivers' caches with it\n */\n queryCache?: any\n}\n\n/**\n * Escape a string for use in HTML attributes/text.\n */\nfunction esc(str: string): string {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\n/**\n * PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',\n * layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each\n * one renders here as its own root, so its root is 'u' plus the parts of the shell around it and\n * its own: the same uids as the client's nested instances.\n */\nfunction uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n\nexport function onRenderHtml(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n // SPA mode: return empty shell, let the client render everything.\n // Head component and meta tags are still included — they're static\n // metadata that should be present regardless of SSR being disabled.\n if (config.ssr === false) {\n const lang = config.lang || 'en'\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: {} })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const spaHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\"></div>\n </body>\n</html>`\n return { documentHtml: { _escaped: spaHtml } }\n }\n\n // Merge fetched data into the component's initial state\n const initialState = {\n ...(Page.initialState || {}),\n ...data,\n }\n\n // Inject page data, route params, and URL into the component's context\n // so sub-components can access them without prop drilling during SSR.\n Page.context = {\n ...Page.context,\n pageData: () => data,\n routeParams: () => pageContext.routeParams || {},\n urlPathname: () => pageContext.urlPathname || '',\n }\n\n // PLAN-3 5-5 (H-7): the seeded cache the components' resources render from\n const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined\n\n // Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape\n const wrapperArray = config.Wrapper\n ? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])\n .filter((W: any) => typeof W === 'function')\n : []\n const layoutArray = config.Layout\n ? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])\n .filter((L: any) => typeof L === 'function')\n : []\n const hasShell = wrapperArray.length > 0 || layoutArray.length > 0\n // Combined shell: wrappers (outermost) + layouts (innermost around Page)\n // Must match the order used in onRenderClient's createLayoutWrapper.\n const shell = [\n ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),\n ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),\n ]\n // G-207: with a shell, the client nests each shell component and the Page in the one outside it\n // with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'\n const uidRoot = (i: number) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-')\n const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined\n\n // Render the page component to HTML, with error boundary.\n // When layouts are present, the hydration state is serialized separately\n // as the wrapper's combined state (with page + layout slices).\n // PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)\n const pageHeads: any[] = [], shellHeads: any[] = []\n let pageHtml: string\n try {\n pageHtml = renderToString(Page, {\n state: initialState,\n onError: config.sygnalOnError,\n // G-207: the client's uid base and `id` prop for the nested Page\n ...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),\n hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',\n head: pageHeads,\n cache,\n })\n } catch (err: any) {\n // If the component has an onError boundary, try rendering its fallback\n if (Page.onError) {\n try {\n const fallbackVNode = Page.onError(err, { componentName: Page.name || 'Page' })\n if (fallbackVNode) {\n pageHtml = renderToString(() => fallbackVNode, { state: {} })\n if (!hasShell) {\n pageHtml += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(initialState)}</script>`\n }\n } else {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } catch (_) {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } else {\n console.error('[sygnal/vike] SSR render error:', err)\n pageHtml = `<div data-sygnal-error><!-- SSR render error: ${esc(String(err.message || err))} --></div>`\n }\n }\n\n // If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.\n // HTML is rendered INSIDE #page-view so the structure matches the client-side\n // wrapper component. Nesting order: Wrapper > Layout > Page.\n // Each shell component receives the page content as a placeholder. G-464: a placeholder element\n // as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written\n // for the server only, the `innerHTML` prop.\n let pageViewContent = pageHtml\n if (hasShell) {\n // G-491: with attributes too (a shell whose root, or fragment's first element, is the slot\n // carries the SSR root stamp: data-sygnal-ssr=\"\")\n const SLOT = /<sygnal-page-slot(?:\\s[^>]*)?><\\/sygnal-page-slot>/\n const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'\n // Wrap from innermost to outermost (reverse order)\n for (let i = shell.length - 1; i >= 0; i--) {\n const { comp, key } = shell[i]\n const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined }\n const compHtml = renderToString(comp, {\n state: comp.initialState || {},\n // G-207: the uid root and `id` prop the client's nested instance has\n uid: uidRoot(i),\n props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },\n head: shellHeads,\n cache,\n onError: config.sygnalOnError,\n })\n const m = SLOT.exec(compHtml)\n let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0\n if (splitIdx === -1) splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length\n if (splitIdx !== -1) {\n pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len)\n } else {\n // Fallback: component didn't use children/innerHTML, wrap content after it\n pageViewContent = compHtml + pageViewContent\n }\n }\n // Wrap in a shell div matching the client-side wrapper's root element\n pageViewContent = `<div id=\"vike-shell\">${pageViewContent}</div>`\n\n // Serialize the wrapper's combined state for hydration. Must match the state shape\n // from createLayoutWrapper (D50: sibling slices at the root):\n // { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }\n const wrapperState: any = {}\n shell.forEach(({ comp, key }: any) => { wrapperState[key] = { ...(comp.initialState || {}) } })\n wrapperState.page = initialState\n pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`\n }\n\n // Render Head component for <head> tags\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: initialState })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const lang = config.lang || 'en'\n\n const heads = [...shellHeads, ...pageHeads].filter(Boolean)\n // with `head` statics, config.title / description are the defaults they override\n const titleTag = heads.length\n ? renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])\n : title ? `<title>${esc(title)}</title>` : ''\n const descTag = description && !heads.length\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n const documentHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\">${pageViewContent}</div>\n </body>\n</html>`\n\n // Produce the shape Vike's isDocumentHtml() recognizes: { _escaped: string }\n // This is equivalent to dangerouslySkipEscape(html) from vike/server,\n // but avoids importing vike/server (which isn't resolvable from within\n // node_modules/sygnal/ in Vite's module runner).\n return { documentHtml: { _escaped: documentHtml } }\n}\n"],"names":["renderToString","queryCache","renderHead"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { renderToString } from 'sygnal';
|
|
1
|
+
import { renderToString, queryCache, renderHead } from 'sygnal';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Vike server-side render hook for Sygnal.
|
|
@@ -26,6 +26,15 @@ function esc(str) {
|
|
|
26
26
|
.replace(/>/g, '>')
|
|
27
27
|
.replace(/"/g, '"');
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',
|
|
31
|
+
* layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each
|
|
32
|
+
* one renders here as its own root, so its root is 'u' plus the parts of the shell around it and
|
|
33
|
+
* its own: the same uids as the client's nested instances.
|
|
34
|
+
*/
|
|
35
|
+
function uidPart(key) {
|
|
36
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1);
|
|
37
|
+
}
|
|
29
38
|
function onRenderHtml(pageContext) {
|
|
30
39
|
const { Page, config } = pageContext;
|
|
31
40
|
const data = pageContext.data || {};
|
|
@@ -82,6 +91,8 @@ function onRenderHtml(pageContext) {
|
|
|
82
91
|
routeParams: () => pageContext.routeParams || {},
|
|
83
92
|
urlPathname: () => pageContext.urlPathname || '',
|
|
84
93
|
};
|
|
94
|
+
// PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
|
|
95
|
+
const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined;
|
|
85
96
|
// Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape
|
|
86
97
|
const wrapperArray = config.Wrapper
|
|
87
98
|
? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])
|
|
@@ -92,14 +103,31 @@ function onRenderHtml(pageContext) {
|
|
|
92
103
|
.filter((L) => typeof L === 'function')
|
|
93
104
|
: [];
|
|
94
105
|
const hasShell = wrapperArray.length > 0 || layoutArray.length > 0;
|
|
106
|
+
// Combined shell: wrappers (outermost) + layouts (innermost around Page)
|
|
107
|
+
// Must match the order used in onRenderClient's createLayoutWrapper.
|
|
108
|
+
const shell = [
|
|
109
|
+
...wrapperArray.map((w, i) => ({ comp: w, key: 'wrapper_' + i })),
|
|
110
|
+
...layoutArray.map((l, i) => ({ comp: l, key: 'layout_' + i })),
|
|
111
|
+
];
|
|
112
|
+
// G-207: with a shell, the client nests each shell component and the Page in the one outside it
|
|
113
|
+
// with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
|
|
114
|
+
const uidRoot = (i) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-');
|
|
115
|
+
const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined;
|
|
95
116
|
// Render the page component to HTML, with error boundary.
|
|
96
117
|
// When layouts are present, the hydration state is serialized separately
|
|
97
118
|
// as the wrapper's combined state (with page + layout slices).
|
|
119
|
+
// PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)
|
|
120
|
+
const pageHeads = [], shellHeads = [];
|
|
98
121
|
let pageHtml;
|
|
99
122
|
try {
|
|
100
123
|
pageHtml = renderToString(Page, {
|
|
101
124
|
state: initialState,
|
|
125
|
+
onError: config.sygnalOnError,
|
|
126
|
+
// G-207: the client's uid base and `id` prop for the nested Page
|
|
127
|
+
...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),
|
|
102
128
|
hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',
|
|
129
|
+
head: pageHeads,
|
|
130
|
+
cache,
|
|
103
131
|
});
|
|
104
132
|
}
|
|
105
133
|
catch (err) {
|
|
@@ -129,26 +157,34 @@ function onRenderHtml(pageContext) {
|
|
|
129
157
|
// If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.
|
|
130
158
|
// HTML is rendered INSIDE #page-view so the structure matches the client-side
|
|
131
159
|
// wrapper component. Nesting order: Wrapper > Layout > Page.
|
|
132
|
-
// Each shell component receives page content
|
|
160
|
+
// Each shell component receives the page content as a placeholder. G-464: a placeholder element
|
|
161
|
+
// as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written
|
|
162
|
+
// for the server only, the `innerHTML` prop.
|
|
133
163
|
let pageViewContent = pageHtml;
|
|
134
164
|
if (hasShell) {
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
...layoutArray.map((l, i) => ({ comp: l, key: 'layout_' + i })),
|
|
140
|
-
];
|
|
165
|
+
// G-491: with attributes too (a shell whose root, or fragment's first element, is the slot
|
|
166
|
+
// carries the SSR root stamp: data-sygnal-ssr="")
|
|
167
|
+
const SLOT = /<sygnal-page-slot(?:\s[^>]*)?><\/sygnal-page-slot>/;
|
|
168
|
+
const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->';
|
|
141
169
|
// Wrap from innermost to outermost (reverse order)
|
|
142
170
|
for (let i = shell.length - 1; i >= 0; i--) {
|
|
143
|
-
const { comp } = shell[i];
|
|
144
|
-
const
|
|
171
|
+
const { comp, key } = shell[i];
|
|
172
|
+
const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined };
|
|
145
173
|
const compHtml = renderToString(comp, {
|
|
146
174
|
state: comp.initialState || {},
|
|
147
|
-
|
|
175
|
+
// G-207: the uid root and `id` prop the client's nested instance has
|
|
176
|
+
uid: uidRoot(i),
|
|
177
|
+
props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },
|
|
178
|
+
head: shellHeads,
|
|
179
|
+
cache,
|
|
180
|
+
onError: config.sygnalOnError,
|
|
148
181
|
});
|
|
149
|
-
const
|
|
182
|
+
const m = SLOT.exec(compHtml);
|
|
183
|
+
let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0;
|
|
184
|
+
if (splitIdx === -1)
|
|
185
|
+
splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length;
|
|
150
186
|
if (splitIdx !== -1) {
|
|
151
|
-
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx +
|
|
187
|
+
pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len);
|
|
152
188
|
}
|
|
153
189
|
else {
|
|
154
190
|
// Fallback: component didn't use children/innerHTML, wrap content after it
|
|
@@ -157,17 +193,12 @@ function onRenderHtml(pageContext) {
|
|
|
157
193
|
}
|
|
158
194
|
// Wrap in a shell div matching the client-side wrapper's root element
|
|
159
195
|
pageViewContent = `<div id="vike-shell">${pageViewContent}</div>`;
|
|
160
|
-
// Serialize the wrapper's combined state for hydration.
|
|
161
|
-
//
|
|
162
|
-
// { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState }
|
|
196
|
+
// Serialize the wrapper's combined state for hydration. Must match the state shape
|
|
197
|
+
// from createLayoutWrapper (D50: sibling slices at the root):
|
|
198
|
+
// { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }
|
|
163
199
|
const wrapperState = {};
|
|
164
|
-
shell.forEach(({ comp, key }
|
|
165
|
-
|
|
166
|
-
if (i === shell.length - 1) {
|
|
167
|
-
compState.page = initialState;
|
|
168
|
-
}
|
|
169
|
-
wrapperState[key] = compState;
|
|
170
|
-
});
|
|
200
|
+
shell.forEach(({ comp, key }) => { wrapperState[key] = { ...(comp.initialState || {}) }; });
|
|
201
|
+
wrapperState.page = initialState;
|
|
171
202
|
pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`;
|
|
172
203
|
}
|
|
173
204
|
// Render Head component for <head> tags
|
|
@@ -184,8 +215,12 @@ function onRenderHtml(pageContext) {
|
|
|
184
215
|
const description = config.description || '';
|
|
185
216
|
const favicon = config.favicon || '';
|
|
186
217
|
const lang = config.lang || 'en';
|
|
187
|
-
const
|
|
188
|
-
|
|
218
|
+
const heads = [...shellHeads, ...pageHeads].filter(Boolean);
|
|
219
|
+
// with `head` statics, config.title / description are the defaults they override
|
|
220
|
+
const titleTag = heads.length
|
|
221
|
+
? renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])
|
|
222
|
+
: title ? `<title>${esc(title)}</title>` : '';
|
|
223
|
+
const descTag = description && !heads.length
|
|
189
224
|
? `<meta name="description" content="${esc(description)}">`
|
|
190
225
|
: '';
|
|
191
226
|
const faviconTag = favicon
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onRenderHtml.mjs","sources":["../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * Vike server-side render hook for Sygnal.\n *\n * Renders the Page component to HTML using Sygnal's renderToString,\n * wraps it in a full HTML document, and embeds serialized state for\n * client hydration.\n *\n * When a Layout is configured, the Layout HTML wraps the Page HTML\n * inside #page-view so the structure matches the client-side wrapper\n * component (see onRenderClient.ts).\n *\n * Returns a plain HTML string. Vike wraps it with dangerouslySkipEscape\n * automatically. We avoid importing from vike/server because our bundled\n * output lives in node_modules/sygnal/ where vike isn't resolvable.\n */\n\n// @ts-ignore — resolved at runtime via package exports\nimport { renderToString } from 'sygnal'\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n Head?: any\n title?: string\n description?: string\n favicon?: string\n lang?: string\n ssr?: boolean\n }\n is404?: boolean\n}\n\n/**\n * Escape a string for use in HTML attributes/text.\n */\nfunction esc(str: string): string {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\nexport function onRenderHtml(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n // SPA mode: return empty shell, let the client render everything.\n // Head component and meta tags are still included — they're static\n // metadata that should be present regardless of SSR being disabled.\n if (config.ssr === false) {\n const lang = config.lang || 'en'\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: {} })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const spaHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\"></div>\n </body>\n</html>`\n return { documentHtml: { _escaped: spaHtml } }\n }\n\n // Merge fetched data into the component's initial state\n const initialState = {\n ...(Page.initialState || {}),\n ...data,\n }\n\n // Inject page data, route params, and URL into the component's context\n // so sub-components can access them without prop drilling during SSR.\n Page.context = {\n ...Page.context,\n pageData: () => data,\n routeParams: () => pageContext.routeParams || {},\n urlPathname: () => pageContext.urlPathname || '',\n }\n\n // Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape\n const wrapperArray = config.Wrapper\n ? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])\n .filter((W: any) => typeof W === 'function')\n : []\n const layoutArray = config.Layout\n ? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])\n .filter((L: any) => typeof L === 'function')\n : []\n const hasShell = wrapperArray.length > 0 || layoutArray.length > 0\n\n // Render the page component to HTML, with error boundary.\n // When layouts are present, the hydration state is serialized separately\n // as the wrapper's combined state (with page + layout slices).\n let pageHtml: string\n try {\n pageHtml = renderToString(Page, {\n state: initialState,\n hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',\n })\n } catch (err: any) {\n // If the component has an onError boundary, try rendering its fallback\n if (Page.onError) {\n try {\n const fallbackVNode = Page.onError(err, { componentName: Page.name || 'Page' })\n if (fallbackVNode) {\n pageHtml = renderToString(() => fallbackVNode, { state: {} })\n if (!hasShell) {\n pageHtml += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(initialState)}</script>`\n }\n } else {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } catch (_) {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } else {\n console.error('[sygnal/vike] SSR render error:', err)\n pageHtml = `<div data-sygnal-error><!-- SSR render error: ${esc(String(err.message || err))} --></div>`\n }\n }\n\n // If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.\n // HTML is rendered INSIDE #page-view so the structure matches the client-side\n // wrapper component. Nesting order: Wrapper > Layout > Page.\n // Each shell component receives page content via a placeholder in its children slot.\n let pageViewContent = pageHtml\n if (hasShell) {\n // Combined shell: wrappers (outermost) + layouts (innermost around Page)\n // Must match the order used in onRenderClient's createLayoutWrapper.\n const shell = [\n ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),\n ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),\n ]\n\n // Wrap from innermost to outermost (reverse order)\n for (let i = shell.length - 1; i >= 0; i--) {\n const { comp } = shell[i]\n const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'\n const compHtml = renderToString(comp, {\n state: comp.initialState || {},\n props: { innerHTML: PLACEHOLDER },\n })\n const splitIdx = compHtml.indexOf(PLACEHOLDER)\n if (splitIdx !== -1) {\n pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + PLACEHOLDER.length)\n } else {\n // Fallback: component didn't use children/innerHTML, wrap content after it\n pageViewContent = compHtml + pageViewContent\n }\n }\n // Wrap in a shell div matching the client-side wrapper's root element\n pageViewContent = `<div id=\"vike-shell\">${pageViewContent}</div>`\n\n // Serialize the wrapper's combined state for hydration.\n // Must match the state shape from createLayoutWrapper:\n // { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState } }\n const wrapperState: any = {}\n shell.forEach(({ comp, key }: any, i: number) => {\n const compState: any = { ...(comp.initialState || {}) }\n if (i === shell.length - 1) {\n compState.page = initialState\n }\n wrapperState[key] = compState\n })\n pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`\n }\n\n // Render Head component for <head> tags\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: initialState })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const lang = config.lang || 'en'\n\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n const documentHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\">${pageViewContent}</div>\n </body>\n</html>`\n\n // Produce the shape Vike's isDocumentHtml() recognizes: { _escaped: string }\n // This is equivalent to dangerouslySkipEscape(html) from vike/server,\n // but avoids importing vike/server (which isn't resolvable from within\n // node_modules/sygnal/ in Vite's module runner).\n return { documentHtml: { _escaped: documentHtml } }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onRenderHtml.mjs","sources":["../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * Vike server-side render hook for Sygnal.\n *\n * Renders the Page component to HTML using Sygnal's renderToString,\n * wraps it in a full HTML document, and embeds serialized state for\n * client hydration.\n *\n * When a Layout is configured, the Layout HTML wraps the Page HTML\n * inside #page-view so the structure matches the client-side wrapper\n * component (see onRenderClient.ts).\n *\n * Returns a plain HTML string. Vike wraps it with dangerouslySkipEscape\n * automatically. We avoid importing from vike/server because our bundled\n * output lives in node_modules/sygnal/ where vike isn't resolvable.\n */\n\n// @ts-ignore — resolved at runtime via package exports\nimport { renderToString, renderHead, queryCache } from 'sygnal'\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n Head?: any\n title?: string\n description?: string\n favicon?: string\n lang?: string\n ssr?: boolean\n // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)\n sygnalOnError?: (error: any, info: any) => void\n }\n is404?: boolean\n /**\n * PLAN-3 5-5 (H-7): a queryCache() snapshot a loader (+data) seeded:\n * `pageContext.queryCache = cache.dehydrate()`. Resources render from it here, and Vike passes\n * it to the client (passToClient), where onRenderClient hydrates the drivers' caches with it\n */\n queryCache?: any\n}\n\n/**\n * Escape a string for use in HTML attributes/text.\n */\nfunction esc(str: string): string {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\n/**\n * PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',\n * layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each\n * one renders here as its own root, so its root is 'u' plus the parts of the shell around it and\n * its own: the same uids as the client's nested instances.\n */\nfunction uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n\nexport function onRenderHtml(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n // SPA mode: return empty shell, let the client render everything.\n // Head component and meta tags are still included — they're static\n // metadata that should be present regardless of SSR being disabled.\n if (config.ssr === false) {\n const lang = config.lang || 'en'\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const titleTag = title ? `<title>${esc(title)}</title>` : ''\n const descTag = description\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: {} })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const spaHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\"></div>\n </body>\n</html>`\n return { documentHtml: { _escaped: spaHtml } }\n }\n\n // Merge fetched data into the component's initial state\n const initialState = {\n ...(Page.initialState || {}),\n ...data,\n }\n\n // Inject page data, route params, and URL into the component's context\n // so sub-components can access them without prop drilling during SSR.\n Page.context = {\n ...Page.context,\n pageData: () => data,\n routeParams: () => pageContext.routeParams || {},\n urlPathname: () => pageContext.urlPathname || '',\n }\n\n // PLAN-3 5-5 (H-7): the seeded cache the components' resources render from\n const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined\n\n // Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape\n const wrapperArray = config.Wrapper\n ? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])\n .filter((W: any) => typeof W === 'function')\n : []\n const layoutArray = config.Layout\n ? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])\n .filter((L: any) => typeof L === 'function')\n : []\n const hasShell = wrapperArray.length > 0 || layoutArray.length > 0\n // Combined shell: wrappers (outermost) + layouts (innermost around Page)\n // Must match the order used in onRenderClient's createLayoutWrapper.\n const shell = [\n ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),\n ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),\n ]\n // G-207: with a shell, the client nests each shell component and the Page in the one outside it\n // with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'\n const uidRoot = (i: number) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-')\n const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined\n\n // Render the page component to HTML, with error boundary.\n // When layouts are present, the hydration state is serialized separately\n // as the wrapper's combined state (with page + layout slices).\n // PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)\n const pageHeads: any[] = [], shellHeads: any[] = []\n let pageHtml: string\n try {\n pageHtml = renderToString(Page, {\n state: initialState,\n onError: config.sygnalOnError,\n // G-207: the client's uid base and `id` prop for the nested Page\n ...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),\n hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',\n head: pageHeads,\n cache,\n })\n } catch (err: any) {\n // If the component has an onError boundary, try rendering its fallback\n if (Page.onError) {\n try {\n const fallbackVNode = Page.onError(err, { componentName: Page.name || 'Page' })\n if (fallbackVNode) {\n pageHtml = renderToString(() => fallbackVNode, { state: {} })\n if (!hasShell) {\n pageHtml += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(initialState)}</script>`\n }\n } else {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } catch (_) {\n pageHtml = `<div data-sygnal-error>Render error</div>`\n }\n } else {\n console.error('[sygnal/vike] SSR render error:', err)\n pageHtml = `<div data-sygnal-error><!-- SSR render error: ${esc(String(err.message || err))} --></div>`\n }\n }\n\n // If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.\n // HTML is rendered INSIDE #page-view so the structure matches the client-side\n // wrapper component. Nesting order: Wrapper > Layout > Page.\n // Each shell component receives the page content as a placeholder. G-464: a placeholder element\n // as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written\n // for the server only, the `innerHTML` prop.\n let pageViewContent = pageHtml\n if (hasShell) {\n // G-491: with attributes too (a shell whose root, or fragment's first element, is the slot\n // carries the SSR root stamp: data-sygnal-ssr=\"\")\n const SLOT = /<sygnal-page-slot(?:\\s[^>]*)?><\\/sygnal-page-slot>/\n const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'\n // Wrap from innermost to outermost (reverse order)\n for (let i = shell.length - 1; i >= 0; i--) {\n const { comp, key } = shell[i]\n const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined }\n const compHtml = renderToString(comp, {\n state: comp.initialState || {},\n // G-207: the uid root and `id` prop the client's nested instance has\n uid: uidRoot(i),\n props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },\n head: shellHeads,\n cache,\n onError: config.sygnalOnError,\n })\n const m = SLOT.exec(compHtml)\n let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0\n if (splitIdx === -1) splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length\n if (splitIdx !== -1) {\n pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len)\n } else {\n // Fallback: component didn't use children/innerHTML, wrap content after it\n pageViewContent = compHtml + pageViewContent\n }\n }\n // Wrap in a shell div matching the client-side wrapper's root element\n pageViewContent = `<div id=\"vike-shell\">${pageViewContent}</div>`\n\n // Serialize the wrapper's combined state for hydration. Must match the state shape\n // from createLayoutWrapper (D50: sibling slices at the root):\n // { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }\n const wrapperState: any = {}\n shell.forEach(({ comp, key }: any) => { wrapperState[key] = { ...(comp.initialState || {}) } })\n wrapperState.page = initialState\n pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`\n }\n\n // Render Head component for <head> tags\n let headContent = ''\n if (config.Head && typeof config.Head === 'function') {\n try {\n headContent = renderToString(config.Head, { state: initialState })\n } catch (_) {\n // Head rendering failure is non-fatal\n }\n }\n\n const title = config.title || ''\n const description = config.description || ''\n const favicon = config.favicon || ''\n const lang = config.lang || 'en'\n\n const heads = [...shellHeads, ...pageHeads].filter(Boolean)\n // with `head` statics, config.title / description are the defaults they override\n const titleTag = heads.length\n ? renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])\n : title ? `<title>${esc(title)}</title>` : ''\n const descTag = description && !heads.length\n ? `<meta name=\"description\" content=\"${esc(description)}\">`\n : ''\n const faviconTag = favicon\n ? `<link rel=\"icon\" href=\"${esc(favicon)}\">`\n : ''\n\n const documentHtml = `<!DOCTYPE html>\n<html lang=\"${lang}\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${titleTag}\n ${descTag}\n ${faviconTag}\n ${headContent}\n </head>\n <body>\n <div id=\"page-view\">${pageViewContent}</div>\n </body>\n</html>`\n\n // Produce the shape Vike's isDocumentHtml() recognizes: { _escaped: string }\n // This is equivalent to dangerouslySkipEscape(html) from vike/server,\n // but avoids importing vike/server (which isn't resolvable from within\n // node_modules/sygnal/ in Vite's module runner).\n return { documentHtml: { _escaped: documentHtml } }\n}\n"],"names":[],"mappings":"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"}
|