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.
- package/RenderErrorPage.js +2 -2
- package/abort.js +2 -2
- package/dist/client/__internal/index.d.ts +2 -0
- package/dist/client/__internal/index.js +3 -0
- package/dist/client/runtime-client-routing/createPageContextClient.d.ts +5 -0
- package/dist/client/runtime-client-routing/getGlobalContextClientInternal.d.ts +5 -0
- package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +26 -2
- package/dist/client/runtime-client-routing/getPageContextFromHooks.js +4 -5
- package/dist/client/runtime-client-routing/renderPageClient.d.ts +481 -10
- package/dist/client/runtime-client-routing/renderPageClient.js +116 -41
- package/dist/client/runtime-client-routing/streamedValues.d.ts +5 -0
- package/dist/client/runtime-client-routing/streamedValues.js +23 -0
- package/dist/client/runtime-server-routing/createPageContextClient.d.ts +5 -0
- package/dist/client/runtime-server-routing/entry.js +1 -1
- package/dist/client/runtime-server-routing/getGlobalContextClientInternal.d.ts +5 -0
- package/dist/client/shared/getGlobalContextClientInternalShared.d.ts +5 -0
- package/dist/client/shared/getGlobalContextClientInternalShared.js +2 -0
- package/dist/client/shared/getJsonSerializedInHtml.d.ts +2 -2
- package/dist/client/shared/getJsonSerializedInHtml.js +9 -6
- package/dist/client/shared/loadPageConfigsLazyClientSide.js +0 -4
- package/dist/client/shared/removeFoucBuster.js +14 -3
- package/dist/client/shared/streamedValues/asyncIterable.d.ts +4 -0
- package/dist/client/shared/streamedValues/asyncIterable.js +26 -0
- package/dist/client/shared/streamedValues/lines.d.ts +11 -0
- package/dist/client/shared/streamedValues/lines.js +19 -0
- package/dist/client/shared/streamedValues/promise.d.ts +4 -0
- package/dist/client/shared/streamedValues/promise.js +19 -0
- package/dist/client/shared/streamedValues/readableStream.d.ts +4 -0
- package/dist/client/shared/streamedValues/readableStream.js +44 -0
- package/dist/client/shared/streamedValues/registry.d.ts +21 -0
- package/dist/client/shared/streamedValues/registry.js +40 -0
- package/dist/client/shared/streamedValues.d.ts +7 -0
- package/dist/client/shared/streamedValues.js +82 -0
- package/dist/node/api/dev.js +15 -1
- package/dist/node/api/resolveViteConfigUser.js +2 -2
- package/dist/node/api/serverEntryDev.d.ts +10 -0
- package/dist/node/api/serverEntryDev.js +125 -0
- package/dist/node/createDevMiddleware.js +12 -0
- package/dist/node/prerender/resolvePrerenderConfig.d.ts +1 -1
- package/dist/node/prerender/resolvePrerenderConfig.js +4 -1
- package/dist/node/prerender/runPrerender.d.ts +18 -18
- package/dist/node/prerender/runPrerender.js +61 -16
- package/dist/node/vite/assertEnvVite.js +1 -1
- package/dist/node/vite/index.js +2 -0
- package/dist/node/vite/plugins/build/handleAssetsManifest.js +6 -2
- package/dist/node/vite/plugins/build/pluginBuildApp.js +25 -26
- package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +2 -2
- package/dist/node/vite/plugins/build/pluginBuildConfig.js +25 -17
- package/dist/node/vite/plugins/build/pluginDistFileNames.js +70 -50
- package/dist/node/vite/plugins/build/pluginEnvironmentEntries.d.ts +6 -0
- package/dist/node/vite/plugins/build/pluginEnvironmentEntries.js +71 -0
- package/dist/node/vite/plugins/build/pluginSuppressRollupWarning.js +19 -17
- package/dist/node/vite/plugins/pluginCommon.js +10 -7
- package/dist/node/vite/plugins/pluginDev/optimizeDeps.d.ts +2 -2
- package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +6 -2
- package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +6 -4
- package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.d.ts +3 -0
- package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.js +28 -2
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.d.ts +1 -1
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.js +22 -11
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.d.ts +4 -0
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.js +29 -0
- package/dist/node/vite/plugins/pluginUniversalDeploy.js +29 -5
- package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.d.ts +2 -1
- package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +29 -12
- package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -2
- package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +7 -7
- package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +10 -6
- package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js +5 -11
- package/dist/node/vite/plugins/pluginVirtualFiles.js +20 -0
- package/dist/node/vite/shared/addSsrMiddleware.js +11 -27
- package/dist/node/vite/shared/findPageFiles.d.ts +1 -1
- package/dist/node/vite/shared/findPageFiles.js +1 -11
- package/dist/node/vite/shared/getAssetsDir.d.ts +3 -2
- package/dist/node/vite/shared/getAssetsDir.js +3 -3
- package/dist/node/vite/shared/isViteCli.d.ts +3 -3
- package/dist/node/vite/shared/isViteCli.js +80 -84
- package/dist/node/vite/shared/isViteServerSide.js +2 -7
- package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +6 -4
- package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +17 -6
- package/dist/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +9 -2
- package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +5 -1
- package/dist/node/vite/shared/resolveVikeConfigInternal.js +86 -13
- package/dist/server/__internal/fetch-deprecated.d.ts +2 -0
- package/dist/server/__internal/fetch-deprecated.js +6 -0
- package/dist/server/__internal/fetch.d.ts +9 -0
- package/dist/server/__internal/fetch.js +5 -0
- package/dist/server/__internal/index.d.ts +4 -0
- package/dist/server/__internal/index.js +8 -0
- package/dist/server/createPageRenderer.d.ts +2 -2
- package/dist/server/createPageRenderer.js +2 -2
- package/dist/server/runtime/createDevMiddleware.js +3 -1
- package/dist/server/runtime/globalContext.d.ts +69 -10
- package/dist/server/runtime/globalContext.js +35 -2
- package/dist/server/runtime/index.d.ts +1 -1
- package/dist/server/runtime/index.js +1 -1
- package/dist/server/runtime/renderPageServer/analyzePage.js +3 -3
- package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +20 -9
- package/dist/server/runtime/renderPageServer/createHttpResponse.js +34 -21
- package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +13 -23
- package/dist/server/runtime/renderPageServer/csp.d.ts +2 -1
- package/dist/server/runtime/renderPageServer/csp.js +2 -1
- package/dist/server/runtime/renderPageServer/execHookOnError.js +1 -1
- package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.d.ts +9 -0
- package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.js +21 -9
- package/dist/server/runtime/renderPageServer/getHttpResponseBody.d.ts +2 -2
- package/dist/server/runtime/renderPageServer/getHttpResponseBody.js +19 -12
- package/dist/server/runtime/renderPageServer/getPageContextJson.d.ts +8 -0
- package/dist/server/runtime/renderPageServer/getPageContextJson.js +47 -0
- package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +2 -0
- package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +1 -1
- package/dist/server/runtime/renderPageServer/handlePageContextRequestUrl.js +2 -2
- package/dist/server/runtime/renderPageServer/headersResponse.d.ts +11 -2
- package/dist/server/runtime/renderPageServer/headersResponse.js +22 -2
- package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +5 -4
- package/dist/server/runtime/renderPageServer/html/injectAssets.d.ts +3 -2
- package/dist/server/runtime/renderPageServer/html/injectAssets.js +7 -1
- package/dist/server/runtime/renderPageServer/html/renderHtml.js +4 -2
- package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +5 -1
- package/dist/server/runtime/renderPageServer/html/serializeContext.js +12 -9
- package/dist/server/runtime/renderPageServer/html/stream.d.ts +13 -6
- package/dist/server/runtime/renderPageServer/html/stream.js +135 -32
- package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.d.ts +30 -0
- package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.js +92 -0
- package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +10 -14
- package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.js +5 -1
- package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.d.ts +15 -0
- package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.js +61 -0
- package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +320 -55
- package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +21 -12
- package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.d.ts +4 -0
- package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.js +12 -0
- package/dist/server/runtime/renderPageServer/streamedValues/lines.d.ts +10 -0
- package/dist/server/runtime/renderPageServer/streamedValues/lines.js +49 -0
- package/dist/server/runtime/renderPageServer/streamedValues/promise.d.ts +4 -0
- package/dist/server/runtime/renderPageServer/streamedValues/promise.js +14 -0
- package/dist/server/runtime/renderPageServer/streamedValues/pump.d.ts +10 -0
- package/dist/server/runtime/renderPageServer/streamedValues/pump.js +67 -0
- package/dist/server/runtime/renderPageServer/streamedValues/readableStream.d.ts +4 -0
- package/dist/server/runtime/renderPageServer/streamedValues/readableStream.js +12 -0
- package/dist/server/runtime/renderPageServer/streamedValues/registry.d.ts +28 -0
- package/dist/server/runtime/renderPageServer/streamedValues/registry.js +33 -0
- package/dist/server/runtime/renderPageServer.d.ts +65 -18
- package/dist/server/runtime/renderPageServer.js +33 -62
- package/dist/server/runtime/universal-middleware/core.d.ts +25 -0
- package/dist/server/runtime/universal-middleware/core.js +167 -0
- package/dist/server/runtime/universal-middleware/deprecated-export.d.ts +3 -0
- package/dist/server/runtime/universal-middleware/deprecated-export.js +10 -0
- package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.d.ts +15 -0
- package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.js +51 -0
- package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.d.ts +9 -0
- package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.js +22 -0
- package/dist/shared-server-client/createGlobalContextShared.d.ts +8 -0
- package/dist/shared-server-client/createGlobalContextShared.js +2 -1
- package/dist/shared-server-client/getPageContextPublicShared.js +0 -2
- package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.d.ts +8 -0
- package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js +17 -7
- package/dist/shared-server-client/hooks/execHook.d.ts +1 -1
- package/dist/shared-server-client/hooks/execHook.js +2 -2
- package/dist/shared-server-client/page-configs/serialize/serializeConfigValues.js +2 -0
- package/dist/shared-server-client/route/abort.d.ts +1 -1
- package/dist/shared-server-client/route/abort.js +4 -2
- package/dist/shared-server-client/streamedValues.d.ts +22 -0
- package/dist/shared-server-client/streamedValues.js +24 -0
- package/dist/shared-server-node/vike-environments.d.ts +4 -0
- package/dist/shared-server-node/vike-environments.js +10 -0
- package/dist/shared-server-node/virtualFileId.d.ts +7 -5
- package/dist/shared-server-node/virtualFileId.js +42 -42
- package/dist/types/Config.d.ts +11 -3
- package/dist/types/GlobalContext.d.ts +3 -3
- package/dist/types/PageConfig.d.ts +13 -5
- package/dist/types/PageContext.d.ts +18 -10
- package/dist/types/PageContext.js +1 -0
- package/dist/types/Server.d.ts +1 -1
- package/dist/types/VikeNamespace.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/utils/PROJECT_VERSION.js +1 -1
- package/dist/utils/assertViteVersion.d.ts +1 -3
- package/dist/utils/assertViteVersion.js +6 -9
- package/dist/utils/catchInfiniteLoop.js +33 -11
- package/dist/utils/deepEqual.d.ts +2 -1
- package/dist/utils/deepEqual.js +21 -6
- package/dist/utils/getContentTypeFromUrl.d.ts +2 -0
- package/dist/utils/getContentTypeFromUrl.js +39 -0
- package/dist/utils/injectRollupInputs.d.ts +2 -2
- package/dist/utils/injectRollupInputs.js +2 -2
- package/dist/utils/installUncaughtErrorHandlers.js +9 -0
- package/dist/utils/isDev.js +2 -7
- package/dist/utils/parseUrl-extras.js +4 -0
- package/fetch.js +2 -2
- package/modifyUrl.js +2 -2
- package/package.json +42 -26
- package/routing.js +2 -2
- package/universal-middleware.js +2 -2
- package/vike-server.d.ts +14 -0
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.d.ts +0 -4
- package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.js +0 -22
- package/dist/server/runtime/fetch.d.ts +0 -10
- package/dist/server/runtime/fetch.js +0 -5
- package/dist/server/runtime/universal-middleware.d.ts +0 -10
- package/dist/server/runtime/universal-middleware.js +0 -27
- package/dist/shared-server-client/addIs404ToPageProps.d.ts +0 -2
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
662
|
+
async cancel(reason) {
|
|
563
663
|
debug('stream cancelled');
|
|
564
664
|
isCancel = true;
|
|
565
|
-
|
|
566
|
-
//
|
|
567
|
-
await
|
|
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(
|
|
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
|
+
}
|