vike 0.4.267 → 0.4.268-commit-ca58695

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 (204) hide show
  1. package/RenderErrorPage.js +2 -2
  2. package/abort.js +2 -2
  3. package/dist/client/__internal/index.d.ts +3 -0
  4. package/dist/client/__internal/index.js +4 -0
  5. package/dist/client/runtime-client-routing/createPageContextClient.d.ts +5 -0
  6. package/dist/client/runtime-client-routing/getGlobalContextClientInternal.d.ts +5 -0
  7. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +28 -2
  8. package/dist/client/runtime-client-routing/getPageContextFromHooks.js +5 -5
  9. package/dist/client/runtime-client-routing/renderPageClient.d.ts +490 -10
  10. package/dist/client/runtime-client-routing/renderPageClient.js +149 -43
  11. package/dist/client/runtime-client-routing/streamedValues.d.ts +5 -0
  12. package/dist/client/runtime-client-routing/streamedValues.js +23 -0
  13. package/dist/client/runtime-server-routing/createPageContextClient.d.ts +5 -0
  14. package/dist/client/runtime-server-routing/entry.js +1 -1
  15. package/dist/client/runtime-server-routing/getGlobalContextClientInternal.d.ts +5 -0
  16. package/dist/client/shared/getGlobalContextClientInternalShared.d.ts +5 -0
  17. package/dist/client/shared/getGlobalContextClientInternalShared.js +2 -0
  18. package/dist/client/shared/getJsonSerializedInHtml.d.ts +2 -2
  19. package/dist/client/shared/getJsonSerializedInHtml.js +9 -6
  20. package/dist/client/shared/loadPageConfigsLazyClientSide.js +0 -4
  21. package/dist/client/shared/removeFoucBuster.js +14 -3
  22. package/dist/client/shared/streamedValues/asyncIterable.d.ts +4 -0
  23. package/dist/client/shared/streamedValues/asyncIterable.js +26 -0
  24. package/dist/client/shared/streamedValues/lines.d.ts +11 -0
  25. package/dist/client/shared/streamedValues/lines.js +19 -0
  26. package/dist/client/shared/streamedValues/promise.d.ts +4 -0
  27. package/dist/client/shared/streamedValues/promise.js +19 -0
  28. package/dist/client/shared/streamedValues/readableStream.d.ts +4 -0
  29. package/dist/client/shared/streamedValues/readableStream.js +44 -0
  30. package/dist/client/shared/streamedValues/registry.d.ts +21 -0
  31. package/dist/client/shared/streamedValues/registry.js +40 -0
  32. package/dist/client/shared/streamedValues.d.ts +7 -0
  33. package/dist/client/shared/streamedValues.js +82 -0
  34. package/dist/node/api/dev.js +15 -1
  35. package/dist/node/api/resolveViteConfigUser.js +2 -2
  36. package/dist/node/api/serverEntryDev.d.ts +10 -0
  37. package/dist/node/api/serverEntryDev.js +125 -0
  38. package/dist/node/createDevMiddleware.js +12 -0
  39. package/dist/node/prerender/resolvePrerenderConfig.d.ts +1 -1
  40. package/dist/node/prerender/resolvePrerenderConfig.js +4 -1
  41. package/dist/node/prerender/runPrerender.d.ts +18 -18
  42. package/dist/node/prerender/runPrerender.js +61 -16
  43. package/dist/node/vite/assertEnvVite.js +1 -1
  44. package/dist/node/vite/index.js +2 -0
  45. package/dist/node/vite/plugins/build/handleAssetsManifest.js +6 -2
  46. package/dist/node/vite/plugins/build/pluginBuildApp.js +25 -26
  47. package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +2 -2
  48. package/dist/node/vite/plugins/build/pluginBuildConfig.js +25 -17
  49. package/dist/node/vite/plugins/build/pluginDistFileNames.js +70 -50
  50. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.d.ts +6 -0
  51. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.js +71 -0
  52. package/dist/node/vite/plugins/build/pluginSuppressRollupWarning.js +19 -17
  53. package/dist/node/vite/plugins/pluginCommon.js +10 -7
  54. package/dist/node/vite/plugins/pluginDev/optimizeDeps.d.ts +2 -2
  55. package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +6 -2
  56. package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +6 -4
  57. package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.d.ts +3 -0
  58. package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.js +28 -2
  59. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.d.ts +1 -1
  60. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.js +22 -11
  61. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.d.ts +4 -0
  62. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.js +29 -0
  63. package/dist/node/vite/plugins/pluginUniversalDeploy.js +29 -5
  64. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.d.ts +2 -1
  65. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +29 -12
  66. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -2
  67. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +7 -7
  68. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +10 -6
  69. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js +5 -11
  70. package/dist/node/vite/plugins/pluginVirtualFiles.js +20 -0
  71. package/dist/node/vite/shared/addSsrMiddleware.js +11 -27
  72. package/dist/node/vite/shared/findPageFiles.d.ts +1 -1
  73. package/dist/node/vite/shared/findPageFiles.js +1 -11
  74. package/dist/node/vite/shared/getAssetsDir.d.ts +3 -2
  75. package/dist/node/vite/shared/getAssetsDir.js +3 -3
  76. package/dist/node/vite/shared/isViteCli.d.ts +3 -3
  77. package/dist/node/vite/shared/isViteCli.js +80 -84
  78. package/dist/node/vite/shared/isViteServerSide.js +2 -7
  79. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +6 -4
  80. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +17 -6
  81. package/dist/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +9 -2
  82. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +5 -1
  83. package/dist/node/vite/shared/resolveVikeConfigInternal.js +86 -13
  84. package/dist/server/__internal/fetch-deprecated.d.ts +2 -0
  85. package/dist/server/__internal/fetch-deprecated.js +6 -0
  86. package/dist/server/__internal/fetch.d.ts +9 -0
  87. package/dist/server/__internal/fetch.js +5 -0
  88. package/dist/server/__internal/index.d.ts +4 -0
  89. package/dist/server/__internal/index.js +8 -0
  90. package/dist/server/createPageRenderer.d.ts +2 -2
  91. package/dist/server/createPageRenderer.js +2 -2
  92. package/dist/server/runtime/createDevMiddleware.js +3 -1
  93. package/dist/server/runtime/globalContext.d.ts +69 -10
  94. package/dist/server/runtime/globalContext.js +35 -2
  95. package/dist/server/runtime/index.d.ts +1 -1
  96. package/dist/server/runtime/index.js +1 -1
  97. package/dist/server/runtime/renderPageServer/analyzePage.js +3 -3
  98. package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +20 -9
  99. package/dist/server/runtime/renderPageServer/createHttpResponse.js +34 -21
  100. package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +13 -23
  101. package/dist/server/runtime/renderPageServer/csp.d.ts +2 -1
  102. package/dist/server/runtime/renderPageServer/csp.js +2 -1
  103. package/dist/server/runtime/renderPageServer/execHookOnError.js +1 -1
  104. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.d.ts +9 -0
  105. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.js +21 -9
  106. package/dist/server/runtime/renderPageServer/getHttpResponseBody.d.ts +2 -2
  107. package/dist/server/runtime/renderPageServer/getHttpResponseBody.js +19 -12
  108. package/dist/server/runtime/renderPageServer/getPageContextJson.d.ts +8 -0
  109. package/dist/server/runtime/renderPageServer/getPageContextJson.js +47 -0
  110. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +2 -0
  111. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +1 -1
  112. package/dist/server/runtime/renderPageServer/handlePageContextRequestUrl.js +2 -2
  113. package/dist/server/runtime/renderPageServer/headersResponse.d.ts +11 -2
  114. package/dist/server/runtime/renderPageServer/headersResponse.js +22 -2
  115. package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +5 -4
  116. package/dist/server/runtime/renderPageServer/html/injectAssets.d.ts +3 -2
  117. package/dist/server/runtime/renderPageServer/html/injectAssets.js +7 -1
  118. package/dist/server/runtime/renderPageServer/html/renderHtml.js +4 -2
  119. package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +5 -1
  120. package/dist/server/runtime/renderPageServer/html/serializeContext.js +12 -9
  121. package/dist/server/runtime/renderPageServer/html/stream.d.ts +13 -6
  122. package/dist/server/runtime/renderPageServer/html/stream.js +135 -32
  123. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.d.ts +30 -0
  124. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.js +92 -0
  125. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +10 -14
  126. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.js +5 -1
  127. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.d.ts +15 -0
  128. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.js +61 -0
  129. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +320 -55
  130. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +21 -12
  131. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.d.ts +4 -0
  132. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.js +12 -0
  133. package/dist/server/runtime/renderPageServer/streamedValues/lines.d.ts +10 -0
  134. package/dist/server/runtime/renderPageServer/streamedValues/lines.js +49 -0
  135. package/dist/server/runtime/renderPageServer/streamedValues/promise.d.ts +4 -0
  136. package/dist/server/runtime/renderPageServer/streamedValues/promise.js +14 -0
  137. package/dist/server/runtime/renderPageServer/streamedValues/pump.d.ts +10 -0
  138. package/dist/server/runtime/renderPageServer/streamedValues/pump.js +67 -0
  139. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.d.ts +4 -0
  140. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.js +12 -0
  141. package/dist/server/runtime/renderPageServer/streamedValues/registry.d.ts +28 -0
  142. package/dist/server/runtime/renderPageServer/streamedValues/registry.js +33 -0
  143. package/dist/server/runtime/renderPageServer.d.ts +65 -18
  144. package/dist/server/runtime/renderPageServer.js +33 -62
  145. package/dist/server/runtime/universal-middleware/core.d.ts +25 -0
  146. package/dist/server/runtime/universal-middleware/core.js +167 -0
  147. package/dist/server/runtime/universal-middleware/deprecated-export.d.ts +3 -0
  148. package/dist/server/runtime/universal-middleware/deprecated-export.js +10 -0
  149. package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.d.ts +15 -0
  150. package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.js +51 -0
  151. package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.d.ts +9 -0
  152. package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.js +22 -0
  153. package/dist/shared-server-client/createGlobalContextShared.d.ts +8 -0
  154. package/dist/shared-server-client/createGlobalContextShared.js +2 -1
  155. package/dist/shared-server-client/getPageContextPublicShared.js +1 -3
  156. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.d.ts +8 -0
  157. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js +17 -7
  158. package/dist/shared-server-client/hooks/execHook.d.ts +1 -1
  159. package/dist/shared-server-client/hooks/execHook.js +2 -2
  160. package/dist/shared-server-client/page-configs/serialize/serializeConfigValues.js +2 -0
  161. package/dist/shared-server-client/route/abort.d.ts +1 -1
  162. package/dist/shared-server-client/route/abort.js +4 -2
  163. package/dist/shared-server-client/streamedValues.d.ts +22 -0
  164. package/dist/shared-server-client/streamedValues.js +24 -0
  165. package/dist/shared-server-node/vike-environments.d.ts +4 -0
  166. package/dist/shared-server-node/vike-environments.js +10 -0
  167. package/dist/shared-server-node/virtualFileId.d.ts +7 -5
  168. package/dist/shared-server-node/virtualFileId.js +42 -42
  169. package/dist/types/Config.d.ts +11 -3
  170. package/dist/types/GlobalContext.d.ts +3 -3
  171. package/dist/types/PageConfig.d.ts +13 -5
  172. package/dist/types/PageContext.d.ts +18 -10
  173. package/dist/types/PageContext.js +1 -0
  174. package/dist/types/Server.d.ts +1 -1
  175. package/dist/types/VikeNamespace.d.ts +1 -1
  176. package/dist/types/index.d.ts +1 -0
  177. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  178. package/dist/utils/PROJECT_VERSION.js +1 -1
  179. package/dist/utils/assertViteVersion.d.ts +1 -3
  180. package/dist/utils/assertViteVersion.js +6 -9
  181. package/dist/utils/catchInfiniteLoop.js +33 -11
  182. package/dist/utils/deepEqual.d.ts +2 -1
  183. package/dist/utils/deepEqual.js +21 -6
  184. package/dist/utils/getContentTypeFromUrl.d.ts +2 -0
  185. package/dist/utils/getContentTypeFromUrl.js +39 -0
  186. package/dist/utils/injectRollupInputs.d.ts +2 -2
  187. package/dist/utils/injectRollupInputs.js +2 -2
  188. package/dist/utils/installUncaughtErrorHandlers.js +9 -0
  189. package/dist/utils/isDev.js +2 -7
  190. package/dist/utils/parseUrl-extras.js +4 -0
  191. package/fetch.js +2 -2
  192. package/modifyUrl.js +2 -2
  193. package/package.json +42 -26
  194. package/routing.js +2 -2
  195. package/universal-middleware.js +2 -2
  196. package/vike-server.d.ts +14 -0
  197. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.d.ts +0 -4
  198. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.js +0 -22
  199. package/dist/server/runtime/fetch.d.ts +0 -10
  200. package/dist/server/runtime/fetch.js +0 -5
  201. package/dist/server/runtime/universal-middleware.d.ts +0 -10
  202. package/dist/server/runtime/universal-middleware.js +0 -27
  203. package/dist/shared-server-client/addIs404ToPageProps.d.ts +0 -2
  204. package/dist/shared-server-client/addIs404ToPageProps.js +0 -17
@@ -2,6 +2,7 @@ export { renderPageClient };
2
2
  export { getRenderCount };
3
3
  export { disableClientRouting };
4
4
  export { getPageContextClient };
5
+ export { createPageContextFromServer_experimentalRSC };
5
6
  import { assert, assertInfo, assertWarning } from '../../utils/assert.js';
6
7
  import { catchInfiniteLoop } from '../../utils/catchInfiniteLoop.js';
7
8
  import { genPromise } from '../../utils/genPromise.js';
@@ -12,7 +13,8 @@ import { isReact } from '../../utils/isReact.js';
12
13
  import { objectAssign } from '../../utils/objectAssign.js';
13
14
  import { redirectHard } from '../../utils/redirectHard.js';
14
15
  import { updateType } from '../../utils/updateType.js';
15
- import { getPageContextFromHooksClient, getPageContextFromHooksServer, getPageContextFromHooksClient_firstRender, getPageContextFromHooksServer_firstRender, setPageContextInitIsPassedToClient, } from './getPageContextFromHooks.js';
16
+ import { getPageContextFromHooksClient, getPageContextFromHooksServer, getPageContextFromHooksClient_firstRender, getPageContextFromHooksServer_firstRender, setPageContextInitIsPassedToClient, processPageContextFromServer, } from './getPageContextFromHooks.js';
17
+ import { cancelStreamedValues } from './streamedValues.js';
16
18
  import { createPageContextClient } from './createPageContextClient.js';
17
19
  import { addLinkPrefetchHandlers, addLinkPrefetchHandlers_unwatch, addLinkPrefetchHandlers_watch, getPageContextPrefetched, populatePageContextPrefetchCache, } from './prefetch.js';
18
20
  import { execHookOnRenderClient } from '../shared/execHookOnRenderClient.js';
@@ -20,6 +22,7 @@ import { isErrorFetchingStaticAssets, loadPageConfigsLazyClientSide, } from '../
20
22
  import { changeUrl, saveScrollPosition } from './history.js';
21
23
  import { addNewPageContextAborted, getPageContextAddendumAbort, isAbortError, logAbort, } from '../../shared-server-client/route/abort.js';
22
24
  import { route } from '../../shared-server-client/route/index.js';
25
+ import { forkPageContext } from '../../shared-server-client/forkPageContext.js';
23
26
  import { isClientSideRoutable } from './isClientSideRoutable.js';
24
27
  import { isScrollPosition, setScrollPosition } from './setScrollPosition.js';
25
28
  import { scrollRestoration_initialRenderIsDone } from './scrollRestoration.js';
@@ -101,7 +104,7 @@ async function renderPageClient(renderArgs) {
101
104
  }
102
105
  // Get pageContext serialized in <script id="vike_pageContext" type="application/json">
103
106
  if (isFirstRender) {
104
- const pageContextSerialized = getPageContextFromHooksServer_firstRender();
107
+ const pageContextSerialized = await getPageContextFromHooksServer_firstRender();
105
108
  // TO-DO/eventually: create helper assertPageContextFromHook()
106
109
  assert(!('urlOriginal' in pageContextSerialized));
107
110
  objectAssign(pageContext, pageContextSerialized);
@@ -226,8 +229,10 @@ async function renderPageClient(renderArgs) {
226
229
  return;
227
230
  }
228
231
  }
229
- if (isRenderOutdated())
232
+ if (isRenderOutdated()) {
233
+ cancelStreamedValues(pageContextFromHooksServer, false);
230
234
  return;
235
+ }
231
236
  // TO-DO/eventually: create helper assertPageContextFromHook()
232
237
  assert(!('urlOriginal' in pageContextFromHooksServer));
233
238
  objectAssign(pageContext, pageContextFromHooksServer);
@@ -308,13 +313,6 @@ async function renderPageClient(renderArgs) {
308
313
  else {
309
314
  objectAssign(pageContext, { is404: false });
310
315
  }
311
- const isClientRoutable = await isClientSideRoutable(pageContext.pageId, pageContext);
312
- if (isRenderOutdated())
313
- return;
314
- if (!isClientRoutable) {
315
- redirectHard(urlOriginal);
316
- return;
317
- }
318
316
  if (import.meta.env.DEV || globalThis.__VIKE__IS_DEBUG) {
319
317
  assertInfo(false, `Rendering error page ${errorPageId}`, { onlyOnce: false });
320
318
  }
@@ -363,7 +361,7 @@ async function renderPageClient(renderArgs) {
363
361
  const errAbort = err;
364
362
  logAbort(err, !import.meta.env.DEV, pageContext);
365
363
  const pageContextAbort = errAbort._pageContextAbort;
366
- addNewPageContextAborted(pageContextsAborted, pageContext, pageContextAbort);
364
+ addNewPageContextAborted(pageContextsAborted, pageContext, pageContextAbort, getPageContextPublicClientMinimal);
367
365
  // throw render('/some-url')
368
366
  if (pageContextAbort._urlRewrite) {
369
367
  await renderPageClient({
@@ -405,6 +403,12 @@ async function renderPageClient(renderArgs) {
405
403
  }
406
404
  };
407
405
  changeUrl(urlOriginal, overwriteLastHistoryEntry);
406
+ {
407
+ const previousPageContextBefore = globalObject.renderedPageContext?.previousPageContext;
408
+ // Remove previousPageContext of past pages (otherwise all the past pageContext are kept in memory)
409
+ if (previousPageContextBefore)
410
+ previousPageContextBefore.previousPageContext = null;
411
+ }
408
412
  globalObject.previousPageContext = pageContext;
409
413
  // There should never be concurrent onRenderClient() calls
410
414
  assert(globalObject.onRenderClientPreviousPromise === undefined);
@@ -447,6 +451,7 @@ async function renderPageClient(renderArgs) {
447
451
  // We purposely abort *after* onHydrationEnd() is called (see comment above).
448
452
  if (isRenderOutdated(true))
449
453
  return;
454
+ cancelStreamedValues(pageContext, true);
450
455
  // onPageTransitionEnd()
451
456
  if (globalObject.isTransitioning) {
452
457
  globalObject.isTransitioning = undefined;
@@ -491,7 +496,9 @@ async function renderPageClient(renderArgs) {
491
496
  }
492
497
  }
493
498
  async function getPageContextBegin(isForErrorPage, { urlOriginal, isBackwardNavigation, isHistoryNavigation, pageContextsAborted, isClientSideNavigation, pageContextInitClient, isFirstRender, }) {
494
- const previousPageContext = globalObject.previousPageContext ?? null;
499
+ const previousPageContext = globalObject.previousPageContext
500
+ ? getPageContextPublicClient(globalObject.previousPageContext)
501
+ : null;
495
502
  const pageContext = await createPageContextClient(urlOriginal);
496
503
  objectAssign(pageContext, {
497
504
  isBackwardNavigation,
@@ -510,7 +517,7 @@ async function getPageContextBegin(isForErrorPage, { urlOriginal, isBackwardNavi
510
517
  showStackTrace: true,
511
518
  onlyOnce: true,
512
519
  });
513
- return previousPageContext;
520
+ return this.previousPageContext;
514
521
  },
515
522
  enumerable: false,
516
523
  });
@@ -527,21 +534,12 @@ function stampFinished(urlOriginal) {
527
534
  window._vike ?? (window._vike = {});
528
535
  window._vike.fullyRenderedUrl = urlOriginal;
529
536
  }
530
- function disableClientRouting(err, log) {
537
+ function disableClientRouting(err, logError) {
531
538
  globalObject.clientRoutingIsDisabled = true;
532
539
  assert(isErrorFetchingStaticAssets(err));
533
- if (log) {
534
- // We purposely don't use console.error() to avoid flooding error trackers such as Sentry
535
- console.log(err);
536
- }
537
- assertInfo(false, [
538
- 'Failed to fetch static asset.',
539
- import.meta.env.PROD ? 'This usually happens when a new frontend is deployed.' : null,
540
- 'Falling back to Server Routing.',
541
- '(The next page navigation will use Server Routing instead of Client Routing.)',
542
- ]
543
- .filter(Boolean)
544
- .join(' '), { onlyOnce: true });
540
+ if (logError)
541
+ console.log(err); // We purposely don't use console.error() to avoid flooding error trackers such as Sentry
542
+ assertInfo(false, 'Failed to fetch static asset (due to a connection issue, or a new deployment) — falling back to Server Routing', { onlyOnce: true });
545
543
  }
546
544
  function getIsRenderOutdated() {
547
545
  const renderNumber = ++globalObject.renderCounter;
@@ -581,7 +579,7 @@ function getKeepScrollPositionSetting(pageContext) {
581
579
  assert(configDefinedAt);
582
580
  const routeParameterList = getRouteStringParameterList(configDefinedAt);
583
581
  if (isCallable(val))
584
- val = val(pageContext, {
582
+ val = val(getPageContextPublicClient(pageContext), {
585
583
  configDefinedAt: c.definedAt,
586
584
  /* We don't pass routeParameterList because it's useless: the user knows the parameter list.
587
585
  routeParameterList
@@ -618,6 +616,29 @@ function getPageContextClient() {
618
616
  return null;
619
617
  return getPageContextPublicClient(pageContext);
620
618
  }
619
+ // TODO/soon: check whether this is the right API
620
+ /**
621
+ * Creates a new `pageContext` for the page that `pageContext` renders, with the values of `pageContextFromServer` on top.
622
+ * - `pageContext` is the `pageContext` of the page rendered last
623
+ * - `pageContext` and `pageContextFromServer` aren't modified
624
+ * - The new `pageContext` is the `pageContext.previousPageContext` of the next navigation, including a navigation that has already started
625
+ * - Unless a navigation has started, `getPageContextClient()` returns the new `pageContext`
626
+ */
627
+ function createPageContextFromServer_experimentalRSC(pageContext, pageContextFromServer) {
628
+ const pageContextFromServerCopy = { ...pageContextFromServer };
629
+ processPageContextFromServer(pageContextFromServerCopy);
630
+ const pageContextNew = forkPageContext(pageContext._originalObject);
631
+ objectAssign(pageContextNew, pageContextFromServerCopy);
632
+ // A navigation sets currentPageContext and reads previousPageContext when it starts, and sets previousPageContext when it renders
633
+ if (globalObject.currentPageContext === globalObject.previousPageContext) {
634
+ globalObject.currentPageContext = pageContextNew;
635
+ }
636
+ else {
637
+ globalObject.currentPageContext.previousPageContext = getPageContextPublicClient(pageContextNew);
638
+ }
639
+ globalObject.previousPageContext = pageContextNew;
640
+ return getPageContextPublicClient(pageContextNew);
641
+ }
621
642
  async function loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRender, isRenderOutdated) {
622
643
  let hasErr = false;
623
644
  let err;
@@ -628,17 +649,14 @@ async function loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRend
628
649
  catch (err_) {
629
650
  err = err_;
630
651
  hasErr = true;
631
- if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender)) {
632
- return { skip: true };
633
- }
634
- else {
635
- // Syntax error in user file
636
- }
637
652
  }
638
653
  if (isRenderOutdated())
639
654
  return { skip: true };
640
- if (hasErr)
655
+ if (hasErr) {
656
+ if (await handleErrorFetchingStaticAssets(err, pageContext, isFirstRender))
657
+ return { skip: true };
641
658
  return { err };
659
+ }
642
660
  objectAssign(pageContext, pageContextAddendum);
643
661
  try {
644
662
  await execHook('onCreatePageContext', pageContext, getPageContextPublicClient);
@@ -653,21 +671,109 @@ async function loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRend
653
671
  return { err };
654
672
  return { pageContext };
655
673
  }
656
- function handleErrorFetchingStaticAssets(err, pageContext, isFirstRender) {
657
- if (!isErrorFetchingStaticAssets(err)) {
674
+ async function handleErrorFetchingStaticAssets(err, pageContext, isFirstRender) {
675
+ if (import.meta.env.DEV)
658
676
  return false;
659
- }
660
- if (isFirstRender) {
677
+ if (!isErrorFetchingStaticAssets(err))
678
+ return false; // Syntax error in user file
679
+ // *******************************************
680
+ // ******* The three possible actions ********
681
+ // *******************************************
682
+ /** Show Vike's error page */
683
+ const showErrorPage = () => {
684
+ disableClientRouting(err, false);
685
+ // Vike handles the error like any other error: Vike logs it with `console.error()` and renders Vike's error page
686
+ return false;
687
+ };
688
+ /** Show the rendered HTML (with broken hydration) */
689
+ const showCurrentBrokenPage = () => {
661
690
  disableClientRouting(err, false);
662
- // This may happen if the frontend was newly deployed during hydration.
663
- // Ideally: re-try a couple of times by reloading the page (not entirely trivial to implement since `localStorage` is needed.)
691
+ // Abort rendering (and don't show error page), not gracefully: the error throws (i.e. the error is handled by the browser and shown in the browser's developer console)
664
692
  throw err;
693
+ };
694
+ /** Do a full (re-)load of the page */
695
+ const hardReload = (url) => {
696
+ disableClientRouting(err, true);
697
+ if (url) {
698
+ redirectHard(url);
699
+ }
700
+ else {
701
+ // We use `location.reload()` instead of redirectHard(): navigating with `location.href = url` creates a `type: 'navigate'` entry, which would lead to an infinite reload loop — see isPageReload()
702
+ window.location.reload();
703
+ }
704
+ // Abort rendering (and don't show error page), gracefully (i.e. without throwing nor logging any error)
705
+ return true;
706
+ };
707
+ // **************************
708
+ // ******* The logic ********
709
+ // **************************
710
+ // Possible causes that lead to this point:
711
+ // - New deployment
712
+ // - Connection problem
713
+ // === Client-side navigation ===
714
+ // We hard load the next page:
715
+ // - New deployment => fully reloading the website is exactly what we want
716
+ // - Connection problem => next page isn't shown => only useful action is to try again with a hard reload
717
+ // - It's usually better to show the browser's offline page than to leave the user stuck on the old page. (This way, the user knows there's a connection problem instead of wondering whether the website is broken.)
718
+ if (!isFirstRender) {
719
+ return hardReload(pageContext.urlOriginal);
720
+ }
721
+ // === First render ===
722
+ // Avoid infinite reload loop: we don't reload a page that was itself loaded by a reload
723
+ if (isPageReload()) {
724
+ if (isBlankPage()) {
725
+ return showErrorPage();
726
+ }
727
+ else {
728
+ return showCurrentBrokenPage();
729
+ }
730
+ }
731
+ if (isBlankPage()) {
732
+ return hardReload();
665
733
  }
666
734
  else {
667
- disableClientRouting(err, true);
735
+ globalObject.clientRoutingIsDisabled = true; // Eagerly disable before connection check
736
+ if (!(await isConnectionDown())) {
737
+ // Most likely a new deployment (or the connection is back): either way, reloading fixes the page
738
+ return hardReload();
739
+ }
740
+ else {
741
+ // - Reloading is counterproductive since it would likely get another connection error, resulting in either: the browser's offline page, or repeating this asset loading failure.
742
+ // - Handling flaky connections is the browser's job (e.g. the user reloads the page)
743
+ // - Showing the rendered HTML is usually more useful to the user (even when unhydrated thus broken) than showing Vike's error page
744
+ return showCurrentBrokenPage();
745
+ }
668
746
  }
669
- redirectHard(pageContext.urlOriginal);
670
- return true;
747
+ }
748
+ // Whether fetching static assets fails because of the connection. (The error thrown by `import()` doesn't tell: it's the same whether a new frontend was deployed, i.e. the static assets don't exist anymore, or the connection is down.)
749
+ async function isConnectionDown() {
750
+ try {
751
+ await fetch(window.location.href, {
752
+ method: 'HEAD',
753
+ cache: 'no-store',
754
+ // On a flaky connection, the request may hang and succeed much later: we don't want to reload the page long after it was shown (e.g. while the user is filling a form)
755
+ signal: AbortSignal.timeout(4000),
756
+ });
757
+ // The server responds
758
+ return false;
759
+ }
760
+ catch {
761
+ return true;
762
+ }
763
+ }
764
+ // The page shows nothing (e.g. SPA)
765
+ function isBlankPage() {
766
+ return !document.body.innerText.trim();
767
+ }
768
+ // Whether the current page was loaded by a page reload
769
+ function isPageReload() {
770
+ // The browser records how the current document was loaded (Navigation Timing API)
771
+ const navigation = performance.getEntriesByType('navigation')[0];
772
+ return (
773
+ // Cannot be determined (e.g. older browsers)
774
+ !navigation ||
775
+ // A document loaded by `location.reload()` has `type: 'reload'`
776
+ navigation.type === 'reload');
671
777
  }
672
778
  // [HMR] If error page is shown => re-render whole page
673
779
  if (import.meta.env.DEV && import.meta.hot)
@@ -0,0 +1,5 @@
1
+ export { readPageContextJson };
2
+ export { cancelStreamedValues };
3
+ import '../assertEnvClient.js';
4
+ declare function readPageContextJson(response: Response): Promise<unknown>;
5
+ declare function cancelStreamedValues(pageContext: object, isRendered: boolean): void;
@@ -0,0 +1,23 @@
1
+ // Streamed pageContext values https://vike.dev/passToClient#streaming, upon client-side navigation: the decoder
2
+ // (../shared/streamedValues.ts) is loaded only if the `.pageContext.json` response is a JSON array (see
3
+ // server/runtime/renderPageServer/getPageContextJson.ts).
4
+ export { readPageContextJson };
5
+ export { cancelStreamedValues };
6
+ import { parse } from '@brillout/json-serializer/parse';
7
+ import '../assertEnvClient.js';
8
+ let decoder;
9
+ async function readPageContextJson(response) {
10
+ const reader = response.clone().body.getReader();
11
+ let chunk = await reader.read();
12
+ while (!chunk.done && !chunk.value.length)
13
+ chunk = await reader.read();
14
+ reader.cancel();
15
+ // A pageContext always serializes as `{…}`, so an array (`[` is 91) means streamed values
16
+ if (chunk.value?.[0] !== 91)
17
+ return parse(await response.text());
18
+ decoder ?? (decoder = await import('../shared/streamedValues.js'));
19
+ return decoder.readPageContextJsonStreamed(response);
20
+ }
21
+ function cancelStreamedValues(pageContext, isRendered) {
22
+ decoder?.cancelStreamedValues(pageContext, isRendered);
23
+ }
@@ -35,9 +35,14 @@ declare function createPageContextClient(): Promise<{
35
35
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
36
36
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
37
37
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
38
+ _environmentEntries: Record<string, {
39
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
40
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
41
+ } | null>;
38
42
  _allPageIds: string[];
39
43
  } & {
40
44
  isClientSide: true;
45
+ devMiddleware: null;
41
46
  };
42
47
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
43
48
  } & import("../../shared-server-client/page-configs/resolveVikeConfigPublic.js").GlobalConfigPublic>;
@@ -23,7 +23,7 @@ if (import.meta.env.DEV)
23
23
  hydrate();
24
24
  async function hydrate() {
25
25
  const pageContext = await createPageContextClient();
26
- objectAssign(pageContext, getPageContextSerializedInHtml());
26
+ objectAssign(pageContext, await getPageContextSerializedInHtml());
27
27
  // Sets pageContext.config using non-global configs — overrides the pageContext.config set using global configs at createPageContextClient()
28
28
  const pageContextAddendum = await loadPageConfigsLazyClientSide(pageContext.pageId, pageContext._pageFilesAll, pageContext._globalContext._pageConfigs, pageContext._globalContext._pageConfigGlobal);
29
29
  objectAssign(pageContext, pageContextAddendum);
@@ -25,7 +25,12 @@ declare function getGlobalContextClientInternal(): Promise<{
25
25
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
26
26
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
27
27
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
28
+ _environmentEntries: Record<string, {
29
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
30
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
31
+ } | null>;
28
32
  _allPageIds: string[];
29
33
  } & {
30
34
  isClientSide: true;
35
+ devMiddleware: null;
31
36
  }>;
@@ -29,6 +29,10 @@ declare function getGlobalContextClientInternalShared(): Promise<{
29
29
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
30
30
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
31
31
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
32
+ _environmentEntries: Record<string, {
33
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
34
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
35
+ } | null>;
32
36
  _allPageIds: string[];
33
37
  } & {
34
38
  /**
@@ -39,6 +43,7 @@ declare function getGlobalContextClientInternalShared(): Promise<{
39
43
  * https://vike.dev/globalContext#isClientSide
40
44
  */
41
45
  isClientSide: true;
46
+ devMiddleware: null;
42
47
  }>;
43
48
  type TypeIsNotExported = never;
44
49
  declare function getGlobalContext(): Promise<TypeIsNotExported>;
@@ -36,6 +36,8 @@ async function getGlobalContextClientInternalShared() {
36
36
  * https://vike.dev/globalContext#isClientSide
37
37
  */
38
38
  isClientSide: true,
39
+ // https://vike.dev/globalContext#devMiddleware
40
+ devMiddleware: null,
39
41
  };
40
42
  objectAssign(globalContextAddendum, getGlobalContextSerializedInHtml());
41
43
  return globalContextAddendum;
@@ -1,8 +1,8 @@
1
1
  export { getPageContextSerializedInHtml };
2
2
  export { getGlobalContextSerializedInHtml };
3
3
  import '../assertEnvClient.js';
4
- declare function getPageContextSerializedInHtml(): {
4
+ declare function getPageContextSerializedInHtml(): Promise<{
5
5
  pageId: string;
6
6
  routeParams: Record<string, string>;
7
- };
7
+ }>;
8
8
  declare function getGlobalContextSerializedInHtml(): object;
@@ -9,23 +9,26 @@ import '../assertEnvClient.js';
9
9
  // 1. <script id="vike_pageContext" type="application/json"> appears before the <script> that loads Vike's client runtime (which includes this file)
10
10
  // 2. <script id="vike_pageContext" type="application/json"> is neither async nor defer
11
11
  // See https://github.com/vikejs/vike/pull/1271
12
- function getPageContextSerializedInHtml() {
13
- const pageContextSerializedInHtml = findAndParseJson(htmlElementId_pageContext);
12
+ async function getPageContextSerializedInHtml() {
13
+ const pageContextJson = findJson(htmlElementId_pageContext);
14
+ // A pageContext always serializes as `{…}`, so an array means streamed values https://vike.dev/passToClient#streaming
15
+ const pageContextSerializedInHtml = pageContextJson[0] === '['
16
+ ? (await import('./streamedValues.js')).parsePageContextHtml(pageContextJson)
17
+ : parse(pageContextJson);
14
18
  assert(hasProp(pageContextSerializedInHtml, 'pageId', 'string'));
15
19
  assert(hasProp(pageContextSerializedInHtml, 'routeParams', 'string{}'));
16
20
  return pageContextSerializedInHtml;
17
21
  }
18
22
  function getGlobalContextSerializedInHtml() {
19
- const globalContextSerializedInHtml = findAndParseJson(htmlElementId_globalContext);
23
+ const globalContextSerializedInHtml = parse(findJson(htmlElementId_globalContext));
20
24
  return globalContextSerializedInHtml;
21
25
  }
22
- function findAndParseJson(id) {
26
+ function findJson(id) {
23
27
  const elem = document.getElementById(id);
24
28
  assertUsage(elem,
25
29
  // It seems like it can be missing when HTML is malformed: https://github.com/vikejs/vike/issues/913
26
30
  `Couldn't find #${id} (which Vike automatically injects in the HTML): make sure it exists (i.e. don't remove it and make sure your HTML isn't malformed)`);
27
31
  const jsonStr = elem.textContent;
28
32
  assert(jsonStr);
29
- const json = parse(jsonStr);
30
- return json;
33
+ return jsonStr;
31
34
  }
@@ -53,10 +53,6 @@ function isFetchError(err) {
53
53
  'error loading dynamically imported module',
54
54
  // safari
55
55
  'Importing a module script failed',
56
- // ??
57
- 'error resolving module specifier',
58
- // ??
59
- 'failed to resolve module',
60
56
  ];
61
57
  return FAILED_TO_FETCH_MESSAGES.some((s) => err.message.toLowerCase().includes(s.toLowerCase()));
62
58
  }
@@ -38,9 +38,20 @@ function clean() {
38
38
  const href = linkVike.getAttribute('href');
39
39
  assert(href && href.endsWith(suffix));
40
40
  let filePathAbsoluteUserRootDir = href.slice(0, -suffix.length);
41
- const prefix = '/@fs/';
42
- if (filePathAbsoluteUserRootDir.startsWith(prefix))
43
- filePathAbsoluteUserRootDir = filePathAbsoluteUserRootDir.slice(prefix.length);
41
+ const prefixFs = '/@fs/';
42
+ if (filePathAbsoluteUserRootDir.startsWith(prefixFs))
43
+ filePathAbsoluteUserRootDir = filePathAbsoluteUserRootDir.slice(prefixFs.length);
44
+ // CSS virtual module:
45
+ // ```js
46
+ // import 'virtual:some.css'
47
+ // ```
48
+ // ID becomes:
49
+ // ```
50
+ // <link href="/@id/__x00__virtual:some.css?direct" rel="stylesheet" type="text/css">
51
+ // ```
52
+ const prefixId = '/@id/';
53
+ if (filePathAbsoluteUserRootDir.startsWith(prefixId))
54
+ filePathAbsoluteUserRootDir = filePathAbsoluteUserRootDir.slice(prefixId.length).replace('__x00__', '\0');
44
55
  if (injectedByVite.some((filePathAbsoluteFilesystem) => filePathAbsoluteFilesystem.endsWith(filePathAbsoluteUserRootDir))) {
45
56
  linkVike.remove();
46
57
  }
@@ -0,0 +1,4 @@
1
+ export { asyncIterable };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const asyncIterable: StreamedValueType;
@@ -0,0 +1,26 @@
1
+ export { asyncIterable };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { readableStream } from './readableStream.js';
4
+ import '../../assertEnvClient.js';
5
+ // A ReadableStream, consumed as an async iterable: `for await (const chunk of pageContext.someAsyncIterable)` (Safari's
6
+ // ReadableStream isn't async-iterable)
7
+ const asyncIterable = {
8
+ marker: markers.asyncIterable,
9
+ revive(parseValue) {
10
+ const streamedValue = readableStream.revive(parseValue);
11
+ return { ...streamedValue, value: toAsyncIterable(streamedValue.value) };
12
+ },
13
+ };
14
+ function toAsyncIterable(stream) {
15
+ const reader = stream.getReader();
16
+ const iterator = {
17
+ next: () => reader.read(),
18
+ // Called upon `break` in `for await`
19
+ async return(value) {
20
+ await reader.cancel();
21
+ return { done: true, value };
22
+ },
23
+ [Symbol.asyncIterator]: () => iterator,
24
+ };
25
+ return iterator;
26
+ }
@@ -0,0 +1,11 @@
1
+ export { decodeChunk };
2
+ export { getLineError };
3
+ import '../../assertEnvClient.js';
4
+ declare function decodeChunk(line: {
5
+ t: string;
6
+ } | {
7
+ b: string;
8
+ } | {
9
+ v: unknown;
10
+ }, parseValue: (value: unknown) => unknown): unknown;
11
+ declare function getLineError(): Error;
@@ -0,0 +1,19 @@
1
+ // The decoding of the lines (see shared-server-client/streamedValues.ts)
2
+ export { decodeChunk };
3
+ export { getLineError };
4
+ import '../../assertEnvClient.js';
5
+ const textEncoder = new TextEncoder();
6
+ function decodeChunk(line, parseValue) {
7
+ if ('t' in line)
8
+ return textEncoder.encode(line.t);
9
+ if ('b' in line)
10
+ return decodeBase64url(line.b);
11
+ return parseValue(line.v);
12
+ }
13
+ function getLineError() {
14
+ return new Error('A streamed pageContext value failed on the server-side (see the server logs)');
15
+ }
16
+ function decodeBase64url(str) {
17
+ const binary = atob(str.replaceAll('-', '+').replaceAll('_', '/'));
18
+ return Uint8Array.from(binary, (c) => c.charCodeAt(0));
19
+ }
@@ -0,0 +1,4 @@
1
+ export { promise };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const promise: StreamedValueType;
@@ -0,0 +1,19 @@
1
+ export { promise };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { getLineError } from './lines.js';
4
+ import { genPromise } from '../../../utils/genPromise.js';
5
+ import '../../assertEnvClient.js';
6
+ // Settled by its `v` or `error` line
7
+ const promise = {
8
+ marker: markers.promise,
9
+ revive(parseValue) {
10
+ const { promise: value, resolve, reject } = genPromise({ timeout: null });
11
+ // Avoid an unhandled rejection if the user doesn't use the promise
12
+ value.catch(() => { });
13
+ return {
14
+ value,
15
+ push: (line) => ('v' in line ? resolve(parseValue(line.v)) : reject(getLineError())),
16
+ fail: reject,
17
+ };
18
+ },
19
+ };
@@ -0,0 +1,4 @@
1
+ export { readableStream };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const readableStream: StreamedValueType;
@@ -0,0 +1,44 @@
1
+ export { readableStream };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { decodeChunk, getLineError } from './lines.js';
4
+ import '../../assertEnvClient.js';
5
+ // Fed by its chunk lines, until its `end` or `error` line
6
+ const readableStream = {
7
+ marker: markers.readableStream,
8
+ revive(parseValue) {
9
+ let controller;
10
+ let isClosed = false;
11
+ const value = new ReadableStream({
12
+ start(controller_) {
13
+ controller = controller_;
14
+ },
15
+ cancel() {
16
+ // Released by its consumer: the rest is ignored
17
+ isClosed = true;
18
+ },
19
+ });
20
+ const close = (err) => {
21
+ if (isClosed)
22
+ return;
23
+ isClosed = true;
24
+ if (err)
25
+ controller.error(err);
26
+ else
27
+ controller.close();
28
+ };
29
+ return {
30
+ value,
31
+ push(line) {
32
+ if (isClosed)
33
+ return;
34
+ if ('end' in line)
35
+ close();
36
+ else if ('error' in line)
37
+ close(getLineError());
38
+ else
39
+ controller.enqueue(decodeChunk(line, parseValue));
40
+ },
41
+ fail: close,
42
+ };
43
+ },
44
+ };