vike 0.4.267 → 0.4.268-commit-45c1759

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 +2 -0
  4. package/dist/client/__internal/index.js +3 -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 +26 -2
  8. package/dist/client/runtime-client-routing/getPageContextFromHooks.js +4 -5
  9. package/dist/client/runtime-client-routing/renderPageClient.d.ts +481 -10
  10. package/dist/client/runtime-client-routing/renderPageClient.js +116 -41
  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 +0 -2
  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
@@ -16,6 +16,8 @@ export { isStreamReadableNode };
16
16
  export { getStreamName };
17
17
  export { inferStreamName };
18
18
  export { streamReadableWebToString };
19
+ export { streamReadableWebToBytes };
20
+ export { awaitFirstChunk };
19
21
  export { streamPipeNodeToString };
20
22
  export { isStreamWritableWeb };
21
23
  export { isStreamWritableNode };
@@ -74,9 +76,60 @@ async function streamReadableWebToString(readableWeb) {
74
76
  str += getClosingChunk();
75
77
  return str;
76
78
  }
79
+ async function streamReadableWebToBytes(readableWeb) {
80
+ const reader = readableWeb.getReader();
81
+ const chunks = [];
82
+ while (true) {
83
+ const { done, value } = await reader.read();
84
+ if (done)
85
+ break;
86
+ assertUsage(value instanceof Uint8Array, `The stream emitted a chunk that isn't a Uint8Array: ${String(value)}`);
87
+ chunks.push(value);
88
+ }
89
+ const bytes = new Uint8Array(chunks.reduce((len, chunk) => len + chunk.length, 0));
90
+ let offset = 0;
91
+ for (const chunk of chunks) {
92
+ bytes.set(chunk, offset);
93
+ offset += chunk.length;
94
+ }
95
+ return bytes;
96
+ }
97
+ // Resolves after the first chunk (rejects if the stream errors before), then reads on demand
98
+ async function awaitFirstChunk(stream, onErrorWhileStreaming) {
99
+ const reader = stream.getReader();
100
+ const firstChunk = await reader.read();
101
+ const streamStarted = new ReadableStream({
102
+ start(controller) {
103
+ if (firstChunk.done)
104
+ controller.close();
105
+ else
106
+ controller.enqueue(firstChunk.value);
107
+ },
108
+ async pull(controller) {
109
+ let chunk;
110
+ try {
111
+ chunk = await reader.read();
112
+ }
113
+ catch (err) {
114
+ onErrorWhileStreaming(err);
115
+ controller.error(err);
116
+ return;
117
+ }
118
+ if (chunk.done)
119
+ controller.close();
120
+ else
121
+ controller.enqueue(chunk.value);
122
+ },
123
+ cancel(reason) {
124
+ return reader.cancel(reason);
125
+ },
126
+ });
127
+ return streamStarted;
128
+ }
77
129
  async function stringToStreamReadableNode(str) {
78
130
  const { Readable } = await loadStreamNodeModule();
79
- return Readable.from(str);
131
+ // Readable.from() iterates a Uint8Array byte by byte
132
+ return Readable.from(typeof str === 'string' ? str : [str]);
80
133
  }
81
134
  async function streamReadableWebToStreamReadableNode(stream) {
82
135
  const { Readable } = await loadStreamNodeModule();
@@ -156,16 +209,19 @@ function streamPipeWebToString(streamPipeWeb) {
156
209
  return promise;
157
210
  }
158
211
  async function getStreamReadableNode(htmlRender) {
159
- if (typeof htmlRender === 'string') {
212
+ if (typeof htmlRender === 'string' || htmlRender instanceof Uint8Array) {
160
213
  return stringToStreamReadableNode(htmlRender);
161
214
  }
162
215
  if (isStreamReadableNode(htmlRender)) {
163
216
  return htmlRender;
164
217
  }
218
+ if (isStreamReadableWeb(htmlRender)) {
219
+ return streamReadableWebToStreamReadableNode(htmlRender);
220
+ }
165
221
  return null;
166
222
  }
167
223
  function getStreamReadableWeb(htmlRender) {
168
- if (typeof htmlRender === 'string') {
224
+ if (typeof htmlRender === 'string' || htmlRender instanceof Uint8Array) {
169
225
  return stringToStreamReadableWeb(htmlRender);
170
226
  }
171
227
  if (isStreamReadableWeb(htmlRender)) {
@@ -178,16 +234,30 @@ function getStreamReadableWeb(htmlRender) {
178
234
  streamPipeWeb(writable);
179
235
  return readable;
180
236
  }
181
- return null;
237
+ if (isStreamReadableNode(htmlRender) || isStreamPipeNode(htmlRender)) {
238
+ // A Node.js stream implies that Node.js's `stream` module is available
239
+ const { readable, writable } = new TransformStream();
240
+ loadStreamNodeModule().then(({ Readable, PassThrough }) => {
241
+ const passThrough = new PassThrough();
242
+ pipeToStreamWritableNode(htmlRender, passThrough);
243
+ Readable.toWeb(passThrough)
244
+ .pipeTo(writable)
245
+ .catch(() => { });
246
+ });
247
+ return readable;
248
+ }
249
+ checkType(htmlRender);
250
+ assert(false);
182
251
  }
183
252
  function pipeToStreamWritableWeb(htmlRender, writable) {
184
- if (typeof htmlRender === 'string') {
253
+ if (typeof htmlRender === 'string' || htmlRender instanceof Uint8Array) {
185
254
  const streamPipeWeb = stringToStreamPipeWeb(htmlRender);
186
255
  streamPipeWeb(writable);
187
256
  return true;
188
257
  }
189
258
  if (isStreamReadableWeb(htmlRender)) {
190
- htmlRender.pipeTo(writable);
259
+ // pipeTo() propagates a failure of either side to the other side
260
+ htmlRender.pipeTo(writable).catch(() => { });
191
261
  return true;
192
262
  }
193
263
  if (isStreamPipeWeb(htmlRender)) {
@@ -203,23 +273,30 @@ function pipeToStreamWritableWeb(htmlRender, writable) {
203
273
  assert(false);
204
274
  }
205
275
  function pipeToStreamWritableNode(htmlRender, writable) {
206
- if (typeof htmlRender === 'string') {
276
+ if (typeof htmlRender === 'string' || htmlRender instanceof Uint8Array) {
207
277
  const streamPipeNode = stringToStreamPipeNode(htmlRender);
208
278
  streamPipeNode(writable);
209
279
  return true;
210
280
  }
211
- if (isStreamReadableNode(htmlRender)) {
212
- htmlRender.pipe(writable);
213
- return true;
214
- }
215
281
  if (isStreamPipeNode(htmlRender)) {
216
282
  const streamPipeNode = getStreamPipeNode(htmlRender);
217
283
  assert(streamPipeNode);
218
284
  streamPipeNode(writable);
219
285
  return true;
220
286
  }
221
- if (isStreamReadableWeb(htmlRender)) {
222
- streamReadableWebToStreamReadableNode(htmlRender).then((s) => s.pipe(writable));
287
+ if (isStreamReadableNode(htmlRender) || isStreamReadableWeb(htmlRender)) {
288
+ getStreamReadableNode(htmlRender).then(async (readable) => {
289
+ assert(readable);
290
+ const { pipeline } = await loadStreamNodeModule();
291
+ // pipeline() throws if the writable is already destroyed (e.g. the client left before the first chunk)
292
+ if (writable.destroyed)
293
+ return readable.destroy();
294
+ // Unlike pipe(), pipeline() destroys the readable if the writable closes early, and the writable if the readable errors or closes before its end
295
+ pipeline(readable, writable, () => { });
296
+ // E.g. compression() holds the writes until flush()
297
+ const w = writable;
298
+ readable.on('data', () => w.flush?.());
299
+ });
223
300
  return true;
224
301
  }
225
302
  if (isStreamPipeWeb(htmlRender)) {
@@ -228,7 +305,7 @@ function pipeToStreamWritableNode(htmlRender, writable) {
228
305
  checkType(htmlRender);
229
306
  assert(false);
230
307
  }
231
- async function processStream(streamOriginal, { injectStringAtBegin, injectStringAfterFirstChunk, injectStringAtEnd, onErrorWhileStreaming, enableEagerStreaming, }) {
308
+ async function processStream(streamOriginal, { injectStringAtBegin, injectStringAfterFirstChunk, injectStringAtEnd, onErrorWhileStreaming, enableEagerStreaming, onCancel, }) {
232
309
  const buffer = [];
233
310
  let streamOriginalHasStartedEmitting = false;
234
311
  let streamOriginalEnded = false;
@@ -275,6 +352,8 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
275
352
  resolveReadyToWrite();
276
353
  },
277
354
  onError(err) {
355
+ // The HTML won't end: its streamed pageContext values won't be sent
356
+ onCancel();
278
357
  if (!promiseHasResolved) {
279
358
  reject(err);
280
359
  }
@@ -303,7 +382,10 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
303
382
  streamOriginalEnded = true;
304
383
  });
305
384
  if (injectStringAtEnd && !isCancel) {
306
- const injectedChunk = await injectStringAtEnd();
385
+ const injectedChunk = await injectStringAtEnd((html) => {
386
+ writeStream(html);
387
+ flushStream();
388
+ });
307
389
  writeStream(injectedChunk);
308
390
  }
309
391
  await promiseReadyToWrite; // E.g. if the user calls the pipe wrapper after the original writable has ended
@@ -326,6 +408,7 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
326
408
  onFlush() {
327
409
  flushStream();
328
410
  },
411
+ onCancel,
329
412
  });
330
413
  wrapperCreated = true;
331
414
  flushBuffer(); // In case onReadyToWrite() was already called (the flushBuffer() of onReadyToWrite() wasn't called because `wrapperCreated === false`)
@@ -388,7 +471,7 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
388
471
  return !enableEagerStreaming && !streamOriginalHasStartedEmitting;
389
472
  }
390
473
  }
391
- async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onFlush, onReadyToWrite, }) {
474
+ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onFlush, onReadyToWrite, onCancel, }) {
392
475
  if (isStreamFromReactStreamingPackage(streamOriginal)) {
393
476
  debug(`onRenderHtml() hook returned ${pc.cyan('react-streaming')} result`);
394
477
  const stream = getStreamOfReactStreamingPackage(streamOriginal);
@@ -400,6 +483,16 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
400
483
  const pipeProxy = (writable_) => {
401
484
  writableOriginal = writable_;
402
485
  debug('original Node.js Writable received');
486
+ // Let the source know when the response closes early (no-op once it has ended)
487
+ const onClose = () => {
488
+ if (!hasEnded)
489
+ onCancel();
490
+ writableProxy.destroy();
491
+ };
492
+ if (writableOriginal.destroyed)
493
+ onClose();
494
+ else
495
+ writableOriginal.on('close', onClose);
403
496
  onReadyToWrite();
404
497
  if (hasEnded) {
405
498
  // onReadyToWrite() already wrote everything; we can close the stream right away
@@ -463,6 +556,11 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
463
556
  const pipeProxy = (writableOriginal) => {
464
557
  writerOriginal = writableOriginal.getWriter();
465
558
  debug('original Web Writable received');
559
+ // Let the source know when the response closes early
560
+ writerOriginal.closed.catch((err) => {
561
+ onCancel();
562
+ readerProxy?.cancel(err);
563
+ });
466
564
  (async () => {
467
565
  // CloudFlare Workers does not implement `ready` property
468
566
  // - https://github.com/vuejs/vue-next/issues/4287
@@ -480,7 +578,7 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
480
578
  stampPipe(pipeProxy, 'web-stream');
481
579
  const writeChunk = (chunk) => {
482
580
  assert(writerOriginal);
483
- writerOriginal.write(encodeForWebStream(chunk));
581
+ writerOriginal.write(encodeForWebStream(chunk)).catch(() => { });
484
582
  debugWithChunk('data written (Web Writable)', chunk);
485
583
  };
486
584
  // Web Streams have compression built-in
@@ -491,10 +589,11 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
491
589
  const endStream = () => {
492
590
  hasEnded = true;
493
591
  if (writerOriginal) {
494
- writerOriginal.close();
592
+ writerOriginal.close().catch(() => { });
495
593
  }
496
594
  };
497
595
  let writableProxy;
596
+ let readerProxy;
498
597
  if (typeof ReadableStream !== 'function') {
499
598
  writableProxy = new WritableStream({
500
599
  write(chunk) {
@@ -513,7 +612,8 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
513
612
  else {
514
613
  const { readable, writable } = new TransformStream();
515
614
  writableProxy = writable;
516
- handleReadableWeb(readable, {
615
+ readerProxy = readable.getReader();
616
+ handleReadableWeb(readerProxy, {
517
617
  onData,
518
618
  onError(err) {
519
619
  onError(err);
@@ -531,7 +631,7 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
531
631
  }
532
632
  if (isStreamReadableWeb(streamOriginal)) {
533
633
  debug('onRenderHtml() hook returned Web Readable');
534
- const readableOriginal = streamOriginal;
634
+ const readerOriginal = streamOriginal.getReader();
535
635
  let isClosed = false;
536
636
  let isCancel = false;
537
637
  const closeStream = async () => {
@@ -548,7 +648,7 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
548
648
  start(controller) {
549
649
  controllerProxy = controller;
550
650
  onReadyToWrite();
551
- handleReadableWeb(readableOriginal, {
651
+ handleReadableWeb(readerOriginal, {
552
652
  onData,
553
653
  onError(err) {
554
654
  onError(err);
@@ -559,18 +659,16 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
559
659
  },
560
660
  });
561
661
  },
562
- async cancel(...args) {
662
+ async cancel(reason) {
563
663
  debug('stream cancelled');
564
664
  isCancel = true;
565
- await readableOriginal.cancel(...args);
566
- // If readableOriginal has implemented readableOriginal.cancel() then the onEnd() callback and therefore closeStream() may already have been called at this point
567
- await closeStream();
665
+ onCancel();
666
+ // Ends handleReadableWeb() which then calls closeStream()
667
+ await readerOriginal.cancel(reason);
568
668
  },
569
669
  });
570
670
  const writeChunk = (chunk) => {
571
- if (!isCancel &&
572
- // If readableOriginal doesn't implement readableOriginal.cancel() then it may still emit data after we close the stream. We therefore need to check whether the steam is closed.
573
- !isClosed) {
671
+ if (!isCancel && !isClosed) {
574
672
  controllerProxy.enqueue(encodeForWebStream(chunk));
575
673
  debugWithChunk('data written (Web Readable)', chunk);
576
674
  }
@@ -603,6 +701,12 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
603
701
  readableProxy.push(null);
604
702
  };
605
703
  const readableProxy = new Readable({ read() { } });
704
+ // Destroy the source when the consumer closes early
705
+ readableProxy.once('close', () => {
706
+ if (!readableProxy.readableEnded)
707
+ onCancel();
708
+ readableOriginal.destroy();
709
+ });
606
710
  onReadyToWrite();
607
711
  readableOriginal.on('data', (chunk) => {
608
712
  onData(chunk);
@@ -622,8 +726,7 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
622
726
  }
623
727
  assert(false);
624
728
  }
625
- async function handleReadableWeb(readable, { onData, onError, onEnd, }) {
626
- const reader = readable.getReader();
729
+ async function handleReadableWeb(reader, { onData, onError, onEnd, }) {
627
730
  while (true) {
628
731
  let result;
629
732
  try {
@@ -776,8 +879,8 @@ function encodeForWebStream(thing) {
776
879
  // Because of Cloudflare Workers, we cannot statically import the `stream` module, instead we dynamically import it.
777
880
  async function loadStreamNodeModule() {
778
881
  const streamModule = (await import_('stream')).default;
779
- const { Readable, Writable } = streamModule;
780
- return { Readable, Writable };
882
+ const { Readable, Writable, PassThrough, pipeline } = streamModule;
883
+ return { Readable, Writable, PassThrough, pipeline };
781
884
  }
782
885
  function getStreamName(kind, type) {
783
886
  let typeName = capitalizeFirstLetter(type);
@@ -0,0 +1,30 @@
1
+ export { serializePageContextHtml };
2
+ export { getStreamedValuesHtml };
3
+ export { writeStreamedValuesHtmlAtStreamEnd };
4
+ export { cancelStreamedValuesHtml };
5
+ export { getStreamedValuesLinesPrerendered };
6
+ export type { PageContextStreamedValuesHtml };
7
+ import { type PageContextSerialization } from './serializeContext.js';
8
+ import type { PageContextCreatedServer } from '../createPageContextServer.js';
9
+ import type { StreamFromReactStreamingPackage } from './stream/react-streaming.js';
10
+ import { type PageContextCspNonce } from '../csp.js';
11
+ import '../../../assertEnvServer.js';
12
+ type StreamedValuesHtml = {
13
+ done: Promise<void>;
14
+ cancel: () => void;
15
+ /** The `<script>` tags not sent yet */
16
+ pending: string[];
17
+ /** Set once the HTML stream is ending */
18
+ writeHtml: null | ((html: string) => void);
19
+ /** Pre-rendering: all lines */
20
+ lines: null | string[];
21
+ };
22
+ type PageContextStreamedValuesHtml = PageContextCreatedServer & PageContextCspNonce & {
23
+ _requestId: number;
24
+ _streamedValuesHtml?: StreamedValuesHtml;
25
+ };
26
+ declare function serializePageContextHtml(pageContext: PageContextStreamedValuesHtml & PageContextSerialization, streamFromReactStreamingPackage: null | StreamFromReactStreamingPackage): string;
27
+ declare function getStreamedValuesHtml(pageContext: PageContextStreamedValuesHtml): Promise<null | string>;
28
+ declare function writeStreamedValuesHtmlAtStreamEnd(pageContext: PageContextStreamedValuesHtml, htmlEnd: string, writeHtml: (html: string) => void): Promise<string>;
29
+ declare function cancelStreamedValuesHtml(pageContext: PageContextStreamedValuesHtml): void;
30
+ declare function getStreamedValuesLinesPrerendered(pageContext: PageContextStreamedValuesHtml): Promise<null | string[]>;
@@ -0,0 +1,92 @@
1
+ // The streamed pageContext values (see shared-server-client/streamedValues.ts) of the HTML's
2
+ // `<script id="vike_pageContext">`: each line is sent as a `<script>` that pushes it to `self.__vike_streamed` (read by
3
+ // Vike's client runtime, see client/shared/streamedValues.ts).
4
+ // - HTML stream of react-streaming: the lines are injected into the stream as they're produced.
5
+ // - HTML stream: the lines produced while the stream is running are sent after it ends, and the lines produced
6
+ // afterwards are sent as they're produced; the HTML ends once all values have ended.
7
+ // - HTML string: the lines are appended to the HTML once all values have ended.
8
+ // - Pre-rendering: the lines are also collected for `index.pageContext.json`, so that the values are read once.
9
+ export { serializePageContextHtml };
10
+ export { getStreamedValuesHtml };
11
+ export { writeStreamedValuesHtmlAtStreamEnd };
12
+ export { cancelStreamedValuesHtml };
13
+ export { getStreamedValuesLinesPrerendered };
14
+ import { assert } from '../../../../utils/assert.js';
15
+ import { pumpStreamedValues } from '../streamedValues/pump.js';
16
+ import { getPageContextClientSerialized } from './serializeContext.js';
17
+ import { inferNonceAttr } from '../csp.js';
18
+ import '../../../assertEnvServer.js';
19
+ // The pageContext of `<script id="vike_pageContext">`, as `[pageContext]` if it has streamed values (which start streaming)
20
+ function serializePageContextHtml(pageContext, streamFromReactStreamingPackage) {
21
+ const { pageContextSerialized, streamedValues } = getPageContextClientSerialized(pageContext, true);
22
+ if (streamedValues.length === 0)
23
+ return pageContextSerialized;
24
+ // The pageContext is serialized once per HTML
25
+ assert(!pageContext._streamedValuesHtml);
26
+ const { isPrerendering } = pageContext;
27
+ const write = (line) => {
28
+ streamedValuesHtml.lines?.push(line);
29
+ const script = getScript(line, pageContext);
30
+ if (streamedValuesHtml.writeHtml) {
31
+ streamedValuesHtml.writeHtml(script);
32
+ }
33
+ else if (streamFromReactStreamingPackage && !streamFromReactStreamingPackage.hasStreamEnded()) {
34
+ streamFromReactStreamingPackage.injectToStream(script, { flush: true });
35
+ }
36
+ else {
37
+ streamedValuesHtml.pending.push(script);
38
+ }
39
+ };
40
+ const streamedValuesHtml = {
41
+ // A pre-rendered page can't have a failed value
42
+ ...pumpStreamedValues(pageContext, streamedValues, write, { failFast: isPrerendering }),
43
+ pending: [],
44
+ writeHtml: null,
45
+ lines: isPrerendering ? [] : null,
46
+ };
47
+ // Pre-rendering: the error is thrown by getStreamedValuesLinesPrerendered()
48
+ streamedValuesHtml.done.catch(() => { });
49
+ pageContext._streamedValuesHtml = streamedValuesHtml;
50
+ return `[${pageContextSerialized}]`;
51
+ }
52
+ // HTML string
53
+ async function getStreamedValuesHtml(pageContext) {
54
+ const streamedValuesHtml = pageContext._streamedValuesHtml;
55
+ if (!streamedValuesHtml)
56
+ return null;
57
+ await streamedValuesHtml.done.catch(() => { });
58
+ return streamedValuesHtml.pending.join('');
59
+ }
60
+ // HTML stream: `htmlEnd` is what Vike appends after the HTML stream ended. The lines are sent before `</body>`.
61
+ async function writeStreamedValuesHtmlAtStreamEnd(pageContext, htmlEnd, writeHtml) {
62
+ const streamedValuesHtml = pageContext._streamedValuesHtml;
63
+ if (!streamedValuesHtml)
64
+ return htmlEnd;
65
+ let i = htmlEnd.lastIndexOf('</body>');
66
+ if (i === -1)
67
+ i = htmlEnd.length;
68
+ writeHtml(htmlEnd.slice(0, i) + streamedValuesHtml.pending.join(''));
69
+ streamedValuesHtml.writeHtml = writeHtml;
70
+ await streamedValuesHtml.done.catch(() => { });
71
+ return htmlEnd.slice(i);
72
+ }
73
+ // The HTML response was cancelled (e.g. the user closed the tab) or failed
74
+ function cancelStreamedValuesHtml(pageContext) {
75
+ pageContext._streamedValuesHtml?.cancel();
76
+ }
77
+ // Pre-rendering: the lines for `index.pageContext.json` (the values are read once, while rendering the HTML)
78
+ async function getStreamedValuesLinesPrerendered(pageContext) {
79
+ const streamedValuesHtml = pageContext._streamedValuesHtml;
80
+ if (!streamedValuesHtml)
81
+ return null;
82
+ await streamedValuesHtml.done;
83
+ assert(streamedValuesHtml.lines);
84
+ return streamedValuesHtml.lines;
85
+ }
86
+ function getScript(line, pageContext) {
87
+ // A JavaScript string literal: JSON.stringify() escapes quotes, backslashes and line breaks; `<` is escaped so that the
88
+ // script never contains `</script>` nor `<!--`; `/` is escaped for the same reason as in `<script id="vike_pageContext">`
89
+ // (https://github.com/vikejs/vike/pull/2603)
90
+ const literal = JSON.stringify(line).replaceAll('<', '\\u003c').replaceAll('/', '\\/');
91
+ return `<script${inferNonceAttr(pageContext)}>(self.__vike_streamed=self.__vike_streamed||[]).push(${literal})</script>`;
92
+ }
@@ -23,12 +23,6 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
23
23
  isPrerendering: boolean;
24
24
  _requestId: number;
25
25
  } & import("../renderPageServer.js").PageContextInit & {
26
- _nodeDev?: {
27
- req: import("http").IncomingMessage;
28
- res: import("http").ServerResponse;
29
- };
30
- _reqWeb?: Request;
31
- } & {
32
26
  _globalContext: ({
33
27
  config: import("../../../types/index.js").ConfigResolved;
34
28
  _source: import("../../../shared-server-client/page-configs/resolveVikeConfigPublic.js").Source;
@@ -52,6 +46,10 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
52
46
  _pageFilesAll: import("../../../shared-server-client/getPageFiles.js").PageFile[];
53
47
  _pageConfigs: PageConfigRuntime[];
54
48
  _pageConfigGlobal: import("../../../types/PageConfig.js").PageConfigGlobalRuntime;
49
+ _environmentEntries: Record<string, {
50
+ pageConfigs: PageConfigRuntime[];
51
+ pageConfigGlobal: import("../../../types/PageConfig.js").PageConfigGlobalRuntime;
52
+ } | null>;
55
53
  _allPageIds: string[];
56
54
  } & (({
57
55
  isClientSide: false;
@@ -61,6 +59,7 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
61
59
  _isPrerendering: false;
62
60
  assetsManifest: null;
63
61
  _viteDevServer: import("vite").ViteDevServer | undefined;
62
+ devMiddleware: import("vite").Connect.Server | null;
64
63
  viteConfig: import("vite").ResolvedConfig | undefined;
65
64
  } | {
66
65
  isClientSide: false;
@@ -69,6 +68,7 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
69
68
  _isProduction: true;
70
69
  assetsManifest: import("../../../types/ViteManifest.js").ViteManifest;
71
70
  _viteDevServer: null;
71
+ devMiddleware: null;
72
72
  _usesClientRouter: boolean;
73
73
  _isPrerendering: true;
74
74
  viteConfig: import("vite").ResolvedConfig;
@@ -79,12 +79,11 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
79
79
  _isProduction: true;
80
80
  assetsManifest: import("../../../types/ViteManifest.js").ViteManifest;
81
81
  _viteDevServer: null;
82
+ devMiddleware: null;
82
83
  _usesClientRouter: boolean;
83
84
  _isPrerendering: false;
84
85
  viteConfig: null;
85
86
  }) & {
86
- baseServer: string;
87
- baseAssets: string;
88
87
  viteConfigRuntime: {
89
88
  root: string;
90
89
  build: {
@@ -95,6 +94,9 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
95
94
  inject: boolean | undefined;
96
95
  };
97
96
  };
97
+ baseServer: string;
98
+ baseAssets: string;
99
+ middlewares: import("../universal-middleware/core.js").Middleware[];
98
100
  })) & {
99
101
  prerenderContext: import("../../../types/index.js").PrerenderContext | undefined;
100
102
  };
@@ -102,12 +104,6 @@ declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPage
102
104
  _baseServer: string;
103
105
  _baseAssets: string;
104
106
  _pageContextInit: import("../renderPageServer.js").PageContextInit & {
105
- _nodeDev?: {
106
- req: import("http").IncomingMessage;
107
- res: import("http").ServerResponse;
108
- };
109
- _reqWeb?: Request;
110
- } & {
111
107
  headers?: Record<string, unknown>;
112
108
  };
113
109
  _urlHandler: ((url: string) => string) | null;
@@ -15,6 +15,7 @@ import { loadAndParseVirtualFilePageEntry } from '../../../shared-server-client/
15
15
  import { execHookServer } from './execHookServer.js';
16
16
  import { resolveHeadersResponseEarly } from './headersResponse.js';
17
17
  import { resolvePageContextCspNone } from './csp.js';
18
+ import { loadPageContextEnvironments } from './loadPageContextEnvironments.js';
18
19
  import '../../assertEnvServer.js';
19
20
  async function loadPageConfigsLazyServerSide(pageContext) {
20
21
  objectAssign(pageContext, {
@@ -109,7 +110,7 @@ async function resolvePageContext(pageContext) {
109
110
  return pageContext;
110
111
  }
111
112
  async function loadPageUserFiles(pageContext) {
112
- const [{ pageContextAddendum }] = await Promise.all([
113
+ const [{ pageContextAddendum }, pageContextEnvironments] = await Promise.all([
113
114
  (async () => {
114
115
  const pageFilesServerSide = getPageFilesServerSide(pageContext._pageFilesAll, pageContext.pageId);
115
116
  const isDev = !pageContext._globalContext._isProduction;
@@ -120,9 +121,12 @@ async function loadPageUserFiles(pageContext) {
120
121
  const pageContextAddendum = resolvePageContextConfig(pageFilesServerSide, pageConfigLoaded, pageContext._globalContext._pageConfigGlobal);
121
122
  return { pageContextAddendum };
122
123
  })(),
124
+ pageContext._pageConfig && loadPageContextEnvironments(pageContext),
123
125
  analyzePageClientSideInit(pageContext._globalContext._pageFilesAll, pageContext.pageId, {
124
126
  sharedPageFilesAlreadyLoaded: true,
125
127
  }),
126
128
  ]);
129
+ if (pageContextEnvironments)
130
+ objectAssign(pageContextAddendum, pageContextEnvironments);
127
131
  return pageContextAddendum;
128
132
  }
@@ -0,0 +1,15 @@
1
+ export { loadPageContextEnvironments };
2
+ import type { GlobalContextServerInternal } from '../globalContext.js';
3
+ import type { PageContextPublicMinimum } from '../../../shared-server-client/getPageContextPublicShared.js';
4
+ import '../../assertEnvServer.js';
5
+ declare function loadPageContextEnvironments(pageContext: PageContextPublicMinimum & {
6
+ pageId: string;
7
+ _globalContext: GlobalContextServerInternal;
8
+ }): Promise<{
9
+ environments: {
10
+ [k: string]: {
11
+ config: import("../../../types/index.js").ConfigResolved;
12
+ pageContext: object;
13
+ };
14
+ };
15
+ }>;
@@ -0,0 +1,61 @@
1
+ export { loadPageContextEnvironments };
2
+ import { resolvePageContextConfig } from '../../../shared-server-client/page-configs/resolveVikeConfigPublic.js';
3
+ import { parseGlobalEntryPageConfigs, } from '../../../shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js';
4
+ import { findPageConfig } from '../../../shared-server-client/page-configs/findPageConfig.js';
5
+ import { loadAndParseVirtualFilePageEntry } from '../../../shared-server-client/page-configs/loadAndParseVirtualFilePageEntry.js';
6
+ import { generateVirtualFileIdAdditionalEnvironment } from '../../../shared-server-node/virtualFileId.js';
7
+ import { isRunnableDevEnvironment } from '../../../utils/isRunnableDevEnvironment.js';
8
+ import { assert, assertUsage } from '../../../utils/assert.js';
9
+ import { getPageContextPublicServer } from './getPageContextPublicServer.js';
10
+ import '../../assertEnvServer.js';
11
+ // Additional environments (e.g. `rsc`) run in the same runtime as the server environment => their functions can be called directly
12
+ // - `pageContext.environments[environmentName]` holds the environment's config values and its view of pageContext, which its functions are called with
13
+ async function loadPageContextEnvironments(pageContext) {
14
+ const environmentEntries = pageContext._globalContext._environmentEntries;
15
+ const environments = Object.fromEntries(await Promise.all(Object.entries(environmentEntries).map(async ([environmentName, environmentEntry]) => {
16
+ const pageContextConfigEnv = await loadPageContextConfig(pageContext, environmentName, environmentEntry);
17
+ const environment = {
18
+ config: pageContextConfigEnv.config,
19
+ pageContext: getPageContextEnvView(getPageContextPublicServer(pageContext), pageContextConfigEnv),
20
+ };
21
+ return [environmentName, environment];
22
+ })));
23
+ const pageContextEnvironments = { environments };
24
+ return pageContextEnvironments;
25
+ }
26
+ // The same pageContext object, except for the config values (and what's derived from them) which are the environment's
27
+ function getPageContextEnvView(pageContext, pageContextConfig) {
28
+ // TO-DO/soon/flat-pageContext make this clean using same mechanism as [Flat `pageContext`](https://github.com/vikejs/vike/issues/1268)
29
+ return new Proxy(pageContext, {
30
+ get(target, prop) {
31
+ if (prop === 'Page')
32
+ return pageContextConfig.exports.Page;
33
+ if (prop in pageContextConfig)
34
+ return pageContextConfig[prop];
35
+ return Reflect.get(target, prop);
36
+ },
37
+ });
38
+ }
39
+ async function loadPageContextConfig(pageContext, environmentName, environmentEntry) {
40
+ const globalContext = pageContext._globalContext;
41
+ const { pageConfigs, pageConfigGlobal } = await importEnvironmentEntry(globalContext, environmentName, environmentEntry);
42
+ const pageConfig = findPageConfig(pageConfigs, pageContext.pageId);
43
+ assert(pageConfig);
44
+ const pageConfigLoaded = await loadAndParseVirtualFilePageEntry(pageConfig, !globalContext._isProduction);
45
+ return resolvePageContextConfig([], pageConfigLoaded, pageConfigGlobal);
46
+ }
47
+ async function importEnvironmentEntry(globalContext, environmentName, environmentEntry) {
48
+ if (environmentEntry) {
49
+ // Prod
50
+ assert(globalContext._isProduction);
51
+ return environmentEntry;
52
+ }
53
+ else {
54
+ // Dev
55
+ assert(!globalContext._isProduction);
56
+ const environment = globalContext._viteDevServer?.environments[environmentName];
57
+ assertUsage(isRunnableDevEnvironment(environment), `The Vike environment ${environmentName} should be a server-side environment running in the same runtime (process or worker) as Vike's server`);
58
+ const virtualFileId = generateVirtualFileIdAdditionalEnvironment(environmentName);
59
+ return parseGlobalEntryPageConfigs(await environment.runner.import(virtualFileId));
60
+ }
61
+ }