vinext 0.0.41 → 0.0.43
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 +0 -1
- 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 +2 -2
- package/dist/check.js.map +1 -1
- package/dist/cli.js +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 +315 -101
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/index.d.ts +1 -169
- package/dist/index.js +112 -432
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.d.ts +49 -1
- package/dist/plugins/fonts.js +96 -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 +44 -25
- package/dist/routing/app-router.js.map +1 -1
- package/dist/server/app-browser-entry.js +307 -100
- 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 +2 -1
- package/dist/server/app-page-boundary-render.js +40 -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 +7 -4
- package/dist/server/app-page-render.js +13 -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 +1 -0
- package/dist/server/app-page-response.js +1 -0
- 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 -83
- package/dist/server/app-page-route-wiring.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-policy.js +5 -3
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.js +2 -0
- 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.js +6 -2
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/dev-server.js +2 -4
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/middleware.js +1 -5
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/prod-server.d.ts +3 -3
- package/dist/server/prod-server.js +1 -1
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +2 -1
- package/dist/server/request-pipeline.js +34 -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 +56 -9
- package/dist/shims/navigation.js +112 -28
- 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/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/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 +3 -3
- 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, useRef, useState } 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,55 @@ let nextNavigationRenderId = 0;
|
|
|
14
21
|
let activeNavigationId = 0;
|
|
15
22
|
const pendingNavigationCommits = /* @__PURE__ */ new Map();
|
|
16
23
|
const pendingNavigationPrePaintEffects = /* @__PURE__ */ new Map();
|
|
17
|
-
|
|
24
|
+
function isRouterStatePromise(value) {
|
|
25
|
+
return value instanceof Promise;
|
|
26
|
+
}
|
|
27
|
+
let setBrowserRouterState = null;
|
|
28
|
+
let browserRouterStateRef = null;
|
|
29
|
+
let activePendingBrowserRouterState = null;
|
|
18
30
|
let latestClientParams = {};
|
|
19
31
|
const visitedResponseCache = /* @__PURE__ */ new Map();
|
|
20
32
|
function isServerActionResult(value) {
|
|
21
33
|
return !!value && typeof value === "object" && "root" in value;
|
|
22
34
|
}
|
|
23
|
-
function
|
|
24
|
-
if (!
|
|
25
|
-
return
|
|
35
|
+
function getBrowserRouterStateSetter() {
|
|
36
|
+
if (!setBrowserRouterState) throw new Error("[vinext] Browser router state setter is not initialized");
|
|
37
|
+
return setBrowserRouterState;
|
|
38
|
+
}
|
|
39
|
+
function getBrowserRouterState() {
|
|
40
|
+
if (!browserRouterStateRef) throw new Error("[vinext] Browser router state is not initialized");
|
|
41
|
+
return browserRouterStateRef.current;
|
|
42
|
+
}
|
|
43
|
+
function beginPendingBrowserRouterState() {
|
|
44
|
+
const setter = getBrowserRouterStateSetter();
|
|
45
|
+
if (activePendingBrowserRouterState && !activePendingBrowserRouterState.settled) {
|
|
46
|
+
activePendingBrowserRouterState.settled = true;
|
|
47
|
+
activePendingBrowserRouterState.resolve(getBrowserRouterState());
|
|
48
|
+
}
|
|
49
|
+
let resolve;
|
|
50
|
+
const promise = new Promise((resolvePromise) => {
|
|
51
|
+
resolve = resolvePromise;
|
|
52
|
+
});
|
|
53
|
+
const pending = {
|
|
54
|
+
promise,
|
|
55
|
+
resolve,
|
|
56
|
+
settled: false
|
|
57
|
+
};
|
|
58
|
+
activePendingBrowserRouterState = pending;
|
|
59
|
+
setter(promise);
|
|
60
|
+
return pending;
|
|
61
|
+
}
|
|
62
|
+
function settlePendingBrowserRouterState(pending) {
|
|
63
|
+
if (!pending || pending.settled) return;
|
|
64
|
+
pending.settled = true;
|
|
65
|
+
pending.resolve(getBrowserRouterState());
|
|
66
|
+
if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
|
|
67
|
+
}
|
|
68
|
+
function resolvePendingBrowserRouterState(pending, action) {
|
|
69
|
+
if (!pending || pending.settled) return;
|
|
70
|
+
pending.settled = true;
|
|
71
|
+
pending.resolve(routerReducer(getBrowserRouterState(), action));
|
|
72
|
+
if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
|
|
26
73
|
}
|
|
27
74
|
function applyClientParams(params) {
|
|
28
75
|
latestClientParams = params;
|
|
@@ -62,15 +109,21 @@ function drainPrePaintEffects(upToRenderId) {
|
|
|
62
109
|
for (const [id, effect] of pendingNavigationPrePaintEffects) if (id <= upToRenderId) {
|
|
63
110
|
pendingNavigationPrePaintEffects.delete(id);
|
|
64
111
|
if (id === upToRenderId) effect();
|
|
65
|
-
else commitClientNavigationState();
|
|
112
|
+
else commitClientNavigationState(void 0);
|
|
66
113
|
}
|
|
67
114
|
}
|
|
68
|
-
function createNavigationCommitEffect(href, historyUpdateMode) {
|
|
115
|
+
function createNavigationCommitEffect(href, historyUpdateMode, navId, params, previousNextUrl) {
|
|
69
116
|
return () => {
|
|
117
|
+
if (navId !== activeNavigationId) {
|
|
118
|
+
commitClientNavigationState(void 0);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
70
121
|
const targetHref = new URL(href, window.location.origin).href;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
stageClientParams(params);
|
|
123
|
+
const historyState = createHistoryStateWithPreviousNextUrl(historyUpdateMode === "replace" ? window.history.state : null, previousNextUrl);
|
|
124
|
+
if (historyUpdateMode === "replace" && window.location.href !== targetHref) replaceHistoryStateWithoutNotify(historyState, "", href);
|
|
125
|
+
else if (historyUpdateMode === "push" && window.location.href !== targetHref) pushHistoryStateWithoutNotify(historyState, "", href);
|
|
126
|
+
commitClientNavigationState(navId);
|
|
74
127
|
};
|
|
75
128
|
}
|
|
76
129
|
function evictVisitedResponseCacheIfNeeded() {
|
|
@@ -80,38 +133,76 @@ function evictVisitedResponseCacheIfNeeded() {
|
|
|
80
133
|
visitedResponseCache.delete(oldest);
|
|
81
134
|
}
|
|
82
135
|
}
|
|
83
|
-
function getVisitedResponse(rscUrl, navigationKind) {
|
|
84
|
-
const
|
|
136
|
+
function getVisitedResponse(rscUrl, interceptionContext, mountedSlotsHeader, navigationKind) {
|
|
137
|
+
const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
|
|
138
|
+
const cached = visitedResponseCache.get(cacheKey);
|
|
85
139
|
if (!cached) return null;
|
|
140
|
+
if ((cached.response.mountedSlotsHeader ?? null) !== mountedSlotsHeader) {
|
|
141
|
+
visitedResponseCache.delete(cacheKey);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
86
144
|
if (navigationKind === "refresh") return null;
|
|
87
145
|
if (navigationKind === "traverse") {
|
|
88
146
|
const createdAt = cached.expiresAt - VISITED_RESPONSE_CACHE_TTL;
|
|
89
147
|
if (Date.now() - createdAt >= MAX_TRAVERSAL_CACHE_TTL) {
|
|
90
|
-
visitedResponseCache.delete(
|
|
148
|
+
visitedResponseCache.delete(cacheKey);
|
|
91
149
|
return null;
|
|
92
150
|
}
|
|
93
|
-
visitedResponseCache.delete(
|
|
94
|
-
visitedResponseCache.set(
|
|
151
|
+
visitedResponseCache.delete(cacheKey);
|
|
152
|
+
visitedResponseCache.set(cacheKey, cached);
|
|
95
153
|
return cached;
|
|
96
154
|
}
|
|
97
155
|
if (cached.expiresAt > Date.now()) {
|
|
98
|
-
visitedResponseCache.delete(
|
|
99
|
-
visitedResponseCache.set(
|
|
156
|
+
visitedResponseCache.delete(cacheKey);
|
|
157
|
+
visitedResponseCache.set(cacheKey, cached);
|
|
100
158
|
return cached;
|
|
101
159
|
}
|
|
102
|
-
visitedResponseCache.delete(
|
|
160
|
+
visitedResponseCache.delete(cacheKey);
|
|
103
161
|
return null;
|
|
104
162
|
}
|
|
105
|
-
function storeVisitedResponseSnapshot(rscUrl, snapshot, params) {
|
|
106
|
-
|
|
163
|
+
function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, params) {
|
|
164
|
+
const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
|
|
165
|
+
visitedResponseCache.delete(cacheKey);
|
|
107
166
|
evictVisitedResponseCacheIfNeeded();
|
|
108
167
|
const now = Date.now();
|
|
109
|
-
visitedResponseCache.set(
|
|
168
|
+
visitedResponseCache.set(cacheKey, {
|
|
110
169
|
params,
|
|
111
170
|
expiresAt: now + VISITED_RESPONSE_CACHE_TTL,
|
|
112
171
|
response: snapshot
|
|
113
172
|
});
|
|
114
173
|
}
|
|
174
|
+
function getRequestState(navigationKind, previousNextUrlOverride) {
|
|
175
|
+
if (previousNextUrlOverride !== void 0) return {
|
|
176
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrlOverride, __basePath),
|
|
177
|
+
previousNextUrl: previousNextUrlOverride
|
|
178
|
+
};
|
|
179
|
+
switch (navigationKind) {
|
|
180
|
+
case "navigate": return {
|
|
181
|
+
interceptionContext: getCurrentInterceptionContext(),
|
|
182
|
+
previousNextUrl: getCurrentNextUrl()
|
|
183
|
+
};
|
|
184
|
+
case "traverse": {
|
|
185
|
+
const previousNextUrl = readHistoryStatePreviousNextUrl(window.history.state);
|
|
186
|
+
return {
|
|
187
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrl, __basePath),
|
|
188
|
+
previousNextUrl
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
case "refresh": {
|
|
192
|
+
const currentPreviousNextUrl = getBrowserRouterState().previousNextUrl;
|
|
193
|
+
return {
|
|
194
|
+
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(currentPreviousNextUrl, __basePath),
|
|
195
|
+
previousNextUrl: currentPreviousNextUrl
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
default: throw new Error("[vinext] Unknown navigation kind: " + String(navigationKind));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function createRscRequestHeaders(interceptionContext) {
|
|
202
|
+
const headers = new Headers({ Accept: "text/x-component" });
|
|
203
|
+
if (interceptionContext !== null) headers.set("X-Vinext-Interception-Context", interceptionContext);
|
|
204
|
+
return headers;
|
|
205
|
+
}
|
|
115
206
|
/**
|
|
116
207
|
* Resolve all pending navigation commits with renderId <= the committed renderId.
|
|
117
208
|
* Note: Map iteration handles concurrent deletion safely — entries are visited in
|
|
@@ -137,63 +228,137 @@ function NavigationCommitSignal({ renderId, children }) {
|
|
|
137
228
|
}, [renderId]);
|
|
138
229
|
return children;
|
|
139
230
|
}
|
|
140
|
-
function
|
|
141
|
-
|
|
231
|
+
function normalizeAppElementsPromise(payload) {
|
|
232
|
+
return Promise.resolve(payload).then((elements) => normalizeAppElements(elements));
|
|
233
|
+
}
|
|
234
|
+
async function commitSameUrlNavigatePayload(nextElements, returnValue) {
|
|
235
|
+
const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
236
|
+
const currentState = getBrowserRouterState();
|
|
237
|
+
const startedNavigationId = activeNavigationId;
|
|
238
|
+
const { disposition, pending } = await resolveAndClassifyNavigationCommit({
|
|
239
|
+
activeNavigationId,
|
|
240
|
+
currentState,
|
|
241
|
+
navigationSnapshot,
|
|
242
|
+
nextElements,
|
|
243
|
+
renderId: ++nextNavigationRenderId,
|
|
244
|
+
startedNavigationId,
|
|
245
|
+
type: "navigate"
|
|
246
|
+
});
|
|
247
|
+
if (disposition === "hard-navigate") {
|
|
248
|
+
window.location.assign(window.location.href);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (disposition === "dispatch") dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "navigate", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
|
|
252
|
+
if (returnValue) {
|
|
253
|
+
if (!returnValue.ok) throw returnValue.data;
|
|
254
|
+
return returnValue.data;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
258
|
+
const resolvedElements = use(initialElements);
|
|
259
|
+
const initialMetadata = readAppElementsMetadata(resolvedElements);
|
|
260
|
+
const [treeStateValue, setTreeStateValue] = useState({
|
|
261
|
+
elements: resolvedElements,
|
|
262
|
+
interceptionContext: initialMetadata.interceptionContext,
|
|
263
|
+
layoutFlags: initialMetadata.layoutFlags,
|
|
264
|
+
navigationSnapshot: initialNavigationSnapshot,
|
|
265
|
+
previousNextUrl: null,
|
|
142
266
|
renderId: 0,
|
|
143
|
-
|
|
144
|
-
|
|
267
|
+
rootLayoutTreePath: initialMetadata.rootLayoutTreePath,
|
|
268
|
+
routeId: initialMetadata.routeId
|
|
145
269
|
});
|
|
270
|
+
const treeState = isRouterStatePromise(treeStateValue) ? use(treeStateValue) : treeStateValue;
|
|
271
|
+
const stateRef = useRef(treeState);
|
|
272
|
+
stateRef.current = treeState;
|
|
146
273
|
useLayoutEffect(() => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
274
|
+
setBrowserRouterState = setTreeStateValue;
|
|
275
|
+
browserRouterStateRef = stateRef;
|
|
276
|
+
return () => {
|
|
277
|
+
if (setBrowserRouterState === setTreeStateValue) setBrowserRouterState = null;
|
|
278
|
+
if (browserRouterStateRef === stateRef) browserRouterStateRef = null;
|
|
279
|
+
setMountedSlotsHeader(null);
|
|
280
|
+
};
|
|
281
|
+
}, [setTreeStateValue]);
|
|
282
|
+
useLayoutEffect(() => {
|
|
283
|
+
setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
|
|
284
|
+
}, [treeState.elements]);
|
|
285
|
+
useLayoutEffect(() => {
|
|
286
|
+
if (treeState.renderId !== 0) return;
|
|
287
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, treeState.previousNextUrl), "", window.location.href);
|
|
288
|
+
}, [treeState.previousNextUrl, treeState.renderId]);
|
|
289
|
+
const committedTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
|
|
150
290
|
const ClientNavigationRenderContext = getClientNavigationRenderContext();
|
|
151
291
|
if (!ClientNavigationRenderContext) return committedTree;
|
|
152
292
|
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, committedTree);
|
|
153
293
|
}
|
|
154
|
-
function
|
|
155
|
-
const setter =
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
294
|
+
function dispatchBrowserTree(elements, navigationSnapshot, renderId, actionType, interceptionContext, layoutFlags, previousNextUrl, routeId, rootLayoutTreePath, pendingRouterState, useTransitionMode) {
|
|
295
|
+
const setter = getBrowserRouterStateSetter();
|
|
296
|
+
const action = {
|
|
297
|
+
elements,
|
|
298
|
+
interceptionContext,
|
|
299
|
+
layoutFlags,
|
|
300
|
+
navigationSnapshot,
|
|
301
|
+
previousNextUrl,
|
|
302
|
+
renderId,
|
|
303
|
+
rootLayoutTreePath,
|
|
304
|
+
routeId,
|
|
305
|
+
type: actionType
|
|
162
306
|
};
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
307
|
+
const applyAction = () => {
|
|
308
|
+
if (pendingRouterState) {
|
|
309
|
+
resolvePendingBrowserRouterState(pendingRouterState, action);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
setter(routerReducer(getBrowserRouterState(), action));
|
|
169
313
|
};
|
|
170
|
-
if (
|
|
171
|
-
|
|
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);
|
|
314
|
+
if (useTransitionMode) startTransition(applyAction);
|
|
315
|
+
else applyAction();
|
|
182
316
|
}
|
|
183
|
-
function renderNavigationPayload(payload, navigationSnapshot,
|
|
317
|
+
async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, useTransition = true, actionType = "navigate") {
|
|
184
318
|
const renderId = ++nextNavigationRenderId;
|
|
185
|
-
queuePrePaintNavigationEffect(renderId, prePaintEffect);
|
|
186
319
|
const committed = new Promise((resolve) => {
|
|
187
320
|
pendingNavigationCommits.set(renderId, resolve);
|
|
188
321
|
});
|
|
189
|
-
|
|
322
|
+
let snapshotActivated = false;
|
|
190
323
|
try {
|
|
191
|
-
|
|
324
|
+
const currentState = getBrowserRouterState();
|
|
325
|
+
const pending = await createPendingNavigationCommit({
|
|
326
|
+
currentState,
|
|
327
|
+
nextElements: payload,
|
|
328
|
+
navigationSnapshot,
|
|
329
|
+
previousNextUrl,
|
|
330
|
+
renderId,
|
|
331
|
+
type: actionType
|
|
332
|
+
});
|
|
333
|
+
const disposition = resolvePendingNavigationCommitDisposition({
|
|
334
|
+
activeNavigationId,
|
|
335
|
+
currentRootLayoutTreePath: currentState.rootLayoutTreePath,
|
|
336
|
+
nextRootLayoutTreePath: pending.rootLayoutTreePath,
|
|
337
|
+
startedNavigationId: navId
|
|
338
|
+
});
|
|
339
|
+
if (disposition === "skip") {
|
|
340
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
341
|
+
const resolve = pendingNavigationCommits.get(renderId);
|
|
342
|
+
pendingNavigationCommits.delete(renderId);
|
|
343
|
+
resolve?.();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (disposition === "hard-navigate") {
|
|
347
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
348
|
+
pendingNavigationCommits.delete(renderId);
|
|
349
|
+
window.location.assign(targetHref);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
queuePrePaintNavigationEffect(renderId, createNavigationCommitEffect(targetHref, historyUpdateMode, navId, params, pending.previousNextUrl));
|
|
353
|
+
activateNavigationSnapshot();
|
|
354
|
+
snapshotActivated = true;
|
|
355
|
+
dispatchBrowserTree(pending.action.elements, navigationSnapshot, renderId, actionType, pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, pendingRouterState, useTransition);
|
|
192
356
|
} catch (error) {
|
|
193
357
|
pendingNavigationPrePaintEffects.delete(renderId);
|
|
194
358
|
const resolve = pendingNavigationCommits.get(renderId);
|
|
195
359
|
pendingNavigationCommits.delete(renderId);
|
|
196
|
-
commitClientNavigationState();
|
|
360
|
+
if (snapshotActivated) commitClientNavigationState(navId);
|
|
361
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
197
362
|
resolve?.();
|
|
198
363
|
throw error;
|
|
199
364
|
}
|
|
@@ -245,9 +410,16 @@ function registerServerActionCallback() {
|
|
|
245
410
|
setServerCallback(async (id, args) => {
|
|
246
411
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
247
412
|
const body = await encodeReply(args, { temporaryReferences });
|
|
413
|
+
const currentState = getBrowserRouterState();
|
|
414
|
+
const { headers } = resolveServerActionRequestState({
|
|
415
|
+
actionId: id,
|
|
416
|
+
basePath: __basePath,
|
|
417
|
+
elements: currentState.elements,
|
|
418
|
+
previousNextUrl: currentState.previousNextUrl
|
|
419
|
+
});
|
|
248
420
|
const fetchResponse = await fetch(toRscUrl(window.location.pathname + window.location.search), {
|
|
249
421
|
method: "POST",
|
|
250
|
-
headers
|
|
422
|
+
headers,
|
|
251
423
|
body
|
|
252
424
|
});
|
|
253
425
|
const actionRedirect = fetchResponse.headers.get("x-action-redirect");
|
|
@@ -264,51 +436,58 @@ function registerServerActionCallback() {
|
|
|
264
436
|
}
|
|
265
437
|
clearClientNavigationCaches();
|
|
266
438
|
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;
|
|
439
|
+
if (isServerActionResult(result)) return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result.root)), result.returnValue);
|
|
440
|
+
return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result)));
|
|
277
441
|
});
|
|
278
442
|
}
|
|
279
443
|
async function main() {
|
|
280
444
|
registerServerActionCallback();
|
|
281
|
-
const root = createFromReadableStream(await readInitialRscStream());
|
|
445
|
+
const root = normalizeAppElementsPromise(createFromReadableStream(await readInitialRscStream()));
|
|
282
446
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
447
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, null), "", window.location.href);
|
|
283
448
|
window.__VINEXT_RSC_ROOT__ = hydrateRoot(document, createElement(BrowserRoot, {
|
|
284
|
-
|
|
449
|
+
initialElements: root,
|
|
285
450
|
initialNavigationSnapshot
|
|
286
|
-
}), import.meta.env.DEV ? { onCaughtError
|
|
451
|
+
}), import.meta.env.DEV ? { onCaughtError: devOnCaughtError } : void 0);
|
|
287
452
|
window.__VINEXT_HYDRATED_AT = performance.now();
|
|
288
|
-
window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode) {
|
|
453
|
+
window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false) {
|
|
289
454
|
if (redirectDepth > 10) {
|
|
290
455
|
console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
291
456
|
window.location.href = href;
|
|
292
457
|
return;
|
|
293
458
|
}
|
|
294
459
|
let _snapshotPending = false;
|
|
460
|
+
let pendingRouterState = null;
|
|
295
461
|
const navId = ++activeNavigationId;
|
|
296
462
|
try {
|
|
463
|
+
if (programmaticTransition) pendingRouterState = beginPendingBrowserRouterState();
|
|
297
464
|
const url = new URL(href, window.location.origin);
|
|
298
465
|
const rscUrl = toRscUrl(url.pathname + url.search);
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
const
|
|
466
|
+
const requestState = getRequestState(navigationKind, previousNextUrlOverride);
|
|
467
|
+
const requestInterceptionContext = requestState.interceptionContext;
|
|
468
|
+
const requestPreviousNextUrl = requestState.previousNextUrl;
|
|
469
|
+
const navState = getClientNavigationState();
|
|
470
|
+
const currentPath = navState?.pendingPathname ?? navState?.cachedPathname ?? stripBasePath(window.location.pathname, __basePath);
|
|
471
|
+
const isSameRoute = stripBasePath(url.pathname, __basePath) === currentPath;
|
|
472
|
+
setPendingPathname(url.pathname, navId);
|
|
473
|
+
const elementsAtNavStart = getBrowserRouterState().elements;
|
|
474
|
+
const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
|
|
475
|
+
const cachedRoute = getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
|
|
302
476
|
if (cachedRoute) {
|
|
303
|
-
if (navId !== activeNavigationId)
|
|
477
|
+
if (navId !== activeNavigationId) {
|
|
478
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
304
481
|
const cachedParams = cachedRoute.params;
|
|
305
482
|
const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(href, cachedParams);
|
|
306
|
-
const cachedPayload =
|
|
307
|
-
if (navId !== activeNavigationId)
|
|
483
|
+
const cachedPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
|
|
484
|
+
if (navId !== activeNavigationId) {
|
|
485
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
308
488
|
_snapshotPending = true;
|
|
309
|
-
stageClientParams(cachedParams);
|
|
310
489
|
try {
|
|
311
|
-
await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot,
|
|
490
|
+
await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, href, navId, historyUpdateMode, cachedParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
|
|
312
491
|
} finally {
|
|
313
492
|
_snapshotPending = false;
|
|
314
493
|
}
|
|
@@ -317,28 +496,37 @@ async function main() {
|
|
|
317
496
|
let navResponse;
|
|
318
497
|
let navResponseUrl = null;
|
|
319
498
|
if (navigationKind !== "refresh") {
|
|
320
|
-
const prefetchedResponse = consumePrefetchResponse(rscUrl);
|
|
499
|
+
const prefetchedResponse = consumePrefetchResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader);
|
|
321
500
|
if (prefetchedResponse) {
|
|
322
501
|
navResponse = restoreRscResponse(prefetchedResponse, false);
|
|
323
502
|
navResponseUrl = prefetchedResponse.url;
|
|
324
503
|
}
|
|
325
504
|
}
|
|
326
|
-
if (!navResponse)
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
505
|
+
if (!navResponse) {
|
|
506
|
+
const requestHeaders = createRscRequestHeaders(requestInterceptionContext);
|
|
507
|
+
if (mountedSlotsHeader) requestHeaders.set("X-Vinext-Mounted-Slots", mountedSlotsHeader);
|
|
508
|
+
navResponse = await fetch(rscUrl, {
|
|
509
|
+
headers: requestHeaders,
|
|
510
|
+
credentials: "include"
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (navId !== activeNavigationId) {
|
|
514
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
331
517
|
const finalUrl = new URL(navResponseUrl ?? navResponse.url, window.location.origin);
|
|
332
518
|
const requestedUrl = new URL(rscUrl, window.location.origin);
|
|
333
519
|
if (finalUrl.pathname !== requestedUrl.pathname) {
|
|
334
520
|
const destinationPath = finalUrl.pathname.replace(/\.rsc$/, "") + finalUrl.search;
|
|
335
|
-
replaceHistoryStateWithoutNotify(null, "", destinationPath);
|
|
521
|
+
replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(null, requestPreviousNextUrl), "", destinationPath);
|
|
336
522
|
const navigate = window.__VINEXT_RSC_NAVIGATE__;
|
|
337
523
|
if (!navigate) {
|
|
524
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
338
525
|
window.location.href = destinationPath;
|
|
339
526
|
return;
|
|
340
527
|
}
|
|
341
|
-
|
|
528
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
529
|
+
return navigate(destinationPath, redirectDepth + 1, navigationKind, void 0, requestPreviousNextUrl, false);
|
|
342
530
|
}
|
|
343
531
|
let navParams = {};
|
|
344
532
|
const paramsHeader = navResponse.headers.get("X-Vinext-Params");
|
|
@@ -347,23 +535,34 @@ async function main() {
|
|
|
347
535
|
} catch {}
|
|
348
536
|
const navigationSnapshot = createClientNavigationRenderSnapshot(href, navParams);
|
|
349
537
|
const responseSnapshot = await snapshotRscResponse(navResponse);
|
|
350
|
-
if (navId !== activeNavigationId)
|
|
351
|
-
|
|
352
|
-
|
|
538
|
+
if (navId !== activeNavigationId) {
|
|
539
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
const rscPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(responseSnapshot))));
|
|
543
|
+
if (navId !== activeNavigationId) {
|
|
544
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
353
547
|
_snapshotPending = true;
|
|
354
|
-
stageClientParams(navParams);
|
|
355
548
|
try {
|
|
356
|
-
await renderNavigationPayload(rscPayload, navigationSnapshot,
|
|
549
|
+
await renderNavigationPayload(rscPayload, navigationSnapshot, href, navId, historyUpdateMode, navParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
|
|
357
550
|
} finally {
|
|
358
551
|
_snapshotPending = false;
|
|
359
552
|
}
|
|
360
|
-
|
|
553
|
+
if (navId !== activeNavigationId) {
|
|
554
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, readAppElementsMetadata(await rscPayload).interceptionContext), responseSnapshot, navParams);
|
|
361
558
|
return;
|
|
362
559
|
} catch (error) {
|
|
363
560
|
if (_snapshotPending) {
|
|
364
561
|
_snapshotPending = false;
|
|
365
|
-
commitClientNavigationState();
|
|
562
|
+
commitClientNavigationState(navId);
|
|
366
563
|
}
|
|
564
|
+
settlePendingBrowserRouterState(pendingRouterState);
|
|
565
|
+
if (navId === activeNavigationId) clearPendingPathname(navId);
|
|
367
566
|
if (navId !== activeNavigationId) return;
|
|
368
567
|
console.error("[vinext] RSC navigation error:", error);
|
|
369
568
|
window.location.href = href;
|
|
@@ -382,13 +581,21 @@ async function main() {
|
|
|
382
581
|
if (import.meta.hot) import.meta.hot.on("rsc:update", async () => {
|
|
383
582
|
try {
|
|
384
583
|
clearClientNavigationCaches();
|
|
385
|
-
|
|
584
|
+
const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
585
|
+
const pending = await createPendingNavigationCommit({
|
|
586
|
+
currentState: getBrowserRouterState(),
|
|
587
|
+
nextElements: normalizeAppElementsPromise(createFromFetch(fetch(toRscUrl(window.location.pathname + window.location.search)))),
|
|
588
|
+
navigationSnapshot,
|
|
589
|
+
renderId: ++nextNavigationRenderId,
|
|
590
|
+
type: "replace"
|
|
591
|
+
});
|
|
592
|
+
dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "replace", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
|
|
386
593
|
} catch (error) {
|
|
387
594
|
console.error("[vinext] RSC HMR error:", error);
|
|
388
595
|
}
|
|
389
596
|
});
|
|
390
597
|
}
|
|
391
|
-
main();
|
|
598
|
+
if (typeof document !== "undefined") main();
|
|
392
599
|
//#endregion
|
|
393
600
|
export {};
|
|
394
601
|
|