vike 0.4.152-commit-3d25618 → 0.4.152-commit-6f928f9

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.
Files changed (33) hide show
  1. package/dist/cjs/node/runtime/html/stream.js +2 -1
  2. package/dist/cjs/node/runtime/renderPage/isNewError.js +1 -1
  3. package/dist/cjs/node/runtime/utils.js +1 -2
  4. package/dist/cjs/utils/isSameErrorMessage.js +10 -0
  5. package/dist/cjs/utils/projectInfo.js +1 -1
  6. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +0 -1
  7. package/dist/esm/client/client-routing-runtime/createPageContext.js +0 -3
  8. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.d.ts +2 -2
  9. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +4 -4
  10. package/dist/esm/client/client-routing-runtime/prefetch/getPrefetchSettings.d.ts +1 -3
  11. package/dist/esm/client/client-routing-runtime/prefetch/getPrefetchSettings.js +1 -1
  12. package/dist/esm/client/client-routing-runtime/prefetch.d.ts +0 -1
  13. package/dist/esm/client/client-routing-runtime/renderPageClientSide.d.ts +1 -1
  14. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +193 -167
  15. package/dist/esm/client/client-routing-runtime/utils.d.ts +1 -1
  16. package/dist/esm/client/client-routing-runtime/utils.js +1 -1
  17. package/dist/esm/client/shared/executeOnRenderClientHook.d.ts +4 -2
  18. package/dist/esm/node/runtime/html/stream.js +3 -2
  19. package/dist/esm/node/runtime/renderPage/isNewError.js +2 -2
  20. package/dist/esm/node/runtime/utils.d.ts +1 -2
  21. package/dist/esm/node/runtime/utils.js +1 -2
  22. package/dist/esm/shared/page-configs/Config.d.ts +1 -1
  23. package/dist/esm/utils/isSameErrorMessage.d.ts +2 -0
  24. package/dist/esm/utils/isSameErrorMessage.js +7 -0
  25. package/dist/esm/utils/projectInfo.d.ts +2 -2
  26. package/dist/esm/utils/projectInfo.js +1 -1
  27. package/package.json +2 -2
  28. package/dist/cjs/utils/dynamicImport.js +0 -8
  29. package/dist/cjs/utils/isEquivalentError.js +0 -18
  30. package/dist/esm/utils/dynamicImport.d.ts +0 -2
  31. package/dist/esm/utils/dynamicImport.js +0 -4
  32. package/dist/esm/utils/isEquivalentError.d.ts +0 -2
  33. package/dist/esm/utils/isEquivalentError.js +0 -15
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isStreamWritableNode = exports.isStreamWritableWeb = exports.streamPipeNodeToString = exports.streamReadableWebToString = exports.inferStreamName = exports.getStreamName = exports.isStreamReadableNode = exports.isStreamReadableWeb = exports.isStreamPipeNode = exports.isStreamPipeWeb = exports.isStream = exports.pipeToStreamWritableWeb = exports.pipeToStreamWritableNode = exports.getStreamReadableWeb = exports.getStreamReadableNode = exports.pipeNodeStream = exports.pipeWebStream = exports.pipeStream = exports.stampPipe = exports.streamToString = exports.processStream = void 0;
7
7
  const utils_js_1 = require("../utils.js");
8
8
  const react_streaming_js_1 = require("./stream/react-streaming.js");
9
+ const import_1 = require("@brillout/import");
9
10
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
10
11
  const debug = (0, utils_js_1.createDebugger)('vike:stream');
11
12
  function isStreamReadableWeb(thing) {
@@ -757,7 +758,7 @@ function encodeForWebStream(thing) {
757
758
  }
758
759
  // Because of Cloudflare Workers, we cannot statically import the `stream` module, instead we dynamically import it.
759
760
  async function loadStreamNodeModule() {
760
- const streamModule = await (0, utils_js_1.dynamicImport)('stream');
761
+ const streamModule = (await (0, import_1.import_)('stream')).default;
761
762
  const { Readable, Writable } = streamModule;
762
763
  return { Readable, Writable };
763
764
  }
@@ -7,7 +7,7 @@ const globalObject = (0, utils_js_1.getGlobalObject)('runtime/renderPage/isNewEr
7
7
  });
8
8
  function isNewError(errErrorPage, errNominalPage) {
9
9
  (0, utils_js_1.warnIfErrorIsNotObject)(errErrorPage);
10
- return !(0, utils_js_1.isEquivalentError)(errNominalPage, errErrorPage) || !hasAlreadyLogged(errNominalPage);
10
+ return !(0, utils_js_1.isSameErrorMessage)(errNominalPage, errErrorPage) || !hasAlreadyLogged(errNominalPage);
11
11
  }
12
12
  exports.isNewError = isNewError;
13
13
  function hasAlreadyLogged(err) {
@@ -42,7 +42,7 @@ __exportStar(require("../../utils/filesystemPathHandling.js"), exports);
42
42
  __exportStar(require("../../utils/getOutDirs.js"), exports);
43
43
  __exportStar(require("../../utils/capitalizeFirstLetter.js"), exports);
44
44
  __exportStar(require("../../utils/debugGlob.js"), exports);
45
- __exportStar(require("../../utils/isEquivalentError.js"), exports);
45
+ __exportStar(require("../../utils/isSameErrorMessage.js"), exports);
46
46
  __exportStar(require("../../utils/styleFileRE.js"), exports);
47
47
  __exportStar(require("../../utils/isPropertyGetter.js"), exports);
48
48
  __exportStar(require("../../utils/debug.js"), exports);
@@ -64,7 +64,6 @@ __exportStar(require("../../utils/path-shim.js"), exports);
64
64
  __exportStar(require("../../utils/nodeEnv.js"), exports);
65
65
  __exportStar(require("../../utils/isHtml.js"), exports);
66
66
  __exportStar(require("../../utils/warnIfErrorIsNotObject.js"), exports);
67
- __exportStar(require("../../utils/dynamicImport.js"), exports);
68
67
  __exportStar(require("../../utils/stripAnsi.js"), exports);
69
68
  __exportStar(require("../../utils/getTerminWidth.js"), exports);
70
69
  __exportStar(require("../../utils/truncateString.js"), exports);
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSameErrorMessage = void 0;
4
+ const isObject_js_1 = require("./isObject.js");
5
+ function isSameErrorMessage(err1, err2) {
6
+ if (!(0, isObject_js_1.isObject)(err1) || !(0, isObject_js_1.isObject)(err2))
7
+ return false;
8
+ return err1.message === err2.message;
9
+ }
10
+ exports.isSameErrorMessage = isSameErrorMessage;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = exports.projectInfo = void 0;
4
4
  const assertSingleInstance_js_1 = require("./assertSingleInstance.js");
5
- const PROJECT_VERSION = '0.4.152-commit-3d25618';
5
+ const PROJECT_VERSION = '0.4.152-commit-6f928f9';
6
6
  exports.PROJECT_VERSION = PROJECT_VERSION;
7
7
  const projectInfo = {
8
8
  projectName: 'Vike',
@@ -5,7 +5,6 @@ declare function createPageContext(urlOriginal: string): Promise<{
5
5
  _urlHandler: null;
6
6
  _urlRewrite: null;
7
7
  _baseServer: string;
8
- _isProduction: boolean;
9
8
  _pageFilesAll: import("../../shared/getPageFiles/getPageFileObject.js").PageFile[];
10
9
  _pageConfigs: import("../../shared/page-configs/PageConfig.js").PageConfigRuntime[];
11
10
  _pageConfigGlobal: import("../../shared/page-configs/PageConfig.js").PageConfigGlobalRuntime;
@@ -13,15 +13,12 @@ async function createPageContext(urlOriginal) {
13
13
  const { pageRoutes, onBeforeRouteHook } = await loadPageRoutes(pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds);
14
14
  const baseServer = getBaseServer();
15
15
  assert(isBaseServer(baseServer));
16
- // @ts-ignore Since dist/cjs/client/ is never used, we can ignore this error.
17
- const isProd = import.meta.env.PROD;
18
16
  const pageContext = {
19
17
  urlOriginal,
20
18
  _objectCreatedByVike: true,
21
19
  _urlHandler: null,
22
20
  _urlRewrite: null,
23
21
  _baseServer: baseServer,
24
- _isProduction: isProd,
25
22
  _pageFilesAll: pageFilesAll,
26
23
  _pageConfigs: pageConfigs,
27
24
  _pageConfigGlobal: pageConfigGlobal,
@@ -1,7 +1,7 @@
1
1
  export { getPageContextFromHooks_firstRender };
2
2
  export { getPageContextFromHooks_uponNavigation };
3
3
  export { getPageContextFromHooks_errorPage };
4
- export { isAlreadyServerSideRouted };
4
+ export { isServerSideRouted as isServerSideRouted };
5
5
  export type { PageContextFromHooks };
6
6
  import type { PageContextExports, PageFile } from '../../shared/getPageFiles.js';
7
7
  import type { PageContextUrlComputedPropsInternal } from '../../shared/addUrlComputedProps.js';
@@ -36,4 +36,4 @@ declare function getPageContextFromHooks_errorPage(pageContext: {
36
36
  declare function getPageContextFromHooks_uponNavigation(pageContext: {
37
37
  _pageId: string;
38
38
  } & PageContext): Promise<PageContextFromHooks>;
39
- declare function isAlreadyServerSideRouted(err: unknown): boolean;
39
+ declare function isServerSideRouted(err: unknown): boolean;
@@ -1,7 +1,7 @@
1
1
  export { getPageContextFromHooks_firstRender };
2
2
  export { getPageContextFromHooks_uponNavigation };
3
3
  export { getPageContextFromHooks_errorPage };
4
- export { isAlreadyServerSideRouted };
4
+ export { isServerSideRouted as isServerSideRouted };
5
5
  import { assert, assertUsage, hasProp, objectAssign, getProjectError, serverSideRouteTo, executeHook, isObject, getGlobalObject } from './utils.js';
6
6
  import { parse } from '@brillout/json-serializer/parse';
7
7
  import { getPageContextSerializedInHtml } from '../shared/getPageContextSerializedInHtml.js';
@@ -237,7 +237,7 @@ async function fetchPageContextFromServer(pageContext) {
237
237
  // Static hosts + page doesn't exist
238
238
  if (!isCorrect && response.status === 404) {
239
239
  serverSideRouteTo(pageContext.urlOriginal);
240
- throw AlreadyServerSideRouted();
240
+ throw ServerSideRouted();
241
241
  }
242
242
  assertUsage(isCorrect, `Wrong Content-Type for ${pageContextUrl}: it should be ${contentTypeCorrect} but it's ${contentType} instead. Make sure to properly use pageContext.httpResponse.headers, see https://vike.dev/renderPage`);
243
243
  }
@@ -254,10 +254,10 @@ async function fetchPageContextFromServer(pageContext) {
254
254
  removeBuiltInOverrides(pageContextFromServer);
255
255
  return pageContextFromServer;
256
256
  }
257
- function isAlreadyServerSideRouted(err) {
257
+ function isServerSideRouted(err) {
258
258
  return isObject(err) && !!err._alreadyServerSideRouted;
259
259
  }
260
- function AlreadyServerSideRouted() {
260
+ function ServerSideRouted() {
261
261
  const err = new Error("Page doesn't exist");
262
262
  Object.assign(err, { _alreadyServerSideRouted: true });
263
263
  return err;
@@ -1,10 +1,8 @@
1
1
  export { getPrefetchSettings };
2
- export type { PrefetchStaticAssets };
2
+ import type { PrefetchStaticAssets } from '../../../shared/types/PrefetchStaticAssets.js';
3
3
  type PageContextPrefetch = {
4
4
  exports: Record<string, unknown>;
5
- _isProduction: boolean;
6
5
  };
7
- type PrefetchStaticAssets = false | 'hover' | 'viewport';
8
6
  type PrefetchSettings = {
9
7
  prefetchStaticAssets: PrefetchStaticAssets;
10
8
  };
@@ -2,7 +2,7 @@ export { getPrefetchSettings };
2
2
  import { assert, assertUsage, assertInfo, assertWarning, isPlainObject } from '../utils.js';
3
3
  function getPrefetchSettings(pageContext, linkTag) {
4
4
  let prefetchStaticAssets = getPrefetchStaticAssets(pageContext, linkTag);
5
- if (prefetchStaticAssets === 'viewport' && !pageContext._isProduction) {
5
+ if (prefetchStaticAssets === 'viewport' && import.meta.env.DEV) {
6
6
  assertInfo(false, 'Viewport prefetching is disabled in development', { onlyOnce: true });
7
7
  prefetchStaticAssets = 'hover';
8
8
  }
@@ -10,6 +10,5 @@ export { addLinkPrefetchHandlers };
10
10
  declare function prefetch(url: string): Promise<void>;
11
11
  declare function addLinkPrefetchHandlers(pageContext: {
12
12
  exports: Record<string, unknown>;
13
- _isProduction: boolean;
14
13
  urlPathname: string;
15
14
  }): void;
@@ -1,7 +1,7 @@
1
1
  export { renderPageClientSide };
2
2
  export { getRenderCount };
3
3
  export { disableClientRouting };
4
- import { PageContextFromRewrite } from '../../shared/route/abort.js';
4
+ import { type PageContextFromRewrite } from '../../shared/route/abort.js';
5
5
  import { type ScrollTarget } from './setScrollPosition.js';
6
6
  type RenderArgs = {
7
7
  scrollTarget: ScrollTarget;
@@ -1,8 +1,8 @@
1
1
  export { renderPageClientSide };
2
2
  export { getRenderCount };
3
3
  export { disableClientRouting };
4
- import { assert, getCurrentUrl, isEquivalentError, objectAssign, serverSideRouteTo, getGlobalObject, executeHook, hasProp } from './utils.js';
5
- import { getPageContextFromHooks_errorPage, getPageContextFromHooks_firstRender, getPageContextFromHooks_uponNavigation, isAlreadyServerSideRouted } from './getPageContextFromHooks.js';
4
+ import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, serverSideRouteTo, getGlobalObject, executeHook, hasProp } from './utils.js';
5
+ import { getPageContextFromHooks_errorPage, getPageContextFromHooks_firstRender, getPageContextFromHooks_uponNavigation, isServerSideRouted } from './getPageContextFromHooks.js';
6
6
  import { createPageContext } from './createPageContext.js';
7
7
  import { addLinkPrefetchHandlers } from './prefetch.js';
8
8
  import { assertInfo, assertWarning, isReact } from './utils.js';
@@ -19,113 +19,127 @@ import { browserNativeScrollRestoration_disable, setInitialRenderIsDone } from '
19
19
  const globalObject = getGlobalObject('renderPageClientSide.ts', { renderCounter: 0 });
20
20
  async function renderPageClientSide(renderArgs) {
21
21
  const { scrollTarget, urlOriginal = getCurrentUrl(), overwriteLastHistoryEntry = false, isBackwardNavigation, pageContextsFromRewrite = [], redirectCount = 0, isUserLandPushStateNavigation, isClientSideNavigation = true } = renderArgs;
22
- const { abortRender, setHydrationCanBeAborted, isFirstRender } = getAbortRender();
22
+ const { isRenderOutdated, setHydrationCanBeAborted, isFirstRender } = getIsRenderOutdated();
23
+ const callTransitionHooks = !isFirstRender;
23
24
  assert(isClientSideNavigation === !isFirstRender);
24
25
  assertNoInfiniteAbortLoop(pageContextsFromRewrite.length, redirectCount);
25
26
  if (globalObject.clientRoutingIsDisabled) {
26
27
  serverSideRouteTo(urlOriginal);
27
28
  return;
28
29
  }
29
- const pageContext = await createPageContext(urlOriginal);
30
- if (abortRender())
31
- return;
32
- objectAssign(pageContext, {
33
- isBackwardNavigation,
34
- isClientSideNavigation
35
- });
36
- {
37
- const pageContextFromAllRewrites = getPageContextFromAllRewrites(pageContextsFromRewrite);
38
- objectAssign(pageContext, pageContextFromAllRewrites);
39
- }
40
- let renderState = {};
41
- const onError = (err) => {
42
- assert(err);
43
- assert(!('err' in renderState));
44
- assert(!('errorWhileRendering' in pageContext));
45
- renderState.err = err;
46
- pageContext.errorWhileRendering = err;
47
- };
48
- if (!isFirstRender) {
49
- // Route
50
- try {
51
- renderState = { pageContextFromRoute: await route(pageContext) };
52
- }
53
- catch (err) {
54
- onError(err);
55
- }
56
- if (abortRender())
30
+ await renderPageNominal();
31
+ return;
32
+ async function renderPageNominal() {
33
+ const pageContext = await getPageContextBegin();
34
+ if (isRenderOutdated())
57
35
  return;
58
- // Check whether rendering should be skipped
59
- if (renderState.pageContextFromRoute) {
60
- const { pageContextFromRoute } = renderState;
61
- objectAssign(pageContext, pageContextFromRoute);
62
- let isClientRoutable;
63
- if (!pageContextFromRoute._pageId) {
64
- isClientRoutable = false;
65
- }
66
- else {
67
- isClientRoutable = await isClientSideRoutable(pageContextFromRoute._pageId, pageContext);
68
- if (abortRender())
69
- return;
36
+ let renderState = {};
37
+ if (!isFirstRender) {
38
+ // Route
39
+ try {
40
+ renderState = { pageContextFromRoute: await route(pageContext) };
70
41
  }
71
- if (!isClientRoutable) {
72
- serverSideRouteTo(urlOriginal);
42
+ catch (err) {
43
+ await renderErrorPage(err);
73
44
  return;
74
45
  }
75
- const isSamePage = pageContextFromRoute._pageId &&
76
- globalObject.previousPageContext?._pageId &&
77
- pageContextFromRoute._pageId === globalObject.previousPageContext._pageId;
78
- if (isUserLandPushStateNavigation && isSamePage) {
79
- // Skip's Vike's rendering; let the user handle the navigation
46
+ if (isRenderOutdated())
80
47
  return;
48
+ // Check whether rendering should be skipped
49
+ if (renderState.pageContextFromRoute) {
50
+ const { pageContextFromRoute } = renderState;
51
+ assert(!('urlOriginal' in pageContextFromRoute));
52
+ objectAssign(pageContext, pageContextFromRoute);
53
+ let isClientRoutable;
54
+ if (!pageContextFromRoute._pageId) {
55
+ isClientRoutable = false;
56
+ }
57
+ else {
58
+ isClientRoutable = await isClientSideRoutable(pageContextFromRoute._pageId, pageContext);
59
+ if (isRenderOutdated())
60
+ return;
61
+ }
62
+ if (!isClientRoutable) {
63
+ serverSideRouteTo(urlOriginal);
64
+ return;
65
+ }
66
+ const isSamePage = pageContextFromRoute._pageId &&
67
+ globalObject.previousPageContext?._pageId &&
68
+ pageContextFromRoute._pageId === globalObject.previousPageContext._pageId;
69
+ if (isUserLandPushStateNavigation && isSamePage) {
70
+ // Skip's Vike's rendering; let the user handle the navigation
71
+ return;
72
+ }
81
73
  }
82
74
  }
83
- }
84
- // onPageTransitionStart()
85
- const callTransitionHooks = !isFirstRender;
86
- if (callTransitionHooks) {
87
- if (!globalObject.isTransitioning) {
88
- if (globalObject.onPageTransitionStart) {
89
- const hook = globalObject.onPageTransitionStart;
90
- const { hookFn } = hook;
91
- await executeHook(() => hookFn(pageContext), hook);
75
+ // onPageTransitionStart()
76
+ if (callTransitionHooks) {
77
+ if (!globalObject.isTransitioning) {
78
+ if (globalObject.onPageTransitionStart) {
79
+ const hook = globalObject.onPageTransitionStart;
80
+ const { hookFn } = hook;
81
+ await executeHook(() => hookFn(pageContext), hook);
82
+ }
83
+ globalObject.isTransitioning = true;
84
+ if (isRenderOutdated())
85
+ return;
92
86
  }
93
- globalObject.isTransitioning = true;
94
- if (abortRender())
95
- return;
96
- }
97
- }
98
- if (isFirstRender) {
99
- assert(!renderState.pageContextFromRoute);
100
- assert(!renderState.err);
101
- try {
102
- renderState.pageContextFromHooks = await getPageContextFromHooks_firstRender(pageContext);
103
87
  }
104
- catch (err) {
105
- onError(err);
88
+ if (isFirstRender) {
89
+ assert(!renderState.pageContextFromRoute);
90
+ try {
91
+ renderState.pageContextFromHooks = await getPageContextFromHooks_firstRender(pageContext);
92
+ }
93
+ catch (err) {
94
+ await renderErrorPage(err);
95
+ return;
96
+ }
97
+ if (isRenderOutdated())
98
+ return;
106
99
  }
107
- if (abortRender())
108
- return;
109
- }
110
- else {
111
- if (!renderState.err) {
100
+ else {
112
101
  const { pageContextFromRoute } = renderState;
113
102
  assert(pageContextFromRoute);
114
103
  assert(pageContextFromRoute._pageId);
115
104
  assert(hasProp(pageContextFromRoute, '_pageId', 'string')); // Help TS
105
+ assert(!('urlOriginal' in pageContextFromRoute));
116
106
  objectAssign(pageContext, pageContextFromRoute);
117
107
  try {
118
108
  renderState.pageContextFromHooks = await getPageContextFromHooks_uponNavigation(pageContext);
119
109
  }
120
110
  catch (err) {
121
- onError(err);
111
+ await renderErrorPage(err);
112
+ return;
122
113
  }
123
- if (abortRender())
114
+ if (isRenderOutdated())
124
115
  return;
125
116
  }
117
+ const { pageContextFromHooks } = renderState;
118
+ assert(pageContextFromHooks);
119
+ assert(!('urlOriginal' in pageContextFromHooks));
120
+ objectAssign(pageContext, pageContextFromHooks);
121
+ await renderPageView(pageContext);
122
+ }
123
+ async function getPageContextBegin() {
124
+ const pageContext = await createPageContext(urlOriginal);
125
+ objectAssign(pageContext, {
126
+ isBackwardNavigation,
127
+ isClientSideNavigation
128
+ });
129
+ {
130
+ const pageContextFromAllRewrites = getPageContextFromAllRewrites(pageContextsFromRewrite);
131
+ assert(!('urlOriginal' in pageContextFromAllRewrites));
132
+ objectAssign(pageContext, pageContextFromAllRewrites);
133
+ }
134
+ return pageContext;
126
135
  }
127
- if ('err' in renderState) {
128
- const { err } = renderState;
136
+ async function renderErrorPage(err) {
137
+ const pageContext = await getPageContextBegin();
138
+ if (isRenderOutdated())
139
+ return;
140
+ assert(err);
141
+ assert(!('errorWhileRendering' in pageContext));
142
+ pageContext.errorWhileRendering = err;
129
143
  if (!isAbortError(err)) {
130
144
  // We don't swallow 404 errors:
131
145
  // - On the server-side, Vike swallows / doesn't show any 404 error log because it's expected that a user may go to some random non-existent URL. (We don't want to flood the app's error tracking with 404 logs.)
@@ -133,14 +147,14 @@ async function renderPageClientSide(renderArgs) {
133
147
  console.error(err);
134
148
  }
135
149
  else {
136
- // We swallow throw redirect()/render() called by client-side hooks onBeforeRender(), data() and guard()
150
+ // We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
137
151
  // We handle the abort error down below.
138
152
  }
139
153
  if (shouldSwallowAndInterrupt(err, pageContext, isFirstRender))
140
154
  return;
141
155
  if (isAbortError(err)) {
142
156
  const errAbort = err;
143
- logAbortErrorHandled(err, pageContext._isProduction, pageContext);
157
+ logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
144
158
  const pageContextAbort = errAbort._pageContextAbort;
145
159
  // throw render('/some-url')
146
160
  if (pageContextAbort._urlRewrite) {
@@ -173,6 +187,7 @@ async function renderPageClientSide(renderArgs) {
173
187
  }
174
188
  // throw render(statusCode)
175
189
  assert(pageContextAbort.abortStatusCode);
190
+ assert(!('urlOriginal' in pageContextAbort));
176
191
  objectAssign(pageContext, pageContextAbort);
177
192
  if (pageContextAbort.abortStatusCode === 404) {
178
193
  objectAssign(pageContext, { is404: true });
@@ -181,99 +196,110 @@ async function renderPageClientSide(renderArgs) {
181
196
  else {
182
197
  objectAssign(pageContext, { is404: false });
183
198
  }
199
+ let pageContextFromHooks;
184
200
  try {
185
- renderState.pageContextFromHooks = await getPageContextFromHooks_errorPage(pageContext);
201
+ pageContextFromHooks = await getPageContextFromHooks_errorPage(pageContext);
186
202
  }
187
- catch (err2) {
203
+ catch (errErrorPage) {
188
204
  // - When user hasn't defined a `_error.page.js` file
189
- // - Some unpexected vike internal error
190
- if (shouldSwallowAndInterrupt(err2, pageContext, isFirstRender))
205
+ // - Some Vike unpexected internal error
206
+ if (shouldSwallowAndInterrupt(errErrorPage, pageContext, isFirstRender))
191
207
  return;
192
- if (!isFirstRender) {
193
- setTimeout(() => {
194
- // We let the server show the 404 page
195
- window.location.pathname = urlOriginal;
196
- }, 0);
197
- }
198
- if (!isEquivalentError(err, err2)) {
199
- throw err2;
200
- }
201
- else {
202
- // Abort
208
+ if (isSameErrorMessage(err, errErrorPage)) {
209
+ /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
210
+ - We risk running into an infinite loop of reloads which would overload the server.
211
+ - An infinite reloading page is a even worse UX than a blank page.
212
+ serverSideRouteTo(urlOriginal)
213
+ */
203
214
  return;
204
215
  }
216
+ // We `throw err2` instead of `console.error(err2)` so that, when using `navigate()`, the error propagates to the user `navigate()` call
217
+ throw errErrorPage;
205
218
  }
206
- if (abortRender())
219
+ if (isRenderOutdated())
207
220
  return;
221
+ assert(pageContextFromHooks);
222
+ assert(!('urlOriginal' in pageContextFromHooks));
223
+ objectAssign(pageContext, pageContextFromHooks);
224
+ await renderPageView(pageContext, true);
208
225
  }
209
- const { pageContextFromHooks } = renderState;
210
- assert(pageContextFromHooks);
211
- objectAssign(pageContext, pageContextFromHooks);
212
- // Set global onPageTransitionStart()
213
- assertHook(pageContext, 'onPageTransitionStart');
214
- const onPageTransitionStartHook = getHook(pageContext, 'onPageTransitionStart');
215
- globalObject.onPageTransitionStart = onPageTransitionStartHook;
216
- // Set global hydrationCanBeAborted
217
- if (pageContext.exports.hydrationCanBeAborted) {
218
- setHydrationCanBeAborted();
219
- }
220
- else {
221
- assertWarning(!isReact(), 'You seem to be using React; we recommend setting hydrationCanBeAborted to true, see https://vike.dev/hydrationCanBeAborted', { onlyOnce: true });
222
- }
223
- // There wasn't any `await` but result may change because we just called setHydrationCanBeAborted()
224
- if (abortRender())
225
- return;
226
- // We use globalObject.renderPromise in order to ensure that there is never two concurrent onRenderClient() calls
227
- if (globalObject.renderPromise) {
228
- // Make sure that the previous render has finished
229
- await globalObject.renderPromise;
230
- assert(globalObject.renderPromise === undefined);
231
- if (abortRender())
226
+ async function renderPageView(pageContext, isErrorPage) {
227
+ // Set global onPageTransitionStart()
228
+ assertHook(pageContext, 'onPageTransitionStart');
229
+ const onPageTransitionStartHook = getHook(pageContext, 'onPageTransitionStart');
230
+ globalObject.onPageTransitionStart = onPageTransitionStartHook;
231
+ // Set global hydrationCanBeAborted
232
+ if (pageContext.exports.hydrationCanBeAborted) {
233
+ setHydrationCanBeAborted();
234
+ }
235
+ else {
236
+ assertWarning(!isReact(), 'You seem to be using React; we recommend setting hydrationCanBeAborted to true, see https://vike.dev/hydrationCanBeAborted', { onlyOnce: true });
237
+ }
238
+ // There wasn't any `await` but result may change because we just called setHydrationCanBeAborted()
239
+ if (isRenderOutdated())
232
240
  return;
233
- }
234
- changeUrl(urlOriginal, overwriteLastHistoryEntry);
235
- globalObject.previousPageContext = pageContext;
236
- assert(globalObject.renderPromise === undefined);
237
- globalObject.renderPromise = (async () => {
238
- await executeOnRenderClientHook(pageContext, true);
239
- addLinkPrefetchHandlers(pageContext);
240
- globalObject.renderPromise = undefined;
241
- })();
242
- await globalObject.renderPromise;
243
- assert(globalObject.renderPromise === undefined);
244
- /* We don't abort in order to ensure that onHydrationEnd() is called: we abort only after onHydrationEnd() is called.
245
- if (abortRender(true)) return
246
- */
247
- // onHydrationEnd()
248
- if (isFirstRender) {
249
- assertHook(pageContext, 'onHydrationEnd');
250
- const hook = getHook(pageContext, 'onHydrationEnd');
251
- if (hook) {
252
- const { hookFn } = hook;
253
- await executeHook(() => hookFn(pageContext), hook);
254
- if (abortRender(true))
241
+ // We use globalObject.renderPromise in order to ensure that there is never two concurrent onRenderClient() calls
242
+ if (globalObject.renderPromise) {
243
+ // Make sure that the previous render has finished
244
+ await globalObject.renderPromise;
245
+ assert(globalObject.renderPromise === undefined);
246
+ if (isRenderOutdated())
255
247
  return;
256
248
  }
257
- }
258
- // We abort only after onHydrationEnd() is called
259
- if (abortRender(true))
260
- return;
261
- // onPageTransitionEnd()
262
- if (callTransitionHooks) {
263
- assertHook(pageContext, 'onPageTransitionEnd');
264
- const hook = getHook(pageContext, 'onPageTransitionEnd');
265
- if (hook) {
266
- const { hookFn } = hook;
267
- await executeHook(() => hookFn(pageContext), hook);
268
- if (abortRender(true))
269
- return;
249
+ changeUrl(urlOriginal, overwriteLastHistoryEntry);
250
+ globalObject.previousPageContext = pageContext;
251
+ assert(globalObject.renderPromise === undefined);
252
+ globalObject.renderPromise = (async () => {
253
+ try {
254
+ await executeOnRenderClientHook(pageContext, true);
255
+ }
256
+ catch (err) {
257
+ if (!isErrorPage) {
258
+ renderErrorPage(err);
259
+ }
260
+ else {
261
+ throw err;
262
+ }
263
+ }
264
+ addLinkPrefetchHandlers(pageContext);
265
+ globalObject.renderPromise = undefined;
266
+ })();
267
+ await globalObject.renderPromise;
268
+ assert(globalObject.renderPromise === undefined);
269
+ /* We don't abort in order to ensure that onHydrationEnd() is called: we abort only after onHydrationEnd() is called.
270
+ if (isRenderOutdated(true)) return
271
+ */
272
+ // onHydrationEnd()
273
+ if (isFirstRender) {
274
+ assertHook(pageContext, 'onHydrationEnd');
275
+ const hook = getHook(pageContext, 'onHydrationEnd');
276
+ if (hook) {
277
+ const { hookFn } = hook;
278
+ await executeHook(() => hookFn(pageContext), hook);
279
+ if (isRenderOutdated(true))
280
+ return;
281
+ }
270
282
  }
271
- globalObject.isTransitioning = undefined;
283
+ // We abort only after onHydrationEnd() is called
284
+ if (isRenderOutdated(true))
285
+ return;
286
+ // onPageTransitionEnd()
287
+ if (callTransitionHooks) {
288
+ assertHook(pageContext, 'onPageTransitionEnd');
289
+ const hook = getHook(pageContext, 'onPageTransitionEnd');
290
+ if (hook) {
291
+ const { hookFn } = hook;
292
+ await executeHook(() => hookFn(pageContext), hook);
293
+ if (isRenderOutdated(true))
294
+ return;
295
+ }
296
+ globalObject.isTransitioning = undefined;
297
+ }
298
+ // Page scrolling
299
+ setScrollPosition(scrollTarget);
300
+ browserNativeScrollRestoration_disable();
301
+ setInitialRenderIsDone();
272
302
  }
273
- // Page scrolling
274
- setScrollPosition(scrollTarget);
275
- browserNativeScrollRestoration_disable();
276
- setInitialRenderIsDone();
277
303
  }
278
304
  function changeUrl(url, overwriteLastHistoryEntry) {
279
305
  if (getCurrentUrl() === url)
@@ -283,7 +309,7 @@ function changeUrl(url, overwriteLastHistoryEntry) {
283
309
  updateState();
284
310
  }
285
311
  function shouldSwallowAndInterrupt(err, pageContext, isFirstRender) {
286
- if (isAlreadyServerSideRouted(err))
312
+ if (isServerSideRouted(err))
287
313
  return true;
288
314
  if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender))
289
315
  return true;
@@ -323,7 +349,7 @@ function disableClientRouting(err, log) {
323
349
  .filter(Boolean)
324
350
  .join(' '), { onlyOnce: true });
325
351
  }
326
- function getAbortRender() {
352
+ function getIsRenderOutdated() {
327
353
  const renderNumber = ++globalObject.renderCounter;
328
354
  assert(renderNumber >= 1);
329
355
  let hydrationCanBeAborted = false;
@@ -331,11 +357,11 @@ function getAbortRender() {
331
357
  hydrationCanBeAborted = true;
332
358
  };
333
359
  /** Whether the rendering should be aborted because a new rendering has started. We should call this after each `await`. */
334
- const abortRender = (isRenderCleanup) => {
360
+ const isRenderOutdated = (isRenderCleanup) => {
335
361
  // Never abort hydration if `hydrationCanBeAborted` isn't `true`
336
- if (!isRenderCleanup) {
362
+ {
337
363
  const isHydration = renderNumber === 1;
338
- if (isHydration && !hydrationCanBeAborted) {
364
+ if (isHydration && !hydrationCanBeAborted && !isRenderCleanup) {
339
365
  return false;
340
366
  }
341
367
  }
@@ -343,7 +369,7 @@ function getAbortRender() {
343
369
  return renderNumber !== globalObject.renderCounter;
344
370
  };
345
371
  return {
346
- abortRender,
372
+ isRenderOutdated,
347
373
  setHydrationCanBeAborted,
348
374
  isFirstRender: renderNumber === 1
349
375
  };
@@ -10,7 +10,7 @@ export * from '../../utils/isCallable.js';
10
10
  export * from '../../utils/isObject.js';
11
11
  export * from '../../utils/isPlainObject.js';
12
12
  export * from '../../utils/isReact.js';
13
- export * from '../../utils/isEquivalentError.js';
13
+ export * from '../../utils/isSameErrorMessage.js';
14
14
  export * from '../../utils/objectAssign.js';
15
15
  export * from '../../utils/parseUrl.js';
16
16
  export * from '../../utils/projectInfo.js';
@@ -16,7 +16,7 @@ export * from '../../utils/isCallable.js';
16
16
  export * from '../../utils/isObject.js';
17
17
  export * from '../../utils/isPlainObject.js';
18
18
  export * from '../../utils/isReact.js';
19
- export * from '../../utils/isEquivalentError.js';
19
+ export * from '../../utils/isSameErrorMessage.js';
20
20
  export * from '../../utils/objectAssign.js';
21
21
  export * from '../../utils/parseUrl.js';
22
22
  export * from '../../utils/projectInfo.js';
@@ -1,11 +1,13 @@
1
1
  export { executeOnRenderClientHook };
2
+ export type { PageContextBeforeRenderClient };
2
3
  import type { PageFile, PageContextExports } from '../../shared/getPageFiles.js';
3
4
  import { type PageContextForUserConsumptionClientSide } from './preparePageContextForUserConsumptionClientSide.js';
4
5
  import type { PageConfigRuntime } from '../../shared/page-configs/PageConfig.js';
5
- declare function executeOnRenderClientHook<PC extends {
6
+ type PageContextBeforeRenderClient = {
6
7
  _pageFilesLoaded: PageFile[];
7
8
  urlOriginal?: string;
8
9
  urlPathname?: string;
9
10
  _pageId: string;
10
11
  _pageConfigs: PageConfigRuntime[];
11
- } & PageContextExports & PageContextForUserConsumptionClientSide>(pageContext: PC, isClientRouting: boolean): Promise<void>;
12
+ } & PageContextExports & PageContextForUserConsumptionClientSide;
13
+ declare function executeOnRenderClientHook<PC extends PageContextBeforeRenderClient>(pageContext: PC, isClientRouting: boolean): Promise<void>;
@@ -19,8 +19,9 @@ export { streamReadableWebToString };
19
19
  export { streamPipeNodeToString };
20
20
  export { isStreamWritableWeb };
21
21
  export { isStreamWritableNode };
22
- import { assert, assertUsage, checkType, isObject, hasProp, objectAssign, capitalizeFirstLetter, assertWarning, isCallable, createDebugger, dynamicImport, isBug } from '../utils.js';
22
+ import { assert, assertUsage, checkType, isObject, hasProp, objectAssign, capitalizeFirstLetter, assertWarning, isCallable, createDebugger, isBug } from '../utils.js';
23
23
  import { getStreamFromReactStreaming, isStreamReactStreaming, streamReactStreamingToString } from './stream/react-streaming.js';
24
+ import { import_ } from '@brillout/import';
24
25
  import pc from '@brillout/picocolors';
25
26
  const debug = createDebugger('vike:stream');
26
27
  function isStreamReadableWeb(thing) {
@@ -753,7 +754,7 @@ function encodeForWebStream(thing) {
753
754
  }
754
755
  // Because of Cloudflare Workers, we cannot statically import the `stream` module, instead we dynamically import it.
755
756
  async function loadStreamNodeModule() {
756
- const streamModule = await dynamicImport('stream');
757
+ const streamModule = (await import_('stream')).default;
757
758
  const { Readable, Writable } = streamModule;
758
759
  return { Readable, Writable };
759
760
  }
@@ -1,12 +1,12 @@
1
1
  export { isNewError };
2
2
  export { setAlreadyLogged };
3
- import { getGlobalObject, isObject, isEquivalentError, warnIfErrorIsNotObject } from '../utils.js';
3
+ import { getGlobalObject, isObject, isSameErrorMessage, warnIfErrorIsNotObject } from '../utils.js';
4
4
  const globalObject = getGlobalObject('runtime/renderPage/isNewError.ts', {
5
5
  wasAlreadyLogged: new WeakSet()
6
6
  });
7
7
  function isNewError(errErrorPage, errNominalPage) {
8
8
  warnIfErrorIsNotObject(errErrorPage);
9
- return !isEquivalentError(errNominalPage, errErrorPage) || !hasAlreadyLogged(errNominalPage);
9
+ return !isSameErrorMessage(errNominalPage, errErrorPage) || !hasAlreadyLogged(errNominalPage);
10
10
  }
11
11
  function hasAlreadyLogged(err) {
12
12
  if (!isObject(err))
@@ -23,7 +23,7 @@ export * from '../../utils/filesystemPathHandling.js';
23
23
  export * from '../../utils/getOutDirs.js';
24
24
  export * from '../../utils/capitalizeFirstLetter.js';
25
25
  export * from '../../utils/debugGlob.js';
26
- export * from '../../utils/isEquivalentError.js';
26
+ export * from '../../utils/isSameErrorMessage.js';
27
27
  export * from '../../utils/styleFileRE.js';
28
28
  export * from '../../utils/isPropertyGetter.js';
29
29
  export * from '../../utils/debug.js';
@@ -45,7 +45,6 @@ export * from '../../utils/path-shim.js';
45
45
  export * from '../../utils/nodeEnv.js';
46
46
  export * from '../../utils/isHtml.js';
47
47
  export * from '../../utils/warnIfErrorIsNotObject.js';
48
- export * from '../../utils/dynamicImport.js';
49
48
  export * from '../../utils/stripAnsi.js';
50
49
  export * from '../../utils/getTerminWidth.js';
51
50
  export * from '../../utils/truncateString.js';
@@ -26,7 +26,7 @@ export * from '../../utils/filesystemPathHandling.js';
26
26
  export * from '../../utils/getOutDirs.js';
27
27
  export * from '../../utils/capitalizeFirstLetter.js';
28
28
  export * from '../../utils/debugGlob.js';
29
- export * from '../../utils/isEquivalentError.js';
29
+ export * from '../../utils/isSameErrorMessage.js';
30
30
  export * from '../../utils/styleFileRE.js';
31
31
  export * from '../../utils/isPropertyGetter.js';
32
32
  export * from '../../utils/debug.js';
@@ -48,7 +48,6 @@ export * from '../../utils/path-shim.js';
48
48
  export * from '../../utils/nodeEnv.js';
49
49
  export * from '../../utils/isHtml.js';
50
50
  export * from '../../utils/warnIfErrorIsNotObject.js';
51
- export * from '../../utils/dynamicImport.js';
52
51
  export * from '../../utils/stripAnsi.js';
53
52
  export * from '../../utils/getTerminWidth.js';
54
53
  export * from '../../utils/truncateString.js';
@@ -29,13 +29,13 @@ export type { OnRenderHtmlAsync };
29
29
  export type { OnRenderHtmlSync };
30
30
  export type { RouteAsync };
31
31
  export type { RouteSync };
32
- import type { PrefetchStaticAssets } from '../../client/client-routing-runtime/prefetch/getPrefetchSettings.js';
33
32
  import type { ConfigDefinition } from '../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js';
34
33
  import type { DocumentHtml } from '../../node/runtime/html/renderHtml.js';
35
34
  import type { ConfigVikeUserProvided } from '../ConfigVike.js';
36
35
  import type { Vike, VikePackages } from '../VikeNamespace.js';
37
36
  import type { HooksTimeoutProvidedByUser } from '../hooks/getHook.js';
38
37
  import type { PageContextClient, PageContextServer } from '../types.js';
38
+ import type { PrefetchStaticAssets } from '../types/PrefetchStaticAssets.js';
39
39
  type HookName = HookNamePage | HookNameGlobal | HookNameOldDesign;
40
40
  type HookNamePage = 'onHydrationEnd' | 'onBeforePrerenderStart' | 'onBeforeRender' | 'onPageTransitionStart' | 'onPageTransitionEnd' | 'onRenderHtml' | 'onRenderClient' | 'guard' | 'data';
41
41
  type HookNameGlobal = 'onBeforePrerender' | 'onBeforeRoute' | 'onPrerenderStart';
@@ -0,0 +1,2 @@
1
+ export { isSameErrorMessage };
2
+ declare function isSameErrorMessage(err1: unknown, err2: unknown): boolean;
@@ -0,0 +1,7 @@
1
+ import { isObject } from './isObject.js';
2
+ export { isSameErrorMessage };
3
+ function isSameErrorMessage(err1, err2) {
4
+ if (!isObject(err1) || !isObject(err2))
5
+ return false;
6
+ return err1.message === err2.message;
7
+ }
@@ -1,13 +1,13 @@
1
1
  export { projectInfo };
2
2
  export type { ProjectTag };
3
3
  export { PROJECT_VERSION };
4
- declare const PROJECT_VERSION: "0.4.152-commit-3d25618";
4
+ declare const PROJECT_VERSION: "0.4.152-commit-6f928f9";
5
5
  type PackageName = typeof projectInfo.npmPackageName;
6
6
  type ProjectVersion = typeof projectInfo.projectVersion;
7
7
  type ProjectTag = `[${PackageName}]` | `[${PackageName}@${ProjectVersion}]`;
8
8
  declare const projectInfo: {
9
9
  projectName: "Vike";
10
- projectVersion: "0.4.152-commit-3d25618";
10
+ projectVersion: "0.4.152-commit-6f928f9";
11
11
  npmPackageName: "vike";
12
12
  githubRepository: "https://github.com/vikejs/vike";
13
13
  };
@@ -1,7 +1,7 @@
1
1
  export { projectInfo };
2
2
  export { PROJECT_VERSION };
3
3
  import { onProjectInfo } from './assertSingleInstance.js';
4
- const PROJECT_VERSION = '0.4.152-commit-3d25618';
4
+ const PROJECT_VERSION = '0.4.152-commit-6f928f9';
5
5
  const projectInfo = {
6
6
  projectName: 'Vike',
7
7
  projectVersion: PROJECT_VERSION,
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.152-commit-3d25618",
3
+ "version": "0.4.152-commit-6f928f9",
4
4
  "scripts": {
5
5
  "dev": "tsc --watch",
6
6
  "build": "rimraf dist/ && pnpm run build:esm && pnpm run build:cjs",
7
7
  "build:esm": "tsc",
8
8
  "build:cjs": "pnpm run build:cjs:ts && pnpm run build:cjs:fixup",
9
- "build:cjs:ts": "tsc --outDir ./dist/cjs/ --module CommonJS --target ES2020 --moduleResolution Node10 --declaration false",
9
+ "build:cjs:ts": "tsc --project ./tsconfig.cjs.json",
10
10
  "build:cjs:fixup": "node ./dist-cjs-fixup.mjs",
11
11
  "release": "release-me patch",
12
12
  "release:commit": "release-me commit"
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dynamicImport = void 0;
4
- /** Only works for npm packages, for files use @brillout/import instead */
5
- function dynamicImport(mod) {
6
- return new Function('mod', 'return import(mod)')(mod);
7
- }
8
- exports.dynamicImport = dynamicImport;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEquivalentError = void 0;
4
- const isObject_js_1 = require("./isObject.js");
5
- const deepEqual_js_1 = require("./deepEqual.js");
6
- function isEquivalentError(err1, err2) {
7
- return ((0, isObject_js_1.isObject)(err1) &&
8
- (0, isObject_js_1.isObject)(err2) &&
9
- err1.constructor === err2.constructor &&
10
- (0, deepEqual_js_1.deepEqual)({ ...err1, stack: null }, { ...err2, stack: null }) &&
11
- // 'message' and 'stack' are usually non-emurable
12
- err2.message === err2.message
13
- /* Doesn't work because: the stack trace isn't exactly the same between the original page rendering and the fallback error page rendering
14
- err2.stack === err2.stack
15
- */
16
- );
17
- }
18
- exports.isEquivalentError = isEquivalentError;
@@ -1,2 +0,0 @@
1
- /** Only works for npm packages, for files use @brillout/import instead */
2
- export declare function dynamicImport<Mod = never>(mod: string): Promise<Mod>;
@@ -1,4 +0,0 @@
1
- /** Only works for npm packages, for files use @brillout/import instead */
2
- export function dynamicImport(mod) {
3
- return new Function('mod', 'return import(mod)')(mod);
4
- }
@@ -1,2 +0,0 @@
1
- export { isEquivalentError };
2
- declare function isEquivalentError(err1: unknown, err2: unknown): boolean;
@@ -1,15 +0,0 @@
1
- import { isObject } from './isObject.js';
2
- import { deepEqual } from './deepEqual.js';
3
- export { isEquivalentError };
4
- function isEquivalentError(err1, err2) {
5
- return (isObject(err1) &&
6
- isObject(err2) &&
7
- err1.constructor === err2.constructor &&
8
- deepEqual({ ...err1, stack: null }, { ...err2, stack: null }) &&
9
- // 'message' and 'stack' are usually non-emurable
10
- err2.message === err2.message
11
- /* Doesn't work because: the stack trace isn't exactly the same between the original page rendering and the fallback error page rendering
12
- err2.stack === err2.stack
13
- */
14
- );
15
- }