vinext 0.0.40 → 0.0.42
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/README.md +1 -2
- package/dist/build/client-build-config.d.ts +119 -0
- package/dist/build/client-build-config.js +149 -0
- package/dist/build/client-build-config.js.map +1 -0
- package/dist/build/layout-classification-types.d.ts +62 -0
- package/dist/build/layout-classification-types.js +1 -0
- package/dist/build/layout-classification.d.ts +60 -0
- package/dist/build/layout-classification.js +98 -0
- package/dist/build/layout-classification.js.map +1 -0
- package/dist/build/report.d.ts +15 -1
- package/dist/build/report.js +50 -1
- package/dist/build/report.js.map +1 -1
- package/dist/build/route-classification-manifest.d.ts +53 -0
- package/dist/build/route-classification-manifest.js +145 -0
- package/dist/build/route-classification-manifest.js.map +1 -0
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/ssr-manifest.d.ts +19 -0
- package/dist/build/ssr-manifest.js +71 -0
- package/dist/build/ssr-manifest.js.map +1 -0
- package/dist/check.js +4 -4
- package/dist/check.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client/entry.js +1 -1
- package/dist/config/config-matchers.js +1 -0
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +341 -114
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +205 -199
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.d.ts +1 -169
- package/dist/index.js +113 -432
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.js +2 -2
- package/dist/init.js.map +1 -1
- package/dist/plugins/fonts.d.ts +49 -1
- package/dist/plugins/fonts.js +97 -3
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/postcss.d.ts +27 -0
- package/dist/plugins/postcss.js +94 -0
- package/dist/plugins/postcss.js.map +1 -0
- package/dist/plugins/strip-server-exports.d.ts +14 -0
- package/dist/plugins/strip-server-exports.js +73 -0
- package/dist/plugins/strip-server-exports.js.map +1 -0
- package/dist/routing/app-router.d.ts +6 -4
- package/dist/routing/app-router.js +21 -22
- package/dist/routing/app-router.js.map +1 -1
- package/dist/server/app-browser-entry.js +235 -97
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.d.ts +8 -0
- package/dist/server/app-browser-error.js +9 -0
- package/dist/server/app-browser-error.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +93 -0
- package/dist/server/app-browser-state.js +132 -0
- package/dist/server/app-browser-state.js.map +1 -0
- package/dist/server/app-elements.d.ts +92 -0
- package/dist/server/app-elements.js +122 -0
- package/dist/server/app-elements.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +41 -1
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +6 -3
- package/dist/server/app-page-cache.js +14 -8
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +36 -3
- package/dist/server/app-page-execution.js +50 -10
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +10 -4
- package/dist/server/app-page-probe.js +24 -15
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +8 -4
- package/dist/server/app-page-render.js +15 -4
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +52 -4
- package/dist/server/app-page-request.js +86 -16
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +4 -11
- package/dist/server/app-page-response.js +7 -19
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +22 -8
- package/dist/server/app-page-route-wiring.js +219 -81
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +4 -1
- package/dist/server/app-page-stream.js +2 -1
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-render-dependency.d.ts +13 -0
- package/dist/server/app-render-dependency.js +35 -0
- package/dist/server/app-render-dependency.js.map +1 -0
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.js +2 -1
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +26 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +3 -1
- package/dist/server/app-ssr-entry.js +23 -19
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +1 -1
- package/dist/server/app-ssr-stream.js +4 -4
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/csp.d.ts +12 -0
- package/dist/server/csp.js +46 -0
- package/dist/server/csp.js.map +1 -0
- package/dist/server/dev-server.js +22 -18
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/html.d.ts +4 -1
- package/dist/server/html.js +11 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/middleware-response-headers.d.ts +12 -0
- package/dist/server/middleware-response-headers.js +23 -0
- package/dist/server/middleware-response-headers.js.map +1 -0
- package/dist/server/middleware.js +1 -5
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +1 -0
- package/dist/server/pages-page-data.js +2 -2
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +2 -1
- package/dist/server/pages-page-response.js +16 -14
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +3 -3
- package/dist/server/prod-server.js +5 -4
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +15 -1
- package/dist/server/request-pipeline.js +88 -5
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +1 -0
- package/dist/shims/cache-runtime.js +0 -5
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -8
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-hook-error.d.ts +14 -0
- package/dist/shims/client-hook-error.js +19 -0
- package/dist/shims/client-hook-error.js.map +1 -0
- package/dist/shims/constants.d.ts +3 -3
- package/dist/shims/constants.js +3 -3
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/document.d.ts +6 -6
- package/dist/shims/error-boundary.d.ts +4 -4
- package/dist/shims/error-boundary.js +1 -1
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/form.d.ts +3 -3
- package/dist/shims/head-state.d.ts +1 -0
- package/dist/shims/head-state.js +0 -5
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/headers.d.ts +11 -0
- package/dist/shims/headers.js +13 -10
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-state.d.ts +1 -0
- package/dist/shims/i18n-state.js +0 -4
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +6 -6
- package/dist/shims/internal/router-context.d.ts +2 -2
- package/dist/shims/layout-segment-context.d.ts +2 -2
- package/dist/shims/link.js +19 -11
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +3 -3
- package/dist/shims/navigation-state.d.ts +2 -0
- package/dist/shims/navigation-state.js +0 -13
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +55 -8
- package/dist/shims/navigation.js +97 -23
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +14 -0
- package/dist/shims/navigation.react-server.js +29 -0
- package/dist/shims/navigation.react-server.js.map +1 -0
- package/dist/shims/request-context.d.ts +1 -0
- package/dist/shims/request-context.js +0 -9
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +0 -5
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/script-nonce-context.d.ts +12 -0
- package/dist/shims/script-nonce-context.js +17 -0
- package/dist/shims/script-nonce-context.js.map +1 -0
- package/dist/shims/script.js +41 -10
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +6 -1
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +11 -7
- package/dist/shims/slot.js +28 -19
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +2 -0
- package/dist/shims/unified-request-context.js +0 -14
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/url-safety.js +25 -4
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/utils/mdx-scan.d.ts +10 -0
- package/dist/utils/mdx-scan.js +36 -0
- package/dist/utils/mdx-scan.js.map +1 -0
- package/dist/utils/public-routes.d.ts +5 -0
- package/dist/utils/public-routes.js +50 -0
- package/dist/utils/public-routes.js.map +1 -0
- package/package.json +9 -9
- package/dist/plugins/fix-use-server-closure-collision.d.ts +0 -29
- package/dist/plugins/fix-use-server-closure-collision.js +0 -204
- package/dist/plugins/fix-use-server-closure-collision.js.map +0 -1
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
3
|
-
import {
|
|
3
|
+
import { createAppPayloadCacheKey, getMountedSlotIdsHeader, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
|
|
4
|
+
import { __basePath, activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getClientNavigationState, getCurrentInterceptionContext, getCurrentNextUrl, getPrefetchCache, getPrefetchedUrls, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, toRscUrl } from "../shims/navigation.js";
|
|
5
|
+
import { ElementsContext, Slot } from "../shims/slot.js";
|
|
4
6
|
import "../client/instrumentation-client.js";
|
|
5
7
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
6
|
-
import {
|
|
8
|
+
import { createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveAndClassifyNavigationCommit, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDisposition, resolveServerActionRequestState, routerReducer } from "./app-browser-state.js";
|
|
9
|
+
import { devOnCaughtError } from "./app-browser-error.js";
|
|
10
|
+
import { createElement, startTransition, use, useLayoutEffect, useReducer, useRef } from "react";
|
|
7
11
|
import { hydrateRoot } from "react-dom/client";
|
|
8
12
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
9
13
|
//#region src/server/app-browser-entry.ts
|
|
14
|
+
function toActionType(kind) {
|
|
15
|
+
return kind === "traverse" ? "traverse" : "navigate";
|
|
16
|
+
}
|
|
10
17
|
const MAX_VISITED_RESPONSE_CACHE_SIZE = 50;
|
|
11
18
|
const VISITED_RESPONSE_CACHE_TTL = 5 * 6e4;
|
|
12
19
|
const MAX_TRAVERSAL_CACHE_TTL = 30 * 6e4;
|
|
@@ -14,15 +21,20 @@ let nextNavigationRenderId = 0;
|
|
|
14
21
|
let activeNavigationId = 0;
|
|
15
22
|
const pendingNavigationCommits = /* @__PURE__ */ new Map();
|
|
16
23
|
const pendingNavigationPrePaintEffects = /* @__PURE__ */ new Map();
|
|
17
|
-
let
|
|
24
|
+
let dispatchBrowserRouterAction = null;
|
|
25
|
+
let browserRouterStateRef = null;
|
|
18
26
|
let latestClientParams = {};
|
|
19
27
|
const visitedResponseCache = /* @__PURE__ */ new Map();
|
|
20
28
|
function isServerActionResult(value) {
|
|
21
29
|
return !!value && typeof value === "object" && "root" in value;
|
|
22
30
|
}
|
|
23
|
-
function
|
|
24
|
-
if (!
|
|
25
|
-
return
|
|
31
|
+
function getBrowserRouterDispatch() {
|
|
32
|
+
if (!dispatchBrowserRouterAction) throw new Error("[vinext] Browser router dispatch is not initialized");
|
|
33
|
+
return dispatchBrowserRouterAction;
|
|
34
|
+
}
|
|
35
|
+
function getBrowserRouterState() {
|
|
36
|
+
if (!browserRouterStateRef) throw new Error("[vinext] Browser router state is not initialized");
|
|
37
|
+
return browserRouterStateRef.current;
|
|
26
38
|
}
|
|
27
39
|
function applyClientParams(params) {
|
|
28
40
|
latestClientParams = params;
|
|
@@ -62,15 +74,21 @@ function drainPrePaintEffects(upToRenderId) {
|
|
|
62
74
|
for (const [id, effect] of pendingNavigationPrePaintEffects) if (id <= upToRenderId) {
|
|
63
75
|
pendingNavigationPrePaintEffects.delete(id);
|
|
64
76
|
if (id === upToRenderId) effect();
|
|
65
|
-
else commitClientNavigationState();
|
|
77
|
+
else commitClientNavigationState(void 0);
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
|
-
function createNavigationCommitEffect(href, historyUpdateMode) {
|
|
80
|
+
function createNavigationCommitEffect(href, historyUpdateMode, navId, params, previousNextUrl) {
|
|
69
81
|
return () => {
|
|
82
|
+
if (navId !== activeNavigationId) {
|
|
83
|
+
commitClientNavigationState(void 0);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
70
86
|
const targetHref = new URL(href, window.location.origin).href;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
stageClientParams(params);
|
|
88
|
+
const historyState = createHistoryStateWithPreviousNextUrl(historyUpdateMode === "replace" ? window.history.state : null, previousNextUrl);
|
|
89
|
+
if (historyUpdateMode === "replace" && window.location.href !== targetHref) replaceHistoryStateWithoutNotify(historyState, "", href);
|
|
90
|
+
else if (historyUpdateMode === "push" && window.location.href !== targetHref) pushHistoryStateWithoutNotify(historyState, "", href);
|
|
91
|
+
commitClientNavigationState(navId);
|
|
74
92
|
};
|
|
75
93
|
}
|
|
76
94
|
function evictVisitedResponseCacheIfNeeded() {
|
|
@@ -80,38 +98,76 @@ function evictVisitedResponseCacheIfNeeded() {
|
|
|
80
98
|
visitedResponseCache.delete(oldest);
|
|
81
99
|
}
|
|
82
100
|
}
|
|
83
|
-
function getVisitedResponse(rscUrl, navigationKind) {
|
|
84
|
-
const
|
|
101
|
+
function getVisitedResponse(rscUrl, interceptionContext, mountedSlotsHeader, navigationKind) {
|
|
102
|
+
const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
|
|
103
|
+
const cached = visitedResponseCache.get(cacheKey);
|
|
85
104
|
if (!cached) return null;
|
|
105
|
+
if ((cached.response.mountedSlotsHeader ?? null) !== mountedSlotsHeader) {
|
|
106
|
+
visitedResponseCache.delete(cacheKey);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
86
109
|
if (navigationKind === "refresh") return null;
|
|
87
110
|
if (navigationKind === "traverse") {
|
|
88
111
|
const createdAt = cached.expiresAt - VISITED_RESPONSE_CACHE_TTL;
|
|
89
112
|
if (Date.now() - createdAt >= MAX_TRAVERSAL_CACHE_TTL) {
|
|
90
|
-
visitedResponseCache.delete(
|
|
113
|
+
visitedResponseCache.delete(cacheKey);
|
|
91
114
|
return null;
|
|
92
115
|
}
|
|
93
|
-
visitedResponseCache.delete(
|
|
94
|
-
visitedResponseCache.set(
|
|
116
|
+
visitedResponseCache.delete(cacheKey);
|
|
117
|
+
visitedResponseCache.set(cacheKey, cached);
|
|
95
118
|
return cached;
|
|
96
119
|
}
|
|
97
120
|
if (cached.expiresAt > Date.now()) {
|
|
98
|
-
visitedResponseCache.delete(
|
|
99
|
-
visitedResponseCache.set(
|
|
121
|
+
visitedResponseCache.delete(cacheKey);
|
|
122
|
+
visitedResponseCache.set(cacheKey, cached);
|
|
100
123
|
return cached;
|
|
101
124
|
}
|
|
102
|
-
visitedResponseCache.delete(
|
|
125
|
+
visitedResponseCache.delete(cacheKey);
|
|
103
126
|
return null;
|
|
104
127
|
}
|
|
105
|
-
function storeVisitedResponseSnapshot(rscUrl, snapshot, params) {
|
|
106
|
-
|
|
128
|
+
function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, params) {
|
|
129
|
+
const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
|
|
130
|
+
visitedResponseCache.delete(cacheKey);
|
|
107
131
|
evictVisitedResponseCacheIfNeeded();
|
|
108
132
|
const now = Date.now();
|
|
109
|
-
visitedResponseCache.set(
|
|
133
|
+
visitedResponseCache.set(cacheKey, {
|
|
110
134
|
params,
|
|
111
135
|
expiresAt: now + VISITED_RESPONSE_CACHE_TTL,
|
|
112
136
|
response: snapshot
|
|
113
137
|
});
|
|
114
138
|
}
|
|
139
|
+
function getRequestState(navigationKind, previousNextUrlOverride) {
|
|
140
|
+
if (previousNextUrlOverride !== void 0) return {
|
|
141
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrlOverride, __basePath),
|
|
142
|
+
previousNextUrl: previousNextUrlOverride
|
|
143
|
+
};
|
|
144
|
+
switch (navigationKind) {
|
|
145
|
+
case "navigate": return {
|
|
146
|
+
interceptionContext: getCurrentInterceptionContext(),
|
|
147
|
+
previousNextUrl: getCurrentNextUrl()
|
|
148
|
+
};
|
|
149
|
+
case "traverse": {
|
|
150
|
+
const previousNextUrl = readHistoryStatePreviousNextUrl(window.history.state);
|
|
151
|
+
return {
|
|
152
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrl, __basePath),
|
|
153
|
+
previousNextUrl
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "refresh": {
|
|
157
|
+
const currentPreviousNextUrl = getBrowserRouterState().previousNextUrl;
|
|
158
|
+
return {
|
|
159
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(currentPreviousNextUrl, __basePath),
|
|
160
|
+
previousNextUrl: currentPreviousNextUrl
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
default: throw new Error("[vinext] Unknown navigation kind: " + String(navigationKind));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function createRscRequestHeaders(interceptionContext) {
|
|
167
|
+
const headers = new Headers({ Accept: "text/x-component" });
|
|
168
|
+
if (interceptionContext !== null) headers.set("X-Vinext-Interception-Context", interceptionContext);
|
|
169
|
+
return headers;
|
|
170
|
+
}
|
|
115
171
|
/**
|
|
116
172
|
* Resolve all pending navigation commits with renderId <= the committed renderId.
|
|
117
173
|
* Note: Map iteration handles concurrent deletion safely — entries are visited in
|
|
@@ -137,63 +193,126 @@ function NavigationCommitSignal({ renderId, children }) {
|
|
|
137
193
|
}, [renderId]);
|
|
138
194
|
return children;
|
|
139
195
|
}
|
|
140
|
-
function
|
|
141
|
-
|
|
196
|
+
function normalizeAppElementsPromise(payload) {
|
|
197
|
+
return Promise.resolve(payload).then((elements) => normalizeAppElements(elements));
|
|
198
|
+
}
|
|
199
|
+
async function commitSameUrlNavigatePayload(nextElements, returnValue) {
|
|
200
|
+
const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
201
|
+
const currentState = getBrowserRouterState();
|
|
202
|
+
const startedNavigationId = activeNavigationId;
|
|
203
|
+
const { disposition, pending } = await resolveAndClassifyNavigationCommit({
|
|
204
|
+
activeNavigationId,
|
|
205
|
+
currentState,
|
|
206
|
+
navigationSnapshot,
|
|
207
|
+
nextElements,
|
|
208
|
+
renderId: ++nextNavigationRenderId,
|
|
209
|
+
startedNavigationId,
|
|
210
|
+
type: "navigate"
|
|
211
|
+
});
|
|
212
|
+
if (disposition === "hard-navigate") {
|
|
213
|
+
window.location.assign(window.location.href);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (disposition === "dispatch") dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "navigate", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, false);
|
|
217
|
+
if (returnValue) {
|
|
218
|
+
if (!returnValue.ok) throw returnValue.data;
|
|
219
|
+
return returnValue.data;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
223
|
+
const resolvedElements = use(initialElements);
|
|
224
|
+
const initialMetadata = readAppElementsMetadata(resolvedElements);
|
|
225
|
+
const [treeState, dispatchTreeState] = useReducer(routerReducer, {
|
|
226
|
+
elements: resolvedElements,
|
|
227
|
+
interceptionContext: initialMetadata.interceptionContext,
|
|
228
|
+
layoutFlags: initialMetadata.layoutFlags,
|
|
229
|
+
navigationSnapshot: initialNavigationSnapshot,
|
|
230
|
+
previousNextUrl: null,
|
|
142
231
|
renderId: 0,
|
|
143
|
-
|
|
144
|
-
|
|
232
|
+
rootLayoutTreePath: initialMetadata.rootLayoutTreePath,
|
|
233
|
+
routeId: initialMetadata.routeId
|
|
145
234
|
});
|
|
235
|
+
const stateRef = useRef(treeState);
|
|
236
|
+
stateRef.current = treeState;
|
|
237
|
+
useLayoutEffect(() => {
|
|
238
|
+
dispatchBrowserRouterAction = dispatchTreeState;
|
|
239
|
+
browserRouterStateRef = stateRef;
|
|
240
|
+
return () => {
|
|
241
|
+
if (dispatchBrowserRouterAction === dispatchTreeState) dispatchBrowserRouterAction = null;
|
|
242
|
+
if (browserRouterStateRef === stateRef) browserRouterStateRef = null;
|
|
243
|
+
setMountedSlotsHeader(null);
|
|
244
|
+
};
|
|
245
|
+
}, [dispatchTreeState]);
|
|
246
|
+
useLayoutEffect(() => {
|
|
247
|
+
setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
|
|
248
|
+
}, [treeState.elements]);
|
|
146
249
|
useLayoutEffect(() => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
250
|
+
if (treeState.renderId !== 0) return;
|
|
251
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, treeState.previousNextUrl), "", window.location.href);
|
|
252
|
+
}, [treeState.previousNextUrl, treeState.renderId]);
|
|
253
|
+
const committedTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
|
|
150
254
|
const ClientNavigationRenderContext = getClientNavigationRenderContext();
|
|
151
255
|
if (!ClientNavigationRenderContext) return committedTree;
|
|
152
256
|
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, committedTree);
|
|
153
257
|
}
|
|
154
|
-
function
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
};
|
|
170
|
-
if (node != null && typeof node.then === "function") {
|
|
171
|
-
const thenable = node;
|
|
172
|
-
if (useTransitionMode) thenable.then((resolved) => startTransition(() => resolvedThenSet(resolved)), handleAsyncError);
|
|
173
|
-
else thenable.then(resolvedThenSet, handleAsyncError);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
const syncNode = node;
|
|
177
|
-
if (useTransitionMode) {
|
|
178
|
-
startTransition(() => resolvedThenSet(syncNode));
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
resolvedThenSet(syncNode);
|
|
258
|
+
function dispatchBrowserTree(elements, navigationSnapshot, renderId, actionType, interceptionContext, layoutFlags, previousNextUrl, routeId, rootLayoutTreePath, useTransitionMode) {
|
|
259
|
+
const dispatch = getBrowserRouterDispatch();
|
|
260
|
+
const applyAction = () => dispatch({
|
|
261
|
+
elements,
|
|
262
|
+
interceptionContext,
|
|
263
|
+
layoutFlags,
|
|
264
|
+
navigationSnapshot,
|
|
265
|
+
previousNextUrl,
|
|
266
|
+
renderId,
|
|
267
|
+
rootLayoutTreePath,
|
|
268
|
+
routeId,
|
|
269
|
+
type: actionType
|
|
270
|
+
});
|
|
271
|
+
if (useTransitionMode) startTransition(applyAction);
|
|
272
|
+
else applyAction();
|
|
182
273
|
}
|
|
183
|
-
function renderNavigationPayload(payload, navigationSnapshot,
|
|
274
|
+
async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, useTransition = true, actionType = "navigate") {
|
|
184
275
|
const renderId = ++nextNavigationRenderId;
|
|
185
|
-
queuePrePaintNavigationEffect(renderId, prePaintEffect);
|
|
186
276
|
const committed = new Promise((resolve) => {
|
|
187
277
|
pendingNavigationCommits.set(renderId, resolve);
|
|
188
278
|
});
|
|
189
|
-
|
|
279
|
+
let snapshotActivated = false;
|
|
190
280
|
try {
|
|
191
|
-
|
|
281
|
+
const currentState = getBrowserRouterState();
|
|
282
|
+
const pending = await createPendingNavigationCommit({
|
|
283
|
+
currentState,
|
|
284
|
+
nextElements: payload,
|
|
285
|
+
navigationSnapshot,
|
|
286
|
+
previousNextUrl,
|
|
287
|
+
renderId,
|
|
288
|
+
type: actionType
|
|
289
|
+
});
|
|
290
|
+
const disposition = resolvePendingNavigationCommitDisposition({
|
|
291
|
+
activeNavigationId,
|
|
292
|
+
currentRootLayoutTreePath: currentState.rootLayoutTreePath,
|
|
293
|
+
nextRootLayoutTreePath: pending.rootLayoutTreePath,
|
|
294
|
+
startedNavigationId: navId
|
|
295
|
+
});
|
|
296
|
+
if (disposition === "skip") {
|
|
297
|
+
const resolve = pendingNavigationCommits.get(renderId);
|
|
298
|
+
pendingNavigationCommits.delete(renderId);
|
|
299
|
+
resolve?.();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (disposition === "hard-navigate") {
|
|
303
|
+
pendingNavigationCommits.delete(renderId);
|
|
304
|
+
window.location.assign(targetHref);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
queuePrePaintNavigationEffect(renderId, createNavigationCommitEffect(targetHref, historyUpdateMode, navId, params, pending.previousNextUrl));
|
|
308
|
+
activateNavigationSnapshot();
|
|
309
|
+
snapshotActivated = true;
|
|
310
|
+
dispatchBrowserTree(pending.action.elements, navigationSnapshot, renderId, actionType, pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, useTransition);
|
|
192
311
|
} catch (error) {
|
|
193
312
|
pendingNavigationPrePaintEffects.delete(renderId);
|
|
194
313
|
const resolve = pendingNavigationCommits.get(renderId);
|
|
195
314
|
pendingNavigationCommits.delete(renderId);
|
|
196
|
-
commitClientNavigationState();
|
|
315
|
+
if (snapshotActivated) commitClientNavigationState(navId);
|
|
197
316
|
resolve?.();
|
|
198
317
|
throw error;
|
|
199
318
|
}
|
|
@@ -245,9 +364,16 @@ function registerServerActionCallback() {
|
|
|
245
364
|
setServerCallback(async (id, args) => {
|
|
246
365
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
247
366
|
const body = await encodeReply(args, { temporaryReferences });
|
|
367
|
+
const currentState = getBrowserRouterState();
|
|
368
|
+
const { headers } = resolveServerActionRequestState({
|
|
369
|
+
actionId: id,
|
|
370
|
+
basePath: __basePath,
|
|
371
|
+
elements: currentState.elements,
|
|
372
|
+
previousNextUrl: currentState.previousNextUrl
|
|
373
|
+
});
|
|
248
374
|
const fetchResponse = await fetch(toRscUrl(window.location.pathname + window.location.search), {
|
|
249
375
|
method: "POST",
|
|
250
|
-
headers
|
|
376
|
+
headers,
|
|
251
377
|
body
|
|
252
378
|
});
|
|
253
379
|
const actionRedirect = fetchResponse.headers.get("x-action-redirect");
|
|
@@ -264,28 +390,21 @@ function registerServerActionCallback() {
|
|
|
264
390
|
}
|
|
265
391
|
clearClientNavigationCaches();
|
|
266
392
|
const result = await createFromFetch(Promise.resolve(fetchResponse), { temporaryReferences });
|
|
267
|
-
if (isServerActionResult(result))
|
|
268
|
-
|
|
269
|
-
if (result.returnValue) {
|
|
270
|
-
if (!result.returnValue.ok) throw result.returnValue.data;
|
|
271
|
-
return result.returnValue.data;
|
|
272
|
-
}
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
updateBrowserTree(result, createClientNavigationRenderSnapshot(window.location.href, latestClientParams), ++nextNavigationRenderId, false);
|
|
276
|
-
return result;
|
|
393
|
+
if (isServerActionResult(result)) return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result.root)), result.returnValue);
|
|
394
|
+
return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result)));
|
|
277
395
|
});
|
|
278
396
|
}
|
|
279
397
|
async function main() {
|
|
280
398
|
registerServerActionCallback();
|
|
281
|
-
const root = createFromReadableStream(await readInitialRscStream());
|
|
399
|
+
const root = normalizeAppElementsPromise(createFromReadableStream(await readInitialRscStream()));
|
|
282
400
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
401
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, null), "", window.location.href);
|
|
283
402
|
window.__VINEXT_RSC_ROOT__ = hydrateRoot(document, createElement(BrowserRoot, {
|
|
284
|
-
|
|
403
|
+
initialElements: root,
|
|
285
404
|
initialNavigationSnapshot
|
|
286
|
-
}), import.meta.env.DEV ? { onCaughtError
|
|
405
|
+
}), import.meta.env.DEV ? { onCaughtError: devOnCaughtError } : void 0);
|
|
287
406
|
window.__VINEXT_HYDRATED_AT = performance.now();
|
|
288
|
-
window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode) {
|
|
407
|
+
window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride) {
|
|
289
408
|
if (redirectDepth > 10) {
|
|
290
409
|
console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
291
410
|
window.location.href = href;
|
|
@@ -296,19 +415,25 @@ async function main() {
|
|
|
296
415
|
try {
|
|
297
416
|
const url = new URL(href, window.location.origin);
|
|
298
417
|
const rscUrl = toRscUrl(url.pathname + url.search);
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
const
|
|
418
|
+
const requestState = getRequestState(navigationKind, previousNextUrlOverride);
|
|
419
|
+
const requestInterceptionContext = requestState.interceptionContext;
|
|
420
|
+
const requestPreviousNextUrl = requestState.previousNextUrl;
|
|
421
|
+
const navState = getClientNavigationState();
|
|
422
|
+
const currentPath = navState?.pendingPathname ?? navState?.cachedPathname ?? stripBasePath(window.location.pathname, __basePath);
|
|
423
|
+
const isSameRoute = stripBasePath(url.pathname, __basePath) === currentPath;
|
|
424
|
+
setPendingPathname(url.pathname, navId);
|
|
425
|
+
const elementsAtNavStart = getBrowserRouterState().elements;
|
|
426
|
+
const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
|
|
427
|
+
const cachedRoute = getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
|
|
302
428
|
if (cachedRoute) {
|
|
303
429
|
if (navId !== activeNavigationId) return;
|
|
304
430
|
const cachedParams = cachedRoute.params;
|
|
305
431
|
const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(href, cachedParams);
|
|
306
|
-
const cachedPayload =
|
|
432
|
+
const cachedPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
|
|
307
433
|
if (navId !== activeNavigationId) return;
|
|
308
434
|
_snapshotPending = true;
|
|
309
|
-
stageClientParams(cachedParams);
|
|
310
435
|
try {
|
|
311
|
-
await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot,
|
|
436
|
+
await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, href, navId, historyUpdateMode, cachedParams, requestPreviousNextUrl, isSameRoute, toActionType(navigationKind));
|
|
312
437
|
} finally {
|
|
313
438
|
_snapshotPending = false;
|
|
314
439
|
}
|
|
@@ -317,28 +442,32 @@ async function main() {
|
|
|
317
442
|
let navResponse;
|
|
318
443
|
let navResponseUrl = null;
|
|
319
444
|
if (navigationKind !== "refresh") {
|
|
320
|
-
const prefetchedResponse = consumePrefetchResponse(rscUrl);
|
|
445
|
+
const prefetchedResponse = consumePrefetchResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader);
|
|
321
446
|
if (prefetchedResponse) {
|
|
322
447
|
navResponse = restoreRscResponse(prefetchedResponse, false);
|
|
323
448
|
navResponseUrl = prefetchedResponse.url;
|
|
324
449
|
}
|
|
325
450
|
}
|
|
326
|
-
if (!navResponse)
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
451
|
+
if (!navResponse) {
|
|
452
|
+
const requestHeaders = createRscRequestHeaders(requestInterceptionContext);
|
|
453
|
+
if (mountedSlotsHeader) requestHeaders.set("X-Vinext-Mounted-Slots", mountedSlotsHeader);
|
|
454
|
+
navResponse = await fetch(rscUrl, {
|
|
455
|
+
headers: requestHeaders,
|
|
456
|
+
credentials: "include"
|
|
457
|
+
});
|
|
458
|
+
}
|
|
330
459
|
if (navId !== activeNavigationId) return;
|
|
331
460
|
const finalUrl = new URL(navResponseUrl ?? navResponse.url, window.location.origin);
|
|
332
461
|
const requestedUrl = new URL(rscUrl, window.location.origin);
|
|
333
462
|
if (finalUrl.pathname !== requestedUrl.pathname) {
|
|
334
463
|
const destinationPath = finalUrl.pathname.replace(/\.rsc$/, "") + finalUrl.search;
|
|
335
|
-
replaceHistoryStateWithoutNotify(null, "", destinationPath);
|
|
464
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(null, requestPreviousNextUrl), "", destinationPath);
|
|
336
465
|
const navigate = window.__VINEXT_RSC_NAVIGATE__;
|
|
337
466
|
if (!navigate) {
|
|
338
467
|
window.location.href = destinationPath;
|
|
339
468
|
return;
|
|
340
469
|
}
|
|
341
|
-
return navigate(destinationPath, redirectDepth + 1, navigationKind, void 0);
|
|
470
|
+
return navigate(destinationPath, redirectDepth + 1, navigationKind, void 0, requestPreviousNextUrl);
|
|
342
471
|
}
|
|
343
472
|
let navParams = {};
|
|
344
473
|
const paramsHeader = navResponse.headers.get("X-Vinext-Params");
|
|
@@ -348,22 +477,23 @@ async function main() {
|
|
|
348
477
|
const navigationSnapshot = createClientNavigationRenderSnapshot(href, navParams);
|
|
349
478
|
const responseSnapshot = await snapshotRscResponse(navResponse);
|
|
350
479
|
if (navId !== activeNavigationId) return;
|
|
351
|
-
const rscPayload =
|
|
480
|
+
const rscPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(responseSnapshot))));
|
|
352
481
|
if (navId !== activeNavigationId) return;
|
|
353
482
|
_snapshotPending = true;
|
|
354
|
-
stageClientParams(navParams);
|
|
355
483
|
try {
|
|
356
|
-
await renderNavigationPayload(rscPayload, navigationSnapshot,
|
|
484
|
+
await renderNavigationPayload(rscPayload, navigationSnapshot, href, navId, historyUpdateMode, navParams, requestPreviousNextUrl, isSameRoute, toActionType(navigationKind));
|
|
357
485
|
} finally {
|
|
358
486
|
_snapshotPending = false;
|
|
359
487
|
}
|
|
360
|
-
|
|
488
|
+
if (navId !== activeNavigationId) return;
|
|
489
|
+
storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, readAppElementsMetadata(await rscPayload).interceptionContext), responseSnapshot, navParams);
|
|
361
490
|
return;
|
|
362
491
|
} catch (error) {
|
|
363
492
|
if (_snapshotPending) {
|
|
364
493
|
_snapshotPending = false;
|
|
365
|
-
commitClientNavigationState();
|
|
494
|
+
commitClientNavigationState(navId);
|
|
366
495
|
}
|
|
496
|
+
if (navId === activeNavigationId) clearPendingPathname(navId);
|
|
367
497
|
if (navId !== activeNavigationId) return;
|
|
368
498
|
console.error("[vinext] RSC navigation error:", error);
|
|
369
499
|
window.location.href = href;
|
|
@@ -382,13 +512,21 @@ async function main() {
|
|
|
382
512
|
if (import.meta.hot) import.meta.hot.on("rsc:update", async () => {
|
|
383
513
|
try {
|
|
384
514
|
clearClientNavigationCaches();
|
|
385
|
-
|
|
515
|
+
const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
516
|
+
const pending = await createPendingNavigationCommit({
|
|
517
|
+
currentState: getBrowserRouterState(),
|
|
518
|
+
nextElements: normalizeAppElementsPromise(createFromFetch(fetch(toRscUrl(window.location.pathname + window.location.search)))),
|
|
519
|
+
navigationSnapshot,
|
|
520
|
+
renderId: ++nextNavigationRenderId,
|
|
521
|
+
type: "replace"
|
|
522
|
+
});
|
|
523
|
+
dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "replace", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, false);
|
|
386
524
|
} catch (error) {
|
|
387
525
|
console.error("[vinext] RSC HMR error:", error);
|
|
388
526
|
}
|
|
389
527
|
});
|
|
390
528
|
}
|
|
391
|
-
main();
|
|
529
|
+
if (typeof document !== "undefined") main();
|
|
392
530
|
//#endregion
|
|
393
531
|
export {};
|
|
394
532
|
|