vike 0.4.197 → 0.4.198-commit-05a4973
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/node/plugin/plugins/fileEnv.js +3 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +14 -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 +16 -7
- package/dist/cjs/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +2 -2
- 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/cjs/utils/parseUrl.js +2 -10
- package/dist/esm/client/client-routing-runtime/entry.js +2 -2
- package/dist/esm/client/client-routing-runtime/getPageContextCurrent.d.ts +8 -0
- package/dist/esm/client/client-routing-runtime/getPageContextCurrent.js +13 -0
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.d.ts +26 -16
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +34 -30
- 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/navigate.js +3 -2
- package/dist/esm/client/client-routing-runtime/normalizeUrlArgument.d.ts +2 -0
- package/dist/esm/client/client-routing-runtime/normalizeUrlArgument.js +14 -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 +196 -68
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +71 -28
- package/dist/esm/node/plugin/plugins/fileEnv.js +3 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +14 -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 +16 -7
- package/dist/esm/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/esm/shared/page-configs/Config.d.ts +10 -1
- package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +1 -1
- package/dist/esm/shared/types.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/parseUrl.d.ts +2 -2
- package/dist/esm/utils/parseUrl.js +2 -10
- package/dist/esm/utils/projectInfo.d.ts +1 -1
- package/package.json +1 -1
- 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
|
@@ -1,21 +1,51 @@
|
|
|
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, 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';
|
|
20
|
+
import { normalizeUrlArgument } from './normalizeUrlArgument.js';
|
|
14
21
|
assertClientRouting();
|
|
15
|
-
const globalObject = getGlobalObject('prefetch.ts', {
|
|
16
|
-
|
|
22
|
+
const globalObject = getGlobalObject('prefetch.ts', {
|
|
23
|
+
linkPrefetchHandlerAdded: new WeakSet(),
|
|
24
|
+
addLinkPrefetchHandlers_debounce: null,
|
|
25
|
+
mutationObserver: new MutationObserver(addLinkPrefetchHandlers),
|
|
26
|
+
// `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.)
|
|
27
|
+
linkTags: document.getElementsByTagName('A'),
|
|
28
|
+
prefetchedPageContexts: {}
|
|
29
|
+
});
|
|
30
|
+
function getPageContextPrefetched(pageContext) {
|
|
31
|
+
const prefetchSettings = getPrefetchSettings(pageContext, null);
|
|
32
|
+
// TODO/pageContext-prefetch: I guess we need linkTag to make this condition work
|
|
33
|
+
if (!prefetchSettings.pageContext)
|
|
34
|
+
return null;
|
|
35
|
+
const key = getCacheKey(pageContext.urlPathname);
|
|
36
|
+
const found = globalObject.prefetchedPageContexts[key];
|
|
37
|
+
if (!found || found.result.is404ServerSideRouted || isExpired(found))
|
|
38
|
+
return null;
|
|
39
|
+
const pageContextPrefetched = found.result.pageContextFromServerHooks;
|
|
40
|
+
/* TODO/pageContext-prefetch: make it work for when resultMaxAge is Infinity.
|
|
41
|
+
// We discard the prefetched pageContext whenever we use it, so that the user always sees fresh data upon naivgating.
|
|
42
|
+
delete globalObject.prefetchedPageContexts[key]
|
|
43
|
+
*/
|
|
44
|
+
return pageContextPrefetched;
|
|
45
|
+
}
|
|
46
|
+
async function prefetchAssets(pageContextLink) {
|
|
17
47
|
try {
|
|
18
|
-
await loadUserFilesClientSide(pageId,
|
|
48
|
+
await loadUserFilesClientSide(pageContextLink.pageId, pageContextLink._pageFilesAll, pageContextLink._pageConfigs);
|
|
19
49
|
}
|
|
20
50
|
catch (err) {
|
|
21
51
|
if (isErrorFetchingStaticAssets(err)) {
|
|
@@ -26,6 +56,36 @@ async function prefetchAssets(pageId, pageContext) {
|
|
|
26
56
|
}
|
|
27
57
|
}
|
|
28
58
|
}
|
|
59
|
+
async function prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge) {
|
|
60
|
+
const result = await getPageContextFromServerHooks(pageContextLink, false);
|
|
61
|
+
setPageContextPrefetchCache(pageContextLink, result, resultMaxAge);
|
|
62
|
+
}
|
|
63
|
+
function populatePageContextPrefetchCache(pageContext /*& PageContextExports*/, result) {
|
|
64
|
+
// TODO/pageContext-prefetch: replace with using pageContext.config.prerender instead. (For being able to do that: eager configs need to be accessible without have to use PageContextExports as it isn't available here.)
|
|
65
|
+
if (!isBrilloutDocpress())
|
|
66
|
+
return;
|
|
67
|
+
setPageContextPrefetchCache(pageContext, result, null);
|
|
68
|
+
}
|
|
69
|
+
function setPageContextPrefetchCache(pageContext, result, resultMaxAge) {
|
|
70
|
+
if (resultMaxAge === null)
|
|
71
|
+
resultMaxAge = getResultMaxAge();
|
|
72
|
+
const key = getCacheKey(pageContext.urlPathname);
|
|
73
|
+
assert(isBrilloutDocpress()); // Ensure this API isn't used by anyone else
|
|
74
|
+
globalObject.prefetchedPageContexts[key] = {
|
|
75
|
+
resultFetchedAt: Date.now(),
|
|
76
|
+
resultMaxAge,
|
|
77
|
+
result
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function getResultMaxAge() {
|
|
81
|
+
const pageContextCurrent = getPageContextCurrent();
|
|
82
|
+
// TODO/pageContext-prefetch: remove this dirty hack used by @brillout/docpress and, instead, use Vike's default if pageContextCurrent isn't defined yet.
|
|
83
|
+
if (!pageContextCurrent)
|
|
84
|
+
return Infinity;
|
|
85
|
+
const prefetchSettings = getPrefetchSettings(pageContextCurrent, null);
|
|
86
|
+
const resultMaxAge = typeof prefetchSettings.pageContext === 'number' ? prefetchSettings.pageContext : PAGE_CONTEXT_MAX_AGE_DEFAULT;
|
|
87
|
+
return resultMaxAge;
|
|
88
|
+
}
|
|
29
89
|
/**
|
|
30
90
|
* Programmatically prefetch client assets.
|
|
31
91
|
*
|
|
@@ -33,85 +93,153 @@ async function prefetchAssets(pageId, pageContext) {
|
|
|
33
93
|
*
|
|
34
94
|
* @param url - The URL of the page you want to prefetch.
|
|
35
95
|
*/
|
|
36
|
-
async function prefetch(url) {
|
|
96
|
+
async function prefetch(url, options) {
|
|
37
97
|
assertUsage(checkIfClientRouting(), 'prefetch() only works with Client Routing, see https://vike.dev/prefetch', {
|
|
38
98
|
showStackTrace: true
|
|
39
99
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (
|
|
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) {
|
|
56
|
-
assertWarning(false, `${errPrefix} ${pc.string(url)} ${noRouteMatch}`, {
|
|
100
|
+
url = normalizeUrlArgument(url, 'prefetch');
|
|
101
|
+
const pageContextLink = await getPageContextLink(url);
|
|
102
|
+
if (!pageContextLink?.pageId) {
|
|
103
|
+
assertWarning(false, `[prefetch(url)] ${pc.string(url)} ${noRouteMatch}`, {
|
|
57
104
|
showStackTrace: true,
|
|
58
105
|
onlyOnce: false
|
|
59
106
|
});
|
|
60
107
|
return;
|
|
61
108
|
}
|
|
62
|
-
|
|
109
|
+
assert(hasProp(pageContextLink, 'pageId', 'string')); // help TypeScript
|
|
110
|
+
await Promise.all([
|
|
111
|
+
(async () => {
|
|
112
|
+
if (options?.staticAssets !== false) {
|
|
113
|
+
await prefetchAssets(pageContextLink);
|
|
114
|
+
}
|
|
115
|
+
})(),
|
|
116
|
+
(async () => {
|
|
117
|
+
if (options?.pageContext !== false) {
|
|
118
|
+
const resultMaxAge = typeof options?.pageContext === 'number' ? options.pageContext : null;
|
|
119
|
+
await prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge);
|
|
120
|
+
}
|
|
121
|
+
})()
|
|
122
|
+
]);
|
|
63
123
|
}
|
|
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 });
|
|
124
|
+
// 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
|
|
125
|
+
function addLinkPrefetchHandlers() {
|
|
126
|
+
if (globalObject.addLinkPrefetchHandlers_debounce)
|
|
127
|
+
clearTimeout(globalObject.addLinkPrefetchHandlers_debounce);
|
|
128
|
+
globalObject.addLinkPrefetchHandlers_debounce = setTimeout(() => {
|
|
129
|
+
// Wait for the next idle period, as it is less likely to interfere with any other work the browser is doing post-mutation.
|
|
130
|
+
if ('requestIdleCallback' in window) {
|
|
131
|
+
requestIdleCallback(addLinkPrefetchHandlers_apply, { timeout: 300 });
|
|
88
132
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (entry.isIntersecting) {
|
|
93
|
-
prefetchIfPossible(url);
|
|
94
|
-
observer.disconnect();
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
observer.observe(linkTag);
|
|
133
|
+
else {
|
|
134
|
+
// Fallback for old versions of Safari, we'll assume that things are less likely to be busy after 150ms.
|
|
135
|
+
setTimeout(addLinkPrefetchHandlers_apply, 150);
|
|
99
136
|
}
|
|
137
|
+
}, 250);
|
|
138
|
+
}
|
|
139
|
+
function initLinkPrefetchHandlers() {
|
|
140
|
+
addLinkPrefetchHandlers();
|
|
141
|
+
}
|
|
142
|
+
function addLinkPrefetchHandlers_watch() {
|
|
143
|
+
// Notes about performance:
|
|
144
|
+
// - https://stackoverflow.com/questions/31659567/performance-of-mutationobserver-to-detect-nodes-in-entire-dom/39332340#39332340
|
|
145
|
+
// - https://news.ycombinator.com/item?id=15274211
|
|
146
|
+
// - https://github.com/kubetail-org/sentineljs
|
|
147
|
+
// - https://stackoverflow.com/questions/55046093/listening-for-changes-in-htmlcollection-or-achieving-a-similar-effect
|
|
148
|
+
globalObject.mutationObserver.observe(document.body, {
|
|
149
|
+
childList: true,
|
|
150
|
+
subtree: true
|
|
100
151
|
});
|
|
101
152
|
}
|
|
102
|
-
|
|
103
|
-
|
|
153
|
+
function addLinkPrefetchHandlers_unwatch() {
|
|
154
|
+
globalObject.mutationObserver.disconnect();
|
|
155
|
+
}
|
|
156
|
+
function addLinkPrefetchHandlers_apply() {
|
|
157
|
+
for (let linkTag of globalObject.linkTags) {
|
|
158
|
+
if (globalObject.linkPrefetchHandlerAdded.has(linkTag))
|
|
159
|
+
continue;
|
|
160
|
+
globalObject.linkPrefetchHandlerAdded.add(linkTag);
|
|
161
|
+
if (skipLink(linkTag))
|
|
162
|
+
continue;
|
|
163
|
+
linkTag.addEventListener('mouseover', () => {
|
|
164
|
+
prefetchOnEvent(linkTag, 'hover');
|
|
165
|
+
}, { passive: true });
|
|
166
|
+
linkTag.addEventListener('touchstart', () => {
|
|
167
|
+
prefetchOnEvent(linkTag, 'hover');
|
|
168
|
+
}, { passive: true });
|
|
169
|
+
const observer = new IntersectionObserver((entries) => {
|
|
170
|
+
entries.forEach((entry) => {
|
|
171
|
+
if (entry.isIntersecting) {
|
|
172
|
+
prefetchOnEvent(linkTag, 'viewport');
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
observer.observe(linkTag);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function prefetchOnEvent(linkTag, event) {
|
|
180
|
+
let prefetchSettings;
|
|
181
|
+
const pageContextCurrent = getPageContextCurrent();
|
|
182
|
+
if (pageContextCurrent) {
|
|
183
|
+
prefetchSettings = getPrefetchSettings(pageContextCurrent, linkTag);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// TODO/pageContext-prefetch: remove this dirty hack used by @brillout/docpress and, instead, use Vike's default if pageContextCurrent isn't defined yet.
|
|
187
|
+
prefetchSettings = { staticAssets: 'hover', pageContext: Infinity };
|
|
188
|
+
}
|
|
189
|
+
// Check again in case DOM was manipulated since last check
|
|
190
|
+
if (skipLink(linkTag))
|
|
191
|
+
return;
|
|
192
|
+
const urlOfLink = linkTag.getAttribute('href');
|
|
193
|
+
const pageContextLink = await getPageContextLink(urlOfLink);
|
|
194
|
+
if (!pageContextLink?.pageId)
|
|
195
|
+
return;
|
|
196
|
+
assert(hasProp(pageContextLink, 'pageId', 'string')); // help TypeScript
|
|
197
|
+
if (!(await isClientSideRoutable(pageContextLink.pageId, pageContextLink)))
|
|
198
|
+
return;
|
|
199
|
+
await Promise.all([
|
|
200
|
+
(async () => {
|
|
201
|
+
if (prefetchSettings.staticAssets === event) {
|
|
202
|
+
await prefetchAssets(pageContextLink);
|
|
203
|
+
}
|
|
204
|
+
})(),
|
|
205
|
+
(async () => {
|
|
206
|
+
if (event !== 'viewport' && prefetchSettings.pageContext) {
|
|
207
|
+
const key = getCacheKey(urlOfLink);
|
|
208
|
+
const found = globalObject.prefetchedPageContexts[key];
|
|
209
|
+
if (!found || isExpired(found)) {
|
|
210
|
+
// TODO/pageContext-prefetch: move this logic in getPrefetchSettings()
|
|
211
|
+
const resultMaxAge = prefetchSettings.pageContext;
|
|
212
|
+
await prefetchPageContextFromServerHooks(pageContextLink, resultMaxAge);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
})()
|
|
216
|
+
]);
|
|
217
|
+
}
|
|
218
|
+
function isExpired(found) {
|
|
219
|
+
return Date.now() - found.resultFetchedAt > found.resultMaxAge;
|
|
220
|
+
}
|
|
221
|
+
// TODO/next-major-release: make it sync
|
|
222
|
+
async function getPageContextLink(urlOfLink) {
|
|
223
|
+
const pageContextLink = await createPageContext(urlOfLink);
|
|
104
224
|
let pageContextFromRoute;
|
|
105
225
|
try {
|
|
106
|
-
pageContextFromRoute = await route(
|
|
226
|
+
pageContextFromRoute = await route(pageContextLink);
|
|
107
227
|
}
|
|
108
228
|
catch {
|
|
109
229
|
// If a route() hook has a bug or `throw render()` / `throw redirect()`
|
|
110
|
-
return;
|
|
230
|
+
return null;
|
|
111
231
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
232
|
+
objectAssign(pageContextLink, pageContextFromRoute);
|
|
233
|
+
return pageContextLink;
|
|
234
|
+
}
|
|
235
|
+
function getCacheKey(url) {
|
|
236
|
+
if (url.startsWith('#'))
|
|
237
|
+
url = '/';
|
|
238
|
+
assert(url.startsWith('/'), { urlPathname: url });
|
|
239
|
+
const key = url.split('#')[0];
|
|
240
|
+
return key;
|
|
241
|
+
}
|
|
242
|
+
// TODO/pageContext-prefetch: remove
|
|
243
|
+
function isBrilloutDocpress() {
|
|
244
|
+
return '_isBrilloutDocpress' in window;
|
|
117
245
|
}
|
|
@@ -3,9 +3,9 @@ export { getRenderCount };
|
|
|
3
3
|
export { disableClientRouting };
|
|
4
4
|
export { firstRenderStartPromise };
|
|
5
5
|
import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType, genPromise, isCallable } from './utils.js';
|
|
6
|
-
import {
|
|
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,7 @@ 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';
|
|
21
22
|
import { getRouteStringParameterList } from '../../shared/route/resolveRouteString.js';
|
|
22
23
|
const globalObject = getGlobalObject('renderPageClientSide.ts', (() => {
|
|
23
24
|
const { promise: firstRenderStartPromise, resolve: firstRenderStartPromiseResolve } = genPromise();
|
|
@@ -32,11 +33,8 @@ async function renderPageClientSide(renderArgs) {
|
|
|
32
33
|
const { urlOriginal = getCurrentUrl(), overwriteLastHistoryEntry = false, isBackwardNavigation, pageContextsFromRewrite = [], redirectCount = 0, isUserLandPushStateNavigation, isClientSideNavigation = true } = renderArgs;
|
|
33
34
|
let { scrollTarget } = renderArgs;
|
|
34
35
|
const { previousPageContext } = globalObject;
|
|
36
|
+
addLinkPrefetchHandlers_unwatch();
|
|
35
37
|
const { isRenderOutdated, setHydrationCanBeAborted, isFirstRender } = getIsRenderOutdated();
|
|
36
|
-
// Note that pageContext.isHydration isn't equivalent to isFirstRender
|
|
37
|
-
// - Thus pageContext.isHydration isn't equivalent to !pageContext.isClientSideNavigation
|
|
38
|
-
// - `pageContext.isHydration === !isFirstRender && !isErrorPage`
|
|
39
|
-
assert(isClientSideNavigation === !isFirstRender);
|
|
40
38
|
assertNoInfiniteAbortLoop(pageContextsFromRewrite.length, redirectCount);
|
|
41
39
|
if (globalObject.clientRoutingIsDisabled) {
|
|
42
40
|
redirectHard(urlOriginal);
|
|
@@ -51,7 +49,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
51
49
|
const onError = async (err) => {
|
|
52
50
|
await renderErrorPage({ err });
|
|
53
51
|
};
|
|
54
|
-
const pageContext = await getPageContextBegin();
|
|
52
|
+
const pageContext = await getPageContextBegin(false);
|
|
55
53
|
if (isRenderOutdated())
|
|
56
54
|
return;
|
|
57
55
|
// onPageTransitionStart()
|
|
@@ -79,10 +77,13 @@ async function renderPageClientSide(renderArgs) {
|
|
|
79
77
|
}
|
|
80
78
|
}
|
|
81
79
|
// Route
|
|
82
|
-
let pageContextRouted;
|
|
83
80
|
if (isFirstRender) {
|
|
84
81
|
const pageContextSerialized = getPageContextFromHooks_serialized();
|
|
85
|
-
|
|
82
|
+
// TODO/eventually: create helper assertPageContextFromHook()
|
|
83
|
+
assert(!('urlOriginal' in pageContextSerialized));
|
|
84
|
+
objectAssign(pageContext, pageContextSerialized);
|
|
85
|
+
// TODO/pageContext-prefetch: remove or change, because this only makes sense for a pre-rendered page
|
|
86
|
+
populatePageContextPrefetchCache(pageContext, { pageContextFromServerHooks: pageContextSerialized });
|
|
86
87
|
}
|
|
87
88
|
else {
|
|
88
89
|
let pageContextFromRoute;
|
|
@@ -123,10 +124,10 @@ async function renderPageClientSide(renderArgs) {
|
|
|
123
124
|
// Skip's Vike's rendering; let the user handle the navigation
|
|
124
125
|
return;
|
|
125
126
|
}
|
|
126
|
-
|
|
127
|
+
// TODO/eventually: create helper assertPageContextFromHook()
|
|
128
|
+
assert(!('urlOriginal' in pageContextFromRoute));
|
|
129
|
+
objectAssign(pageContext, pageContextFromRoute);
|
|
127
130
|
}
|
|
128
|
-
assert(!('urlOriginal' in pageContextRouted));
|
|
129
|
-
objectAssign(pageContext, pageContextRouted);
|
|
130
131
|
try {
|
|
131
132
|
objectAssign(pageContext, await loadUserFilesClientSide(pageContext.pageId, pageContext._pageFilesAll, pageContext._pageConfigs));
|
|
132
133
|
}
|
|
@@ -142,6 +143,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
142
143
|
}
|
|
143
144
|
if (isRenderOutdated())
|
|
144
145
|
return;
|
|
146
|
+
setPageContextCurrent(pageContext);
|
|
145
147
|
// Set global hydrationCanBeAborted
|
|
146
148
|
if (pageContext.exports.hydrationCanBeAborted) {
|
|
147
149
|
setHydrationCanBeAborted();
|
|
@@ -149,7 +151,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
149
151
|
else {
|
|
150
152
|
assertWarning(!isReact(), 'You seem to be using React; we recommend setting hydrationCanBeAborted to true, see https://vike.dev/hydrationCanBeAborted', { onlyOnce: true });
|
|
151
153
|
}
|
|
152
|
-
// There wasn't any `await` but
|
|
154
|
+
// There wasn't any `await` but the isRenderOutdated() return value may have changed because we called setHydrationCanBeAborted()
|
|
153
155
|
if (isRenderOutdated())
|
|
154
156
|
return;
|
|
155
157
|
// Get pageContext from hooks (fetched from server, and/or directly called on the client-side)
|
|
@@ -170,9 +172,35 @@ async function renderPageClientSide(renderArgs) {
|
|
|
170
172
|
await renderPageView(pageContext);
|
|
171
173
|
}
|
|
172
174
|
else {
|
|
173
|
-
|
|
175
|
+
// Fetch pageContext from server-side hooks
|
|
176
|
+
let pageContextFromServerHooks;
|
|
177
|
+
const pageContextPrefetched = getPageContextPrefetched(pageContext);
|
|
178
|
+
if (pageContextPrefetched) {
|
|
179
|
+
pageContextFromServerHooks = pageContextPrefetched;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
try {
|
|
183
|
+
const result = await getPageContextFromServerHooks(pageContext, false);
|
|
184
|
+
if (result.is404ServerSideRouted)
|
|
185
|
+
return;
|
|
186
|
+
pageContextFromServerHooks = result.pageContextFromServerHooks;
|
|
187
|
+
// TODO/pageContext-prefetch: remove or change, because this only makes sense for a pre-rendered page
|
|
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;
|
|
174
202
|
try {
|
|
175
|
-
|
|
203
|
+
pageContextFromClientHooks = await getPageContextFromClientHooks(pageContext, false);
|
|
176
204
|
}
|
|
177
205
|
catch (err) {
|
|
178
206
|
await onError(err);
|
|
@@ -180,18 +208,16 @@ async function renderPageClientSide(renderArgs) {
|
|
|
180
208
|
}
|
|
181
209
|
if (isRenderOutdated())
|
|
182
210
|
return;
|
|
183
|
-
|
|
184
|
-
return;
|
|
185
|
-
augmentType(pageContext, res.pageContextAugmented);
|
|
186
|
-
// Render page view
|
|
211
|
+
augmentType(pageContext, pageContextFromClientHooks);
|
|
187
212
|
await renderPageView(pageContext);
|
|
188
213
|
}
|
|
189
214
|
}
|
|
190
|
-
async function getPageContextBegin() {
|
|
215
|
+
async function getPageContextBegin(isForErrorPage) {
|
|
191
216
|
const pageContext = await createPageContext(urlOriginal);
|
|
192
217
|
objectAssign(pageContext, {
|
|
193
218
|
isBackwardNavigation,
|
|
194
219
|
isClientSideNavigation,
|
|
220
|
+
isHydration: isFirstRender && !isForErrorPage,
|
|
195
221
|
_previousPageContext: previousPageContext
|
|
196
222
|
});
|
|
197
223
|
{
|
|
@@ -226,7 +252,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
226
252
|
// We handle the abort error down below.
|
|
227
253
|
}
|
|
228
254
|
}
|
|
229
|
-
const pageContext = await getPageContextBegin();
|
|
255
|
+
const pageContext = await getPageContextBegin(true);
|
|
230
256
|
if (isRenderOutdated())
|
|
231
257
|
return;
|
|
232
258
|
if (args.is404)
|
|
@@ -310,21 +336,34 @@ async function renderPageClientSide(renderArgs) {
|
|
|
310
336
|
}
|
|
311
337
|
if (isRenderOutdated())
|
|
312
338
|
return;
|
|
313
|
-
|
|
339
|
+
setPageContextCurrent(pageContext);
|
|
340
|
+
let pageContextFromServerHooks;
|
|
314
341
|
try {
|
|
315
|
-
|
|
342
|
+
const result = await getPageContextFromServerHooks(pageContext, true);
|
|
343
|
+
if (result.is404ServerSideRouted)
|
|
344
|
+
return;
|
|
345
|
+
pageContextFromServerHooks = result.pageContextFromServerHooks;
|
|
316
346
|
}
|
|
317
347
|
catch (err) {
|
|
318
|
-
// - When user hasn't defined a `_error.page.js` file
|
|
319
|
-
// - Some Vike unpexected internal error
|
|
320
348
|
onError(err);
|
|
321
349
|
return;
|
|
322
350
|
}
|
|
323
351
|
if (isRenderOutdated())
|
|
324
352
|
return;
|
|
325
|
-
|
|
353
|
+
// TODO/eventually: create helper assertPageContextFromHook()
|
|
354
|
+
assert(!('urlOriginal' in pageContextFromServerHooks));
|
|
355
|
+
objectAssign(pageContext, pageContextFromServerHooks);
|
|
356
|
+
let pageContextFromClientHooks;
|
|
357
|
+
try {
|
|
358
|
+
pageContextFromClientHooks = await getPageContextFromClientHooks(pageContext, true);
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
onError(err);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (isRenderOutdated())
|
|
326
365
|
return;
|
|
327
|
-
augmentType(pageContext,
|
|
366
|
+
augmentType(pageContext, pageContextFromClientHooks);
|
|
328
367
|
objectAssign(pageContext, { routeParams: {} });
|
|
329
368
|
await renderPageView(pageContext, args);
|
|
330
369
|
}
|
|
@@ -372,7 +411,6 @@ async function renderPageClientSide(renderArgs) {
|
|
|
372
411
|
/* We don't abort in order to ensure that onHydrationEnd() is called: we abort only after onHydrationEnd() is called.
|
|
373
412
|
if (isRenderOutdated(true)) return
|
|
374
413
|
*/
|
|
375
|
-
addLinkPrefetchHandlers(pageContext);
|
|
376
414
|
// onHydrationEnd()
|
|
377
415
|
if (isFirstRender && !onRenderClientError) {
|
|
378
416
|
assertHook(pageContext, 'onHydrationEnd');
|
|
@@ -427,6 +465,11 @@ async function renderPageClientSide(renderArgs) {
|
|
|
427
465
|
setScrollPosition(scrollTarget);
|
|
428
466
|
browserNativeScrollRestoration_disable();
|
|
429
467
|
setInitialRenderIsDone();
|
|
468
|
+
if (pageContext._hasPageContextFromServer)
|
|
469
|
+
setPageContextInitIsPassedToClient(pageContext);
|
|
470
|
+
// Add link prefetch handlers
|
|
471
|
+
addLinkPrefetchHandlers_watch();
|
|
472
|
+
addLinkPrefetchHandlers();
|
|
430
473
|
}
|
|
431
474
|
}
|
|
432
475
|
function changeUrl(url, overwriteLastHistoryEntry) {
|
|
@@ -17,6 +17,9 @@ function fileEnv() {
|
|
|
17
17
|
return;
|
|
18
18
|
if (skip(id))
|
|
19
19
|
return;
|
|
20
|
+
// For `.vue` files: https://github.com/vikejs/vike/issues/1912#issuecomment-2394981475
|
|
21
|
+
if (id.endsWith('?direct'))
|
|
22
|
+
id = id.slice(0, -1 * '?direct'.length);
|
|
20
23
|
const moduleInfo = viteDevServer.moduleGraph.getModuleById(id);
|
|
21
24
|
assert(moduleInfo);
|
|
22
25
|
const importers = Array.from(moduleInfo.importers)
|
|
@@ -67,6 +67,11 @@ const configDefinitionsBuiltIn = {
|
|
|
67
67
|
hydrationCanBeAborted: {
|
|
68
68
|
env: { client: true }
|
|
69
69
|
},
|
|
70
|
+
prefetch: {
|
|
71
|
+
env: { client: true },
|
|
72
|
+
eager: true
|
|
73
|
+
},
|
|
74
|
+
// TODO/v1-release: remove
|
|
70
75
|
prefetchStaticAssets: {
|
|
71
76
|
env: { client: true }
|
|
72
77
|
},
|
|
@@ -100,10 +105,12 @@ const configDefinitionsBuiltIn = {
|
|
|
100
105
|
},
|
|
101
106
|
onBeforeRenderEnv: {
|
|
102
107
|
env: { client: true },
|
|
108
|
+
eager: true,
|
|
103
109
|
_computed: (configValueSources) => !isConfigSet(configValueSources, 'onBeforeRender') ? null : getConfigEnv(configValueSources, 'onBeforeRender')
|
|
104
110
|
},
|
|
105
111
|
dataEnv: {
|
|
106
112
|
env: { client: true },
|
|
113
|
+
eager: true,
|
|
107
114
|
_computed: (configValueSources) => !isConfigSet(configValueSources, 'data') ? null : getConfigEnv(configValueSources, 'data')
|
|
108
115
|
},
|
|
109
116
|
hooksTimeout: {
|
|
@@ -149,7 +156,13 @@ function getConfigEnv(configValueSources, configName) {
|
|
|
149
156
|
const configValueSource = getConfigValueSource(configValueSources, configName);
|
|
150
157
|
if (!configValueSource)
|
|
151
158
|
return null;
|
|
152
|
-
|
|
159
|
+
const { configEnv } = configValueSource;
|
|
160
|
+
const env = {};
|
|
161
|
+
if (configEnv.client)
|
|
162
|
+
env.client = true;
|
|
163
|
+
if (configEnv.server)
|
|
164
|
+
env.server = true;
|
|
165
|
+
return env;
|
|
153
166
|
}
|
|
154
167
|
function isConfigSet(configValueSources, configName) {
|
|
155
168
|
const configValueSource = getConfigValueSource(configValueSources, configName);
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js
CHANGED
|
@@ -6,7 +6,7 @@ import { assert, assertUsage, hasProp, assertIsNotProductionRuntime } from '../.
|
|
|
6
6
|
import { transpileAndExecuteFile } from './transpileAndExecuteFile.js';
|
|
7
7
|
import { assertPlusFileExport } from '../../../../../../shared/page-configs/assertPlusFileExport.js';
|
|
8
8
|
import pc from '@brillout/picocolors';
|
|
9
|
-
import { parsePointerImportData } from './
|
|
9
|
+
import { parsePointerImportData } from './transformPointerImports.js';
|
|
10
10
|
import { getConfigFileExport } from '../getConfigFileExport.js';
|
|
11
11
|
import { resolvePointerImport } from './resolvePointerImport.js';
|
|
12
12
|
assertIsNotProductionRuntime();
|
|
@@ -2,7 +2,7 @@ export { resolvePointerImportOfConfig };
|
|
|
2
2
|
export { resolvePointerImport };
|
|
3
3
|
export { clearFilesEnvMap };
|
|
4
4
|
import type { ConfigEnvInternal, DefinedAtFilePath } from '../../../../../../shared/page-configs/PageConfig.js';
|
|
5
|
-
import { type PointerImportData } from './
|
|
5
|
+
import { type PointerImportData } from './transformPointerImports.js';
|
|
6
6
|
import type { FilePath, FilePathResolved } from '../../../../../../shared/page-configs/FilePath.js';
|
|
7
7
|
type PointerImportResolved = DefinedAtFilePath & {
|
|
8
8
|
fileExportName: string;
|