vike 0.4.267-commit-b005535 → 0.4.267-commit-5676e14

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 (139) hide show
  1. package/dist/client/runtime-client-routing/createPageContextClient.d.ts +4 -0
  2. package/dist/client/runtime-client-routing/getGlobalContextClientInternal.d.ts +4 -0
  3. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +22 -2
  4. package/dist/client/runtime-client-routing/getPageContextFromHooks.js +4 -5
  5. package/dist/client/runtime-client-routing/renderPageClient.d.ts +472 -9
  6. package/dist/client/runtime-client-routing/renderPageClient.js +11 -5
  7. package/dist/client/runtime-client-routing/streamedValues.d.ts +5 -0
  8. package/dist/client/runtime-client-routing/streamedValues.js +23 -0
  9. package/dist/client/runtime-server-routing/createPageContextClient.d.ts +4 -0
  10. package/dist/client/runtime-server-routing/entry.js +1 -1
  11. package/dist/client/runtime-server-routing/getGlobalContextClientInternal.d.ts +4 -0
  12. package/dist/client/shared/getGlobalContextClientInternalShared.d.ts +4 -0
  13. package/dist/client/shared/getJsonSerializedInHtml.d.ts +2 -2
  14. package/dist/client/shared/getJsonSerializedInHtml.js +9 -6
  15. package/dist/client/shared/streamedValues/asyncIterable.d.ts +4 -0
  16. package/dist/client/shared/streamedValues/asyncIterable.js +26 -0
  17. package/dist/client/shared/streamedValues/lines.d.ts +11 -0
  18. package/dist/client/shared/streamedValues/lines.js +19 -0
  19. package/dist/client/shared/streamedValues/promise.d.ts +4 -0
  20. package/dist/client/shared/streamedValues/promise.js +19 -0
  21. package/dist/client/shared/streamedValues/readableStream.d.ts +4 -0
  22. package/dist/client/shared/streamedValues/readableStream.js +44 -0
  23. package/dist/client/shared/streamedValues/registry.d.ts +21 -0
  24. package/dist/client/shared/streamedValues/registry.js +40 -0
  25. package/dist/client/shared/streamedValues.d.ts +7 -0
  26. package/dist/client/shared/streamedValues.js +82 -0
  27. package/dist/node/api/resolveViteConfigUser.js +2 -2
  28. package/dist/node/prerender/runPrerender.d.ts +12 -4
  29. package/dist/node/prerender/runPrerender.js +60 -15
  30. package/dist/node/vite/assertEnvVite.js +1 -1
  31. package/dist/node/vite/index.js +2 -0
  32. package/dist/node/vite/plugins/build/handleAssetsManifest.js +6 -2
  33. package/dist/node/vite/plugins/build/pluginBuildApp.js +25 -26
  34. package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +2 -2
  35. package/dist/node/vite/plugins/build/pluginBuildConfig.js +24 -16
  36. package/dist/node/vite/plugins/build/pluginDistFileNames.js +70 -50
  37. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.d.ts +6 -0
  38. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.js +71 -0
  39. package/dist/node/vite/plugins/build/pluginSuppressRollupWarning.js +19 -17
  40. package/dist/node/vite/plugins/pluginCommon.js +9 -6
  41. package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +1 -1
  42. package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +6 -4
  43. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.d.ts +2 -1
  44. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +29 -12
  45. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -2
  46. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +7 -7
  47. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +7 -5
  48. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js +4 -10
  49. package/dist/node/vite/plugins/pluginVirtualFiles.js +20 -0
  50. package/dist/node/vite/shared/addSsrMiddleware.js +13 -1
  51. package/dist/node/vite/shared/getAssetsDir.d.ts +3 -2
  52. package/dist/node/vite/shared/getAssetsDir.js +3 -3
  53. package/dist/node/vite/shared/isViteCli.d.ts +3 -3
  54. package/dist/node/vite/shared/isViteCli.js +80 -84
  55. package/dist/node/vite/shared/isViteServerSide.js +2 -7
  56. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +1 -1
  57. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +8 -6
  58. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +4 -1
  59. package/dist/node/vite/shared/resolveVikeConfigInternal.js +82 -11
  60. package/dist/server/runtime/globalContext.d.ts +20 -0
  61. package/dist/server/runtime/renderPageServer/analyzePage.js +3 -3
  62. package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +20 -7
  63. package/dist/server/runtime/renderPageServer/createHttpResponse.js +34 -15
  64. package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +4 -0
  65. package/dist/server/runtime/renderPageServer/execHookOnError.js +1 -1
  66. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.d.ts +9 -0
  67. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.js +17 -5
  68. package/dist/server/runtime/renderPageServer/getHttpResponseBody.d.ts +2 -2
  69. package/dist/server/runtime/renderPageServer/getHttpResponseBody.js +17 -2
  70. package/dist/server/runtime/renderPageServer/getPageContextJson.d.ts +8 -0
  71. package/dist/server/runtime/renderPageServer/getPageContextJson.js +47 -0
  72. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +2 -0
  73. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +1 -1
  74. package/dist/server/runtime/renderPageServer/headersResponse.d.ts +11 -2
  75. package/dist/server/runtime/renderPageServer/headersResponse.js +20 -1
  76. package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +5 -4
  77. package/dist/server/runtime/renderPageServer/html/injectAssets.d.ts +3 -2
  78. package/dist/server/runtime/renderPageServer/html/injectAssets.js +7 -1
  79. package/dist/server/runtime/renderPageServer/html/renderHtml.js +4 -2
  80. package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +5 -1
  81. package/dist/server/runtime/renderPageServer/html/serializeContext.js +12 -9
  82. package/dist/server/runtime/renderPageServer/html/stream.d.ts +13 -6
  83. package/dist/server/runtime/renderPageServer/html/stream.js +121 -31
  84. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.d.ts +30 -0
  85. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.js +92 -0
  86. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +4 -0
  87. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.js +5 -1
  88. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.d.ts +15 -0
  89. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.js +61 -0
  90. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +314 -1
  91. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +21 -12
  92. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.d.ts +4 -0
  93. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.js +12 -0
  94. package/dist/server/runtime/renderPageServer/streamedValues/lines.d.ts +10 -0
  95. package/dist/server/runtime/renderPageServer/streamedValues/lines.js +49 -0
  96. package/dist/server/runtime/renderPageServer/streamedValues/promise.d.ts +4 -0
  97. package/dist/server/runtime/renderPageServer/streamedValues/promise.js +14 -0
  98. package/dist/server/runtime/renderPageServer/streamedValues/pump.d.ts +10 -0
  99. package/dist/server/runtime/renderPageServer/streamedValues/pump.js +67 -0
  100. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.d.ts +4 -0
  101. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.js +12 -0
  102. package/dist/server/runtime/renderPageServer/streamedValues/registry.d.ts +28 -0
  103. package/dist/server/runtime/renderPageServer/streamedValues/registry.js +33 -0
  104. package/dist/server/runtime/renderPageServer.d.ts +4 -0
  105. package/dist/server/runtime/renderPageServer.js +18 -8
  106. package/dist/shared-server-client/createGlobalContextShared.d.ts +8 -0
  107. package/dist/shared-server-client/createGlobalContextShared.js +2 -1
  108. package/dist/shared-server-client/getPageContextPublicShared.js +0 -2
  109. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.d.ts +8 -0
  110. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js +17 -7
  111. package/dist/shared-server-client/hooks/execHook.d.ts +1 -1
  112. package/dist/shared-server-client/hooks/execHook.js +2 -2
  113. package/dist/shared-server-client/route/abort.d.ts +1 -1
  114. package/dist/shared-server-client/route/abort.js +4 -2
  115. package/dist/shared-server-client/streamedValues.d.ts +22 -0
  116. package/dist/shared-server-client/streamedValues.js +24 -0
  117. package/dist/shared-server-node/vike-environments.d.ts +4 -0
  118. package/dist/shared-server-node/vike-environments.js +10 -0
  119. package/dist/shared-server-node/virtualFileId.d.ts +7 -5
  120. package/dist/shared-server-node/virtualFileId.js +42 -42
  121. package/dist/types/Config.d.ts +1 -1
  122. package/dist/types/PageConfig.d.ts +13 -5
  123. package/dist/types/PageContext.d.ts +18 -1
  124. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  125. package/dist/utils/PROJECT_VERSION.js +1 -1
  126. package/dist/utils/assertViteVersion.d.ts +1 -3
  127. package/dist/utils/assertViteVersion.js +6 -9
  128. package/dist/utils/catchInfiniteLoop.js +33 -11
  129. package/dist/utils/deepEqual.d.ts +2 -1
  130. package/dist/utils/deepEqual.js +21 -6
  131. package/dist/utils/getContentTypeFromUrl.d.ts +2 -0
  132. package/dist/utils/getContentTypeFromUrl.js +39 -0
  133. package/dist/utils/injectRollupInputs.d.ts +2 -2
  134. package/dist/utils/injectRollupInputs.js +2 -2
  135. package/dist/utils/isDev.js +2 -7
  136. package/dist/utils/parseUrl-extras.js +4 -0
  137. package/package.json +7 -7
  138. package/dist/shared-server-client/addIs404ToPageProps.d.ts +0 -2
  139. package/dist/shared-server-client/addIs404ToPageProps.js +0 -17
@@ -0,0 +1,28 @@
1
+ export { getReplacer };
2
+ export type { StreamedValue };
3
+ export type { StreamedValueType };
4
+ import type { Replacer } from '@brillout/json-serializer/stringify';
5
+ import type { LineContent } from '../../../../shared-server-client/streamedValues.js';
6
+ import '../../../assertEnvServer.js';
7
+ type StreamedValueType<Value = any, Result = any> = {
8
+ marker: string;
9
+ is: (value: unknown) => value is Value;
10
+ read: (value: Value) => {
11
+ next: () => Promise<Result>;
12
+ /** `isLast`: the value ended */
13
+ toLine: (result: Result) => {
14
+ line: LineContent;
15
+ isLast: boolean;
16
+ };
17
+ cancel: () => unknown;
18
+ };
19
+ };
20
+ type StreamedValue = {
21
+ id: number;
22
+ type: StreamedValueType;
23
+ value: unknown;
24
+ };
25
+ declare function getReplacer(pageContext: object): {
26
+ replacer: Replacer;
27
+ streamedValues: StreamedValue[];
28
+ };
@@ -0,0 +1,33 @@
1
+ // The types of streamed pageContext values (see shared-server-client/streamedValues.ts), and the serializer's replacer
2
+ // that replaces them with their marker and id.
3
+ export { getReplacer };
4
+ import { readableStream } from './readableStream.js';
5
+ import { promise } from './promise.js';
6
+ import { asyncIterable } from './asyncIterable.js';
7
+ import '../../../assertEnvServer.js';
8
+ // A ReadableStream is also an async iterable
9
+ const types = [readableStream, promise, asyncIterable];
10
+ // Per pageContext: the HTML and the `index.pageContext.json` of a pre-rendered page reference the same values with the
11
+ // same ids.
12
+ const idsByPageContext = new WeakMap();
13
+ // `streamedValues`: the values not seen before, filled while serializing
14
+ function getReplacer(pageContext) {
15
+ let ids = idsByPageContext.get(pageContext);
16
+ if (!ids)
17
+ idsByPageContext.set(pageContext, (ids = { byValue: new Map(), idNext: 0 }));
18
+ const streamedValues = [];
19
+ const replacer = (_key, value) => {
20
+ const type = types.find((type) => type.is(value));
21
+ if (!type)
22
+ return undefined;
23
+ let streamedValue = ids.byValue.get(value);
24
+ if (!streamedValue) {
25
+ streamedValue = { id: ids.idNext++, type, value };
26
+ ids.byValue.set(value, streamedValue);
27
+ // The same value referenced twice is sent once (a stream can be read only once)
28
+ streamedValues.push(streamedValue);
29
+ }
30
+ return { replacement: type.marker + streamedValue.id };
31
+ };
32
+ return { replacer, streamedValues };
33
+ }
@@ -52,6 +52,10 @@ declare function getPageContextBegin(pageContextInit: PageContextInitInternal, g
52
52
  _pageFilesAll: import("../__internal/index.js").PageFile[];
53
53
  _pageConfigs: import("../__internal/index.js").PageConfig[];
54
54
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
55
+ _environmentEntries: Record<string, {
56
+ pageConfigs: import("../__internal/index.js").PageConfig[];
57
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
58
+ } | null>;
55
59
  _allPageIds: string[];
56
60
  } & (({
57
61
  isClientSide: false;
@@ -17,12 +17,13 @@ import { updateType } from '../../utils/updateType.js';
17
17
  import { getPageContextAddendumAbort, isAbortError, logAbort, addNewPageContextAborted, } from '../../shared-server-client/route/abort.js';
18
18
  import { getGlobalContextServerInternal, initGlobalContext_renderPage, } from './globalContext.js';
19
19
  import { handlePageContextRequestUrl } from './renderPageServer/handlePageContextRequestUrl.js';
20
+ import { getPageContextPublicServer } from './renderPageServer/getPageContextPublicServer.js';
20
21
  import { createHttpResponse404, createHttpResponseRedirect, createHttpResponsePageJson, createHttpResponseErrorFallback, createHttpResponseErrorFallback_noGlobalContext, createHttpResponseBaseIsMissing, createHttpResponseFromUniversalMiddleware, } from './renderPageServer/createHttpResponse.js';
21
22
  import { logRuntimeError, logRuntimeInfo } from './loggerRuntime.js';
22
23
  import { assertArguments } from './renderPageServer/assertArguments.js';
23
24
  import { log404 } from './renderPageServer/log404/index.js';
24
25
  import pc from '@brillout/picocolors';
25
- import { getPageContextClientSerializedAbort, getPageContextClientSerialized, } from './renderPageServer/html/serializeContext.js';
26
+ import { getPageContextClientSerializedAbort } from './renderPageServer/html/serializeContext.js';
26
27
  import { getErrorPageId } from '../../shared-server-client/error-page.js';
27
28
  import { handleErrorWithoutErrorPage } from './renderPageServer/handleErrorWithoutErrorPage.js';
28
29
  import { loadPageConfigsLazyServerSide, } from './renderPageServer/loadPageConfigsLazyServerSide.js';
@@ -30,6 +31,7 @@ import { resolveRedirects } from './renderPageServer/resolveRedirects.js';
30
31
  import { getVikeConfigError } from '../../shared-server-node/getVikeConfigError.js';
31
32
  import { forkPageContext } from '../../shared-server-client/forkPageContext.js';
32
33
  import { getAsyncLocalStorage } from './asyncHook.js';
34
+ import { getPageContextJson } from './renderPageServer/getPageContextJson.js';
33
35
  import '../assertEnvServer.js';
34
36
  import { enhance, apply, universalSymbol, UniversalRouter, getAdapterRuntime, } from '@universal-middleware/core';
35
37
  import { createRequestAdapter } from '@universal-middleware/node/request';
@@ -55,7 +57,12 @@ async function renderPageServer(pageContextInit) {
55
57
  logHttpResponse(urlOriginalPretty, pageContextFinish);
56
58
  checkType(pageContextFinish);
57
59
  assertPageContextFinish(pageContextFinish);
58
- return pageContextFinish;
60
+ return getPageContextReturn(pageContextFinish);
61
+ }
62
+ function getPageContextReturn(pageContextFinish) {
63
+ if (!hasProp(pageContextFinish, '_globalContext', 'object'))
64
+ return pageContextFinish;
65
+ return getPageContextPublicServer(pageContextFinish);
59
66
  }
60
67
  async function renderPageServerEntryOnceBegin(pageContextInit, requestId, asyncStore) {
61
68
  // Invalid config
@@ -125,6 +132,7 @@ async function renderPageServerEntryOnce(pageContextBegin, globalContext, reques
125
132
  return await renderPageServerEntryRecursive(pageContextBegin, globalContext, requestId);
126
133
  }
127
134
  async function renderPageServerEntryRecursive(pageContextBegin, globalContext, requestId) {
135
+ assert(requestId);
128
136
  catchInfiniteLoop(`[${getRequestTag(requestId)}] renderPageServerEntryRecursive()`);
129
137
  const pageContextNominalPageBegin = fork(pageContextBegin);
130
138
  const pageContextAddendumAbort = getPageContextAddendumAbort(pageContextBegin.pageContextsAborted);
@@ -217,7 +225,9 @@ async function renderPageServerEntryRecursive_onError(err, pageContextBegin, pag
217
225
  catch (errErrorPage) {
218
226
  // Handle `throw redirect()` and `throw render()` while rendering error page
219
227
  if (isAbortError(errErrorPage)) {
220
- const handled = await handleAbort(errErrorPage, pageContextBegin, pageContextNominalPageBegin, requestId, pageContextErrorPageInit, globalContext);
228
+ const handled = await handleAbort(errErrorPage, pageContextBegin,
229
+ // The error page is the page that aborted
230
+ pageContextErrorPageInit, requestId, pageContextErrorPageInit, globalContext);
221
231
  if (handled.pageContextReturn) {
222
232
  // - throw redirect()
223
233
  // - throw render(url)
@@ -470,14 +480,14 @@ pageContextNominalPageBegin, requestId, pageContextErrorPageInit, globalContext)
470
480
  logAbort(errAbort, globalContext._isProduction, pageContextNominalPageBegin);
471
481
  const pageContextAbort = errAbort._pageContextAbort;
472
482
  assert(pageContextAbort);
473
- addNewPageContextAborted(pageContextBegin.pageContextsAborted, pageContextNominalPageBegin, pageContextAbort);
483
+ addNewPageContextAborted(pageContextBegin.pageContextsAborted, pageContextNominalPageBegin, pageContextAbort, getPageContextPublicServer);
474
484
  const pageContext = fork(pageContextBegin);
475
485
  const pageContextAddendumAbort = getPageContextAddendumAbort(pageContextBegin.pageContextsAborted);
476
486
  objectAssign(pageContext, pageContextAddendumAbort);
477
487
  assert(pageContextAddendumAbort === pageContextAbort);
478
488
  // Client-side navigation — [`pageContext.json` request](https://vike.dev/pageContext.json)
479
489
  if (pageContextBegin.isClientSideNavigation) {
480
- let pageContextSerialized;
490
+ let pageContextJson;
481
491
  if (pageContextAbort.abortStatusCode) {
482
492
  const errorPageId = getErrorPageId(globalContext._pageFilesAll, globalContext._pageConfigs);
483
493
  const abortCall = pageContextAbort._abortCall;
@@ -487,12 +497,12 @@ pageContextNominalPageBegin, requestId, pageContextErrorPageInit, globalContext)
487
497
  objectAssign(pageContext, pageContextErrorPageInit, true);
488
498
  updateType(pageContext, await loadPageConfigsLazyServerSide(pageContext));
489
499
  // We include pageContextInit: we don't only serialize pageContextAbort because the error page may need to access pageContextInit
490
- pageContextSerialized = getPageContextClientSerialized(pageContext, false);
500
+ pageContextJson = getPageContextJson(pageContext);
491
501
  }
492
502
  else {
493
- pageContextSerialized = getPageContextClientSerializedAbort(pageContextAbort, false);
503
+ pageContextJson = getPageContextClientSerializedAbort(pageContextAbort, false);
494
504
  }
495
- const httpResponse = await createHttpResponsePageJson(pageContextSerialized);
505
+ const httpResponse = await createHttpResponsePageJson(pageContextJson, pageContext);
496
506
  objectAssign(pageContext, { httpResponse });
497
507
  return { pageContextReturn: pageContext };
498
508
  }
@@ -42,6 +42,10 @@ declare function createGlobalContextShared<GlobalContextAdded extends {}, Global
42
42
  _pageFilesAll: PageFile[];
43
43
  _pageConfigs: PageConfigRuntime[];
44
44
  _pageConfigGlobal: import("../types/PageConfig.js").PageConfigGlobalRuntime;
45
+ _environmentEntries: Record<string, {
46
+ pageConfigs: PageConfigRuntime[];
47
+ pageConfigGlobal: import("../types/PageConfig.js").PageConfigGlobalRuntime;
48
+ } | null>;
45
49
  _allPageIds: string[];
46
50
  } & GlobalContextAdded & Awaited<GlobalContextAddedAsync>>;
47
51
  type GlobalContextBasePublic = Pick<GlobalContextBase, 'config' | 'pages' | 'isGlobalContext'>;
@@ -74,5 +78,9 @@ declare function createGlobalContextBase(virtualFileExportsGlobalEntry: unknown)
74
78
  _pageFilesAll: PageFile[];
75
79
  _pageConfigs: PageConfigRuntime[];
76
80
  _pageConfigGlobal: import("../types/PageConfig.js").PageConfigGlobalRuntime;
81
+ _environmentEntries: Record<string, {
82
+ pageConfigs: PageConfigRuntime[];
83
+ pageConfigGlobal: import("../types/PageConfig.js").PageConfigGlobalRuntime;
84
+ } | null>;
77
85
  _allPageIds: string[];
78
86
  };
@@ -79,7 +79,7 @@ addGlobalContextTmp, addGlobalContextAsync) {
79
79
  }
80
80
  }
81
81
  function createGlobalContextBase(virtualFileExportsGlobalEntry) {
82
- const { pageFilesAll, pageConfigs, pageConfigGlobal } = parseVirtualFileExportsGlobalEntry(virtualFileExportsGlobalEntry);
82
+ const { pageFilesAll, pageConfigs, pageConfigGlobal, environmentEntries } = parseVirtualFileExportsGlobalEntry(virtualFileExportsGlobalEntry);
83
83
  const allPageIds = getAllPageIds(pageFilesAll, pageConfigs);
84
84
  const globalContextAddendum = resolveGlobalContextConfig(pageConfigs, pageConfigGlobal);
85
85
  const globalContext = {
@@ -94,6 +94,7 @@ function createGlobalContextBase(virtualFileExportsGlobalEntry) {
94
94
  _pageFilesAll: pageFilesAll,
95
95
  _pageConfigs: pageConfigs,
96
96
  _pageConfigGlobal: pageConfigGlobal,
97
+ _environmentEntries: environmentEntries,
97
98
  _allPageIds: allPageIds,
98
99
  ...globalContextAddendum,
99
100
  };
@@ -3,14 +3,12 @@ export { assertPropertyGetters };
3
3
  import { assert, assertWarning } from '../utils/assert.js';
4
4
  import { compareString } from '../utils/compareString.js';
5
5
  import { isPropertyGetter } from '../utils/isPropertyGetter.js';
6
- import { addIs404ToPageProps } from './addIs404ToPageProps.js';
7
6
  import { getGlobalContextPublicShared } from './getGlobalContextPublicShared.js';
8
7
  import { getPublicProxy } from './getPublicProxy.js';
9
8
  function getPageContextPublicShared(pageContext) {
10
9
  assert(!pageContext._isProxyObject);
11
10
  assert(!pageContext.globalContext); // pageContext.globalContext should only be available to users — Vike itself should use pageContext._globalContext instead
12
11
  assert(pageContext._isOriginalObject); // ensure we preserve the original object reference
13
- addIs404ToPageProps(pageContext);
14
12
  // TO-DO/next-major-release: remove
15
13
  if (!('_pageId' in pageContext)) {
16
14
  Object.defineProperty(pageContext, '_pageId', {
@@ -1,8 +1,16 @@
1
1
  export { parseVirtualFileExportsGlobalEntry };
2
+ export { parseGlobalEntryPageConfigs };
3
+ export type { EnvironmentEntry };
2
4
  import { type PageFile } from './getPageFileObject.js';
3
5
  import type { PageConfigRuntime, PageConfigGlobalRuntime } from '../../types/PageConfig.js';
4
6
  declare function parseVirtualFileExportsGlobalEntry(virtualFileExportsGlobalEntry: unknown): {
5
7
  pageFilesAll: PageFile[];
6
8
  pageConfigs: PageConfigRuntime[];
7
9
  pageConfigGlobal: PageConfigGlobalRuntime;
10
+ environmentEntries: Record<string, null | EnvironmentEntry>;
11
+ };
12
+ type EnvironmentEntry = ReturnType<typeof parseGlobalEntryPageConfigs>;
13
+ declare function parseGlobalEntryPageConfigs(virtualFileExportsGlobalEntry: unknown): {
14
+ pageConfigs: PageConfigRuntime[];
15
+ pageConfigGlobal: PageConfigGlobalRuntime;
8
16
  };
@@ -1,4 +1,5 @@
1
1
  export { parseVirtualFileExportsGlobalEntry };
2
+ export { parseGlobalEntryPageConfigs };
2
3
  // TO-DO/next-major-release: remove old design code, and remove all assertions.
3
4
  import { assert } from '../../utils/assert.js';
4
5
  import { cast } from '../../utils/cast.js';
@@ -6,6 +7,7 @@ import { hasProp } from '../../utils/hasProp.js';
6
7
  import { isArray } from '../../utils/isArray.js';
7
8
  import { isCallable } from '../../utils/isCallable.js';
8
9
  import { isObject } from '../../utils/isObject.js';
10
+ import { objectMap } from '../../utils/objectMap.js';
9
11
  import { assertExportValues } from './assert_exports_old_design.js';
10
12
  import { getPageFileObject } from './getPageFileObject.js';
11
13
  import { fileTypes } from './fileTypes.js';
@@ -21,12 +23,12 @@ function parseVirtualFileExportsGlobalEntry(virtualFileExportsGlobalEntry) {
21
23
  assert(hasProp(virtualFileExportsGlobalEntry.pageFilesLazy, '.page.client') ||
22
24
  hasProp(virtualFileExportsGlobalEntry.pageFilesLazy, '.page.server'));
23
25
  assert(hasProp(virtualFileExportsGlobalEntry, 'pageFilesList', 'string[]'));
24
- assert(hasProp(virtualFileExportsGlobalEntry, 'pageConfigsSerialized'));
25
- assert(hasProp(virtualFileExportsGlobalEntry, 'pageConfigGlobalSerialized'));
26
- const { pageConfigsSerialized, pageConfigGlobalSerialized } = virtualFileExportsGlobalEntry;
27
- assertPageConfigsSerialized(pageConfigsSerialized);
28
- assertPageConfigGlobalSerialized(pageConfigGlobalSerialized);
29
- const { pageConfigs, pageConfigGlobal } = parsePageConfigsSerialized(pageConfigsSerialized, pageConfigGlobalSerialized);
26
+ const { pageConfigs, pageConfigGlobal } = parseGlobalEntryPageConfigs(virtualFileExportsGlobalEntry);
27
+ // The global entries of the additional environments (e.g. `rsc`)
28
+ // - `null` in development: they're imported with environment.runner.import()
29
+ const environmentEntries = hasProp(virtualFileExportsGlobalEntry, 'environmentEntries', 'object')
30
+ ? objectMap(virtualFileExportsGlobalEntry.environmentEntries, (environmentEntry) => environmentEntry === null ? null : parseGlobalEntryPageConfigs(environmentEntry))
31
+ : {};
30
32
  const pageFilesMap = {};
31
33
  parseGlobResult(virtualFileExportsGlobalEntry.pageFilesLazy).forEach(({ filePath, pageFile, globValue }) => {
32
34
  pageFile = pageFilesMap[filePath] = pageFilesMap[filePath] ?? pageFile;
@@ -72,7 +74,15 @@ function parseVirtualFileExportsGlobalEntry(virtualFileExportsGlobalEntry) {
72
74
  pageFilesAll.forEach(({ filePath }) => {
73
75
  assert(!filePath.includes('\\'));
74
76
  });
75
- return { pageFilesAll, pageConfigs, pageConfigGlobal };
77
+ return { pageFilesAll, pageConfigs, pageConfigGlobal, environmentEntries };
78
+ }
79
+ function parseGlobalEntryPageConfigs(virtualFileExportsGlobalEntry) {
80
+ assert(hasProp(virtualFileExportsGlobalEntry, 'pageConfigsSerialized'));
81
+ assert(hasProp(virtualFileExportsGlobalEntry, 'pageConfigGlobalSerialized'));
82
+ const { pageConfigsSerialized, pageConfigGlobalSerialized } = virtualFileExportsGlobalEntry;
83
+ assertPageConfigsSerialized(pageConfigsSerialized);
84
+ assertPageConfigGlobalSerialized(pageConfigGlobalSerialized);
85
+ return parsePageConfigsSerialized(pageConfigsSerialized, pageConfigGlobalSerialized);
76
86
  }
77
87
  function parseGlobResult(globObject) {
78
88
  const ret = [];
@@ -38,7 +38,7 @@ declare function execHookSingleWithReturn<PageContext extends PageContextExecHoo
38
38
  }>;
39
39
  declare function isUserHookError(err: unknown): false | HookLoc;
40
40
  declare function execHookSingleWithoutPageContext<HookReturn>(hook: Omit<HookInternal, 'hookFn'>, globalContext: GlobalContextPublicMinimum, hookFnCaller: () => HookReturn): Promise<HookReturn>;
41
- declare function execHookSingleSync<PageContext extends PageContextExecHook>(hook: Omit<HookInternal<PageContext>, 'hookTimeout'>, globalContext: GlobalContextPublicMinimum, pageContext: PageContext | null, getPageContextPublic: (pageContext: PageContext) => PageContext, hookFnCaller?: () => unknown): {
41
+ declare function execHookSingleSync<PageContext extends PageContextExecHook>(hook: Omit<HookInternal<PageContext>, 'hookTimeout'>, globalContext: GlobalContextPublicMinimum, pageContext: PageContext | null, getPageContextPublic: (pageContext: PageContext) => PageContext, hookFnCaller?: (pageContextPublic: PageContext | null) => unknown): {
42
42
  hookReturn: unknown;
43
43
  };
44
44
  type HookPublic = {
@@ -61,8 +61,8 @@ async function execHookSingleWithoutPageContext(hook, globalContext, hookFnCalle
61
61
  }
62
62
  function execHookSingleSync(hook, globalContext, pageContext, getPageContextPublic, hookFnCaller) {
63
63
  const pageContextPublic = pageContext && getPageContextPublic(pageContext);
64
- hookFnCaller ?? (hookFnCaller = () => hook.hookFn(pageContextPublic));
65
- const hookReturn = execHookBase(hookFnCaller, hook, globalContext, pageContextPublic);
64
+ const call = hookFnCaller ? () => hookFnCaller(pageContextPublic) : () => hook.hookFn(pageContextPublic);
65
+ const hookReturn = execHookBase(call, hook, globalContext, pageContextPublic);
66
66
  return { hookReturn };
67
67
  }
68
68
  function execHookBaseAsync(hookFnCaller, hook, globalContext, pageContextPublic) {
@@ -113,7 +113,7 @@ type PageContextAborted = {
113
113
  _pageContextAbort: PageContextAbort;
114
114
  } & PageContextMin;
115
115
  declare function getPageContextAddendumAbort(pageContextsAborted: PageContextAborted[]): PageContextAbort | null;
116
- declare function addNewPageContextAborted(pageContextsAborted: PageContextAborted[], pageContext: PageContextMin, pageContextAbort: PageContextAbort): void;
116
+ declare function addNewPageContextAborted<PageContext extends PageContextMin>(pageContextsAborted: PageContextAborted[], pageContext: PageContext, pageContextAbort: PageContextAbort, getPageContextPublic: (pageContext: PageContext & PageContextAborted) => PageContextAborted): void;
117
117
  type InferTwoOverloads<F extends Function> = F extends {
118
118
  (...a1: infer A1): infer R1;
119
119
  (...a0: infer A0): infer R0;
@@ -189,9 +189,11 @@ function getPageContextAddendumAbort(pageContextsAborted) {
189
189
  // Sets pageContext._urlRewrite from pageContextAbort._urlRewrite
190
190
  return pageContextAbort;
191
191
  }
192
- function addNewPageContextAborted(pageContextsAborted, pageContext, pageContextAbort) {
192
+ function addNewPageContextAborted(pageContextsAborted, pageContext, pageContextAbort,
193
+ // `pageContextsAborted` is exposed to users: https://vike.dev/pageContext#pageContextsAborted
194
+ getPageContextPublic) {
193
195
  objectAssign(pageContext, { _pageContextAbort: pageContextAbort });
194
- pageContextsAborted.push(pageContext);
196
+ pageContextsAborted.push(getPageContextPublic(pageContext));
195
197
  assertNoInfiniteAbortLoop(pageContextsAborted);
196
198
  }
197
199
  // There doesn't seem to be a way to count the number of HTTP redirects (Vike doesn't have access to the HTTP request headers/cookies)
@@ -0,0 +1,22 @@
1
+ export { markers };
2
+ export type { Line };
3
+ export type { LineContent };
4
+ declare const markers: {
5
+ readableStream: string;
6
+ promise: string;
7
+ asyncIterable: string;
8
+ };
9
+ type LineContent = {
10
+ t: string;
11
+ } | {
12
+ b: string;
13
+ } | {
14
+ v: unknown;
15
+ } | {
16
+ end: true;
17
+ } | {
18
+ error: true;
19
+ };
20
+ type Line = {
21
+ s: number;
22
+ } & LineContent;
@@ -0,0 +1,24 @@
1
+ // The wire format of streamed pageContext values: a ReadableStream, a Promise or an async iterable (e.g. an async
2
+ // generator) anywhere in a passToClient value. https://vike.dev/passToClient#streaming
3
+ //
4
+ // - Serialization: a marker followed by the value's id, e.g. `"!VikePromise:0"` (the serializer escapes user strings
5
+ // starting with `!`, so a user string can't be mistaken for a marker).
6
+ // - Delivery: the serialized pageContext is wrapped in a JSON array (the client loads its decoder only then) followed, in
7
+ // the same response, by one JSON line per chunk / result:
8
+ // - HTML: see server/runtime/renderPageServer/html/streamedValuesHtml.ts
9
+ // - `.pageContext.json`: see server/runtime/renderPageServer/getPageContextJson.ts
10
+ //
11
+ // Lines:
12
+ // {"s":<id>,"t":<text>} A chunk that is a Uint8Array of valid UTF-8
13
+ // {"s":<id>,"b":<base64url>} A chunk that is any other Uint8Array
14
+ // {"s":<id>,"v":<value>} Any other chunk, or the value of a Promise (@brillout/json-serializer)
15
+ // {"s":<id>,"end":true} The end of a ReadableStream / async iterable
16
+ // {"s":<id>,"error":true} The value failed (the error is logged on the server-side and isn't sent to the client)
17
+ //
18
+ // A chunk or a Promise value can contain further streamed values: they get new ids and their lines follow.
19
+ export { markers };
20
+ const markers = {
21
+ readableStream: '!VikeStream:',
22
+ promise: '!VikePromise:',
23
+ asyncIterable: '!VikeAsyncIterable:',
24
+ };
@@ -0,0 +1,4 @@
1
+ export { isEnvironmentBuiltIn };
2
+ export { isEnvironmentNameValid };
3
+ declare function isEnvironmentBuiltIn(environmentName: string): boolean;
4
+ declare function isEnvironmentNameValid(environmentName: string): boolean;
@@ -0,0 +1,10 @@
1
+ export { isEnvironmentBuiltIn };
2
+ export { isEnvironmentNameValid };
3
+ // Vike's built-in environments; every other environment name is an additional environment (e.g. `rsc`)
4
+ function isEnvironmentBuiltIn(environmentName) {
5
+ return environmentName === 'server' || environmentName === 'client';
6
+ }
7
+ // `:` separates the environment name from the page ID in virtual file IDs
8
+ function isEnvironmentNameValid(environmentName) {
9
+ return environmentName !== '' && !environmentName.includes(':');
10
+ }
@@ -1,5 +1,6 @@
1
1
  export { parseVirtualFileId };
2
2
  export { generateVirtualFileId };
3
+ export { generateVirtualFileIdAdditionalEnvironment };
3
4
  export { virtualFileIdGlobalEntryServer };
4
5
  export { virtualFileIdGlobalEntryClientSR };
5
6
  export { virtualFileIdGlobalEntryClientCR };
@@ -8,21 +9,22 @@ declare const virtualFileIdGlobalEntryClientSR = "virtual:vike:global-entry:clie
8
9
  declare const virtualFileIdGlobalEntryClientCR = "virtual:vike:global-entry:client:client-routing";
9
10
  type VirtualFileIdEntryParsed = {
10
11
  type: 'global-entry';
11
- isForClientSide: boolean;
12
+ environmentName: string;
12
13
  isClientRouting: boolean;
13
14
  } | {
14
15
  type: 'page-entry';
15
- isForClientSide: boolean;
16
+ environmentName: string;
16
17
  pageId: string;
17
18
  isExtractAssets: boolean;
18
19
  };
19
20
  declare function parseVirtualFileId(id: string): false | VirtualFileIdEntryParsed;
20
21
  declare function generateVirtualFileId(args: {
21
22
  type: 'global-entry';
22
- isForClientSide: boolean;
23
- isClientRouting: boolean;
23
+ environmentName: string;
24
+ isClientRouting?: boolean;
24
25
  } | {
25
26
  type: 'page-entry';
26
27
  pageId: string;
27
- isForClientSide: boolean;
28
+ environmentName: string;
28
29
  }): string;
30
+ declare function generateVirtualFileIdAdditionalEnvironment(environmentName: string): string;
@@ -1,10 +1,12 @@
1
1
  export { parseVirtualFileId };
2
2
  export { generateVirtualFileId };
3
+ export { generateVirtualFileIdAdditionalEnvironment };
3
4
  export { virtualFileIdGlobalEntryServer };
4
5
  export { virtualFileIdGlobalEntryClientSR };
5
6
  export { virtualFileIdGlobalEntryClientCR };
6
7
  import { extractAssetsRemoveQuery } from './extractAssetsQuery.js';
7
8
  import { assert } from '../utils/assert.js';
9
+ import { isEnvironmentBuiltIn, isEnvironmentNameValid } from './vike-environments.js';
8
10
  import { assertIsNotBrowser } from '../utils/assertIsNotBrowser.js';
9
11
  import { removeVirtualFileIdPrefix } from '../utils/virtualFileId.js';
10
12
  assertIsNotBrowser();
@@ -18,13 +20,6 @@ const virtualFileIdGlobalEntryClientSR =
18
20
  const virtualFileIdGlobalEntryClientCR =
19
21
  //
20
22
  'virtual:vike:global-entry:client:client-routing';
21
- // Page entries
22
- const virtualFileIdPageEntryClient =
23
- //
24
- 'virtual:vike:page-entry:client:'; // ${pageId}
25
- const virtualFileIdPageEntryServer =
26
- //
27
- 'virtual:vike:page-entry:server:'; // ${pageId}
28
23
  // Virtual ID prefixes
29
24
  const virtualFileIdPageEntryPrefix =
30
25
  //
@@ -38,11 +33,11 @@ function parseVirtualFileId(id) {
38
33
  return false;
39
34
  // Global entry
40
35
  if (id.includes(virtualFileIdGlobalEntryPrefix)) {
41
- const isForClientSide = id !== virtualFileIdGlobalEntryServer;
42
36
  const isClientRouting = id === virtualFileIdGlobalEntryClientCR;
37
+ const environmentName = parseGlobalEntryEnvironmentName(id);
43
38
  return {
44
39
  type: 'global-entry',
45
- isForClientSide,
40
+ environmentName,
46
41
  isClientRouting,
47
42
  };
48
43
  }
@@ -51,52 +46,57 @@ function parseVirtualFileId(id) {
51
46
  const idOriginal = id;
52
47
  id = extractAssetsRemoveQuery(id);
53
48
  const isExtractAssets = idOriginal !== id;
54
- if (id.startsWith(virtualFileIdPageEntryClient)) {
49
+ const environmentNameBegin = virtualFileIdPageEntryPrefix.length;
50
+ const environmentNameEnd = id.indexOf(':', environmentNameBegin);
51
+ assert(environmentNameEnd > environmentNameBegin);
52
+ const environmentName = id.slice(environmentNameBegin, environmentNameEnd);
53
+ const pageIdSerialized = id.slice(environmentNameEnd + 1);
54
+ const pageId = deserializePageId(pageIdSerialized);
55
+ if (environmentName === 'client')
55
56
  assert(isExtractAssets === false);
56
- const pageIdSerialized = id.slice(virtualFileIdPageEntryClient.length);
57
- const pageId = deserializePageId(pageIdSerialized);
58
- return {
59
- type: 'page-entry',
60
- pageId,
61
- isForClientSide: true,
62
- isExtractAssets,
63
- };
64
- }
65
- if (id.startsWith(virtualFileIdPageEntryServer)) {
66
- const pageIdSerialized = id.slice(virtualFileIdPageEntryServer.length);
67
- const pageId = deserializePageId(pageIdSerialized);
68
- return {
69
- type: 'page-entry',
70
- pageId,
71
- isForClientSide: false,
72
- isExtractAssets,
73
- };
74
- }
75
- assert(false);
57
+ return {
58
+ type: 'page-entry',
59
+ environmentName,
60
+ pageId,
61
+ isExtractAssets,
62
+ };
76
63
  }
77
64
  return false;
78
65
  }
66
+ function parseGlobalEntryEnvironmentName(id) {
67
+ if (id === virtualFileIdGlobalEntryServer)
68
+ return 'server';
69
+ if (id === virtualFileIdGlobalEntryClientSR || id === virtualFileIdGlobalEntryClientCR)
70
+ return 'client';
71
+ const environmentName = id.slice(virtualFileIdGlobalEntryPrefix.length);
72
+ assert(isEnvironmentNameValid(environmentName));
73
+ return environmentName;
74
+ }
79
75
  function generateVirtualFileId(args) {
80
76
  if (args.type === 'global-entry') {
81
- const { isForClientSide, isClientRouting } = args;
82
- if (!isForClientSide) {
83
- return virtualFileIdGlobalEntryServer;
84
- }
85
- else if (isClientRouting) {
86
- return virtualFileIdGlobalEntryClientCR;
87
- }
88
- else {
89
- return virtualFileIdGlobalEntryClientSR;
77
+ const { environmentName, isClientRouting } = args;
78
+ assert(isEnvironmentNameValid(environmentName));
79
+ if (environmentName === 'client') {
80
+ return isClientRouting ? virtualFileIdGlobalEntryClientCR : virtualFileIdGlobalEntryClientSR;
90
81
  }
82
+ assert(!isClientRouting);
83
+ if (environmentName === 'server')
84
+ return virtualFileIdGlobalEntryServer;
85
+ return `${virtualFileIdGlobalEntryPrefix}${environmentName}`;
91
86
  }
92
87
  if (args.type === 'page-entry') {
93
- const { pageId, isForClientSide } = args;
88
+ const { pageId, environmentName } = args;
94
89
  const pageIdSerialized = serializePageId(pageId);
95
- const id = `${isForClientSide ? virtualFileIdPageEntryClient : virtualFileIdPageEntryServer}${pageIdSerialized}`;
96
- return id;
90
+ assert(isEnvironmentNameValid(environmentName));
91
+ return `${virtualFileIdPageEntryPrefix}${environmentName}:${pageIdSerialized}`;
97
92
  }
98
93
  assert(false);
99
94
  }
95
+ // The global entry of an additional environment (e.g. `rsc`)
96
+ function generateVirtualFileIdAdditionalEnvironment(environmentName) {
97
+ assert(!isEnvironmentBuiltIn(environmentName));
98
+ return generateVirtualFileId({ type: 'global-entry', environmentName });
99
+ }
100
100
  // Workaround:
101
101
  // - We replace virtual:vike:page-entry:client:/ with virtual:vike:page-entry:client:ROOT
102
102
  // - In order to avoid Vite to replace `virtual:vike:page-entry:client:/` with `virtual:vike:page-entry:client:`
@@ -211,7 +211,7 @@ type OnRenderHtmlAsync = (pageContext: PageContextServer) => Promise<OnRenderHtm
211
211
  * - https://vike.dev/onRenderHtml
212
212
  */
213
213
  type OnRenderHtmlSync = (pageContext: PageContextServer) => OnRenderHtmlReturn;
214
- type OnRenderHtmlReturn = DocumentHtml | {
214
+ type OnRenderHtmlReturn = DocumentHtml | void | {
215
215
  injectFilter?: (assets: InjectFilterEntry[]) => void;
216
216
  documentHtml?: DocumentHtml;
217
217
  pageContext?: OnRenderHtmlPageContextReturn | (() => Promise<OnRenderHtmlPageContextReturn> | OnRenderHtmlPageContextReturn);
@@ -78,19 +78,27 @@ type VirtualFileExportsPageEntry = {
78
78
  *
79
79
  * https://vike.dev/meta
80
80
  */
81
- type ConfigEnv = ({
81
+ type ConfigEnv = {
82
82
  /** Load value on the client-side */
83
83
  client?: boolean;
84
- } | {
85
- /** @experimental */
86
- client?: 'if-client-routing';
87
- }) & {
88
84
  /** Load value on the server-side */
89
85
  server?: boolean;
90
86
  /** Load value for config files */
91
87
  config?: boolean;
92
88
  /** Load value only in production (`true`), or only in development (`false`), or always (`undefined`). */
93
89
  production?: boolean;
90
+ /** Load value on the client-side only if the page uses Client Routing
91
+ *
92
+ * @experimental
93
+ */
94
+ clientRoutingOnly?: boolean;
95
+ /** Load value in an additional Vike environment, e.g. `rsc`
96
+ *
97
+ * @experimental
98
+ *
99
+ * https://vike.dev/meta#vike-environments
100
+ */
101
+ [environmentName: string]: boolean | undefined;
94
102
  };
95
103
  type ConfigValueSources = Record<string, // configName
96
104
  ConfigValueSource[]>;