vike 0.4.196 → 0.4.197-commit-f4d8658
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/dist/cjs/client/client-routing-runtime/prefetch/PrefetchSetting.js +2 -0
- package/dist/cjs/client/server-routing-runtime/onLoad.js +7 -0
- package/dist/cjs/client/server-routing-runtime/utils.js +34 -0
- package/dist/cjs/client/shared/getPageContextProxyForUser.js +79 -0
- package/dist/cjs/client/shared/preparePageContextForUserConsumptionClientSide.js +46 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +17 -1
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +2 -2
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.js +26 -23
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformFileImports.js → transformPointerImports.js} +3 -4
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +44 -47
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -1
- package/dist/cjs/node/prerender/runPrerender.js +5 -5
- package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
- package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/cjs/node/runtime/html/serializePageContextClientSide.js +2 -2
- package/dist/cjs/node/runtime/renderPage/createHttpResponse.js +3 -3
- package/dist/cjs/node/runtime/renderPage/debugPageFiles.js +1 -1
- package/dist/cjs/node/runtime/renderPage/handleErrorWithoutErrorPage.js +1 -1
- package/dist/cjs/node/runtime/renderPage/loadUserFilesServerSide.js +4 -4
- package/dist/cjs/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.js +2 -7
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +4 -4
- package/dist/cjs/node/runtime/renderPage.js +8 -8
- package/dist/cjs/shared/addIs404ToPageProps.js +1 -1
- package/dist/cjs/shared/assertPageContextProvidedByUser.js +1 -1
- package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +2 -2
- package/dist/cjs/shared/preparePageContextForUserConsumption.js +34 -0
- package/dist/cjs/shared/route/executeGuardHook.js +1 -1
- package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +6 -6
- package/dist/cjs/shared/route/index.js +3 -3
- package/dist/cjs/shared/route/resolveRouteString.js +10 -1
- package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
- package/dist/cjs/utils/isNpmPackage.js +4 -0
- package/dist/cjs/utils/isScriptFile.js +3 -3
- package/dist/esm/client/client-routing-runtime/entry.js +2 -2
- package/dist/esm/client/client-routing-runtime/getPageContextCurrent.d.ts +10 -0
- package/dist/esm/client/client-routing-runtime/getPageContextCurrent.js +25 -0
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.d.ts +28 -18
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +39 -32
- package/dist/esm/client/client-routing-runtime/history.js +1 -1
- package/dist/esm/client/client-routing-runtime/initClientRouter.d.ts +2 -0
- package/dist/esm/client/client-routing-runtime/{installClientRouter.js → initClientRouter.js} +11 -8
- package/dist/esm/client/client-routing-runtime/initOnLinkClick.d.ts +2 -0
- package/dist/esm/client/client-routing-runtime/{onLinkClick.js → initOnLinkClick.js} +2 -2
- package/dist/esm/client/client-routing-runtime/isClientSideRoutable.js +1 -0
- package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +1 -1
- package/dist/esm/client/client-routing-runtime/prefetch/PrefetchSetting.d.ts +7 -0
- package/dist/esm/client/client-routing-runtime/prefetch/PrefetchSetting.js +1 -0
- package/dist/esm/client/client-routing-runtime/prefetch/getPrefetchSettings.d.ts +8 -7
- package/dist/esm/client/client-routing-runtime/prefetch/getPrefetchSettings.js +75 -67
- package/dist/esm/client/client-routing-runtime/prefetch.d.ts +29 -5
- package/dist/esm/client/client-routing-runtime/prefetch.js +178 -65
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +117 -28
- package/dist/esm/client/server-routing-runtime/getPageContext.d.ts +1 -1
- package/dist/esm/client/server-routing-runtime/getPageContext.js +1 -1
- package/dist/esm/client/shared/executeOnRenderClientHook.d.ts +1 -1
- package/dist/esm/client/shared/getPageContextSerializedInHtml.d.ts +1 -1
- package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
- package/dist/esm/client/shared/preparePageContextForUserConsumptionClientSide.d.ts +1 -1
- package/dist/esm/client/shared/preparePageContextForUserConsumptionClientSide.js +20 -29
- package/dist/esm/client/shared/removeFoucBuster.js +17 -11
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +17 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.d.ts +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.js +25 -22
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformFileImports.d.ts → transformPointerImports.d.ts} +2 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformFileImports.js → transformPointerImports.js} +3 -4
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +45 -48
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -1
- package/dist/esm/node/prerender/runPrerender.js +5 -5
- package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
- package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/esm/node/runtime/html/injectAssets.d.ts +1 -1
- package/dist/esm/node/runtime/html/serializePageContextClientSide.d.ts +1 -1
- package/dist/esm/node/runtime/html/serializePageContextClientSide.js +2 -2
- package/dist/esm/node/runtime/renderPage/createHttpResponse.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponse.js +3 -3
- package/dist/esm/node/runtime/renderPage/debugPageFiles.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/debugPageFiles.js +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderAndDataHooks.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/handleErrorWithoutErrorPage.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/handleErrorWithoutErrorPage.js +1 -1
- package/dist/esm/node/runtime/renderPage/loadUserFilesServerSide.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/loadUserFilesServerSide.js +4 -4
- package/dist/esm/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.js +3 -8
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +6 -6
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +4 -4
- package/dist/esm/node/runtime/renderPage.js +8 -8
- package/dist/esm/shared/addIs404ToPageProps.d.ts +1 -1
- package/dist/esm/shared/addIs404ToPageProps.js +1 -1
- package/dist/esm/shared/assertPageContextProvidedByUser.js +1 -1
- package/dist/esm/shared/page-configs/Config.d.ts +21 -1
- package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +1 -1
- package/dist/esm/shared/preparePageContextForUserConsumption.d.ts +5 -0
- package/dist/esm/shared/preparePageContextForUserConsumption.js +32 -0
- package/dist/esm/shared/route/executeGuardHook.d.ts +1 -1
- package/dist/esm/shared/route/executeGuardHook.js +1 -1
- package/dist/esm/shared/route/executeOnBeforeRouteHook.js +6 -6
- package/dist/esm/shared/route/index.d.ts +1 -1
- package/dist/esm/shared/route/index.js +3 -3
- package/dist/esm/shared/route/resolveRouteString.d.ts +2 -15
- package/dist/esm/shared/route/resolveRouteString.js +10 -1
- package/dist/esm/shared/types.d.ts +6 -2
- package/dist/esm/types/index.d.ts +1 -1
- package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/esm/utils/PROJECT_VERSION.js +1 -1
- package/dist/esm/utils/isNpmPackage.d.ts +2 -0
- package/dist/esm/utils/isNpmPackage.js +4 -0
- package/dist/esm/utils/isScriptFile.d.ts +2 -2
- package/dist/esm/utils/isScriptFile.js +3 -3
- package/dist/esm/utils/projectInfo.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cjs/shared/sortPageContext.js +0 -12
- package/dist/esm/client/client-routing-runtime/installClientRouter.d.ts +0 -2
- package/dist/esm/client/client-routing-runtime/onLinkClick.d.ts +0 -2
- package/dist/esm/client/client-routing-runtime/prefetch/alreadyPrefetched.d.ts +0 -4
- package/dist/esm/client/client-routing-runtime/prefetch/alreadyPrefetched.js +0 -16
- package/dist/esm/shared/sortPageContext.d.ts +0 -2
- package/dist/esm/shared/sortPageContext.js +0 -10
- /package/{readme.md → README.md} +0 -0
|
@@ -1,21 +1,46 @@
|
|
|
1
1
|
export { prefetch };
|
|
2
|
+
export { getPageContextPrefetched };
|
|
3
|
+
export { initLinkPrefetchHandlers };
|
|
4
|
+
export { populatePageContextPrefetchCache };
|
|
2
5
|
export { addLinkPrefetchHandlers };
|
|
3
|
-
|
|
6
|
+
export { addLinkPrefetchHandlers_watch };
|
|
7
|
+
export { addLinkPrefetchHandlers_unwatch };
|
|
8
|
+
import { assert, assertClientRouting, assertUsage, assertUsageUrlPathname, assertWarning, checkIfClientRouting, getGlobalObject, hasProp, objectAssign } from './utils.js';
|
|
4
9
|
import { isErrorFetchingStaticAssets, loadUserFilesClientSide } from '../shared/loadUserFilesClientSide.js';
|
|
5
10
|
import { skipLink } from './skipLink.js';
|
|
6
|
-
import { getPrefetchSettings } from './prefetch/getPrefetchSettings.js';
|
|
7
|
-
import { isAlreadyPrefetched, markAsAlreadyPrefetched } from './prefetch/alreadyPrefetched.js';
|
|
8
11
|
import { disableClientRouting } from './renderPageClientSide.js';
|
|
9
12
|
import { isClientSideRoutable } from './isClientSideRoutable.js';
|
|
10
13
|
import { createPageContext } from './createPageContext.js';
|
|
11
14
|
import { route } from '../../shared/route/index.js';
|
|
12
15
|
import { noRouteMatch } from '../../shared/route/noRouteMatch.js';
|
|
16
|
+
import { getPageContextFromServerHooks } from './getPageContextFromHooks.js';
|
|
17
|
+
import { getPageContextCurrent } from './getPageContextCurrent.js';
|
|
18
|
+
import { PAGE_CONTEXT_MAX_AGE_DEFAULT, getPrefetchSettings } from './prefetch/getPrefetchSettings.js';
|
|
13
19
|
import pc from '@brillout/picocolors';
|
|
14
20
|
assertClientRouting();
|
|
15
|
-
const globalObject = getGlobalObject('prefetch.ts', {
|
|
16
|
-
|
|
21
|
+
const globalObject = getGlobalObject('prefetch.ts', {
|
|
22
|
+
linkPrefetchHandlerAdded: new WeakSet(),
|
|
23
|
+
addLinkPrefetchHandlers_debounce: null,
|
|
24
|
+
mutationObserver: new MutationObserver(addLinkPrefetchHandlers),
|
|
25
|
+
// `linkTags` [is automatically updated](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection#:~:text=An%20HTMLCollection%20in%20the%20HTML%20DOM%20is%20live%3B%20it%20is%20automatically%20updated%20when%20the%20underlying%20document%20is%20changed.)
|
|
26
|
+
linkTags: document.getElementsByTagName('A'),
|
|
27
|
+
prefetchedPageContexts: {}
|
|
28
|
+
});
|
|
29
|
+
function getPageContextPrefetched(pageContext) {
|
|
30
|
+
const key = getCacheKey(pageContext.urlPathname);
|
|
31
|
+
const found = globalObject.prefetchedPageContexts[key];
|
|
32
|
+
if (!found || found.result.is404ServerSideRouted || isExpired(found))
|
|
33
|
+
return null;
|
|
34
|
+
const pageContextPrefetched = found.result.pageContextFromServerHooks;
|
|
35
|
+
/* TODO/pageContext-prefetch: make it work for when resultMaxAge is Infinity.
|
|
36
|
+
// We discard the prefetched pageContext whenever we use it, so that the user always sees fresh data upon naivgating.
|
|
37
|
+
delete globalObject.prefetchedPageContexts[key]
|
|
38
|
+
*/
|
|
39
|
+
return pageContextPrefetched;
|
|
40
|
+
}
|
|
41
|
+
async function prefetchAssets(pageContextLink) {
|
|
17
42
|
try {
|
|
18
|
-
await loadUserFilesClientSide(pageId,
|
|
43
|
+
await loadUserFilesClientSide(pageContextLink.pageId, pageContextLink._pageFilesAll, pageContextLink._pageConfigs);
|
|
19
44
|
}
|
|
20
45
|
catch (err) {
|
|
21
46
|
if (isErrorFetchingStaticAssets(err)) {
|
|
@@ -26,6 +51,32 @@ async function prefetchAssets(pageId, pageContext) {
|
|
|
26
51
|
}
|
|
27
52
|
}
|
|
28
53
|
}
|
|
54
|
+
async function prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge) {
|
|
55
|
+
const result = await getPageContextFromServerHooks(pageContextLink, false);
|
|
56
|
+
setPageContextPrefetchCache(pageContextLink, result, resultMaxAge);
|
|
57
|
+
}
|
|
58
|
+
function populatePageContextPrefetchCache(pageContext, result) {
|
|
59
|
+
setPageContextPrefetchCache(pageContext, result, null);
|
|
60
|
+
}
|
|
61
|
+
function setPageContextPrefetchCache(pageContext, result, resultMaxAge) {
|
|
62
|
+
if (resultMaxAge === null)
|
|
63
|
+
resultMaxAge = getResultMaxAge();
|
|
64
|
+
const key = getCacheKey(pageContext.urlPathname);
|
|
65
|
+
globalObject.prefetchedPageContexts[key] = {
|
|
66
|
+
resultFetchedAt: Date.now(),
|
|
67
|
+
resultMaxAge,
|
|
68
|
+
result
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function getResultMaxAge() {
|
|
72
|
+
const pageContextCurrent = getPageContextCurrent();
|
|
73
|
+
// TODO/pageContext-prefetch: remove this dirty hack used by @brillout/docpress and, instead, use Vike's default if pageContextCurrent isn't defined yet.
|
|
74
|
+
if (!pageContextCurrent)
|
|
75
|
+
return Infinity;
|
|
76
|
+
const prefetchSettings = getPrefetchSettings(pageContextCurrent, null);
|
|
77
|
+
const resultMaxAge = typeof prefetchSettings.pageContext === 'number' ? prefetchSettings.pageContext : PAGE_CONTEXT_MAX_AGE_DEFAULT;
|
|
78
|
+
return resultMaxAge;
|
|
79
|
+
}
|
|
29
80
|
/**
|
|
30
81
|
* Programmatically prefetch client assets.
|
|
31
82
|
*
|
|
@@ -33,85 +84,147 @@ async function prefetchAssets(pageId, pageContext) {
|
|
|
33
84
|
*
|
|
34
85
|
* @param url - The URL of the page you want to prefetch.
|
|
35
86
|
*/
|
|
36
|
-
async function prefetch(url) {
|
|
87
|
+
async function prefetch(url, options) {
|
|
37
88
|
assertUsage(checkIfClientRouting(), 'prefetch() only works with Client Routing, see https://vike.dev/prefetch', {
|
|
38
89
|
showStackTrace: true
|
|
39
90
|
});
|
|
40
91
|
const errPrefix = '[prefetch(url)] url';
|
|
41
92
|
assertUsageUrlPathname(url, errPrefix);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
markAsAlreadyPrefetched(url);
|
|
45
|
-
const pageContext = await createPageContext(url);
|
|
46
|
-
let pageContextFromRoute;
|
|
47
|
-
try {
|
|
48
|
-
pageContextFromRoute = await route(pageContext);
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
// If a route() hook has a bug or `throw render()` / `throw redirect()`
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const pageId = pageContextFromRoute._pageId;
|
|
55
|
-
if (!pageId) {
|
|
93
|
+
const pageContextLink = await getPageContextLink(url);
|
|
94
|
+
if (!pageContextLink?.pageId) {
|
|
56
95
|
assertWarning(false, `${errPrefix} ${pc.string(url)} ${noRouteMatch}`, {
|
|
57
96
|
showStackTrace: true,
|
|
58
97
|
onlyOnce: false
|
|
59
98
|
});
|
|
60
99
|
return;
|
|
61
100
|
}
|
|
62
|
-
|
|
101
|
+
assert(hasProp(pageContextLink, 'pageId', 'string')); // help TypeScript
|
|
102
|
+
await Promise.all([
|
|
103
|
+
(async () => {
|
|
104
|
+
if (options?.staticAssets !== false) {
|
|
105
|
+
await prefetchAssets(pageContextLink);
|
|
106
|
+
}
|
|
107
|
+
})(),
|
|
108
|
+
(async () => {
|
|
109
|
+
if (options?.pageContext !== false) {
|
|
110
|
+
const resultMaxAge = typeof options?.pageContext === 'number' ? options.pageContext : null;
|
|
111
|
+
await prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge);
|
|
112
|
+
}
|
|
113
|
+
})()
|
|
114
|
+
]);
|
|
63
115
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const url = linkTag.getAttribute('href');
|
|
73
|
-
if (skipLink(linkTag))
|
|
74
|
-
return;
|
|
75
|
-
assert(url);
|
|
76
|
-
if (isAlreadyPrefetched(url))
|
|
77
|
-
return;
|
|
78
|
-
const { prefetchStaticAssets } = getPrefetchSettings(pageContext, linkTag);
|
|
79
|
-
if (!prefetchStaticAssets)
|
|
80
|
-
return;
|
|
81
|
-
if (prefetchStaticAssets === 'hover') {
|
|
82
|
-
linkTag.addEventListener('mouseover', () => {
|
|
83
|
-
prefetchIfPossible(url);
|
|
84
|
-
});
|
|
85
|
-
linkTag.addEventListener('touchstart', () => {
|
|
86
|
-
prefetchIfPossible(url);
|
|
87
|
-
}, { passive: true });
|
|
116
|
+
// Lazy execution logic copied from: https://github.com/withastro/astro/blob/2594eb088d53a98181ac820243bcb1a765856ecf/packages/astro/src/runtime/client/dev-toolbar/apps/audit/index.ts#L53-L72
|
|
117
|
+
function addLinkPrefetchHandlers() {
|
|
118
|
+
if (globalObject.addLinkPrefetchHandlers_debounce)
|
|
119
|
+
clearTimeout(globalObject.addLinkPrefetchHandlers_debounce);
|
|
120
|
+
globalObject.addLinkPrefetchHandlers_debounce = setTimeout(() => {
|
|
121
|
+
// Wait for the next idle period, as it is less likely to interfere with any other work the browser is doing post-mutation.
|
|
122
|
+
if ('requestIdleCallback' in window) {
|
|
123
|
+
requestIdleCallback(addLinkPrefetchHandlers_apply, { timeout: 300 });
|
|
88
124
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (entry.isIntersecting) {
|
|
93
|
-
prefetchIfPossible(url);
|
|
94
|
-
observer.disconnect();
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
observer.observe(linkTag);
|
|
125
|
+
else {
|
|
126
|
+
// Fallback for old versions of Safari, we'll assume that things are less likely to be busy after 150ms.
|
|
127
|
+
setTimeout(addLinkPrefetchHandlers_apply, 150);
|
|
99
128
|
}
|
|
129
|
+
}, 250);
|
|
130
|
+
}
|
|
131
|
+
function initLinkPrefetchHandlers() {
|
|
132
|
+
addLinkPrefetchHandlers();
|
|
133
|
+
}
|
|
134
|
+
function addLinkPrefetchHandlers_watch() {
|
|
135
|
+
// Notes about performance:
|
|
136
|
+
// - https://stackoverflow.com/questions/31659567/performance-of-mutationobserver-to-detect-nodes-in-entire-dom/39332340#39332340
|
|
137
|
+
// - https://news.ycombinator.com/item?id=15274211
|
|
138
|
+
// - https://github.com/kubetail-org/sentineljs
|
|
139
|
+
// - https://stackoverflow.com/questions/55046093/listening-for-changes-in-htmlcollection-or-achieving-a-similar-effect
|
|
140
|
+
globalObject.mutationObserver.observe(document.body, {
|
|
141
|
+
childList: true,
|
|
142
|
+
subtree: true
|
|
100
143
|
});
|
|
101
144
|
}
|
|
102
|
-
|
|
103
|
-
|
|
145
|
+
function addLinkPrefetchHandlers_unwatch() {
|
|
146
|
+
globalObject.mutationObserver.disconnect();
|
|
147
|
+
}
|
|
148
|
+
function addLinkPrefetchHandlers_apply() {
|
|
149
|
+
for (let linkTag of globalObject.linkTags) {
|
|
150
|
+
if (globalObject.linkPrefetchHandlerAdded.has(linkTag))
|
|
151
|
+
continue;
|
|
152
|
+
globalObject.linkPrefetchHandlerAdded.add(linkTag);
|
|
153
|
+
if (skipLink(linkTag))
|
|
154
|
+
continue;
|
|
155
|
+
linkTag.addEventListener('mouseover', () => {
|
|
156
|
+
prefetchOnEvent(linkTag, 'hover');
|
|
157
|
+
}, { passive: true });
|
|
158
|
+
linkTag.addEventListener('touchstart', () => {
|
|
159
|
+
prefetchOnEvent(linkTag, 'hover');
|
|
160
|
+
}, { passive: true });
|
|
161
|
+
const observer = new IntersectionObserver((entries) => {
|
|
162
|
+
entries.forEach((entry) => {
|
|
163
|
+
if (entry.isIntersecting) {
|
|
164
|
+
prefetchOnEvent(linkTag, 'viewport');
|
|
165
|
+
observer.disconnect();
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
observer.observe(linkTag);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function prefetchOnEvent(linkTag, event) {
|
|
173
|
+
let prefetchSettings;
|
|
174
|
+
const pageContextCurrent = getPageContextCurrent();
|
|
175
|
+
if (pageContextCurrent) {
|
|
176
|
+
prefetchSettings = getPrefetchSettings(pageContextCurrent, linkTag);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// TODO/pageContext-prefetch: remove this dirty hack used by @brillout/docpress and, instead, use Vike's default if pageContextCurrent isn't defined yet.
|
|
180
|
+
prefetchSettings = { staticAssets: 'hover', pageContext: Infinity };
|
|
181
|
+
}
|
|
182
|
+
const urlOfLink = linkTag.getAttribute('href');
|
|
183
|
+
assert(urlOfLink);
|
|
184
|
+
const pageContextLink = await getPageContextLink(urlOfLink);
|
|
185
|
+
if (!pageContextLink?.pageId)
|
|
186
|
+
return;
|
|
187
|
+
assert(hasProp(pageContextLink, 'pageId', 'string')); // help TypeScript
|
|
188
|
+
if (!(await isClientSideRoutable(pageContextLink.pageId, pageContextLink)))
|
|
189
|
+
return;
|
|
190
|
+
await Promise.all([
|
|
191
|
+
(async () => {
|
|
192
|
+
if (prefetchSettings.staticAssets === event) {
|
|
193
|
+
await prefetchAssets(pageContextLink);
|
|
194
|
+
}
|
|
195
|
+
})(),
|
|
196
|
+
(async () => {
|
|
197
|
+
if (event !== 'viewport' && prefetchSettings.pageContext) {
|
|
198
|
+
const key = getCacheKey(urlOfLink);
|
|
199
|
+
const found = globalObject.prefetchedPageContexts[key];
|
|
200
|
+
if (!found || isExpired(found)) {
|
|
201
|
+
// TODO/pageContext-prefetch: move this logic in getPrefetchSettings()
|
|
202
|
+
const resultMaxAge = prefetchSettings.pageContext;
|
|
203
|
+
await prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})()
|
|
207
|
+
]);
|
|
208
|
+
}
|
|
209
|
+
function isExpired(found) {
|
|
210
|
+
return Date.now() - found.resultFetchedAt > found.resultMaxAge;
|
|
211
|
+
}
|
|
212
|
+
// TODO/next-major-release: make it sync
|
|
213
|
+
async function getPageContextLink(urlOfLink) {
|
|
214
|
+
const pageContextLink = await createPageContext(urlOfLink);
|
|
104
215
|
let pageContextFromRoute;
|
|
105
216
|
try {
|
|
106
|
-
pageContextFromRoute = await route(
|
|
217
|
+
pageContextFromRoute = await route(pageContextLink);
|
|
107
218
|
}
|
|
108
219
|
catch {
|
|
109
220
|
// If a route() hook has a bug or `throw render()` / `throw redirect()`
|
|
110
|
-
return;
|
|
221
|
+
return null;
|
|
111
222
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
223
|
+
objectAssign(pageContextLink, pageContextFromRoute);
|
|
224
|
+
return pageContextLink;
|
|
225
|
+
}
|
|
226
|
+
function getCacheKey(urlPathname) {
|
|
227
|
+
assert(urlPathname.startsWith('/'));
|
|
228
|
+
const key = urlPathname.split('#')[0];
|
|
229
|
+
return key;
|
|
117
230
|
}
|
|
@@ -2,10 +2,10 @@ export { renderPageClientSide };
|
|
|
2
2
|
export { getRenderCount };
|
|
3
3
|
export { disableClientRouting };
|
|
4
4
|
export { firstRenderStartPromise };
|
|
5
|
-
import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType, genPromise } from './utils.js';
|
|
6
|
-
import {
|
|
5
|
+
import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType, genPromise, isCallable } from './utils.js';
|
|
6
|
+
import { getPageContextFromClientHooks, getPageContextFromServerHooks, getPageContextFromHooks_isHydration, getPageContextFromHooks_serialized, setPageContextInitIsPassedToClient } from './getPageContextFromHooks.js';
|
|
7
7
|
import { createPageContext } from './createPageContext.js';
|
|
8
|
-
import { addLinkPrefetchHandlers } from './prefetch.js';
|
|
8
|
+
import { addLinkPrefetchHandlers, addLinkPrefetchHandlers_unwatch, addLinkPrefetchHandlers_watch, getPageContextPrefetched, populatePageContextPrefetchCache } from './prefetch.js';
|
|
9
9
|
import { assertInfo, assertWarning, isReact } from './utils.js';
|
|
10
10
|
import { executeOnRenderClientHook } from '../shared/executeOnRenderClientHook.js';
|
|
11
11
|
import { assertHook, getHook } from '../../shared/hooks/getHook.js';
|
|
@@ -18,6 +18,8 @@ import { setScrollPosition } from './setScrollPosition.js';
|
|
|
18
18
|
import { updateState } from './onBrowserHistoryNavigation.js';
|
|
19
19
|
import { browserNativeScrollRestoration_disable, setInitialRenderIsDone } from './scrollRestoration.js';
|
|
20
20
|
import { getErrorPageId } from '../../shared/error-page.js';
|
|
21
|
+
import { setPageContextCurrent } from './getPageContextCurrent.js';
|
|
22
|
+
import { getRouteStringParameterList } from '../../shared/route/resolveRouteString.js';
|
|
21
23
|
const globalObject = getGlobalObject('renderPageClientSide.ts', (() => {
|
|
22
24
|
const { promise: firstRenderStartPromise, resolve: firstRenderStartPromiseResolve } = genPromise();
|
|
23
25
|
return {
|
|
@@ -28,8 +30,10 @@ const globalObject = getGlobalObject('renderPageClientSide.ts', (() => {
|
|
|
28
30
|
})());
|
|
29
31
|
const { firstRenderStartPromise } = globalObject;
|
|
30
32
|
async function renderPageClientSide(renderArgs) {
|
|
31
|
-
const {
|
|
33
|
+
const { urlOriginal = getCurrentUrl(), overwriteLastHistoryEntry = false, isBackwardNavigation, pageContextsFromRewrite = [], redirectCount = 0, isUserLandPushStateNavigation, isClientSideNavigation = true } = renderArgs;
|
|
34
|
+
let { scrollTarget } = renderArgs;
|
|
32
35
|
const { previousPageContext } = globalObject;
|
|
36
|
+
addLinkPrefetchHandlers_unwatch();
|
|
33
37
|
const { isRenderOutdated, setHydrationCanBeAborted, isFirstRender } = getIsRenderOutdated();
|
|
34
38
|
// Note that pageContext.isHydration isn't equivalent to isFirstRender
|
|
35
39
|
// - Thus pageContext.isHydration isn't equivalent to !pageContext.isClientSideNavigation
|
|
@@ -93,7 +97,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
93
97
|
}
|
|
94
98
|
if (isRenderOutdated())
|
|
95
99
|
return;
|
|
96
|
-
if (!pageContextFromRoute.
|
|
100
|
+
if (!pageContextFromRoute.pageId) {
|
|
97
101
|
/*
|
|
98
102
|
// We don't use the client router to render the 404 page:
|
|
99
103
|
// - So that the +redirects setting (https://vike.dev/redirects) can be applied.
|
|
@@ -106,17 +110,17 @@ async function renderPageClientSide(renderArgs) {
|
|
|
106
110
|
redirectHard(urlOriginal);
|
|
107
111
|
return;
|
|
108
112
|
}
|
|
109
|
-
assert(hasProp(pageContextFromRoute, '
|
|
110
|
-
const isClientRoutable = await isClientSideRoutable(pageContextFromRoute.
|
|
113
|
+
assert(hasProp(pageContextFromRoute, 'pageId', 'string')); // Help TS
|
|
114
|
+
const isClientRoutable = await isClientSideRoutable(pageContextFromRoute.pageId, pageContext);
|
|
111
115
|
if (isRenderOutdated())
|
|
112
116
|
return;
|
|
113
117
|
if (!isClientRoutable) {
|
|
114
118
|
redirectHard(urlOriginal);
|
|
115
119
|
return;
|
|
116
120
|
}
|
|
117
|
-
const isSamePage = pageContextFromRoute.
|
|
118
|
-
previousPageContext?.
|
|
119
|
-
pageContextFromRoute.
|
|
121
|
+
const isSamePage = pageContextFromRoute.pageId &&
|
|
122
|
+
previousPageContext?.pageId &&
|
|
123
|
+
pageContextFromRoute.pageId === previousPageContext.pageId;
|
|
120
124
|
if (isUserLandPushStateNavigation && isSamePage) {
|
|
121
125
|
// Skip's Vike's rendering; let the user handle the navigation
|
|
122
126
|
return;
|
|
@@ -126,7 +130,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
126
130
|
assert(!('urlOriginal' in pageContextRouted));
|
|
127
131
|
objectAssign(pageContext, pageContextRouted);
|
|
128
132
|
try {
|
|
129
|
-
objectAssign(pageContext, await loadUserFilesClientSide(pageContext.
|
|
133
|
+
objectAssign(pageContext, await loadUserFilesClientSide(pageContext.pageId, pageContext._pageFilesAll, pageContext._pageConfigs));
|
|
130
134
|
}
|
|
131
135
|
catch (err) {
|
|
132
136
|
if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender)) {
|
|
@@ -140,6 +144,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
140
144
|
}
|
|
141
145
|
if (isRenderOutdated())
|
|
142
146
|
return;
|
|
147
|
+
setPageContextCurrent(pageContext);
|
|
143
148
|
// Set global hydrationCanBeAborted
|
|
144
149
|
if (pageContext.exports.hydrationCanBeAborted) {
|
|
145
150
|
setHydrationCanBeAborted();
|
|
@@ -147,7 +152,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
147
152
|
else {
|
|
148
153
|
assertWarning(!isReact(), 'You seem to be using React; we recommend setting hydrationCanBeAborted to true, see https://vike.dev/hydrationCanBeAborted', { onlyOnce: true });
|
|
149
154
|
}
|
|
150
|
-
// There wasn't any `await` but
|
|
155
|
+
// There wasn't any `await` but the isRenderOutdated() return value may have changed because we called setHydrationCanBeAborted()
|
|
151
156
|
if (isRenderOutdated())
|
|
152
157
|
return;
|
|
153
158
|
// Get pageContext from hooks (fetched from server, and/or directly called on the client-side)
|
|
@@ -168,9 +173,34 @@ async function renderPageClientSide(renderArgs) {
|
|
|
168
173
|
await renderPageView(pageContext);
|
|
169
174
|
}
|
|
170
175
|
else {
|
|
171
|
-
|
|
176
|
+
// Fetch pageContext from server-side hooks
|
|
177
|
+
let pageContextFromServerHooks;
|
|
178
|
+
const pageContextPrefetched = getPageContextPrefetched(pageContext);
|
|
179
|
+
if (pageContextPrefetched) {
|
|
180
|
+
pageContextFromServerHooks = pageContextPrefetched;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
try {
|
|
184
|
+
const result = await getPageContextFromServerHooks(pageContext, false);
|
|
185
|
+
if (result.is404ServerSideRouted)
|
|
186
|
+
return;
|
|
187
|
+
pageContextFromServerHooks = result.pageContextFromServerHooks;
|
|
188
|
+
populatePageContextPrefetchCache(pageContext, result);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
await onError(err);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (isRenderOutdated())
|
|
196
|
+
return;
|
|
197
|
+
// TODO/eventually: create helper assertPageContextFromHook()
|
|
198
|
+
assert(!('urlOriginal' in pageContextFromServerHooks));
|
|
199
|
+
objectAssign(pageContext, pageContextFromServerHooks);
|
|
200
|
+
// Get pageContext from client-side hooks
|
|
201
|
+
let pageContextFromClientHooks;
|
|
172
202
|
try {
|
|
173
|
-
|
|
203
|
+
pageContextFromClientHooks = await getPageContextFromClientHooks(pageContext, false);
|
|
174
204
|
}
|
|
175
205
|
catch (err) {
|
|
176
206
|
await onError(err);
|
|
@@ -178,10 +208,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
178
208
|
}
|
|
179
209
|
if (isRenderOutdated())
|
|
180
210
|
return;
|
|
181
|
-
|
|
182
|
-
return;
|
|
183
|
-
augmentType(pageContext, res.pageContextAugmented);
|
|
184
|
-
// Render page view
|
|
211
|
+
augmentType(pageContext, pageContextFromClientHooks);
|
|
185
212
|
await renderPageView(pageContext);
|
|
186
213
|
}
|
|
187
214
|
}
|
|
@@ -284,9 +311,9 @@ async function renderPageClientSide(renderArgs) {
|
|
|
284
311
|
if (!errorPageId)
|
|
285
312
|
throw new Error('No error page defined.');
|
|
286
313
|
objectAssign(pageContext, {
|
|
287
|
-
|
|
314
|
+
pageId: errorPageId
|
|
288
315
|
});
|
|
289
|
-
const isClientRoutable = await isClientSideRoutable(pageContext.
|
|
316
|
+
const isClientRoutable = await isClientSideRoutable(pageContext.pageId, pageContext);
|
|
290
317
|
if (isRenderOutdated())
|
|
291
318
|
return;
|
|
292
319
|
if (!isClientRoutable) {
|
|
@@ -294,7 +321,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
294
321
|
return;
|
|
295
322
|
}
|
|
296
323
|
try {
|
|
297
|
-
objectAssign(pageContext, await loadUserFilesClientSide(pageContext.
|
|
324
|
+
objectAssign(pageContext, await loadUserFilesClientSide(pageContext.pageId, pageContext._pageFilesAll, pageContext._pageConfigs));
|
|
298
325
|
}
|
|
299
326
|
catch (err) {
|
|
300
327
|
if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender)) {
|
|
@@ -308,21 +335,35 @@ async function renderPageClientSide(renderArgs) {
|
|
|
308
335
|
}
|
|
309
336
|
if (isRenderOutdated())
|
|
310
337
|
return;
|
|
311
|
-
|
|
338
|
+
setPageContextCurrent(pageContext);
|
|
339
|
+
let pageContextFromServerHooks;
|
|
312
340
|
try {
|
|
313
|
-
|
|
341
|
+
const result = await getPageContextFromServerHooks(pageContext, true);
|
|
342
|
+
if (result.is404ServerSideRouted)
|
|
343
|
+
return;
|
|
344
|
+
pageContextFromServerHooks = result.pageContextFromServerHooks;
|
|
314
345
|
}
|
|
315
346
|
catch (err) {
|
|
316
|
-
// - When user hasn't defined a `_error.page.js` file
|
|
317
|
-
// - Some Vike unpexected internal error
|
|
318
347
|
onError(err);
|
|
319
348
|
return;
|
|
320
349
|
}
|
|
321
350
|
if (isRenderOutdated())
|
|
322
351
|
return;
|
|
323
|
-
|
|
352
|
+
// TODO/eventually: create helper assertPageContextFromHook()
|
|
353
|
+
assert(!('urlOriginal' in pageContextFromServerHooks));
|
|
354
|
+
objectAssign(pageContext, pageContextFromServerHooks);
|
|
355
|
+
let pageContextFromClientHooks;
|
|
356
|
+
try {
|
|
357
|
+
pageContextFromClientHooks = await getPageContextFromClientHooks(pageContext, true);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
onError(err);
|
|
324
361
|
return;
|
|
325
|
-
|
|
362
|
+
}
|
|
363
|
+
if (isRenderOutdated())
|
|
364
|
+
return;
|
|
365
|
+
augmentType(pageContext, pageContextFromClientHooks);
|
|
366
|
+
objectAssign(pageContext, { routeParams: {} });
|
|
326
367
|
await renderPageView(pageContext, args);
|
|
327
368
|
}
|
|
328
369
|
async function renderPageView(pageContext, isErrorPage) {
|
|
@@ -369,7 +410,6 @@ async function renderPageClientSide(renderArgs) {
|
|
|
369
410
|
/* We don't abort in order to ensure that onHydrationEnd() is called: we abort only after onHydrationEnd() is called.
|
|
370
411
|
if (isRenderOutdated(true)) return
|
|
371
412
|
*/
|
|
372
|
-
addLinkPrefetchHandlers(pageContext);
|
|
373
413
|
// onHydrationEnd()
|
|
374
414
|
if (isFirstRender && !onRenderClientError) {
|
|
375
415
|
assertHook(pageContext, 'onHydrationEnd');
|
|
@@ -411,10 +451,24 @@ async function renderPageClientSide(renderArgs) {
|
|
|
411
451
|
return;
|
|
412
452
|
}
|
|
413
453
|
}
|
|
454
|
+
if (!scrollTarget && previousPageContext) {
|
|
455
|
+
const keepScrollPositionPrev = getKeepScrollPositionSetting(previousPageContext);
|
|
456
|
+
const keepScrollPositionNext = getKeepScrollPositionSetting(pageContext);
|
|
457
|
+
if (keepScrollPositionNext !== false &&
|
|
458
|
+
keepScrollPositionPrev !== false &&
|
|
459
|
+
areKeysEqual(keepScrollPositionNext, keepScrollPositionPrev)) {
|
|
460
|
+
scrollTarget = { preserveScroll: true };
|
|
461
|
+
}
|
|
462
|
+
}
|
|
414
463
|
// Page scrolling
|
|
415
464
|
setScrollPosition(scrollTarget);
|
|
416
465
|
browserNativeScrollRestoration_disable();
|
|
417
466
|
setInitialRenderIsDone();
|
|
467
|
+
if (pageContext._hasPageContextFromServer)
|
|
468
|
+
setPageContextInitIsPassedToClient(pageContext);
|
|
469
|
+
// Add link prefetch handlers
|
|
470
|
+
addLinkPrefetchHandlers_watch();
|
|
471
|
+
addLinkPrefetchHandlers();
|
|
418
472
|
}
|
|
419
473
|
}
|
|
420
474
|
function changeUrl(url, overwriteLastHistoryEntry) {
|
|
@@ -486,3 +540,38 @@ function getIsRenderOutdated() {
|
|
|
486
540
|
function getRenderCount() {
|
|
487
541
|
return globalObject.renderCounter;
|
|
488
542
|
}
|
|
543
|
+
function getKeepScrollPositionSetting(pageContext) {
|
|
544
|
+
const c = pageContext.from.configsStandard.keepScrollPosition;
|
|
545
|
+
if (!c)
|
|
546
|
+
return false;
|
|
547
|
+
let val = c.value;
|
|
548
|
+
const configDefinedAt = c.definedAt;
|
|
549
|
+
assert(configDefinedAt);
|
|
550
|
+
const routeParameterList = getRouteStringParameterList(configDefinedAt);
|
|
551
|
+
if (isCallable(val))
|
|
552
|
+
val = val(pageContext, {
|
|
553
|
+
configDefinedAt: c.definedAt
|
|
554
|
+
/* We don't pass routeParameterList because it's useless: the user knows the parameter list.
|
|
555
|
+
routeParameterList
|
|
556
|
+
*/
|
|
557
|
+
});
|
|
558
|
+
if (val === true) {
|
|
559
|
+
return [
|
|
560
|
+
configDefinedAt,
|
|
561
|
+
...routeParameterList.map((param) => {
|
|
562
|
+
const val = pageContext.routeParams[param];
|
|
563
|
+
assert(val);
|
|
564
|
+
return val;
|
|
565
|
+
})
|
|
566
|
+
];
|
|
567
|
+
}
|
|
568
|
+
// We skip validation and type-cast instead of assertUsage() in order to save client-side KBs
|
|
569
|
+
return val;
|
|
570
|
+
}
|
|
571
|
+
function areKeysEqual(key1, key2) {
|
|
572
|
+
if (key1 === key2)
|
|
573
|
+
return true;
|
|
574
|
+
if (!Array.isArray(key1) || !Array.isArray(key2))
|
|
575
|
+
return false;
|
|
576
|
+
return key1.length === key2.length && key1.every((_, i) => key1[i] === key2[i]);
|
|
577
|
+
}
|
|
@@ -12,7 +12,7 @@ async function getPageContext() {
|
|
|
12
12
|
_hasPageContextFromServer: true,
|
|
13
13
|
_hasPageContextFromClient: false
|
|
14
14
|
});
|
|
15
|
-
objectAssign(pageContext, await loadPageUserFiles(pageContext.
|
|
15
|
+
objectAssign(pageContext, await loadPageUserFiles(pageContext.pageId));
|
|
16
16
|
assertPristineUrl();
|
|
17
17
|
return pageContext;
|
|
18
18
|
}
|
|
@@ -7,7 +7,7 @@ type PageContextBeforeRenderClient = {
|
|
|
7
7
|
_pageFilesLoaded: PageFile[];
|
|
8
8
|
urlOriginal?: string;
|
|
9
9
|
urlPathname?: string;
|
|
10
|
-
|
|
10
|
+
pageId: string;
|
|
11
11
|
_pageConfigs: PageConfigRuntime[];
|
|
12
12
|
} & PageContextExports & PageContextForUserConsumptionClientSide;
|
|
13
13
|
declare function executeOnRenderClientHook<PC extends PageContextBeforeRenderClient>(pageContext: PC, isClientRouting: boolean): Promise<void>;
|
|
@@ -14,7 +14,7 @@ function getPageContextSerializedInHtml() {
|
|
|
14
14
|
const pageContextJson = elem.textContent;
|
|
15
15
|
assert(pageContextJson);
|
|
16
16
|
const pageContextSerializedInHtml = parse(pageContextJson);
|
|
17
|
-
assert(hasProp(pageContextSerializedInHtml, '
|
|
17
|
+
assert(hasProp(pageContextSerializedInHtml, 'pageId', 'string'));
|
|
18
18
|
assert(hasProp(pageContextSerializedInHtml, 'routeParams', 'string{}'));
|
|
19
19
|
return pageContextSerializedInHtml;
|
|
20
20
|
}
|
|
@@ -4,7 +4,7 @@ import type { PageContextExports } from '../../shared/getPageFiles.js';
|
|
|
4
4
|
import type { PageConfigRuntime } from '../../shared/page-configs/PageConfig.js';
|
|
5
5
|
import { PageContextForPassToClientWarning } from './getPageContextProxyForUser.js';
|
|
6
6
|
type PageContextForUserConsumptionClientSide = PageContextExports & PageContextForPassToClientWarning & {
|
|
7
|
-
|
|
7
|
+
pageId: string;
|
|
8
8
|
_pageConfigs: PageConfigRuntime[];
|
|
9
9
|
};
|
|
10
10
|
declare function preparePageContextForUserConsumptionClientSide<T extends PageContextForUserConsumptionClientSide>(pageContext: T, isClientRouting: boolean): T & {
|