sygnal 6.5.0 → 6.6.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 +24 -0
- package/dist/astro/index.cjs.js +398 -25
- package/dist/astro/index.cjs.js.map +1 -1
- package/dist/astro/index.mjs +398 -25
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs.map +1 -1
- package/dist/devtools.cjs.js +141 -3
- package/dist/devtools.cjs.js.map +1 -1
- package/dist/devtools.esm.js +141 -4
- package/dist/devtools.esm.js.map +1 -1
- package/dist/diagnostics.cjs.js +82 -10
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +82 -10
- package/dist/diagnostics.esm.js.map +1 -1
- package/dist/index.cjs.js +9 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +122 -13
- package/dist/index.esm.js +9 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/sygnal.min.js +1 -1
- package/dist/sygnal.min.js.map +1 -1
- package/dist/vike/config/package.json +1 -1
- package/dist/vike/onRenderClient.cjs.js +63 -43
- package/dist/vike/onRenderClient.cjs.js.map +1 -1
- package/dist/vike/onRenderClient.mjs +63 -43
- package/dist/vike/onRenderClient.mjs.map +1 -1
- package/dist/vike/onRenderHtml.cjs.js +21 -25
- package/dist/vike/onRenderHtml.cjs.js.map +1 -1
- package/dist/vike/onRenderHtml.mjs +21 -25
- package/dist/vike/onRenderHtml.mjs.map +1 -1
- package/dist/vite/plugin.cjs.js +398 -25
- package/dist/vite/plugin.cjs.js.map +1 -1
- package/dist/vite/plugin.mjs +398 -25
- package/dist/vite/plugin.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/hooks.ts +6 -0
- package/src/core/view.ts +2 -0
- package/src/cycle/dom/utils.ts +4 -2
- package/src/devtools.d.ts +13 -0
- package/src/devtools.ts +3 -0
- package/src/extra/devGraph.ts +111 -0
- package/src/extra/devMcp.ts +1 -1
- package/src/extra/devtools.ts +18 -0
- package/src/extra/diagnostics/checks/index.ts +1 -1
- package/src/extra/diagnostics/checks/inspect.ts +68 -6
- package/src/extra/diagnostics/checks/public.d.ts +121 -12
- package/src/extra/diagnostics/codes.ts +6 -0
- package/src/index.d.ts +2 -0
- package/src/vike/onRenderClient.ts +44 -46
- package/src/vike/onRenderHtml.ts +5 -26
- package/src/vike/shell.ts +33 -0
- package/src/vite/graph.ts +247 -0
- package/src/vite/mcp.ts +3 -3
- package/src/vite/plugin.d.ts +12 -0
- package/src/vite/plugin.ts +136 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onRenderClient.mjs","sources":["../../src/extra/owned.ts","../../src/vike/onRenderClient.ts"],"sourcesContent":["/**\n * PLAN-4.5 G-275: marks an initial state that a wrapper built from its caller's values (an\n * element's host props, Vike's pageContext.data or hydrated state, renderComponent's\n * initialState option). The dev statics freeze (D152, checks/statics.ts) leaves a marked object\n * and everything in it alone: the caller may still change those values. A non-enumerable symbol\n * key: spreads, JSON and Object.keys don't see it.\n */\nexport const OWNED = Symbol.for('sygnal.owned')\n\nexport const owned = <T>(v: T): T => {\n // G-289: an object that refuses the key (a Proxy) is returned as is\n try { if (v && typeof v == 'object' && Object.isExtensible(v)) Object.defineProperty(v, OWNED, {value: 1}) } catch {}\n return v\n}\n\n/**\n * G-289: owned() of a shallow copy of a plain object or array (the caller's own object stays\n * unmarked: it may be a component's static, which the freeze must still cover, or sealed, which\n * can't be marked); anything else as owned()\n */\nexport const ownedCopy = <T>(v: T): T => {\n const p = v && typeof v == 'object' ? Object.getPrototypeOf(v) : 0\n return owned(Array.isArray(v) ? [...v] as any : p == Object.prototype || p === null ? {...v} : v)\n}\n","/**\n * Vike client-side render hook for Sygnal.\n *\n * On first page load (hydration): reads server-serialized state and\n * boots the Sygnal app via run().\n *\n * On client-side navigation with a Layout/Wrapper: the Layout and Wrapper\n * stay mounted and only the Page sub-component is hot-swapped. Layout and\n * Wrapper state persists across navigations. Without either, the app is\n * disposed and recreated.\n *\n * Nesting order: Wrapper > Layout > Page\n * - Wrappers are outermost (context providers, state management)\n * - Layouts are inside wrappers (visual structure, navigation chrome)\n * - Page is innermost (route-specific content, swapped on navigation)\n */\n\n// Import from the package entry so rollup externalizes it\n// @ts-ignore — resolved at runtime via package exports\nimport { run } from 'sygnal'\nimport { owned } from '../extra/owned'\n\ndeclare global {\n interface Window {\n __VIKE_SYGNAL_STATE__?: any\n }\n}\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n isHydration?: boolean\n /** PLAN-3 5-5 (H-7): the queryCache() snapshot a loader seeded (see onRenderHtml) */\n queryCache?: any\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n title?: string\n ssr?: boolean\n drivers?: Record<string, (sink: any) => any>\n // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)\n sygnalOnError?: (error: any, info: any) => void\n }\n}\n\n/** Track the running Sygnal app for disposal on navigation */\nlet currentApp: { sources: any; sinks: any; dispose: () => void } | null = null\n\n/**\n * Mutable references read by the wrapper's view function.\n * Updated on navigation to swap the Page without disposing the Layout.\n */\nlet currentPage: any = null\nlet currentPageName: string = ''\nlet currentPageData: any = {}\nlet currentRouteParams: any = {}\nlet currentUrlPathname: string = ''\nlet pageNavCounter: number = 0\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'. Given as the nested vnode's `id` prop, so the Page's uid is\n * 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the same root\n * (renderToString's `uid`), so server and client ids match. (Same helper in onRenderHtml.ts.)\n */\nfunction uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n\n/**\n * PLAN-4.6 R4 (04 §3.11): the core instantiates a component from the vnode's `data.c`, a\n * component function, and reads its statics there (no options object). A shell component or a\n * Page is wrapped once (a per-app / per-navigation function) with the statics the options\n * gave the 5.x core: isolatedState, and the initial state.\n */\nconst shellFns = new WeakMap<any, any>()\nfunction shellFn(comp: any, initialState: any, cache = true): any {\n let f = cache ? shellFns.get(comp) : undefined\n if (!f) {\n f = Object.assign((p: any) => comp(p), comp, { isolatedState: true, initialState })\n try { Object.defineProperty(f, 'name', { value: comp.name, configurable: true }) } catch (_) {}\n if (cache) shellFns.set(comp, f)\n }\n return f\n}\nlet pageFn: any, pageFnNav = -1\n\n/**\n * Build a component vnode that matches what the JSX pragma produces.\n */\nfunction componentVNode(comp: any, key: string, stateField: any, children: any[], compInitialState?: any): any {\n const name = comp.componentName || comp.name || 'FUNCTION_COMPONENT'\n return {\n sel: name,\n data: {\n c: shellFn(comp, owned(comp.initialState)),\n props: {\n state: stateField,\n // G-207: the uid() base, as onRenderHtml gives this shell component (see uidPart)\n id: uidPart(key),\n },\n },\n children,\n text: undefined,\n elm: undefined,\n // no vnode key: it would be the instance identity (D456); `id` is (G-207)\n key: undefined,\n }\n}\n\n/**\n * Build a vnode for the current Page as a child of the Layout.\n * Reads from mutable `currentPage` / `currentPageName` so the wrapper\n * view picks up the new Page component on navigation without being recreated.\n */\nfunction pageChildVNode(pageState: any, stateField: any = 'page'): any {\n // a new function per navigation, so the Page is made again even when both pages are the same\n // function (e.g. 'Page'); the nav counter in `sel` keeps the vnodes apart\n const sel = currentPageName + '__nav' + pageNavCounter\n if (pageFnNav !== pageNavCounter) { pageFnNav = pageNavCounter; pageFn = shellFn(currentPage, undefined, false) }\n return {\n sel,\n data: {\n c: pageFn,\n props: {\n state: stateField,\n // G-207: the Page's uid() base, as onRenderHtml gives it (the same across navigations)\n id: uidPart('page'),\n },\n },\n children: [],\n text: undefined,\n elm: undefined,\n key: undefined,\n }\n}\n\n/**\n * Create a synthetic wrapper component that nests Page inside Layout(s)\n * inside Wrapper(s).\n *\n * Nesting order: Wrapper(s) > Layout(s) > Page\n *\n * The wrapper's view reads `currentPage` from the mutable closure, so\n * on client-side navigation only the Page sub-component changes while\n * the Layout and Wrapper stay mounted with their state preserved.\n */\nfunction createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {\n currentPage = Page\n currentPageName = Page.componentName || Page.name || 'VikePageComponent'\n\n // Combined shell = wrappers (outermost) + layouts (innermost around Page).\n // D50: the root state holds every slice as a sibling, as in 5.4.0 but with the Page at the\n // root too: { wrapper_0, ..., layout_0, ..., page }. A component's `state` prop selects from\n // its parent component's state, and the shell components are nested in each other, so each\n // one (and the Page) gets a { get, set } lens onto its own ROOT slice: an outer component's\n // reducer replacing its state can't wipe the inner slices (R2-2), and no view sees another\n // component's slice.\n const keys = shellKeys(wrappers, layouts)\n const shell = [...wrappers, ...layouts].map((comp: any, i: number) => ({ comp, key: keys[i] }))\n\n // The latest root state. Only the outermost lens gets the root itself; the nested lenses get\n // their parent shell component's state. In both directions the outermost lens runs first and\n // synchronously (state: root -> outer get -> inner get; a reducer: outer get, inner get, inner\n // set, outer set), so the nested lenses read and write through `root`.\n let root: any = {}\n const rootLens = (key: string, outermost: boolean, fresh: boolean) => ({\n get: (state: any) => {\n if (outermost) root = state || {}\n const slice = root[key]\n // a shell slice is a new object on every root state, so the components nested in the\n // shell component see every change (their state stream drops repeated objects)\n return fresh && slice && typeof slice === 'object' && !Array.isArray(slice) ? { ...slice } : slice\n },\n set: (state: any, slice: any) => {\n root = { ...root, [key]: slice }\n // a nested lens returns a changed parent state, so the parent's lens writes `root` back\n return outermost ? root : { ...state }\n },\n })\n const lenses = keys.map((key, i) => rootLens(key, i === 0, true))\n const pageLens = rootLens('page', false, false)\n\n function LayoutWrapperView({ state }: any) {\n if (shell.length === 0) {\n // No wrappers or layouts — render Page directly\n return pageChildVNode(state.page)\n }\n\n const lastIdx = shell.length - 1\n let inner: any = componentVNode(\n shell[lastIdx].comp,\n shell[lastIdx].key,\n lenses[lastIdx],\n [pageChildVNode(state.page, pageLens)],\n state[shell[lastIdx].key]\n )\n\n // Wrap with outer shell components\n for (let i = lastIdx - 1; i >= 0; i--) {\n inner = componentVNode(shell[i].comp, shell[i].key, lenses[i], [inner], state[shell[i].key])\n }\n\n // Wrap in a plain div so the view returns a regular DOM vnode.\n // Sub-component vnodes at the root position are not processed correctly\n // by the rendering pipeline — they must be children of a DOM element.\n return {\n sel: 'div',\n data: { attrs: { id: 'vike-shell' } },\n children: [inner],\n text: undefined,\n elm: undefined,\n key: '__vike_shell__',\n }\n }\n\n LayoutWrapperView.componentName = 'VikeLayoutWrapper'\n // run() names the root by `name` first\n try { Object.defineProperty(LayoutWrapperView, 'name', { value: 'VikeLayoutWrapper', configurable: true }) } catch (_) {}\n\n // The wrapper's initial state: a sibling slice for each shell component and the Page.\n // Must match onRenderHtml's serialized state.\n const initialState: any = {}\n shell.forEach(({ comp, key }: any) => { initialState[key] = { ...(comp.initialState || {}) } })\n initialState.page = Page.initialState || {}\n // G-275: owned (built from the hydrated state and pageContext.data: never frozen in dev)\n LayoutWrapperView.initialState = root = owned(initialState)\n\n // Context uses mutable references so navigation updates are picked up.\n // Wrapper and Layout contexts are merged once; page-level context\n // (pageData, routeParams, urlPathname) reads from mutable variables\n // updated on each navigation.\n const shellContext: any = {}\n shell.forEach(({ comp }: any) => {\n if (comp.context) {\n Object.assign(shellContext, comp.context)\n }\n })\n\n LayoutWrapperView.context = {\n ...shellContext,\n ...(Page.context || {}),\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n return LayoutWrapperView\n}\n\n/** State keys of the shell components, outermost first: wrapper_0, ..., layout_0, ... */\nfunction shellKeys(wrappers: any[], layouts: any[]): string[] {\n return [\n ...wrappers.map((_: any, i: number) => 'wrapper_' + i),\n ...layouts.map((_: any, i: number) => 'layout_' + i),\n ]\n}\n\n/**\n * Normalize a cumulative config value into an array of functions.\n */\nfunction toComponentArray(val: any): any[] {\n if (!val) return []\n return (Array.isArray(val) ? val : [val]).filter((c: any) => typeof c === 'function')\n}\n\nexport function onRenderClient(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n const wrappers = toComponentArray(config.Wrapper)\n const layouts = toComponentArray(config.Layout)\n const hasShell = wrappers.length > 0 || layouts.length > 0\n\n // The shell is wrappers (outermost) + layouts; their state slices and the Page's are\n // siblings at the root (D50).\n const shell = shellKeys(wrappers, layouts)\n\n // PLAN-3 5-5 (H-7): seed the caches of the fetch drivers (makeFetchDriver({ cache: queryCache() })\n // exposes it as driver.cache) before the page renders, so its resources start at 'success'\n if (pageContext.queryCache) {\n for (const d of Object.values(config.drivers || {})) (d as any)?.cache?.hydrate?.(pageContext.queryCache)\n }\n\n // Update mutable context references (used by the wrapper's context functions)\n currentPageData = data\n currentRouteParams = pageContext.routeParams || {}\n // urlPathname is built in on the client with Client Routing (G-046: it is\n // not in passToClient); fall back to the location with Server Routing.\n currentUrlPathname = pageContext.urlPathname\n || (typeof window !== 'undefined' && window.location ? window.location.pathname : '')\n\n // --- Shell path: hot-swap Page, keep Layout/Wrapper alive ---\n if (hasShell) {\n if (currentApp) {\n // Client-side navigation: swap the Page without disposing the shell.\n // PLAN-3 5-4b: a router given Vike's navigate() (makeRouter({ routes, navigate })) re-reads\n // the route on this event; sent before the swap, so the new Page declares after it\n if (typeof window !== 'undefined') window.dispatchEvent?.(new Event('sygnal:navigate'))\n currentPage = Page\n currentPageName = Page.componentName || Page.name || 'VikePageComponent'\n pageNavCounter++\n\n const newPageState = { ...(Page.initialState || {}), ...data }\n // replace the page slice, keeping every shell slice (G-106, D50)\n const swapPage = (state: any) => ({ ...state, page: newPageState })\n // (PLAN-4.6 core: through the runtime API, 04 §3.11)\n const rt = (currentApp as any).__runtime\n rt?.setState('root', swapPage)\n } else {\n // First load: read hydrated state or build from initialState\n let initialState: any\n if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {\n initialState = window.__VIKE_SYGNAL_STATE__\n delete window.__VIKE_SYGNAL_STATE__\n } else {\n initialState = null\n }\n\n if (initialState && initialState[shell[shell.length - 1]] !== undefined) {\n // Hydrated shell state: sibling slices (D50), or the 5.4.0 shape with the Page state\n // under the innermost shell slice (R2-9) — distribute the slices to each component\n const allShellComps = [...wrappers, ...layouts]\n let pageState = initialState.page\n shell.forEach((key: string, i: number) => {\n let slice = initialState[key]\n if (slice === undefined) return\n if (i === shell.length - 1 && slice && 'page' in slice) {\n const { page, ...rest } = slice\n if (pageState === undefined) pageState = page\n slice = rest\n }\n allShellComps[i].initialState = owned(slice)\n })\n Page.initialState = owned(pageState || { ...(Page.initialState || {}), ...data })\n } else {\n // SPA mode or client-side first navigation\n Page.initialState = owned({ ...(Page.initialState || {}), ...data })\n }\n\n // Inject page-level context into Page (for SSR renderToString compat)\n Page.context = {\n ...Page.context,\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n const Component = createLayoutWrapper(wrappers, layouts, Page)\n\n try {\n // 3-B2: `__vike` marks the shell's components (Page, Layouts, Wrappers: sub-components of\n // the shell root) for the dev entry, whose SYG224 then says persist() isn't supported there\n currentApp = run(Component, { ...config.drivers, __vike: () => 1 }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any\n } catch (err: any) {\n console.error('[sygnal/vike] Client render error:', err)\n const container = document.getElementById('page-view')\n if (container) {\n container.innerHTML = `<div data-sygnal-error style=\"padding:2rem;color:#e74c3c;font-family:monospace\">\n <h2>Render Error</h2>\n <pre>${String(err.message || err)}</pre>\n </div>`\n }\n }\n }\n\n // --- No shell path: dispose and recreate ---\n } else {\n if (currentApp) {\n currentApp.dispose()\n currentApp = null\n }\n\n let initialState: any\n // 3-B2: the server's state is here when the page hydrates its HTML\n let serverState = false\n if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {\n initialState = window.__VIKE_SYGNAL_STATE__\n delete window.__VIKE_SYGNAL_STATE__\n serverState = true\n } else {\n initialState = { ...(Page.initialState || {}), ...data }\n }\n\n Page.initialState = owned(initialState)\n Page.context = {\n ...Page.context,\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n try {\n // 3-B2: the Page is the root, so its persist() restores after the first render when this\n // is a hydration (`__hydrate`), keeping that render equal to the server's HTML. A client-side\n // navigation isn't one, though the previous page's markup is still in #page-view\n const hydrating = pageContext.isHydration ?? serverState\n currentApp = run(Page, { ...config.drivers, __hydrate: () => hydrating }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any\n } catch (err: any) {\n console.error('[sygnal/vike] Client render error:', err)\n const container = document.getElementById('page-view')\n if (container) {\n container.innerHTML = `<div data-sygnal-error style=\"padding:2rem;color:#e74c3c;font-family:monospace\">\n <h2>Render Error</h2>\n <pre>${String(err.message || err)}</pre>\n </div>`\n }\n }\n }\n\n // Update document title on client navigation\n if (config.title) {\n document.title = config.title\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onRenderClient.mjs","sources":["../../src/extra/owned.ts","../../src/vike/shell.ts","../../src/vike/onRenderClient.ts"],"sourcesContent":["/**\n * PLAN-4.5 G-275: marks an initial state that a wrapper built from its caller's values (an\n * element's host props, Vike's pageContext.data or hydrated state, renderComponent's\n * initialState option). The dev statics freeze (D152, checks/statics.ts) leaves a marked object\n * and everything in it alone: the caller may still change those values. A non-enumerable symbol\n * key: spreads, JSON and Object.keys don't see it.\n */\nexport const OWNED = Symbol.for('sygnal.owned')\n\nexport const owned = <T>(v: T): T => {\n // G-289: an object that refuses the key (a Proxy) is returned as is\n try { if (v && typeof v == 'object' && Object.isExtensible(v)) Object.defineProperty(v, OWNED, {value: 1}) } catch {}\n return v\n}\n\n/**\n * G-289: owned() of a shallow copy of a plain object or array (the caller's own object stays\n * unmarked: it may be a component's static, which the freeze must still cover, or sealed, which\n * can't be marked); anything else as owned()\n */\nexport const ownedCopy = <T>(v: T): T => {\n const p = v && typeof v == 'object' ? Object.getPrototypeOf(v) : 0\n return owned(Array.isArray(v) ? [...v] as any : p == Object.prototype || p === null ? {...v} : v)\n}\n","/**\n * G-803: the shell components of a page (its Wrappers and Layouts), outermost first, with their\n * state keys. Shared by onRenderHtml and onRenderClient so the server and the client nest them\n * the same way.\n *\n * Vike's cumulative configs (`Layout` and `Wrapper` are, see +config.ts) list the values closest\n * to the page first: pages/admin/+Layout before pages/+Layout (vike's resolveVikeConfigInternal:\n * sortAfterInheritanceOrder puts the longer inheritance root first). So the root's come last, and\n * the shell reverses each list: every Wrapper outside every Layout (as vike-react), and within each\n * the root's outermost. Keys count from the outside in (wrapper_0, ..., layout_0, ...), so a root\n * Layout keeps `layout_0` on every page, nested or not.\n */\nexport interface ShellPart { comp: any; key: string }\n\nconst comps = (val: any): any[] =>\n (val ? (Array.isArray(val) ? val : [val]) : []).filter((c: any) => typeof c === 'function')\n\nexport function shellOf(config: { Wrapper?: any; Layout?: any }): ShellPart[] {\n return [\n ...comps(config.Wrapper).reverse().map((comp, i) => ({ comp, key: 'wrapper_' + i })),\n ...comps(config.Layout).reverse().map((comp, i) => ({ comp, key: 'layout_' + i })),\n ]\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'. onRenderClient gives it as the nested vnode's `id` prop, so the\n * Page's uid is 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the\n * same root (renderToString's `uid`), so server and client ids match.\n */\nexport function uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n","/**\n * Vike client-side render hook for Sygnal.\n *\n * On first page load (hydration): reads server-serialized state and\n * boots the Sygnal app via run().\n *\n * On client-side navigation with a Layout/Wrapper: the Layout and Wrapper\n * stay mounted and only the Page sub-component is hot-swapped. Layout and\n * Wrapper state persists across navigations. Without either, the app is\n * disposed and recreated.\n *\n * Nesting order: Wrapper > Layout > Page\n * - Wrappers are outermost (context providers, state management)\n * - Layouts are inside wrappers (visual structure, navigation chrome)\n * - Page is innermost (route-specific content, swapped on navigation)\n * Cumulative Layouts / Wrappers nest the root's outermost (G-803, see shell.ts). Navigating to a\n * page with another shell (pages/admin/+Layout) keeps the shell components both pages share\n * mounted, from the outside in, and adds or removes the rest.\n */\n\n// Import from the package entry so rollup externalizes it\n// @ts-ignore — resolved at runtime via package exports\nimport { run } from 'sygnal'\nimport { owned } from '../extra/owned'\nimport { shellOf, uidPart, type ShellPart } from './shell'\n\ndeclare global {\n interface Window {\n __VIKE_SYGNAL_STATE__?: any\n }\n}\n\ninterface PageContext {\n Page: any\n data?: any\n routeParams?: Record<string, string>\n urlPathname?: string\n isHydration?: boolean\n /** PLAN-3 5-5 (H-7): the queryCache() snapshot a loader seeded (see onRenderHtml) */\n queryCache?: any\n config: {\n Layout?: any | any[]\n Wrapper?: any | any[]\n title?: string\n ssr?: boolean\n drivers?: Record<string, (sink: any) => any>\n // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)\n sygnalOnError?: (error: any, info: any) => void\n }\n}\n\n/** Track the running Sygnal app for disposal on navigation */\nlet currentApp: { sources: any; sinks: any; dispose: () => void } | null = null\n/** G-803: the running shell, outermost first (read by the wrapper's view); null: an app without one */\nlet currentShell: ShellPart[] | null = null\n\n/**\n * Mutable references read by the wrapper's view function.\n * Updated on navigation to swap the Page without disposing the Layout.\n */\nlet currentPage: any = null\nlet currentPageName: string = ''\nlet currentPageData: any = {}\nlet currentRouteParams: any = {}\nlet currentUrlPathname: string = ''\nlet pageNavCounter: number = 0\n\n/**\n * PLAN-4.6 R4 (04 §3.11): the core instantiates a component from the vnode's `data.c`, a\n * component function, and reads its statics there (no options object). A shell component or a\n * Page is wrapped once (a per-app / per-navigation function) with the statics the options\n * gave the 5.x core: isolatedState, and the initial state.\n */\nconst shellFns = new WeakMap<any, any>()\nfunction shellFn(comp: any, initialState: any, cache = true): any {\n let f = cache ? shellFns.get(comp) : undefined\n if (!f) {\n f = Object.assign((p: any) => comp(p), comp, { isolatedState: true, initialState })\n try { Object.defineProperty(f, 'name', { value: comp.name, configurable: true }) } catch (_) {}\n if (cache) shellFns.set(comp, f)\n }\n return f\n}\nlet pageFn: any, pageFnNav = -1\n\n/**\n * Build a component vnode that matches what the JSX pragma produces.\n */\nfunction componentVNode(comp: any, key: string, stateField: any, children: any[], compInitialState?: any): any {\n const name = comp.componentName || comp.name || 'FUNCTION_COMPONENT'\n return {\n sel: name,\n data: {\n c: shellFn(comp, owned(comp.initialState)),\n props: {\n state: stateField,\n // G-207: the uid() base, as onRenderHtml gives this shell component (see uidPart)\n id: uidPart(key),\n },\n },\n children,\n text: undefined,\n elm: undefined,\n // no vnode key: it would be the instance identity (D456); `id` is (G-207)\n key: undefined,\n }\n}\n\n/**\n * Build a vnode for the current Page as a child of the Layout.\n * Reads from mutable `currentPage` / `currentPageName` so the wrapper\n * view picks up the new Page component on navigation without being recreated.\n */\nfunction pageChildVNode(pageState: any, stateField: any = 'page'): any {\n // a new function per navigation, so the Page is made again even when both pages are the same\n // function (e.g. 'Page'); the nav counter in `sel` keeps the vnodes apart\n const sel = currentPageName + '__nav' + pageNavCounter\n if (pageFnNav !== pageNavCounter) { pageFnNav = pageNavCounter; pageFn = shellFn(currentPage, undefined, false) }\n return {\n sel,\n data: {\n c: pageFn,\n props: {\n state: stateField,\n // G-207: the Page's uid() base, as onRenderHtml gives it (the same across navigations)\n id: uidPart('page'),\n },\n },\n children: [],\n text: undefined,\n elm: undefined,\n key: undefined,\n }\n}\n\n/**\n * Create a synthetic wrapper component that nests Page inside Layout(s)\n * inside Wrapper(s).\n *\n * Nesting order: Wrapper(s) > Layout(s) > Page\n *\n * The wrapper's view reads `currentPage` and `currentShell` from the mutable closure, so\n * on client-side navigation only the Page sub-component (and the shell components the new page\n * doesn't share) change while the Layout and Wrapper stay mounted with their state preserved.\n */\nfunction createLayoutWrapper(Page: any): any {\n currentPage = Page\n currentPageName = Page.componentName || Page.name || 'VikePageComponent'\n\n // Combined shell = wrappers (outermost) + layouts (innermost around Page).\n // D50: the root state holds every slice as a sibling, as in 5.4.0 but with the Page at the\n // root too: { wrapper_0, ..., layout_0, ..., page }. A component's `state` prop selects from\n // its parent component's state, and the shell components are nested in each other, so each\n // one (and the Page) gets a { get, set } lens onto its own ROOT slice: an outer component's\n // reducer replacing its state can't wipe the inner slices (R2-2), and no view sees another\n // component's slice.\n // The latest root state. Only the outermost lens gets the root itself; the nested lenses get\n // their parent shell component's state. In both directions the outermost lens runs first and\n // synchronously (state: root -> outer get -> inner get; a reducer: outer get, inner get, inner\n // set, outer set), so the nested lenses read and write through `root`.\n let root: any = {}\n const rootLens = (key: string, outermost: boolean, fresh: boolean) => ({\n get: (state: any) => {\n if (outermost) root = state || {}\n const slice = root[key]\n // a shell slice is a new object on every root state, so the components nested in the\n // shell component see every change (their state stream drops repeated objects)\n return fresh && slice && typeof slice === 'object' && !Array.isArray(slice) ? { ...slice } : slice\n },\n set: (state: any, slice: any) => {\n root = { ...root, [key]: slice }\n // a nested lens returns a changed parent state, so the parent's lens writes `root` back\n return outermost ? root : { ...state }\n },\n })\n // one lens per key and place (outermost or not), the same object on every render\n const lenses: Record<string, any> = {}\n const lensOf = (key: string, outermost: boolean) => (lenses[key + outermost] ||= rootLens(key, outermost, true))\n const pageLens = rootLens('page', false, false)\n\n function LayoutWrapperView({ state }: any) {\n const shell = currentShell || []\n if (shell.length === 0) {\n // No wrappers or layouts — render Page directly\n return pageChildVNode(state.page)\n }\n\n const lastIdx = shell.length - 1\n let inner: any = componentVNode(\n shell[lastIdx].comp,\n shell[lastIdx].key,\n lensOf(shell[lastIdx].key, lastIdx === 0),\n [pageChildVNode(state.page, pageLens)],\n state[shell[lastIdx].key]\n )\n\n // Wrap with outer shell components\n for (let i = lastIdx - 1; i >= 0; i--) {\n inner = componentVNode(shell[i].comp, shell[i].key, lensOf(shell[i].key, i === 0), [inner], state[shell[i].key])\n }\n\n // Wrap in a plain div so the view returns a regular DOM vnode.\n // Sub-component vnodes at the root position are not processed correctly\n // by the rendering pipeline — they must be children of a DOM element.\n return {\n sel: 'div',\n data: { attrs: { id: 'vike-shell' } },\n children: [inner],\n text: undefined,\n elm: undefined,\n key: '__vike_shell__',\n }\n }\n\n LayoutWrapperView.componentName = 'VikeLayoutWrapper'\n // run() names the root by `name` first\n try { Object.defineProperty(LayoutWrapperView, 'name', { value: 'VikeLayoutWrapper', configurable: true }) } catch (_) {}\n\n // The wrapper's initial state: a sibling slice for each shell component and the Page.\n // Must match onRenderHtml's serialized state.\n const initialState: any = {}\n const shell = currentShell || []\n shell.forEach(({ comp, key }: any) => { initialState[key] = { ...(comp.initialState || {}) } })\n initialState.page = Page.initialState || {}\n // G-275: owned (built from the hydrated state and pageContext.data: never frozen in dev)\n LayoutWrapperView.initialState = root = owned(initialState)\n\n // Context uses mutable references so navigation updates are picked up.\n // Wrapper and Layout contexts are merged once; page-level context\n // (pageData, routeParams, urlPathname) reads from mutable variables\n // updated on each navigation.\n const shellContext: any = {}\n shell.forEach(({ comp }: any) => {\n if (comp.context) {\n Object.assign(shellContext, comp.context)\n }\n })\n\n LayoutWrapperView.context = {\n ...shellContext,\n ...(Page.context || {}),\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n return LayoutWrapperView\n}\n\nexport function onRenderClient(pageContext: PageContext) {\n const { Page, config } = pageContext\n const data = pageContext.data || {}\n\n // The shell, outermost first (G-803: Vike lists cumulative configs closest first); the state\n // slices of its components and the Page's are siblings at the root (D50)\n const parts = shellOf(config)\n const hasShell = parts.length > 0\n const shell = parts.map(p => p.key)\n\n // a shell page after a page without one (or the reverse, below): a new app\n if (hasShell && currentApp && !currentShell) { currentApp.dispose(); currentApp = null }\n\n // PLAN-3 5-5 (H-7): seed the caches of the fetch drivers (makeFetchDriver({ cache: queryCache() })\n // exposes it as driver.cache) before the page renders, so its resources start at 'success'\n if (pageContext.queryCache) {\n for (const d of Object.values(config.drivers || {})) (d as any)?.cache?.hydrate?.(pageContext.queryCache)\n }\n\n // Update mutable context references (used by the wrapper's context functions)\n currentPageData = data\n currentRouteParams = pageContext.routeParams || {}\n // urlPathname is built in on the client with Client Routing (G-046: it is\n // not in passToClient); fall back to the location with Server Routing.\n currentUrlPathname = pageContext.urlPathname\n || (typeof window !== 'undefined' && window.location ? window.location.pathname : '')\n\n // --- Shell path: hot-swap Page, keep Layout/Wrapper alive ---\n if (hasShell) {\n if (currentApp) {\n // Client-side navigation: swap the Page without disposing the shell.\n // PLAN-3 5-4b: a router given Vike's navigate() (makeRouter({ routes, navigate })) re-reads\n // the route on this event; sent before the swap, so the new Page declares after it\n if (typeof window !== 'undefined') window.dispatchEvent?.(new Event('sygnal:navigate'))\n currentPage = Page\n currentPageName = Page.componentName || Page.name || 'VikePageComponent'\n pageNavCounter++\n\n const newPageState = { ...(Page.initialState || {}), ...data }\n // replace the page slice, keeping every shell slice (G-106, D50). G-803: a page with another\n // shell keeps the slices of the components it shares at the same place (key) and starts the\n // others from their initialState\n const old = currentShell!\n const same = parts.length === old.length && parts.every((p, i) => p.comp === old[i].comp)\n let swapPage = (state: any) => ({ ...state, page: newPageState })\n if (!same) {\n currentShell = parts\n swapPage = (state: any) => {\n const next: any = { page: newPageState }\n for (const { comp, key } of parts) {\n next[key] = old.some(o => o.key === key && o.comp === comp) ? state[key] : { ...(comp.initialState || {}) }\n }\n return next\n }\n }\n // (PLAN-4.6 core: through the runtime API, 04 §3.11)\n const rt = (currentApp as any).__runtime\n rt?.setState('root', swapPage)\n } else {\n // First load: read hydrated state or build from initialState\n let initialState: any\n if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {\n initialState = window.__VIKE_SYGNAL_STATE__\n delete window.__VIKE_SYGNAL_STATE__\n } else {\n initialState = null\n }\n\n if (initialState && initialState[shell[shell.length - 1]] !== undefined) {\n // Hydrated shell state: sibling slices (D50), or the 5.4.0 shape with the Page state\n // under the innermost shell slice (R2-9) — distribute the slices to each component\n const allShellComps = parts.map(p => p.comp)\n let pageState = initialState.page\n shell.forEach((key: string, i: number) => {\n let slice = initialState[key]\n if (slice === undefined) return\n if (i === shell.length - 1 && slice && 'page' in slice) {\n const { page, ...rest } = slice\n if (pageState === undefined) pageState = page\n slice = rest\n }\n allShellComps[i].initialState = owned(slice)\n })\n Page.initialState = owned(pageState || { ...(Page.initialState || {}), ...data })\n } else {\n // SPA mode or client-side first navigation\n Page.initialState = owned({ ...(Page.initialState || {}), ...data })\n }\n\n // Inject page-level context into Page (for SSR renderToString compat)\n Page.context = {\n ...Page.context,\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n currentShell = parts\n const Component = createLayoutWrapper(Page)\n\n try {\n // 3-B2: `__vike` marks the shell's components (Page, Layouts, Wrappers: sub-components of\n // the shell root) for the dev entry, whose SYG224 then says persist() isn't supported there\n currentApp = run(Component, { ...config.drivers, __vike: () => 1 }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any\n } catch (err: any) {\n console.error('[sygnal/vike] Client render error:', err)\n const container = document.getElementById('page-view')\n if (container) {\n container.innerHTML = `<div data-sygnal-error style=\"padding:2rem;color:#e74c3c;font-family:monospace\">\n <h2>Render Error</h2>\n <pre>${String(err.message || err)}</pre>\n </div>`\n }\n }\n }\n\n // --- No shell path: dispose and recreate ---\n } else {\n if (currentApp) {\n currentApp.dispose()\n currentApp = null\n }\n currentShell = null\n\n let initialState: any\n // 3-B2: the server's state is here when the page hydrates its HTML\n let serverState = false\n if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {\n initialState = window.__VIKE_SYGNAL_STATE__\n delete window.__VIKE_SYGNAL_STATE__\n serverState = true\n } else {\n initialState = { ...(Page.initialState || {}), ...data }\n }\n\n Page.initialState = owned(initialState)\n Page.context = {\n ...Page.context,\n pageData: () => currentPageData,\n routeParams: () => currentRouteParams,\n urlPathname: () => currentUrlPathname,\n }\n\n try {\n // 3-B2: the Page is the root, so its persist() restores after the first render when this\n // is a hydration (`__hydrate`), keeping that render equal to the server's HTML. A client-side\n // navigation isn't one, though the previous page's markup is still in #page-view\n const hydrating = pageContext.isHydration ?? serverState\n currentApp = run(Page, { ...config.drivers, __hydrate: () => hydrating }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any\n } catch (err: any) {\n console.error('[sygnal/vike] Client render error:', err)\n const container = document.getElementById('page-view')\n if (container) {\n container.innerHTML = `<div data-sygnal-error style=\"padding:2rem;color:#e74c3c;font-family:monospace\">\n <h2>Render Error</h2>\n <pre>${String(err.message || err)}</pre>\n </div>`\n }\n }\n }\n\n // Update document title on client navigation\n if (config.title) {\n document.title = config.title\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
var sygnal = require('sygnal');
|
|
4
4
|
|
|
5
|
+
const comps = (val) => (val ? (Array.isArray(val) ? val : [val]) : []).filter((c) => typeof c === 'function');
|
|
6
|
+
function shellOf(config) {
|
|
7
|
+
return [
|
|
8
|
+
...comps(config.Wrapper).reverse().map((comp, i) => ({ comp, key: 'wrapper_' + i })),
|
|
9
|
+
...comps(config.Layout).reverse().map((comp, i) => ({ comp, key: 'layout_' + i })),
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page: wrapper_0 → 'w0',
|
|
14
|
+
* layout_1 → 'l1', page → 'p'. onRenderClient gives it as the nested vnode's `id` prop, so the
|
|
15
|
+
* Page's uid is 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the
|
|
16
|
+
* same root (renderToString's `uid`), so server and client ids match.
|
|
17
|
+
*/
|
|
18
|
+
function uidPart(key) {
|
|
19
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1);
|
|
20
|
+
}
|
|
21
|
+
|
|
5
22
|
/**
|
|
6
23
|
* Vike server-side render hook for Sygnal.
|
|
7
24
|
*
|
|
@@ -28,15 +45,6 @@ function esc(str) {
|
|
|
28
45
|
.replace(/>/g, '>')
|
|
29
46
|
.replace(/"/g, '"');
|
|
30
47
|
}
|
|
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
|
-
}
|
|
40
48
|
function onRenderHtml(pageContext) {
|
|
41
49
|
const { Page, config } = pageContext;
|
|
42
50
|
const data = pageContext.data || {};
|
|
@@ -95,22 +103,10 @@ function onRenderHtml(pageContext) {
|
|
|
95
103
|
};
|
|
96
104
|
// PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
|
|
97
105
|
const cache = pageContext.queryCache ? sygnal.queryCache({ initial: pageContext.queryCache }) : undefined;
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
: [];
|
|
103
|
-
const layoutArray = config.Layout
|
|
104
|
-
? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])
|
|
105
|
-
.filter((L) => typeof L === 'function')
|
|
106
|
-
: [];
|
|
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
|
-
];
|
|
106
|
+
// Wrapper(s) and/or Layout(s), outermost first (G-803: Vike lists them closest first; shellOf
|
|
107
|
+
// reverses them, the same order as onRenderClient's): they decide the hydration state's shape
|
|
108
|
+
const shell = shellOf(config);
|
|
109
|
+
const hasShell = shell.length > 0;
|
|
114
110
|
// G-207: with a shell, the client nests each shell component and the Page in the one outside it
|
|
115
111
|
// with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
|
|
116
112
|
const uidRoot = (i) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-');
|
|
@@ -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, 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
|
+
{"version":3,"file":"onRenderHtml.cjs.js","sources":["../../src/vike/shell.ts","../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * G-803: the shell components of a page (its Wrappers and Layouts), outermost first, with their\n * state keys. Shared by onRenderHtml and onRenderClient so the server and the client nest them\n * the same way.\n *\n * Vike's cumulative configs (`Layout` and `Wrapper` are, see +config.ts) list the values closest\n * to the page first: pages/admin/+Layout before pages/+Layout (vike's resolveVikeConfigInternal:\n * sortAfterInheritanceOrder puts the longer inheritance root first). So the root's come last, and\n * the shell reverses each list: every Wrapper outside every Layout (as vike-react), and within each\n * the root's outermost. Keys count from the outside in (wrapper_0, ..., layout_0, ...), so a root\n * Layout keeps `layout_0` on every page, nested or not.\n */\nexport interface ShellPart { comp: any; key: string }\n\nconst comps = (val: any): any[] =>\n (val ? (Array.isArray(val) ? val : [val]) : []).filter((c: any) => typeof c === 'function')\n\nexport function shellOf(config: { Wrapper?: any; Layout?: any }): ShellPart[] {\n return [\n ...comps(config.Wrapper).reverse().map((comp, i) => ({ comp, key: 'wrapper_' + i })),\n ...comps(config.Layout).reverse().map((comp, i) => ({ comp, key: 'layout_' + i })),\n ]\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'. onRenderClient gives it as the nested vnode's `id` prop, so the\n * Page's uid is 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the\n * same root (renderToString's `uid`), so server and client ids match.\n */\nexport function uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n","/**\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'\nimport { shellOf, uidPart } from './shell'\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\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 // Wrapper(s) and/or Layout(s), outermost first (G-803: Vike lists them closest first; shellOf\n // reverses them, the same order as onRenderClient's): they decide the hydration state's shape\n const shell = shellOf(config)\n const hasShell = shell.length > 0\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,5 +1,22 @@
|
|
|
1
1
|
import { renderToString, queryCache, renderHead } from 'sygnal';
|
|
2
2
|
|
|
3
|
+
const comps = (val) => (val ? (Array.isArray(val) ? val : [val]) : []).filter((c) => typeof c === 'function');
|
|
4
|
+
function shellOf(config) {
|
|
5
|
+
return [
|
|
6
|
+
...comps(config.Wrapper).reverse().map((comp, i) => ({ comp, key: 'wrapper_' + i })),
|
|
7
|
+
...comps(config.Layout).reverse().map((comp, i) => ({ comp, key: 'layout_' + i })),
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* PLAN-4 G-207: the uid() path part of a shell component or the Page: wrapper_0 → 'w0',
|
|
12
|
+
* layout_1 → 'l1', page → 'p'. onRenderClient gives it as the nested vnode's `id` prop, so the
|
|
13
|
+
* Page's uid is 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the
|
|
14
|
+
* same root (renderToString's `uid`), so server and client ids match.
|
|
15
|
+
*/
|
|
16
|
+
function uidPart(key) {
|
|
17
|
+
return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1);
|
|
18
|
+
}
|
|
19
|
+
|
|
3
20
|
/**
|
|
4
21
|
* Vike server-side render hook for Sygnal.
|
|
5
22
|
*
|
|
@@ -26,15 +43,6 @@ function esc(str) {
|
|
|
26
43
|
.replace(/>/g, '>')
|
|
27
44
|
.replace(/"/g, '"');
|
|
28
45
|
}
|
|
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
|
-
}
|
|
38
46
|
function onRenderHtml(pageContext) {
|
|
39
47
|
const { Page, config } = pageContext;
|
|
40
48
|
const data = pageContext.data || {};
|
|
@@ -93,22 +101,10 @@ function onRenderHtml(pageContext) {
|
|
|
93
101
|
};
|
|
94
102
|
// PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
|
|
95
103
|
const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined;
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
: [];
|
|
101
|
-
const layoutArray = config.Layout
|
|
102
|
-
? (Array.isArray(config.Layout) ? config.Layout : [config.Layout])
|
|
103
|
-
.filter((L) => typeof L === 'function')
|
|
104
|
-
: [];
|
|
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
|
-
];
|
|
104
|
+
// Wrapper(s) and/or Layout(s), outermost first (G-803: Vike lists them closest first; shellOf
|
|
105
|
+
// reverses them, the same order as onRenderClient's): they decide the hydration state's shape
|
|
106
|
+
const shell = shellOf(config);
|
|
107
|
+
const hasShell = shell.length > 0;
|
|
112
108
|
// G-207: with a shell, the client nests each shell component and the Page in the one outside it
|
|
113
109
|
// with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
|
|
114
110
|
const uidRoot = (i) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-');
|
|
@@ -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, 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":";;AAAA;;;;;;;;;;;;;;AAcG;AAEH;AA6BA;;AAEG;AACH,SAAS,GAAG,CAAC,GAAW,EAAA;IACtB,OAAO,MAAM,CAAC,GAAG,CAAC;AACf,SAAA,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;AACtB,SAAA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AACrB,SAAA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AACrB,SAAA,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;AAKG;AACH,SAAS,OAAO,CAAC,GAAW,EAAA;AAC1B,IAAA,OAAO,GAAG,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AACvE,CAAC;AAEK,SAAU,YAAY,CAAC,WAAwB,EAAA;AACnD,IAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAAA;AACpC,IAAA,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,EAAE,CAAA;;;;AAKnC,IAAA,IAAI,MAAM,CAAC,GAAG,KAAK,KAAK,EAAE;AACxB,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAA;AAChC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;AAChC,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAA;AAC5C,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;AACpC,QAAA,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAU,OAAA,EAAA,GAAG,CAAC,KAAK,CAAC,CAAU,QAAA,CAAA,GAAG,EAAE,CAAA;QAC5D,MAAM,OAAO,GAAG,WAAW;AACzB,cAAE,CAAqC,kCAAA,EAAA,GAAG,CAAC,WAAW,CAAC,CAAI,EAAA,CAAA;cACzD,EAAE,CAAA;QACN,MAAM,UAAU,GAAG,OAAO;AACxB,cAAE,CAA0B,uBAAA,EAAA,GAAG,CAAC,OAAO,CAAC,CAAI,EAAA,CAAA;cAC1C,EAAE,CAAA;QAEN,IAAI,WAAW,GAAG,EAAE,CAAA;QACpB,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE;AACpD,YAAA,IAAI;AACF,gBAAA,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;aACzD;YAAC,OAAO,CAAC,EAAE;;aAEX;SACF;AAED,QAAA,MAAM,OAAO,GAAG,CAAA;cACN,IAAI,CAAA;;;;MAIZ,QAAQ,CAAA;MACR,OAAO,CAAA;MACP,UAAU,CAAA;MACV,WAAW,CAAA;;;;;QAKT,CAAA;QACJ,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAA;KAC/C;;AAGD,IAAA,MAAM,YAAY,GAAG;AACnB,QAAA,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;AAC5B,QAAA,GAAG,IAAI;KACR,CAAA;;;IAID,IAAI,CAAC,OAAO,GAAG;QACb,GAAG,IAAI,CAAC,OAAO;AACf,QAAA,QAAQ,EAAE,MAAM,IAAI;QACpB,WAAW,EAAE,MAAM,WAAW,CAAC,WAAW,IAAI,EAAE;QAChD,WAAW,EAAE,MAAM,WAAW,CAAC,WAAW,IAAI,EAAE;KACjD,CAAA;;IAGD,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,GAAG,UAAU,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC,GAAG,SAAS,CAAA;;AAGlG,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO;UAC/B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;aAC/D,MAAM,CAAC,CAAC,CAAM,KAAK,OAAO,CAAC,KAAK,UAAU,CAAC;UAC9C,EAAE,CAAA;AACN,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM;UAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;aAC5D,MAAM,CAAC,CAAC,CAAM,KAAK,OAAO,CAAC,KAAK,UAAU,CAAC;UAC9C,EAAE,CAAA;AACN,IAAA,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAA;;;AAGlE,IAAA,MAAM,KAAK,GAAG;QACZ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9E,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,CAAC;KAC7E,CAAA;;;AAGD,IAAA,MAAM,OAAO,GAAG,CAAC,CAAS,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjG,MAAM,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;;;;;AAMxF,IAAA,MAAM,SAAS,GAAU,EAAE,EAAE,UAAU,GAAU,EAAE,CAAA;AACnD,IAAA,IAAI,QAAgB,CAAA;AACpB,IAAA,IAAI;AACF,QAAA,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE;AAC9B,YAAA,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,MAAM,CAAC,aAAa;;AAE7B,YAAA,IAAI,QAAQ,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACjE,YAAY,EAAE,QAAQ,GAAG,KAAK,GAAG,uBAAuB;AACxD,YAAA,IAAI,EAAE,SAAS;YACf,KAAK;AACN,SAAA,CAAC,CAAA;KACH;IAAC,OAAO,GAAQ,EAAE;;AAEjB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,IAAI;AACF,gBAAA,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC,CAAA;gBAC/E,IAAI,aAAa,EAAE;AACjB,oBAAA,QAAQ,GAAG,cAAc,CAAC,MAAM,aAAa,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;oBAC7D,IAAI,CAAC,QAAQ,EAAE;wBACb,QAAQ,IAAI,wCAAwC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA,SAAA,CAAW,CAAA;qBAC5F;iBACF;qBAAM;oBACL,QAAQ,GAAG,2CAA2C,CAAA;iBACvD;aACF;YAAC,OAAO,CAAC,EAAE;gBACV,QAAQ,GAAG,2CAA2C,CAAA;aACvD;SACF;aAAM;AACL,YAAA,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAA;AACrD,YAAA,QAAQ,GAAG,CAAA,8CAAA,EAAiD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,YAAY,CAAA;SACxG;KACF;;;;;;;IAQD,IAAI,eAAe,GAAG,QAAQ,CAAA;IAC9B,IAAI,QAAQ,EAAE;;;QAGZ,MAAM,IAAI,GAAG,oDAAoD,CAAA;QACjE,MAAM,WAAW,GAAG,yBAAyB,CAAA;;AAE7C,QAAA,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YAC9B,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;AACjH,YAAA,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE;AACpC,gBAAA,KAAK,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;;AAE9B,gBAAA,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACf,gBAAA,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;AACrE,gBAAA,IAAI,EAAE,UAAU;gBAChB,KAAK;gBACL,OAAO,EAAE,MAAM,CAAC,aAAa;AAC9B,aAAA,CAAC,CAAA;YACF,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAC7B,YAAA,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;YAC1D,IAAI,QAAQ,KAAK,CAAC,CAAC;AAAE,gBAAA,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,GAAG,WAAW,CAAC,MAAM,CAAA;AACvF,YAAA,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;gBACnB,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;aACzG;iBAAM;;AAEL,gBAAA,eAAe,GAAG,QAAQ,GAAG,eAAe,CAAA;aAC7C;SACF;;AAED,QAAA,eAAe,GAAG,CAAA,qBAAA,EAAwB,eAAe,CAAA,MAAA,CAAQ,CAAA;;;;QAKjE,MAAM,YAAY,GAAQ,EAAE,CAAA;AAC5B,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAO,KAAI,EAAG,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAA,EAAE,CAAC,CAAA;AAC/F,QAAA,YAAY,CAAC,IAAI,GAAG,YAAY,CAAA;QAChC,eAAe,IAAI,wCAAwC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA,SAAA,CAAW,CAAA;KACnG;;IAGD,IAAI,WAAW,GAAG,EAAE,CAAA;IACpB,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE;AACpD,QAAA,IAAI;AACF,YAAA,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAA;SACnE;QAAC,OAAO,CAAC,EAAE;;SAEX;KACF;AAED,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;AAChC,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAA;AAC5C,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;AACpC,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAA;AAEhC,IAAA,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;;AAE3D,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM;UACzB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,WAAW,IAAI,SAAS,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;AACxG,UAAE,KAAK,GAAG,CAAU,OAAA,EAAA,GAAG,CAAC,KAAK,CAAC,CAAU,QAAA,CAAA,GAAG,EAAE,CAAA;AAC/C,IAAA,MAAM,OAAO,GAAG,WAAW,IAAI,CAAC,KAAK,CAAC,MAAM;AAC1C,UAAE,CAAqC,kCAAA,EAAA,GAAG,CAAC,WAAW,CAAC,CAAI,EAAA,CAAA;UACzD,EAAE,CAAA;IACN,MAAM,UAAU,GAAG,OAAO;AACxB,UAAE,CAA0B,uBAAA,EAAA,GAAG,CAAC,OAAO,CAAC,CAAI,EAAA,CAAA;UAC1C,EAAE,CAAA;AAEN,IAAA,MAAM,YAAY,GAAG,CAAA;cACT,IAAI,CAAA;;;;MAIZ,QAAQ,CAAA;MACR,OAAO,CAAA;MACP,UAAU,CAAA;MACV,WAAW,CAAA;;;0BAGS,eAAe,CAAA;;QAEjC,CAAA;;;;;IAMN,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAA;AACrD;;;;"}
|
|
1
|
+
{"version":3,"file":"onRenderHtml.mjs","sources":["../../src/vike/shell.ts","../../src/vike/onRenderHtml.ts"],"sourcesContent":["/**\n * G-803: the shell components of a page (its Wrappers and Layouts), outermost first, with their\n * state keys. Shared by onRenderHtml and onRenderClient so the server and the client nest them\n * the same way.\n *\n * Vike's cumulative configs (`Layout` and `Wrapper` are, see +config.ts) list the values closest\n * to the page first: pages/admin/+Layout before pages/+Layout (vike's resolveVikeConfigInternal:\n * sortAfterInheritanceOrder puts the longer inheritance root first). So the root's come last, and\n * the shell reverses each list: every Wrapper outside every Layout (as vike-react), and within each\n * the root's outermost. Keys count from the outside in (wrapper_0, ..., layout_0, ...), so a root\n * Layout keeps `layout_0` on every page, nested or not.\n */\nexport interface ShellPart { comp: any; key: string }\n\nconst comps = (val: any): any[] =>\n (val ? (Array.isArray(val) ? val : [val]) : []).filter((c: any) => typeof c === 'function')\n\nexport function shellOf(config: { Wrapper?: any; Layout?: any }): ShellPart[] {\n return [\n ...comps(config.Wrapper).reverse().map((comp, i) => ({ comp, key: 'wrapper_' + i })),\n ...comps(config.Layout).reverse().map((comp, i) => ({ comp, key: 'layout_' + i })),\n ]\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'. onRenderClient gives it as the nested vnode's `id` prop, so the\n * Page's uid is 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the\n * same root (renderToString's `uid`), so server and client ids match.\n */\nexport function uidPart(key: string): string {\n return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)\n}\n","/**\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'\nimport { shellOf, uidPart } from './shell'\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\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 // Wrapper(s) and/or Layout(s), outermost first (G-803: Vike lists them closest first; shellOf\n // reverses them, the same order as onRenderClient's): they decide the hydration state's shape\n const shell = shellOf(config)\n const hasShell = shell.length > 0\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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"}
|