vinext 0.1.2 → 0.1.4
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/dist/build/client-build-config.d.ts +11 -2
- package/dist/build/client-build-config.js +17 -6
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +42 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/pages-router-link-navigation.d.ts +33 -7
- package/dist/client/pages-router-link-navigation.js +32 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/client/window-next.d.ts +2 -1
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -1
- package/dist/config/config-matchers.js +87 -16
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/config/tsconfig-paths.js +14 -1
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +200 -112
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +65 -5
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +66 -20
- package/dist/entries/pages-server-entry.js +47 -31
- package/dist/index.js +417 -102
- package/dist/plugins/dynamic-preload-metadata.js +2 -4
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/fonts.js +5 -4
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +11 -9
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/strip-server-exports.d.ts +9 -7
- package/dist/plugins/strip-server-exports.js +493 -46
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/routing/app-route-graph.d.ts +2 -1
- package/dist/routing/app-route-graph.js +46 -16
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +22 -1
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +20 -11
- package/dist/server/app-browser-entry.js +175 -91
- package/dist/server/app-browser-error.d.ts +10 -6
- package/dist/server/app-browser-error.js +43 -8
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +5 -3
- package/dist/server/app-browser-navigation-controller.js +23 -2
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.d.ts +1 -1
- package/dist/server/app-browser-state.js +19 -11
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -0
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-optimistic-routing.js +2 -2
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +27 -14
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +62 -1
- package/dist/server/app-page-dispatch.d.ts +26 -0
- package/dist/server/app-page-dispatch.js +149 -92
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +5 -2
- package/dist/server/app-page-execution.d.ts +6 -1
- package/dist/server/app-page-execution.js +21 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +12 -1
- package/dist/server/app-page-render.js +42 -4
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +14 -5
- package/dist/server/app-page-stream.d.ts +15 -3
- package/dist/server/app-page-stream.js +11 -5
- package/dist/server/app-pages-bridge.d.ts +23 -1
- package/dist/server/app-pages-bridge.js +26 -17
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +28 -0
- package/dist/server/app-rsc-handler.js +195 -59
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +8 -2
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +84 -39
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/cache-control.js +4 -0
- package/dist/server/csp.js +1 -4
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +321 -83
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/middleware-matcher.js +12 -3
- package/dist/server/middleware-runtime.d.ts +3 -4
- package/dist/server/middleware-runtime.js +2 -0
- package/dist/server/navigation-planner.d.ts +135 -41
- package/dist/server/navigation-planner.js +138 -0
- package/dist/server/navigation-trace.d.ts +9 -1
- package/dist/server/navigation-trace.js +9 -1
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/pages-api-route.d.ts +6 -0
- package/dist/server/pages-api-route.js +13 -2
- package/dist/server/pages-asset-tags.d.ts +2 -1
- package/dist/server/pages-asset-tags.js +6 -2
- package/dist/server/pages-data-route.d.ts +9 -2
- package/dist/server/pages-data-route.js +18 -6
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +4 -15
- package/dist/server/pages-document-initial-props.js +27 -56
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-i18n.js +2 -2
- package/dist/server/pages-node-compat.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +207 -34
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +62 -23
- package/dist/server/pages-page-response.d.ts +4 -1
- package/dist/server/pages-page-response.js +11 -8
- package/dist/server/pages-readiness.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +8 -7
- package/dist/server/pages-request-pipeline.js +126 -47
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +3 -1
- package/dist/server/prod-server.js +50 -13
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/server/static-file-cache.js +16 -4
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/before-interactive-context.d.ts +14 -3
- package/dist/shims/cache-runtime.js +3 -2
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/document.d.ts +15 -20
- package/dist/shims/document.js +5 -8
- package/dist/shims/dynamic-preload-chunks.js +6 -4
- package/dist/shims/error-boundary.d.ts +2 -0
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +3 -2
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +45 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/headers.js +29 -4
- package/dist/shims/image.js +9 -2
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.js +8 -17
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
- package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +47 -19
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +63 -31
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +18 -3
- package/dist/shims/router.js +512 -142
- package/dist/shims/script.js +8 -4
- package/dist/shims/server.d.ts +16 -1
- package/dist/shims/server.js +44 -12
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +7 -1
- package/dist/utils/path.js +9 -1
- package/dist/utils/text-stream.d.ts +1 -1
- package/dist/utils/text-stream.js +2 -2
- package/dist/utils/vite-version.d.ts +12 -1
- package/dist/utils/vite-version.js +9 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ACTION_REVALIDATED_HEADER } from "./headers.js";
|
|
2
|
-
import { VINEXT_RSC_CONTENT_TYPE
|
|
2
|
+
import { VINEXT_RSC_CONTENT_TYPE } from "./app-rsc-cache-busting.js";
|
|
3
3
|
//#region src/server/app-browser-action-result.ts
|
|
4
4
|
const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
|
|
5
5
|
const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
|
|
@@ -33,7 +33,7 @@ function parseServerActionRevalidationHeader(headers) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
function createServerActionHttpFallbackError(status) {
|
|
36
|
-
if (status
|
|
36
|
+
if (status !== 401 && status !== 403 && status !== 404) return null;
|
|
37
37
|
const digest = status === 404 ? "NEXT_HTTP_ERROR_FALLBACK;404" : `NEXT_HTTP_ERROR_FALLBACK;${status}`;
|
|
38
38
|
const error = /* @__PURE__ */ new Error(status === 404 ? "NEXT_NOT_FOUND" : `NEXT_HTTP_ERROR_FALLBACK;${status}`);
|
|
39
39
|
return Object.assign(error, { digest });
|
|
@@ -47,14 +47,23 @@ async function readInvalidServerActionResponseError(response, hasRedirectLocatio
|
|
|
47
47
|
const message = response.status >= 400 && contentType.toLowerCase().startsWith("text/plain") ? await response.text() : "An unexpected response was received from the server.";
|
|
48
48
|
return new Error(message || "An unexpected response was received from the server.");
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return
|
|
50
|
+
/**
|
|
51
|
+
* Converts raw browser response data into the narrow facts expected by the
|
|
52
|
+
* navigation planner. This is the single place where redirect-type
|
|
53
|
+
* normalisation and RSC content-type detection happen for server-action
|
|
54
|
+
* compatibility checks.
|
|
55
|
+
*/
|
|
56
|
+
function createServerActionResultFacts(input) {
|
|
57
|
+
return {
|
|
58
|
+
actionRedirectHref: input.actionRedirectHref,
|
|
59
|
+
actionRedirectType: input.actionRedirectType === "push" ? "push" : "replace",
|
|
60
|
+
clientCompatibilityId: input.clientCompatibilityId,
|
|
61
|
+
compatibilityIdHeader: input.compatibilityIdHeader,
|
|
62
|
+
currentHref: input.currentHref,
|
|
63
|
+
isRscContentType: (input.contentTypeHeader ?? "").startsWith(VINEXT_RSC_CONTENT_TYPE),
|
|
64
|
+
origin: input.origin,
|
|
65
|
+
responseUrl: input.responseUrl
|
|
66
|
+
};
|
|
58
67
|
}
|
|
59
68
|
function shouldScheduleRefreshForDiscardedServerAction(revalidation) {
|
|
60
69
|
return revalidation !== "none";
|
|
@@ -99,4 +108,4 @@ function createDiscardedServerActionRefreshScheduler(options) {
|
|
|
99
108
|
};
|
|
100
109
|
}
|
|
101
110
|
//#endregion
|
|
102
|
-
export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError,
|
|
111
|
+
export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };
|
|
@@ -4,40 +4,43 @@ import { AppElementsWire } from "./app-elements-wire.js";
|
|
|
4
4
|
import { APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI } from "./app-rsc-render-mode.js";
|
|
5
5
|
import { getMountedSlotIdsHeader, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
|
|
6
6
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
7
|
-
import { installWindowNext } from "../client/window-next.js";
|
|
7
|
+
import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
|
|
8
8
|
import { retryScrollTo, scrollToHashTargetOnNextFrame } from "../shims/hash-scroll.js";
|
|
9
9
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
10
10
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
11
|
+
import { clearAppNavigationFailureTarget, installAppNavigationFailureListeners } from "../client/app-nav-failure-handler.js";
|
|
11
12
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
12
13
|
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
13
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId
|
|
14
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
14
15
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
15
16
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
16
17
|
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
17
|
-
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
18
|
-
import
|
|
18
|
+
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
19
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
20
|
+
import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../shims/error-boundary.js";
|
|
19
21
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
20
22
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
21
23
|
import "../client/instrumentation-client.js";
|
|
22
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError,
|
|
24
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
23
25
|
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
24
26
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
25
27
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
|
|
26
28
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
29
|
+
import { applyServerActionResultDecision } from "./app-browser-server-action-navigation.js";
|
|
27
30
|
import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
|
|
28
31
|
import { AppBrowserHistoryController } from "./app-browser-history-controller.js";
|
|
29
32
|
import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
|
|
30
33
|
import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
|
|
31
|
-
import { createOnUncaughtError,
|
|
34
|
+
import { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnRecoverableError } from "./app-browser-error.js";
|
|
32
35
|
import { dismissOverlay } from "./dev-error-overlay-store.js";
|
|
33
|
-
import { devOnCaughtError,
|
|
36
|
+
import { devOnCaughtError, installDevErrorOverlay, installViteHmrErrorHandler, reportInitialDevServerErrors } from "./dev-error-overlay.js";
|
|
34
37
|
import { throwOnServerActionNotFound } from "./server-action-not-found.js";
|
|
35
38
|
import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
|
|
36
39
|
import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
|
|
37
40
|
import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
38
41
|
import { flushSync } from "react-dom";
|
|
39
42
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
40
|
-
import { hydrateRoot } from "react-dom/client";
|
|
43
|
+
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
41
44
|
//#region src/server/app-browser-entry.ts
|
|
42
45
|
function toActionType(kind) {
|
|
43
46
|
return kind === "traverse" ? "traverse" : "navigate";
|
|
@@ -55,6 +58,14 @@ const CLIENT_RSC_COMPATIBILITY_ID = getVinextRscCompatibilityId();
|
|
|
55
58
|
const optimisticRouteTemplates = /* @__PURE__ */ new Map();
|
|
56
59
|
const optimisticRouteTemplateSources = /* @__PURE__ */ new Set();
|
|
57
60
|
const optimisticRouteTemplateLearning = /* @__PURE__ */ new Map();
|
|
61
|
+
function claimInitialAppRouterBootstrap() {
|
|
62
|
+
if (window.__VINEXT_RSC_ROOT__ || window.__VINEXT_RSC_BOOTSTRAP_STATE__) return false;
|
|
63
|
+
window.__VINEXT_RSC_BOOTSTRAP_STATE__ = "starting";
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
function markInitialAppRouterBootstrapHydrated() {
|
|
67
|
+
window.__VINEXT_RSC_BOOTSTRAP_STATE__ = "hydrated";
|
|
68
|
+
}
|
|
58
69
|
function getBrowserRouteManifest() {
|
|
59
70
|
return getNavigationRuntime()?.bootstrap.routeManifest ?? null;
|
|
60
71
|
}
|
|
@@ -109,10 +120,10 @@ function isRouterStatePromise(value) {
|
|
|
109
120
|
let latestClientParams = {};
|
|
110
121
|
const visitedResponseCache = /* @__PURE__ */ new Map();
|
|
111
122
|
let browserRouterStateHasEverCommitted = false;
|
|
112
|
-
let pendingNavigationRecoveryHref = null;
|
|
113
123
|
const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
|
|
114
124
|
const unresolvedMpaNavigation = new Promise(() => {});
|
|
115
125
|
const RSC_HMR_SETTLE_DELAY_MS = 150;
|
|
126
|
+
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
116
127
|
let latestRscHmrUpdateId = 0;
|
|
117
128
|
let synchronousPopstateScrollRestoreNavigationId = null;
|
|
118
129
|
function waitForRscHmrSettle(delayMs = RSC_HMR_SETTLE_DELAY_MS) {
|
|
@@ -262,39 +273,31 @@ function createNavigationCommitEffect(options) {
|
|
|
262
273
|
stageClientParams: () => stageClientParams(params),
|
|
263
274
|
targetHistoryIndex
|
|
264
275
|
});
|
|
265
|
-
|
|
276
|
+
clearAppNavigationFailureTarget(href);
|
|
266
277
|
commitClientNavigationState(navId);
|
|
267
278
|
};
|
|
268
279
|
}
|
|
269
280
|
async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true, visibleCommitMode = "transition") {
|
|
270
281
|
syncServerActionHttpFallbackHead(null);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
targetHref,
|
|
291
|
-
navId,
|
|
292
|
-
visibleCommitMode
|
|
293
|
-
});
|
|
294
|
-
} catch (error) {
|
|
295
|
-
pendingNavigationRecoveryHref = null;
|
|
296
|
-
throw error;
|
|
297
|
-
}
|
|
282
|
+
return browserNavigationController.renderNavigationPayload({
|
|
283
|
+
actionType,
|
|
284
|
+
createNavigationCommitEffect,
|
|
285
|
+
historyUpdateMode,
|
|
286
|
+
navigationSnapshot,
|
|
287
|
+
nextElements: payload,
|
|
288
|
+
operationLane,
|
|
289
|
+
payloadOrigin,
|
|
290
|
+
params,
|
|
291
|
+
pendingRouterState,
|
|
292
|
+
previousNextUrl,
|
|
293
|
+
scrollIntent,
|
|
294
|
+
restoredBfcacheIds,
|
|
295
|
+
reuseCurrentBfcacheIds,
|
|
296
|
+
targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
|
|
297
|
+
targetHref,
|
|
298
|
+
navId,
|
|
299
|
+
visibleCommitMode
|
|
300
|
+
});
|
|
298
301
|
}
|
|
299
302
|
function resolveActionRedirectTarget(response) {
|
|
300
303
|
const actionRedirect = response.headers.get(ACTION_REDIRECT_HEADER);
|
|
@@ -360,23 +363,39 @@ function evictVisitedResponseCacheIfNeeded() {
|
|
|
360
363
|
visitedResponseCache.delete(oldest);
|
|
361
364
|
}
|
|
362
365
|
}
|
|
363
|
-
function
|
|
366
|
+
function readVisitedResponseCacheCandidate(rscUrl, interceptionContext, mountedSlotsHeader, navigationKind) {
|
|
364
367
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
365
368
|
const cached = visitedResponseCache.get(cacheKey);
|
|
366
|
-
if (!cached) return
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
369
|
+
if (!cached) return {
|
|
370
|
+
cacheKey,
|
|
371
|
+
entry: null,
|
|
372
|
+
facts: {
|
|
373
|
+
candidate: "missing",
|
|
374
|
+
navigationKind
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
return {
|
|
378
|
+
cacheKey,
|
|
379
|
+
entry: cached,
|
|
380
|
+
facts: {
|
|
381
|
+
candidate: "present",
|
|
382
|
+
fresh: isVisitedResponseCacheEntryFresh(cached, {
|
|
383
|
+
navigationKind,
|
|
384
|
+
now: Date.now()
|
|
385
|
+
}),
|
|
386
|
+
mountedSlotsMatch: (cached.response.mountedSlotsHeader ?? null) === mountedSlotsHeader,
|
|
387
|
+
navigationKind
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function applyVisitedResponseCacheCandidateDecision(candidate, decision) {
|
|
392
|
+
if (candidate.entry === null) return null;
|
|
393
|
+
if (decision.kind === "reuse") {
|
|
394
|
+
visitedResponseCache.delete(candidate.cacheKey);
|
|
395
|
+
visitedResponseCache.set(candidate.cacheKey, candidate.entry);
|
|
396
|
+
return candidate.entry;
|
|
378
397
|
}
|
|
379
|
-
visitedResponseCache.delete(cacheKey);
|
|
398
|
+
visitedResponseCache.delete(candidate.cacheKey);
|
|
380
399
|
return null;
|
|
381
400
|
}
|
|
382
401
|
function deleteVisitedResponse(rscUrl, interceptionContext) {
|
|
@@ -525,20 +544,25 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
525
544
|
return new Promise(() => {});
|
|
526
545
|
} });
|
|
527
546
|
browserRouterStateHasEverCommitted = true;
|
|
528
|
-
const hydratedAt = performance.now();
|
|
529
|
-
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
530
|
-
window.__NEXT_HYDRATED = true;
|
|
531
|
-
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
532
|
-
window.__NEXT_HYDRATED_CB?.();
|
|
533
547
|
return () => {
|
|
534
548
|
registerNavigationRuntimeFunctions({ navigateExternal: void 0 });
|
|
535
549
|
detach();
|
|
536
550
|
setMountedSlotsHeader(null);
|
|
537
551
|
};
|
|
538
552
|
}, [setTreeStateValue]);
|
|
553
|
+
useEffect(() => {
|
|
554
|
+
const hydratedAt = performance.now();
|
|
555
|
+
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
556
|
+
window.__NEXT_HYDRATED = true;
|
|
557
|
+
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
558
|
+
window.__NEXT_HYDRATED_CB?.();
|
|
559
|
+
}, []);
|
|
539
560
|
useLayoutEffect(() => {
|
|
540
561
|
historyController.rememberHistoryStateSnapshot(treeState);
|
|
541
562
|
}, [treeState]);
|
|
563
|
+
useEffect(() => {
|
|
564
|
+
setWindowNextInternalSourcePage(AppElementsWire.readMetadata(treeState.elements).sourcePage);
|
|
565
|
+
}, [treeState.elements]);
|
|
542
566
|
useLayoutEffect(() => {
|
|
543
567
|
setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
|
|
544
568
|
removeStylesheetLinksCoveredByInlineCss();
|
|
@@ -564,13 +588,17 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
564
588
|
const redirectedTree = createElement(AppRouterRedirectBridge, null, BfcacheIdMapContext ? createElement(BfcacheIdMapContext.Provider, { value: treeState.bfcacheIds }, stateKeyTree) : stateKeyTree);
|
|
565
589
|
const innerTree = AppRouterContext ? createElement(AppRouterContext.Provider, { value: appRouterInstance }, redirectedTree) : redirectedTree;
|
|
566
590
|
const committedTree = import.meta.env.DEV ? createElement(DevRecoveryBoundary, {
|
|
591
|
+
isImplicitRootErrorBoundary: true,
|
|
567
592
|
resetKey: treeState.renderId,
|
|
568
593
|
onCatch: handleDevRecoveryBoundaryCatch
|
|
569
594
|
}, innerTree) : innerTree;
|
|
570
|
-
const
|
|
595
|
+
const rootErrorTree = createElement(GlobalErrorBoundary, {
|
|
596
|
+
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
597
|
+
children: createElement(AppRouterScrollCommitProvider, { commitId: treeState.renderId }, committedTree)
|
|
598
|
+
});
|
|
571
599
|
const ClientNavigationRenderContext = getClientNavigationRenderContext();
|
|
572
|
-
if (!ClientNavigationRenderContext) return
|
|
573
|
-
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot },
|
|
600
|
+
if (!ClientNavigationRenderContext) return rootErrorTree;
|
|
601
|
+
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, rootErrorTree);
|
|
574
602
|
}
|
|
575
603
|
function restoreHydrationNavigationContext(pathname, searchParams, params) {
|
|
576
604
|
setNavigationContext({
|
|
@@ -698,31 +726,23 @@ function registerServerActionCallback() {
|
|
|
698
726
|
const hasActionRedirect = fetchResponse.headers.has(ACTION_REDIRECT_HEADER);
|
|
699
727
|
const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse);
|
|
700
728
|
if (hasActionRedirect && !actionRedirectTarget) return;
|
|
701
|
-
const
|
|
729
|
+
const actionResultFacts = createServerActionResultFacts({
|
|
702
730
|
actionRedirectHref: actionRedirectTarget?.href ?? null,
|
|
731
|
+
actionRedirectType: actionRedirectTarget?.type ?? null,
|
|
703
732
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
if (actionRedirectCompatibilityHardNavigationTarget) {
|
|
707
|
-
clearClientNavigationCaches();
|
|
708
|
-
browserNavigationController.performHardNavigation(actionRedirectCompatibilityHardNavigationTarget, actionRedirectTarget?.type === "push" ? "assign" : "replace");
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
if (!actionRedirectTarget && shouldCheckRscCompatibilityForServerActionResponse(fetchResponse) && resolveRscCompatibilityNavigationDecision({
|
|
712
|
-
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
733
|
+
compatibilityIdHeader: fetchResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
|
|
734
|
+
contentTypeHeader: fetchResponse.headers.get("content-type"),
|
|
713
735
|
currentHref: actionInitiation.href,
|
|
714
736
|
origin: window.location.origin,
|
|
715
|
-
responseCompatibilityId: fetchResponse.headers.get("X-Vinext-RSC-Compatibility-Id"),
|
|
716
737
|
responseUrl: fetchResponse.url
|
|
717
|
-
})
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
738
|
+
});
|
|
739
|
+
const fetchResponseIsRsc = actionResultFacts.isRscContentType;
|
|
740
|
+
if (applyServerActionResultDecision(navigationPlanner.classifyServerActionResult(actionResultFacts), clearClientNavigationCaches, (url, historyMode) => browserNavigationController.performHardNavigation(url, historyMode))) return;
|
|
721
741
|
const revalidation = parseServerActionRevalidationHeader(fetchResponse.headers);
|
|
722
742
|
if (revalidation !== "none") clearClientNavigationCaches();
|
|
723
743
|
const invalidResponseError = await readInvalidServerActionResponseError(fetchResponse.clone(), actionRedirectTarget !== null);
|
|
724
744
|
if (invalidResponseError) throw invalidResponseError;
|
|
725
|
-
if (actionRedirectTarget && !
|
|
745
|
+
if (actionRedirectTarget && !fetchResponseIsRsc) {
|
|
726
746
|
browserNavigationController.performHardNavigation(actionRedirectTarget.href);
|
|
727
747
|
return;
|
|
728
748
|
}
|
|
@@ -770,7 +790,9 @@ function registerServerActionCallback() {
|
|
|
770
790
|
});
|
|
771
791
|
}
|
|
772
792
|
async function main() {
|
|
793
|
+
if (!claimInitialAppRouterBootstrap()) return;
|
|
773
794
|
registerServerActionCallback();
|
|
795
|
+
installAppNavigationFailureListeners();
|
|
774
796
|
if (import.meta.env.DEV) {
|
|
775
797
|
installDevErrorOverlay();
|
|
776
798
|
installViteHmrErrorHandler(import.meta.hot);
|
|
@@ -784,31 +806,47 @@ function bootstrapHydration(rscStream) {
|
|
|
784
806
|
const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
|
|
785
807
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
786
808
|
historyController.writeBootstrapHistoryMetadata();
|
|
787
|
-
const onUncaughtError =
|
|
809
|
+
const onUncaughtError = createOnUncaughtError();
|
|
788
810
|
const formState = consumeInitialFormState(getVinextBrowserGlobal());
|
|
789
811
|
const hydrateRootOptions = import.meta.env.DEV ? createVinextHydrateRootOptions({
|
|
790
812
|
formState,
|
|
791
|
-
onCaughtError: devOnCaughtError,
|
|
813
|
+
onCaughtError: createDevOnCaughtError(devOnCaughtError, onUncaughtError),
|
|
792
814
|
onUncaughtError
|
|
793
815
|
}) : createVinextHydrateRootOptions({
|
|
794
816
|
formState,
|
|
795
|
-
onCaughtError:
|
|
817
|
+
onCaughtError: createProdOnCaughtError(onUncaughtError),
|
|
818
|
+
onRecoverableError: prodOnRecoverableError,
|
|
796
819
|
onUncaughtError
|
|
797
820
|
});
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
821
|
+
const children = createElement(BrowserRoot, {
|
|
822
|
+
initialElements: root,
|
|
823
|
+
initialNavigationSnapshot
|
|
824
|
+
});
|
|
825
|
+
const errorShellStyles = document.querySelectorAll("style[data-vinext-error-shell-style]");
|
|
826
|
+
if (document.documentElement.id === "__next_error__") {
|
|
827
|
+
const { formState: _inertFormState, ...createRootOptions } = hydrateRootOptions;
|
|
828
|
+
for (const style of errorShellStyles) style.remove();
|
|
829
|
+
startTransition(() => {
|
|
830
|
+
const clientRoot = createRoot(document, createRootOptions);
|
|
831
|
+
clientRoot.render(children);
|
|
832
|
+
window.__VINEXT_RSC_ROOT__ = clientRoot;
|
|
833
|
+
});
|
|
834
|
+
} else window.__VINEXT_RSC_ROOT__ = hydrateRootInTransition({
|
|
835
|
+
children,
|
|
803
836
|
container: document,
|
|
804
837
|
hydrateRoot,
|
|
805
838
|
options: hydrateRootOptions,
|
|
806
839
|
startTransition
|
|
807
840
|
});
|
|
841
|
+
markInitialAppRouterBootstrapHydrated();
|
|
842
|
+
let activeNavigationAbortController = null;
|
|
808
843
|
registerNavigationRuntimeFunctions({
|
|
809
844
|
clearNavigationCaches: clearClientNavigationCaches,
|
|
810
845
|
commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
|
|
811
846
|
navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent, visibleCommitMode = "transition") {
|
|
847
|
+
activeNavigationAbortController?.abort();
|
|
848
|
+
const navigationAbortController = new AbortController();
|
|
849
|
+
activeNavigationAbortController = navigationAbortController;
|
|
812
850
|
let pendingRouterState = null;
|
|
813
851
|
const navId = browserNavigationController.beginNavigation();
|
|
814
852
|
discardedServerActionRefreshScheduler.markNavigationStart();
|
|
@@ -820,7 +858,9 @@ function bootstrapHydration(rscStream) {
|
|
|
820
858
|
const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? historyController.resolveTraversalIntent(window.history.state) : null;
|
|
821
859
|
const performHardNavigationForScrollIntent = (targetHref) => {
|
|
822
860
|
consumeAppRouterScrollIntent(scrollIntent ?? null);
|
|
823
|
-
|
|
861
|
+
const didNavigate = browserNavigationController.performHardNavigation(targetHref);
|
|
862
|
+
if (!didNavigate) clearAppNavigationFailureTarget(targetHref);
|
|
863
|
+
return didNavigate;
|
|
824
864
|
};
|
|
825
865
|
let restoredBfcacheIds = navigationKind === "traverse" ? historyController.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
|
|
826
866
|
const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !historyController.isCacheInvalidationGuarded() && historyController.isCurrentBfcacheVersion(activeTraversalIntent?.historyState ?? window.history.state);
|
|
@@ -856,8 +896,35 @@ function bootstrapHydration(rscStream) {
|
|
|
856
896
|
renderMode: navigationKind === "refresh" ? APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI : void 0
|
|
857
897
|
});
|
|
858
898
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
859
|
-
const
|
|
860
|
-
|
|
899
|
+
const visitedResponseCandidate = shouldBypassNavigationCache ? {
|
|
900
|
+
cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
|
|
901
|
+
entry: null,
|
|
902
|
+
facts: {
|
|
903
|
+
candidate: "missing",
|
|
904
|
+
navigationKind
|
|
905
|
+
}
|
|
906
|
+
} : readVisitedResponseCacheCandidate(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
|
|
907
|
+
const cachedRoute = applyVisitedResponseCacheCandidateDecision(visitedResponseCandidate, navigationPlanner.classifyVisitedResponseCacheCandidate(visitedResponseCandidate.facts));
|
|
908
|
+
const visitedResponse = cachedRoute === null ? { status: "unavailable" } : { status: "available" };
|
|
909
|
+
const prefetchProbeDecision = navigationPlanner.classifyNavigationPrefetchProbe({
|
|
910
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
911
|
+
navigationKind,
|
|
912
|
+
visitedResponse
|
|
913
|
+
});
|
|
914
|
+
let routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
915
|
+
const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { notifyInvalidation: false });
|
|
916
|
+
const reuseDecision = navigationPlanner.classifyNavigationReuse({
|
|
917
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
918
|
+
navigationKind,
|
|
919
|
+
optimisticRouteShell: routeManifest === null ? {
|
|
920
|
+
reason: "routeManifestMissing",
|
|
921
|
+
status: "unavailable"
|
|
922
|
+
} : { status: "available" },
|
|
923
|
+
prefetch: hasPrefetchCandidate ? { status: "available" } : { status: "unavailable" },
|
|
924
|
+
targetHref: currentHref,
|
|
925
|
+
visitedResponse
|
|
926
|
+
});
|
|
927
|
+
if (reuseDecision.kind === "reuseVisitedResponse" && cachedRoute) {
|
|
861
928
|
const cachedFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
862
929
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
863
930
|
compatibilityIdHeader: cachedRoute.response.compatibilityIdHeader ?? null,
|
|
@@ -900,7 +967,8 @@ function bootstrapHydration(rscStream) {
|
|
|
900
967
|
let navResponse;
|
|
901
968
|
let navResponseExpiresAt;
|
|
902
969
|
let navResponseUrl = null;
|
|
903
|
-
|
|
970
|
+
let fallbackReuseDecision = reuseDecision;
|
|
971
|
+
if (reuseDecision.kind === "consumePrefetch") {
|
|
904
972
|
const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { shouldConsume: () => browserNavigationController.isCurrentNavigation(navId) });
|
|
905
973
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
906
974
|
if (prefetchedResponse) {
|
|
@@ -908,9 +976,22 @@ function bootstrapHydration(rscStream) {
|
|
|
908
976
|
navResponseExpiresAt = prefetchedResponse.expiresAt;
|
|
909
977
|
navResponseUrl = prefetchedResponse.url;
|
|
910
978
|
}
|
|
979
|
+
if (!navResponse) {
|
|
980
|
+
routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
981
|
+
fallbackReuseDecision = navigationPlanner.classifyNavigationReuse({
|
|
982
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
983
|
+
navigationKind,
|
|
984
|
+
optimisticRouteShell: routeManifest === null ? {
|
|
985
|
+
reason: "routeManifestMissing",
|
|
986
|
+
status: "unavailable"
|
|
987
|
+
} : { status: "available" },
|
|
988
|
+
prefetch: { status: "unavailable" },
|
|
989
|
+
targetHref: currentHref,
|
|
990
|
+
visitedResponse: { status: "unavailable" }
|
|
991
|
+
});
|
|
992
|
+
}
|
|
911
993
|
}
|
|
912
|
-
if (!navResponse &&
|
|
913
|
-
const routeManifest = getBrowserRouteManifest();
|
|
994
|
+
if (!navResponse && fallbackReuseDecision.kind === "attemptOptimisticRouteShell") {
|
|
914
995
|
await learnOptimisticRouteTemplatesFromPrefetchCache({
|
|
915
996
|
interceptionContext: requestInterceptionContext,
|
|
916
997
|
mountedSlotsHeader,
|
|
@@ -942,7 +1023,8 @@ function bootstrapHydration(rscStream) {
|
|
|
942
1023
|
}
|
|
943
1024
|
navResponse = await fetch(rscUrl, {
|
|
944
1025
|
headers: requestHeaders,
|
|
945
|
-
credentials: "include"
|
|
1026
|
+
credentials: "include",
|
|
1027
|
+
signal: navigationAbortController.signal
|
|
946
1028
|
});
|
|
947
1029
|
}
|
|
948
1030
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
@@ -988,6 +1070,7 @@ function bootstrapHydration(rscStream) {
|
|
|
988
1070
|
headers: navResponse.headers
|
|
989
1071
|
});
|
|
990
1072
|
const cacheBufferPromise = new Response(cacheBranch).arrayBuffer();
|
|
1073
|
+
cacheBufferPromise.catch(() => {});
|
|
991
1074
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
992
1075
|
const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
|
|
993
1076
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
@@ -1012,8 +1095,9 @@ function bootstrapHydration(rscStream) {
|
|
|
1012
1095
|
} catch (error) {
|
|
1013
1096
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1014
1097
|
if (!isPageUnloading) console.error("[vinext] RSC navigation error:", error);
|
|
1015
|
-
performHardNavigationForScrollIntent(currentHref);
|
|
1098
|
+
performHardNavigationForScrollIntent(navigationPlanner.classifyRscNavigationError({ currentHref }).url);
|
|
1016
1099
|
} finally {
|
|
1100
|
+
if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
|
|
1017
1101
|
browserNavigationController.finalizeNavigation(navId, pendingRouterState);
|
|
1018
1102
|
discardedServerActionRefreshScheduler.markNavigationSettled();
|
|
1019
1103
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
//#region src/server/app-browser-error.d.ts
|
|
2
|
-
|
|
2
|
+
type VinextHydrateRootErrorInfo = {
|
|
3
3
|
componentStack?: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
errorBoundary?: unknown;
|
|
5
|
+
};
|
|
6
|
+
type HydrateRootErrorHandler = (error: unknown, errorInfo: VinextHydrateRootErrorInfo) => void;
|
|
7
|
+
declare function createOnUncaughtError(): HydrateRootErrorHandler;
|
|
8
|
+
declare function createProdOnCaughtError(onImplicitRootError: HydrateRootErrorHandler): HydrateRootErrorHandler;
|
|
9
|
+
declare function createDevOnCaughtError(onCaughtError: HydrateRootErrorHandler, onImplicitRootError: HydrateRootErrorHandler): HydrateRootErrorHandler;
|
|
10
|
+
declare function prodOnCaughtError(error: unknown, errorInfo: VinextHydrateRootErrorInfo): void;
|
|
11
|
+
declare function prodOnRecoverableError(error: unknown): void;
|
|
8
12
|
//#endregion
|
|
9
|
-
export { createOnUncaughtError, prodOnCaughtError };
|
|
13
|
+
export { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnCaughtError, prodOnRecoverableError };
|
|
@@ -1,17 +1,52 @@
|
|
|
1
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
1
2
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
2
3
|
//#region src/server/app-browser-error.ts
|
|
3
|
-
function
|
|
4
|
+
function isImplicitRootErrorBoundary(errorInfo) {
|
|
5
|
+
if (!isUnknownRecord(errorInfo.errorBoundary)) return false;
|
|
6
|
+
const props = errorInfo.errorBoundary.props;
|
|
7
|
+
return isUnknownRecord(props) && props.isImplicitRootErrorBoundary === true;
|
|
8
|
+
}
|
|
9
|
+
function logCaughtError(error, errorInfo) {
|
|
10
|
+
console.error(error);
|
|
11
|
+
if (errorInfo?.componentStack) console.error("The above error occurred in a React component:\n" + errorInfo.componentStack);
|
|
12
|
+
}
|
|
13
|
+
function reportGlobalError(error) {
|
|
14
|
+
if (typeof globalThis.reportError === "function") {
|
|
15
|
+
globalThis.reportError(error);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.error(error);
|
|
19
|
+
}
|
|
20
|
+
function createOnUncaughtError() {
|
|
21
|
+
return (error) => {
|
|
22
|
+
reportGlobalError(error);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createProdOnCaughtError(onImplicitRootError) {
|
|
26
|
+
return (error, errorInfo) => {
|
|
27
|
+
if (isNavigationSignalError(error)) return;
|
|
28
|
+
if (isImplicitRootErrorBoundary(errorInfo)) {
|
|
29
|
+
onImplicitRootError(error, errorInfo);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
logCaughtError(error, errorInfo);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function createDevOnCaughtError(onCaughtError, onImplicitRootError) {
|
|
4
36
|
return (error, errorInfo) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
37
|
+
if (isImplicitRootErrorBoundary(errorInfo)) {
|
|
38
|
+
onImplicitRootError(error, errorInfo);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
onCaughtError(error, errorInfo);
|
|
9
42
|
};
|
|
10
43
|
}
|
|
11
44
|
function prodOnCaughtError(error, errorInfo) {
|
|
12
45
|
if (isNavigationSignalError(error)) return;
|
|
13
|
-
|
|
14
|
-
|
|
46
|
+
logCaughtError(error, errorInfo);
|
|
47
|
+
}
|
|
48
|
+
function prodOnRecoverableError(error) {
|
|
49
|
+
reportGlobalError(error instanceof Error && error.cause !== void 0 ? error.cause : error);
|
|
15
50
|
}
|
|
16
51
|
//#endregion
|
|
17
|
-
export { createOnUncaughtError, prodOnCaughtError };
|
|
52
|
+
export { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnCaughtError, prodOnRecoverableError };
|
|
@@ -8,6 +8,7 @@ type HydrateRootChildren = Parameters<HydrateRoot>[1];
|
|
|
8
8
|
type HydrateRootReturn = ReturnType<HydrateRoot>;
|
|
9
9
|
type HydrateRootCaughtErrorHandler = NonNullable<HydrateRootOptions["onCaughtError"]>;
|
|
10
10
|
type HydrateRootUncaughtErrorHandler = NonNullable<HydrateRootOptions["onUncaughtError"]>;
|
|
11
|
+
type HydrateRootRecoverableErrorHandler = NonNullable<HydrateRootOptions["onRecoverableError"]>;
|
|
11
12
|
type StartTransition = (action: () => void) => void;
|
|
12
13
|
declare const RSC_FORM_STATE_GLOBAL = "__VINEXT_RSC_FORM_STATE__";
|
|
13
14
|
type FormStateGlobal = {
|
|
@@ -17,6 +18,7 @@ declare function consumeInitialFormState(global: FormStateGlobal): ReactFormStat
|
|
|
17
18
|
declare function createVinextHydrateRootOptions(options: {
|
|
18
19
|
formState: ReactFormState | null;
|
|
19
20
|
onCaughtError?: HydrateRootCaughtErrorHandler;
|
|
21
|
+
onRecoverableError?: HydrateRootRecoverableErrorHandler;
|
|
20
22
|
onUncaughtError: HydrateRootUncaughtErrorHandler;
|
|
21
23
|
}): HydrateRootOptions;
|
|
22
24
|
declare function hydrateRootInTransition(options: {
|
|
@@ -8,6 +8,7 @@ function consumeInitialFormState(global) {
|
|
|
8
8
|
function createVinextHydrateRootOptions(options) {
|
|
9
9
|
const hydrateOptions = {
|
|
10
10
|
formState: options.formState,
|
|
11
|
+
...options.onRecoverableError ? { onRecoverableError: options.onRecoverableError } : {},
|
|
11
12
|
onUncaughtError: options.onUncaughtError
|
|
12
13
|
};
|
|
13
14
|
if (options.onCaughtError) return {
|