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,6 +1,10 @@
|
|
|
1
1
|
export { getPageContextFromHooks_isHydration };
|
|
2
|
-
export { getPageContextFromHooks_isNotHydration };
|
|
3
2
|
export { getPageContextFromHooks_serialized };
|
|
3
|
+
export { getPageContextFromServerHooks };
|
|
4
|
+
export { getPageContextFromClientHooks };
|
|
5
|
+
export { setPageContextInitIsPassedToClient };
|
|
6
|
+
export type { PageContextFromServerHooks };
|
|
7
|
+
export type { PageContextFromClientHooks };
|
|
4
8
|
import type { PageContextExports, PageFile } from '../../shared/getPageFiles.js';
|
|
5
9
|
import type { PageConfigRuntime } from '../../shared/page-configs/PageConfig.js';
|
|
6
10
|
type PageContext = {
|
|
@@ -15,25 +19,31 @@ type PageContextSerialized = {
|
|
|
15
19
|
};
|
|
16
20
|
declare function getPageContextFromHooks_serialized(): PageContextSerialized & {
|
|
17
21
|
routeParams: Record<string, string>;
|
|
22
|
+
_hasPageContextFromServer: true;
|
|
18
23
|
};
|
|
19
|
-
declare function getPageContextFromHooks_isHydration(pageContext: PageContextSerialized & PageContext & PageContextExports
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
declare function getPageContextFromHooks_isHydration(pageContext: PageContextSerialized & PageContext & PageContextExports & {
|
|
25
|
+
_hasPageContextFromServer: true;
|
|
26
|
+
}): Promise<PageContextSerialized & PageContext & PageContextExports & {
|
|
22
27
|
_hasPageContextFromServer: true;
|
|
28
|
+
} & {
|
|
29
|
+
_hasPageContextFromClient: boolean;
|
|
23
30
|
}>;
|
|
24
|
-
|
|
31
|
+
type PageContextFromServerHooks = {
|
|
32
|
+
_hasPageContextFromServer: boolean;
|
|
33
|
+
};
|
|
34
|
+
declare function getPageContextFromServerHooks(pageContext: {
|
|
25
35
|
pageId: string;
|
|
26
|
-
} & PageContext
|
|
27
|
-
is404ServerSideRouted:
|
|
28
|
-
pageContextAugmented?: undefined;
|
|
36
|
+
} & PageContext, isErrorPage: boolean): Promise<{
|
|
37
|
+
is404ServerSideRouted: true;
|
|
29
38
|
} | {
|
|
30
|
-
pageContextAugmented: {
|
|
31
|
-
pageId: string;
|
|
32
|
-
} & PageContext & PageContextExports & {
|
|
33
|
-
isHydration: false;
|
|
34
|
-
_hasPageContextFromClient: boolean;
|
|
35
|
-
} & {
|
|
36
|
-
_hasPageContextFromServer: boolean;
|
|
37
|
-
};
|
|
38
39
|
is404ServerSideRouted?: undefined;
|
|
40
|
+
pageContextFromServerHooks: PageContextFromServerHooks;
|
|
39
41
|
}>;
|
|
42
|
+
type PageContextFromClientHooks = {
|
|
43
|
+
_hasPageContextFromClient: boolean;
|
|
44
|
+
};
|
|
45
|
+
declare function getPageContextFromClientHooks(pageContext: {
|
|
46
|
+
pageId: string;
|
|
47
|
+
_hasPageContextFromServer: boolean;
|
|
48
|
+
} & PageContext & PageContextExports, isErrorPage: boolean): Promise<PageContextFromClientHooks>;
|
|
49
|
+
declare function setPageContextInitIsPassedToClient(pageContext: Record<string, unknown>): void;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { getPageContextFromHooks_isHydration };
|
|
2
|
-
export { getPageContextFromHooks_isNotHydration };
|
|
3
2
|
export { getPageContextFromHooks_serialized };
|
|
3
|
+
export { getPageContextFromServerHooks };
|
|
4
|
+
export { getPageContextFromClientHooks };
|
|
5
|
+
export { setPageContextInitIsPassedToClient };
|
|
4
6
|
import { assert, assertUsage, hasProp, objectAssign, getProjectError, redirectHard, executeHook, isObject, getGlobalObject } from './utils.js';
|
|
5
7
|
import { parse } from '@brillout/json-serializer/parse';
|
|
6
8
|
import { getPageContextSerializedInHtml } from '../shared/getPageContextSerializedInHtml.js';
|
|
@@ -17,6 +19,7 @@ import { AbortRender, isAbortPageContext } from '../../shared/route/abort.js';
|
|
|
17
19
|
import { pageContextInitIsPassedToClient } from '../../shared/misc/pageContextInitIsPassedToClient.js';
|
|
18
20
|
import { isServerSideError } from '../../shared/misc/isServerSideError.js';
|
|
19
21
|
const globalObject = getGlobalObject('router/getPageContext.ts', {});
|
|
22
|
+
// TODO/eventually: rename
|
|
20
23
|
function getPageContextFromHooks_serialized() {
|
|
21
24
|
const pageContextSerialized = getPageContextSerializedInHtml();
|
|
22
25
|
assertUsage(!('urlOriginal' in pageContextSerialized), "Adding 'urlOriginal' to passToClient is forbidden");
|
|
@@ -26,28 +29,24 @@ function getPageContextFromHooks_serialized() {
|
|
|
26
29
|
});
|
|
27
30
|
return pageContextSerialized;
|
|
28
31
|
}
|
|
32
|
+
// TODO/eventually: rename
|
|
29
33
|
async function getPageContextFromHooks_isHydration(pageContext) {
|
|
30
34
|
objectAssign(pageContext, {
|
|
31
|
-
|
|
32
|
-
_hasPageContextFromClient: false,
|
|
33
|
-
_hasPageContextFromServer: true
|
|
35
|
+
_hasPageContextFromClient: false
|
|
34
36
|
});
|
|
35
37
|
for (const hookName of ['data', 'onBeforeRender']) {
|
|
36
38
|
if (hookClientOnlyExists(hookName, pageContext)) {
|
|
37
39
|
const pageContextFromHook = await executeHookClientSide(hookName, pageContext);
|
|
38
|
-
|
|
39
|
-
assert(!('urlOriginal' in pageContextFromHook));
|
|
40
|
+
assert(!('urlOriginal' in pageContextFromHook));
|
|
40
41
|
Object.assign(pageContext, pageContextFromHook);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
return pageContext;
|
|
44
45
|
}
|
|
45
|
-
async function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
let hasPageContextFromServer = false;
|
|
46
|
+
async function getPageContextFromServerHooks(pageContext, isErrorPage) {
|
|
47
|
+
const pageContextFromServerHooks = {
|
|
48
|
+
_hasPageContextFromServer: false
|
|
49
|
+
};
|
|
51
50
|
// If pageContextInit has some client data or if one of the hooks guard(), data() or onBeforeRender() is server-side
|
|
52
51
|
// only, then we need to fetch pageContext from the server.
|
|
53
52
|
// We do it before executing any client-side hook, because it contains pageContextInit which may be needed for guard() / data() / onBeforeRender(), for example pageContextInit.user is crucial for guard()
|
|
@@ -60,13 +59,19 @@ async function getPageContextFromHooks_isNotHydration(pageContext, isErrorPage)
|
|
|
60
59
|
if ('is404ServerSideRouted' in res)
|
|
61
60
|
return { is404ServerSideRouted: true };
|
|
62
61
|
const { pageContextFromServer } = res;
|
|
63
|
-
|
|
62
|
+
pageContextFromServerHooks._hasPageContextFromServer = true;
|
|
64
63
|
// Already handled
|
|
65
64
|
assert(!(isServerSideError in pageContextFromServer));
|
|
66
65
|
assert(!('serverSideError' in pageContextFromServer));
|
|
67
|
-
objectAssign(
|
|
66
|
+
objectAssign(pageContextFromServerHooks, pageContextFromServer);
|
|
68
67
|
}
|
|
69
|
-
|
|
68
|
+
// We cannot return the whole pageContext because this function is used for prefetching `pageContext` (which requires a partial pageContext to be merged with the future pageContext created upon rendering the page in the future).
|
|
69
|
+
return { pageContextFromServerHooks };
|
|
70
|
+
}
|
|
71
|
+
async function getPageContextFromClientHooks(pageContext, isErrorPage) {
|
|
72
|
+
objectAssign(pageContext, {
|
|
73
|
+
_hasPageContextFromClient: false
|
|
74
|
+
});
|
|
70
75
|
// At this point, we need to call the client-side guard(), data() and onBeforeRender() hooks, if they exist on client
|
|
71
76
|
// env. However if we have fetched pageContext from the server, some of them might have run already on the
|
|
72
77
|
// server-side, so we run only the client-only ones in this case.
|
|
@@ -76,7 +81,7 @@ async function getPageContextFromHooks_isNotHydration(pageContext, isErrorPage)
|
|
|
76
81
|
if (hookName === 'guard') {
|
|
77
82
|
if (!isErrorPage &&
|
|
78
83
|
// We don't need to call guard() on the client-side if we fetch pageContext from the server side. (Because the `${url}.pageContext.json` HTTP request will already trigger the routing and guard() hook on the server-side.)
|
|
79
|
-
!
|
|
84
|
+
!pageContext._hasPageContextFromServer) {
|
|
80
85
|
// Should we really call the guard() hook on the client-side? Shouldn't we make the guard() hook a server-side
|
|
81
86
|
// only hook? Or maybe make its env configurable like data() and onBeforeRender()?
|
|
82
87
|
await executeGuardHook(pageContext, (pageContext) => preparePageContextForUserConsumptionClientSide(pageContext, true));
|
|
@@ -84,28 +89,22 @@ async function getPageContextFromHooks_isNotHydration(pageContext, isErrorPage)
|
|
|
84
89
|
}
|
|
85
90
|
else {
|
|
86
91
|
assert(hookName === 'data' || hookName === 'onBeforeRender');
|
|
87
|
-
if (hookClientOnlyExists(hookName, pageContext) || !
|
|
92
|
+
if (hookClientOnlyExists(hookName, pageContext) || !pageContext._hasPageContextFromServer) {
|
|
88
93
|
// This won't do anything if no hook has been defined or if the hook's env.client is false.
|
|
89
94
|
const pageContextFromHook = await executeHookClientSide(hookName, pageContext);
|
|
90
|
-
|
|
91
|
-
assert(!('urlOriginal' in pageContextFromHook));
|
|
95
|
+
assert(!('urlOriginal' in pageContextFromHook));
|
|
92
96
|
Object.assign(pageContext, pageContextFromHook);
|
|
93
97
|
}
|
|
94
|
-
else {
|
|
95
|
-
assert(hasPageContextFromServer);
|
|
96
|
-
}
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
});
|
|
102
|
-
return { pageContextAugmented: pageContext };
|
|
100
|
+
const pageContextFromClientHooks = pageContext;
|
|
101
|
+
return pageContextFromClientHooks;
|
|
103
102
|
}
|
|
104
103
|
async function executeHookClientSide(hookName, pageContext) {
|
|
105
104
|
const hook = getHook(pageContext, hookName);
|
|
106
105
|
if (!hook) {
|
|
107
106
|
// No hook defined or hook's env.client is false
|
|
108
|
-
return
|
|
107
|
+
return {};
|
|
109
108
|
}
|
|
110
109
|
const pageContextForUserConsumption = preparePageContextForUserConsumptionClientSide(pageContext, true);
|
|
111
110
|
const hookResult = await executeHook(() => hook.hookFn(pageContextForUserConsumption), hook, pageContext);
|
|
@@ -165,9 +164,15 @@ async function hookServerOnlyExists(hookName, pageContext) {
|
|
|
165
164
|
if (pageContext._pageConfigs.length > 0) {
|
|
166
165
|
// V1
|
|
167
166
|
const pageConfig = getPageConfig(pageContext.pageId, pageContext._pageConfigs);
|
|
168
|
-
const hookEnv = getConfigValueRuntime(pageConfig, `${hookName}Env`)?.value
|
|
167
|
+
const hookEnv = getConfigValueRuntime(pageConfig, `${hookName}Env`)?.value;
|
|
168
|
+
if (hookEnv === null)
|
|
169
|
+
return false;
|
|
169
170
|
assert(isObject(hookEnv));
|
|
170
|
-
|
|
171
|
+
const { client, server } = hookEnv;
|
|
172
|
+
assert(client === true || client === undefined);
|
|
173
|
+
assert(server === true || server === undefined);
|
|
174
|
+
assert(client || server);
|
|
175
|
+
return !!server && !client;
|
|
171
176
|
}
|
|
172
177
|
else {
|
|
173
178
|
// TODO/v1-release: remove
|
|
@@ -228,6 +233,5 @@ async function fetchPageContextFromServer(pageContext) {
|
|
|
228
233
|
return { pageContextFromServer };
|
|
229
234
|
}
|
|
230
235
|
function processPageContextFromServer(pageContextFromServer) {
|
|
231
|
-
setPageContextInitIsPassedToClient(pageContextFromServer);
|
|
232
236
|
removeBuiltInOverrides(pageContextFromServer);
|
|
233
237
|
}
|
|
@@ -4,7 +4,7 @@ import { assert, assertUsage, hasProp, isObject } from './utils.js';
|
|
|
4
4
|
// - `history.state` can uninitialized (i.e. `null`):
|
|
5
5
|
// - The very first render
|
|
6
6
|
// - The user's code runs `location.hash = '#section'`
|
|
7
|
-
// - The user clicks on an anchor link `<a href="#section">Section</a>` (Vike's `
|
|
7
|
+
// - The user clicks on an anchor link `<a href="#section">Section</a>` (Vike's `initOnLinkClick()` handler skips hash links).
|
|
8
8
|
// - State information may be incomplete if `history.state` is set by an old Vike version. (E.g. `state.timestamp` was introduced for `pageContext.isBackwardNavigation` in `0.4.19`.)
|
|
9
9
|
function initHistoryState() {
|
|
10
10
|
// No way found to add TypeScript types to `window.history.state`: https://github.com/microsoft/TypeScript/issues/36178
|
package/dist/esm/client/client-routing-runtime/{installClientRouter.js → initClientRouter.js}
RENAMED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { initClientRouter };
|
|
2
2
|
import { assert } from './utils.js';
|
|
3
3
|
import { initHistoryState, monkeyPatchHistoryPushState } from './history.js';
|
|
4
4
|
import { getRenderCount, renderPageClientSide } from './renderPageClientSide.js';
|
|
5
5
|
import { onBrowserHistoryNavigation } from './onBrowserHistoryNavigation.js';
|
|
6
|
-
import {
|
|
6
|
+
import { initOnLinkClick } from './initOnLinkClick.js';
|
|
7
7
|
import { setupNativeScrollRestoration } from './scrollRestoration.js';
|
|
8
8
|
import { autoSaveScrollPosition } from './setScrollPosition.js';
|
|
9
|
-
|
|
9
|
+
import { initLinkPrefetchHandlers } from './prefetch.js';
|
|
10
|
+
async function initClientRouter() {
|
|
10
11
|
// Init navigation history and scroll restoration
|
|
11
12
|
initHistoryAndScroll();
|
|
12
|
-
// Render
|
|
13
|
-
const
|
|
13
|
+
// Render/hydrate
|
|
14
|
+
const renderFirstPagePromise = renderFirstPage();
|
|
14
15
|
// Intercept <a> clicks
|
|
15
|
-
|
|
16
|
+
initOnLinkClick();
|
|
17
|
+
// Add <a> prefetch handlers
|
|
18
|
+
initLinkPrefetchHandlers();
|
|
16
19
|
// Preserve stack track
|
|
17
|
-
await
|
|
20
|
+
await renderFirstPagePromise;
|
|
18
21
|
}
|
|
19
|
-
async function
|
|
22
|
+
async function renderFirstPage() {
|
|
20
23
|
assert(getRenderCount() === 0);
|
|
21
24
|
await renderPageClientSide({
|
|
22
25
|
scrollTarget: { preserveScroll: true },
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Code adapted from https://github.com/HenrikJoreteg/internal-nav-helper/blob/5199ec5448d0b0db7ec63cf76d88fa6cad878b7d/src/index.js#L11-L29
|
|
2
|
-
export {
|
|
2
|
+
export { initOnLinkClick };
|
|
3
3
|
import { assert } from './utils.js';
|
|
4
4
|
import { skipLink } from './skipLink.js';
|
|
5
5
|
import { renderPageClientSide } from './renderPageClientSide.js';
|
|
6
|
-
function
|
|
6
|
+
function initOnLinkClick() {
|
|
7
7
|
document.addEventListener('click', handler);
|
|
8
8
|
}
|
|
9
9
|
async function handler(ev) {
|
|
@@ -2,6 +2,7 @@ export { isClientSideRoutable };
|
|
|
2
2
|
import { analyzePageClientSideInit } from '../../shared/getPageFiles/analyzePageClientSide.js';
|
|
3
3
|
import { findPageConfig } from '../../shared/page-configs/findPageConfig.js';
|
|
4
4
|
import { analyzeClientSide } from '../../shared/getPageFiles/analyzeClientSide.js';
|
|
5
|
+
// TODO/next-major-release: make it sync
|
|
5
6
|
async function isClientSideRoutable(pageId, pageContext) {
|
|
6
7
|
await analyzePageClientSideInit(pageContext._pageFilesAll, pageId, {
|
|
7
8
|
sharedPageFilesAlreadyLoaded: false
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { navigate };
|
|
2
2
|
export { reload };
|
|
3
|
+
import { normalizeUrlArgument } from './normalizeUrlArgument.js';
|
|
3
4
|
import { firstRenderStartPromise, renderPageClientSide } from './renderPageClientSide.js';
|
|
4
|
-
import { assertClientRouting,
|
|
5
|
+
import { assertClientRouting, getCurrentUrl } from './utils.js';
|
|
5
6
|
assertClientRouting();
|
|
6
7
|
/** Programmatically navigate to a new page.
|
|
7
8
|
*
|
|
@@ -12,7 +13,7 @@ assertClientRouting();
|
|
|
12
13
|
* @param overwriteLastHistoryEntry - Don't create a new entry in the browser's history, instead let the new URL replace the current URL. (This effectively removes the current URL from the browser history).
|
|
13
14
|
*/
|
|
14
15
|
async function navigate(url, { keepScrollPosition = false, overwriteLastHistoryEntry = false } = {}) {
|
|
15
|
-
|
|
16
|
+
normalizeUrlArgument(url, 'navigate');
|
|
16
17
|
// If `hydrationCanBeAborted === false` (e.g. Vue) then we can apply navigate() only after hydration is done
|
|
17
18
|
await firstRenderStartPromise;
|
|
18
19
|
const scrollTarget = { preserveScroll: keepScrollPosition };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { normalizeUrlArgument };
|
|
2
|
+
import { assertUsage, isUrl, isUrlPathnameRelative } from './utils.js';
|
|
3
|
+
function normalizeUrlArgument(url, fnName) {
|
|
4
|
+
// Succinct error message to save client-side KBs
|
|
5
|
+
const errMsg = `[${fnName}(url)] Invalid URL ${url}`;
|
|
6
|
+
assertUsage(isUrl(url), errMsg);
|
|
7
|
+
if (url.startsWith(location.origin)) {
|
|
8
|
+
url = url.slice(location.origin.length);
|
|
9
|
+
}
|
|
10
|
+
assertUsage(url.startsWith('/') || isUrlPathnameRelative(url),
|
|
11
|
+
// `errMsg` used the original `url` value
|
|
12
|
+
errMsg);
|
|
13
|
+
return url;
|
|
14
|
+
}
|
|
@@ -27,7 +27,7 @@ function onBrowserHistoryNavigation() {
|
|
|
27
27
|
if (isHashNavigation && !isUserLandPushStateNavigation) {
|
|
28
28
|
// - `history.state` is uninitialized (`null`) when:
|
|
29
29
|
// - The user's code runs `window.location.hash = '#section'`.
|
|
30
|
-
// - The user clicks on an anchor link `<a href="#section">Section</a>` (because Vike's `
|
|
30
|
+
// - The user clicks on an anchor link `<a href="#section">Section</a>` (because Vike's `initOnLinkClick()` handler skips hash links).
|
|
31
31
|
// - `history.state` is `null` when uninitialized: https://developer.mozilla.org/en-US/docs/Web/API/History/state
|
|
32
32
|
// - Alternatively, we completely take over hash navigation and reproduce the browser's native behavior upon hash navigation.
|
|
33
33
|
// - Problem: we cannot intercept `window.location.hash = '#section'`. (Or maybe we can with the `hashchange` event?)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export { getPrefetchSettings };
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
|
|
2
|
+
export { PAGE_CONTEXT_MAX_AGE_DEFAULT };
|
|
3
|
+
export type { PrefetchSettingResolved };
|
|
4
|
+
import type { PageContextExports } from '../../../shared/getPageFiles.js';
|
|
5
|
+
declare const PAGE_CONTEXT_MAX_AGE_DEFAULT = 5000;
|
|
6
|
+
type PrefetchSettingResolved = {
|
|
7
|
+
staticAssets: false | 'hover' | 'viewport';
|
|
8
|
+
pageContext: false | number;
|
|
5
9
|
};
|
|
6
|
-
|
|
7
|
-
prefetchStaticAssets: PrefetchStaticAssets;
|
|
8
|
-
};
|
|
9
|
-
declare function getPrefetchSettings(pageContext: PageContextPrefetch, linkTag: HTMLElement): PrefetchSettings;
|
|
10
|
+
declare function getPrefetchSettings(pageContext: PageContextExports, linkTag: null | HTMLElement): PrefetchSettingResolved;
|
|
@@ -1,82 +1,90 @@
|
|
|
1
|
+
// TODO/pageContext-prefetch: rename this file to getPrefetchSettingResolved.ts
|
|
1
2
|
export { getPrefetchSettings };
|
|
2
|
-
|
|
3
|
+
export { PAGE_CONTEXT_MAX_AGE_DEFAULT };
|
|
4
|
+
import { assertUsage, assertInfo } from '../utils.js';
|
|
5
|
+
// TODO/pageContext-prefetch: Make it `Infinity` for pre-rendered pages.
|
|
6
|
+
const PAGE_CONTEXT_MAX_AGE_DEFAULT = 5000;
|
|
7
|
+
const prefetchSettingTrue = {
|
|
8
|
+
staticAssets: 'hover',
|
|
9
|
+
pageContext: PAGE_CONTEXT_MAX_AGE_DEFAULT
|
|
10
|
+
};
|
|
11
|
+
const prefetchSettingFalse = {
|
|
12
|
+
staticAssets: 'hover',
|
|
13
|
+
pageContext: false
|
|
14
|
+
};
|
|
15
|
+
// TODO/v1-release: change to `prefetchSettingTrue`?
|
|
16
|
+
const prefetchSettingDefault = prefetchSettingFalse;
|
|
3
17
|
function getPrefetchSettings(pageContext, linkTag) {
|
|
4
|
-
let
|
|
5
|
-
if (prefetchStaticAssets === 'viewport' && import.meta.env.DEV) {
|
|
6
|
-
assertInfo(false, 'Viewport prefetching is disabled in development', { onlyOnce: true });
|
|
7
|
-
prefetchStaticAssets = 'hover';
|
|
8
|
-
}
|
|
9
|
-
return {
|
|
10
|
-
prefetchStaticAssets
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
function getPrefetchStaticAssets(pageContext, linkTag) {
|
|
14
|
-
{
|
|
15
|
-
const prefetchAttribute = getPrefetchAttribute(linkTag);
|
|
16
|
-
if (prefetchAttribute !== null)
|
|
17
|
-
return prefetchAttribute;
|
|
18
|
-
}
|
|
18
|
+
let prefetchSetting = prefetchSettingDefault;
|
|
19
19
|
// TODO/v1-release: remove
|
|
20
20
|
if ('prefetchLinks' in pageContext.exports) {
|
|
21
21
|
assertUsage(false, '`export { prefetchLinks }` is deprecated, use `export { prefetchStaticAssets }` instead.');
|
|
22
22
|
}
|
|
23
|
+
// TODO/v1-release: remove
|
|
23
24
|
if ('prefetchStaticAssets' in pageContext.exports) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
const prefetchStaticAssets = pageContext.exports.prefetchStaticAssets;
|
|
26
|
+
/* TODO/pageContext-prefetch: uncomment
|
|
27
|
+
const msg = `The 'prefetchStaticAssets' setting is deprecated in favor of the 'prefetch' setting, see https://vike.dev/prefetch`
|
|
28
|
+
assertWarning(false, msg, { onlyOnce: true })
|
|
29
|
+
assertUsage(
|
|
30
|
+
prefetchStaticAssets === false || prefetchStaticAssets === 'hover' || prefetchStaticAssets === 'viewport',
|
|
31
|
+
msg
|
|
32
|
+
)
|
|
33
|
+
//*/
|
|
34
|
+
prefetchSetting.staticAssets = prefetchStaticAssets;
|
|
35
|
+
}
|
|
36
|
+
if ('prefetch' in pageContext.exports) {
|
|
37
|
+
const { prefetch } = pageContext.exports;
|
|
38
|
+
if (prefetch === true)
|
|
39
|
+
prefetchSetting = prefetchSettingTrue;
|
|
40
|
+
if (prefetch === false)
|
|
41
|
+
prefetchSetting = prefetchSettingFalse;
|
|
42
|
+
// No validation in order to save client-side KBs
|
|
43
|
+
Object.assign(prefetchSetting, prefetch);
|
|
44
|
+
if (prefetchSetting.pageContext === true) {
|
|
45
|
+
prefetchSetting.pageContext = PAGE_CONTEXT_MAX_AGE_DEFAULT;
|
|
44
46
|
}
|
|
45
|
-
assertUsage(false, wrongUsageMsg);
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const attr = linkTag.getAttribute('data-prefetch-static-assets');
|
|
51
|
-
const attrOld = linkTag.getAttribute('data-prefetch');
|
|
52
|
-
if (attr === null && attrOld === null) {
|
|
53
|
-
return null;
|
|
48
|
+
if (prefetchSetting.staticAssets === 'viewport' && import.meta.env.DEV) {
|
|
49
|
+
assertInfo(false, 'Viewport prefetching is disabled in development', { onlyOnce: true });
|
|
50
|
+
prefetchSetting.staticAssets = 'hover';
|
|
54
51
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
if (linkTag) {
|
|
53
|
+
{
|
|
54
|
+
let attr = linkTag.getAttribute('data-prefetch');
|
|
55
|
+
if (attr !== null) {
|
|
56
|
+
if (attr === '')
|
|
57
|
+
attr = 'true';
|
|
58
|
+
if (attr === 'true')
|
|
59
|
+
prefetchSetting = prefetchSettingTrue;
|
|
60
|
+
if (attr === 'false')
|
|
61
|
+
prefetchSetting = prefetchSettingFalse;
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
assertWarning(false, deprecationNotice, {
|
|
71
|
-
onlyOnce: true
|
|
72
|
-
});
|
|
73
|
-
if (attrOld === 'true') {
|
|
74
|
-
return 'viewport';
|
|
64
|
+
{
|
|
65
|
+
let attr = linkTag.getAttribute('data-prefetch-static-assets');
|
|
66
|
+
if (attr !== null) {
|
|
67
|
+
if (attr === 'false')
|
|
68
|
+
prefetchSetting.staticAssets = false;
|
|
69
|
+
// No validation in order to save client-side KBs
|
|
70
|
+
prefetchSetting.staticAssets = attr;
|
|
71
|
+
}
|
|
75
72
|
}
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
{
|
|
74
|
+
let attr = linkTag.getAttribute('data-prefetch-page-context');
|
|
75
|
+
if (attr !== null) {
|
|
76
|
+
if (attr === '')
|
|
77
|
+
attr = 'true';
|
|
78
|
+
if (attr === 'true')
|
|
79
|
+
prefetchSetting.pageContext = PAGE_CONTEXT_MAX_AGE_DEFAULT;
|
|
80
|
+
if (attr === 'false')
|
|
81
|
+
prefetchSetting.pageContext = false;
|
|
82
|
+
const n = parseInt(attr, 10);
|
|
83
|
+
if (!Number.isNaN(n))
|
|
84
|
+
prefetchSetting.pageContext = n;
|
|
85
|
+
// No validation in order to save client-side KBs
|
|
86
|
+
}
|
|
78
87
|
}
|
|
79
|
-
assertUsage(false, `data-prefetch has value "${attrOld}" but it should instead be "true" or "false"`);
|
|
80
88
|
}
|
|
81
|
-
|
|
89
|
+
return prefetchSetting;
|
|
82
90
|
}
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
export { prefetch };
|
|
2
|
+
export { getPageContextPrefetched };
|
|
3
|
+
export { initLinkPrefetchHandlers };
|
|
4
|
+
export { populatePageContextPrefetchCache };
|
|
2
5
|
export { addLinkPrefetchHandlers };
|
|
6
|
+
export { addLinkPrefetchHandlers_watch };
|
|
7
|
+
export { addLinkPrefetchHandlers_unwatch };
|
|
8
|
+
import { type PageContextFromServerHooks, getPageContextFromServerHooks } from './getPageContextFromHooks.js';
|
|
9
|
+
import type { PageContextExports, PageFile } from '../../shared/getPageFiles.js';
|
|
10
|
+
import { type PageConfigRuntime } from '../../shared/page-configs/PageConfig.js';
|
|
11
|
+
type ResultPageContextFromServer = Awaited<ReturnType<typeof getPageContextFromServerHooks>>;
|
|
12
|
+
type PageContextForPrefetch = {
|
|
13
|
+
urlOriginal: string;
|
|
14
|
+
urlPathname: string;
|
|
15
|
+
pageId: string;
|
|
16
|
+
_urlRewrite: null;
|
|
17
|
+
_pageFilesAll: PageFile[];
|
|
18
|
+
_pageConfigs: PageConfigRuntime[];
|
|
19
|
+
};
|
|
20
|
+
declare function getPageContextPrefetched(pageContext: {
|
|
21
|
+
urlPathname: string;
|
|
22
|
+
} & PageContextExports): null | PageContextFromServerHooks;
|
|
23
|
+
declare function populatePageContextPrefetchCache(pageContext: PageContextForPrefetch, result: ResultPageContextFromServer): void;
|
|
3
24
|
/**
|
|
4
25
|
* Programmatically prefetch client assets.
|
|
5
26
|
*
|
|
@@ -7,8 +28,11 @@ export { addLinkPrefetchHandlers };
|
|
|
7
28
|
*
|
|
8
29
|
* @param url - The URL of the page you want to prefetch.
|
|
9
30
|
*/
|
|
10
|
-
declare function prefetch(url: string
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
declare function prefetch(url: string, options?: {
|
|
32
|
+
pageContext?: boolean;
|
|
33
|
+
staticAssets?: boolean;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
declare function addLinkPrefetchHandlers(): void;
|
|
36
|
+
declare function initLinkPrefetchHandlers(): void;
|
|
37
|
+
declare function addLinkPrefetchHandlers_watch(): void;
|
|
38
|
+
declare function addLinkPrefetchHandlers_unwatch(): void;
|