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