react-router 8.4.0 → 8.5.0
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/CHANGELOG.md +51 -1
- package/dist/development/dom-export.d.ts +2 -1
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +2 -2
- package/dist/development/index-react-server.d.ts +583 -165
- package/dist/development/index-react-server.js +27 -19
- package/dist/development/index.d.ts +9 -8
- package/dist/development/index.js +5 -4
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +22 -3
- package/dist/development/lib/context.d.ts +6 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.d.ts +3 -0
- package/dist/development/lib/dom/dom.js +1 -1
- package/dist/development/lib/dom/global.d.ts +35 -0
- package/dist/development/lib/dom/lib.d.ts +34 -9
- package/dist/development/lib/dom/lib.js +17 -6
- package/dist/development/lib/dom/server.js +2 -2
- package/dist/development/lib/dom/ssr/components.js +12 -9
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/entry.d.ts +9 -2
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.d.ts +3 -2
- package/dist/development/lib/dom/ssr/fog-of-war.js +14 -11
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/route-discovery.d.ts +120 -0
- package/dist/development/lib/dom/ssr/route-discovery.js +415 -0
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +2 -2
- package/dist/development/lib/dom/ssr/routes.d.ts +2 -2
- package/dist/development/lib/dom/ssr/routes.js +8 -8
- package/dist/development/lib/dom/ssr/server.js +3 -1
- package/dist/development/lib/dom/ssr/single-fetch.d.ts +28 -2
- package/dist/development/lib/dom/ssr/single-fetch.js +73 -55
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.d.ts +28 -0
- package/dist/development/lib/dom-export/hydrated-router.js +32 -12
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +3 -3
- package/dist/development/lib/hooks.js +4 -4
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +1 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/development/lib/router/matcher.js +1 -1
- package/dist/development/lib/router/navigation.js +1 -1
- package/dist/development/lib/router/router.d.ts +6 -0
- package/dist/development/lib/router/router.js +157 -65
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +24 -4
- package/dist/development/lib/router/utils.js +4 -3
- package/dist/development/lib/rsc/browser.js +2 -2
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +24 -12
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/development/lib/rsc/server.ssr.js +1 -1
- package/dist/development/lib/server-runtime/build.d.ts +14 -0
- package/dist/development/lib/server-runtime/cookies.js +1 -1
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.d.ts +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +12 -4
- package/dist/development/lib/server-runtime/serverHandoff.d.ts +17 -0
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions.js +1 -1
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/lib/types/route-data.d.ts +2 -2
- package/dist/development/lib/types/route-module-annotations.d.ts +1 -1
- package/dist/development/route-pattern.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.d.ts +2 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +2 -2
- package/dist/production/index-react-server.d.ts +583 -165
- package/dist/production/index-react-server.js +27 -19
- package/dist/production/index.d.ts +9 -8
- package/dist/production/index.js +5 -4
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +22 -3
- package/dist/production/lib/context.d.ts +6 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.d.ts +3 -0
- package/dist/production/lib/dom/dom.js +1 -1
- package/dist/production/lib/dom/global.d.ts +35 -0
- package/dist/production/lib/dom/lib.d.ts +34 -9
- package/dist/production/lib/dom/lib.js +17 -6
- package/dist/production/lib/dom/server.js +2 -2
- package/dist/production/lib/dom/ssr/components.js +12 -9
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/entry.d.ts +9 -2
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.d.ts +3 -2
- package/dist/production/lib/dom/ssr/fog-of-war.js +14 -11
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/route-discovery.d.ts +120 -0
- package/dist/production/lib/dom/ssr/route-discovery.js +415 -0
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +2 -2
- package/dist/production/lib/dom/ssr/routes.d.ts +2 -2
- package/dist/production/lib/dom/ssr/routes.js +8 -8
- package/dist/production/lib/dom/ssr/server.js +3 -1
- package/dist/production/lib/dom/ssr/single-fetch.d.ts +28 -2
- package/dist/production/lib/dom/ssr/single-fetch.js +73 -55
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.d.ts +28 -0
- package/dist/production/lib/dom-export/hydrated-router.js +32 -12
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +3 -3
- package/dist/production/lib/hooks.js +3 -3
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +1 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/production/lib/router/matcher.js +1 -1
- package/dist/production/lib/router/navigation.js +1 -1
- package/dist/production/lib/router/router.d.ts +6 -0
- package/dist/production/lib/router/router.js +157 -65
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +24 -4
- package/dist/production/lib/router/utils.js +4 -3
- package/dist/production/lib/rsc/browser.js +2 -2
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +24 -12
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/production/lib/rsc/server.ssr.js +1 -1
- package/dist/production/lib/server-runtime/build.d.ts +14 -0
- package/dist/production/lib/server-runtime/cookies.js +1 -1
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.d.ts +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +12 -4
- package/dist/production/lib/server-runtime/serverHandoff.d.ts +17 -0
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions.js +1 -1
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/lib/types/route-data.d.ts +2 -2
- package/dist/production/lib/types/route-module-annotations.d.ts +1 -1
- package/dist/production/route-pattern.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/lazy-route-discovery.md +4 -0
- package/docs/explanation/sessions-and-cookies.md +108 -4
- package/docs/how-to/custom-fetch.md +218 -0
- package/docs/how-to/data-strategy.md +23 -1
- package/docs/how-to/middleware.md +1 -0
- package/docs/how-to/optimize-revalidation.md +2 -2
- package/docs/how-to/pre-rendering.md +23 -1
- package/docs/how-to/route-discovery.md +145 -0
- package/docs/how-to/spa.md +2 -0
- package/docs/how-to/view-transitions.md +80 -13
- package/docs/start/framework/navigating.md +5 -9
- package/docs/start/framework/rendering.md +37 -0
- package/package.json +9 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.5.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -56,7 +56,7 @@ function StreamTransfer({ context, identifier, reader, textDecoder, nonce }) {
|
|
|
56
56
|
nonce
|
|
57
57
|
})));
|
|
58
58
|
}
|
|
59
|
-
function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr) {
|
|
59
|
+
function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, fetchImplementation = (request) => fetch(request), isApiOnly = false, serverOrigin) {
|
|
60
60
|
let dataStrategy = getSingleFetchDataStrategyImpl(getRouter, (match) => {
|
|
61
61
|
let manifestRoute = manifest.routes[match.route.id];
|
|
62
62
|
invariant(manifestRoute, "Route not found in manifest");
|
|
@@ -64,10 +64,10 @@ function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules
|
|
|
64
64
|
hasLoader: manifestRoute.hasLoader,
|
|
65
65
|
hasClientLoader: manifestRoute.hasClientLoader
|
|
66
66
|
};
|
|
67
|
-
}, fetchAndDecodeViaTurboStream, ssr);
|
|
67
|
+
}, fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin), ssr, void 0, isApiOnly);
|
|
68
68
|
return async (args) => args.runClientMiddleware(dataStrategy);
|
|
69
69
|
}
|
|
70
|
-
function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true) {
|
|
70
|
+
function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false) {
|
|
71
71
|
return async (args) => {
|
|
72
72
|
let { request, matches, fetcherKey } = args;
|
|
73
73
|
let router = getRouter();
|
|
@@ -78,7 +78,7 @@ function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode,
|
|
|
78
78
|
});
|
|
79
79
|
if (!ssr && !foundRevalidatingServerLoader) return nonSsrStrategy(args, getRouteInfo, fetchAndDecode);
|
|
80
80
|
if (fetcherKey) return singleFetchLoaderFetcherStrategy(args, fetchAndDecode);
|
|
81
|
-
return singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut);
|
|
81
|
+
return singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut, isApiOnly);
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
async function singleFetchActionStrategy(args, fetchAndDecode) {
|
|
@@ -113,7 +113,7 @@ async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode) {
|
|
|
113
113
|
}));
|
|
114
114
|
return results;
|
|
115
115
|
}
|
|
116
|
-
async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true) {
|
|
116
|
+
async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false) {
|
|
117
117
|
let routesParams = /* @__PURE__ */ new Set();
|
|
118
118
|
let foundOptOutRoute = false;
|
|
119
119
|
let routeDfds = args.matches.map(() => createDeferred());
|
|
@@ -162,7 +162,7 @@ async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, f
|
|
|
162
162
|
}
|
|
163
163
|
})));
|
|
164
164
|
await Promise.all(routeDfds.map((d) => d.promise));
|
|
165
|
-
if ((!router.state.initialized && router.state.navigation.state === "idle" || routesParams.size === 0) && !window.__reactRouterHdrActive) singleFetchDfd.resolve({ routes: {} });
|
|
165
|
+
if ((!router.state.initialized && router.state.navigation.state === "idle" && !isApiOnly || routesParams.size === 0) && !window.__reactRouterHdrActive) singleFetchDfd.resolve({ routes: {} });
|
|
166
166
|
else {
|
|
167
167
|
let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;
|
|
168
168
|
try {
|
|
@@ -216,61 +216,79 @@ function stripIndexParam(url) {
|
|
|
216
216
|
for (let toKeep of indexValuesToKeep) url.searchParams.append("index", toKeep);
|
|
217
217
|
return url;
|
|
218
218
|
}
|
|
219
|
-
function singleFetchUrl(reqUrl, extension) {
|
|
220
|
-
let url = typeof reqUrl === "string" ? new URL(reqUrl, typeof window === "undefined" ? "server://singlefetch/" : window.location.origin) : reqUrl;
|
|
219
|
+
function singleFetchUrl(reqUrl, extension, serverOrigin) {
|
|
220
|
+
let url = typeof reqUrl === "string" ? new URL(reqUrl, serverOrigin ?? (typeof window === "undefined" ? "server://singlefetch/" : window.location.origin)) : new URL(reqUrl);
|
|
221
|
+
if (serverOrigin && url.origin !== serverOrigin) url = new URL(url.pathname + url.search + url.hash, serverOrigin);
|
|
221
222
|
if (url.pathname.endsWith("/")) url.pathname = `${url.pathname}_.${extension}`;
|
|
222
223
|
else url.pathname = `${url.pathname}.${extension}`;
|
|
223
224
|
return url;
|
|
224
225
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
url = stripIndexParam(url);
|
|
230
|
-
if (targetRoutes) url.searchParams.set("_routes", targetRoutes.join(","));
|
|
231
|
-
}
|
|
232
|
-
let res = await fetch(url, await createRequestInit(request));
|
|
233
|
-
if (res.status >= 400 && !res.headers.has("X-Remix-Response")) throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
|
|
234
|
-
if (res.status === 204 && res.headers.has("X-Remix-Redirect")) return {
|
|
235
|
-
status: 202,
|
|
236
|
-
data: { redirect: {
|
|
237
|
-
redirect: res.headers.get("X-Remix-Redirect"),
|
|
238
|
-
status: Number(res.headers.get("X-Remix-Status") || "302"),
|
|
239
|
-
revalidate: res.headers.get("X-Remix-Revalidate") === "true",
|
|
240
|
-
reload: res.headers.get("X-Remix-Reload-Document") === "true",
|
|
241
|
-
replace: res.headers.get("X-Remix-Replace") === "true"
|
|
242
|
-
} }
|
|
243
|
-
};
|
|
244
|
-
if (NO_BODY_STATUS_CODES.has(res.status)) {
|
|
245
|
-
let routes = {};
|
|
246
|
-
if (targetRoutes && request.method !== "GET") routes[targetRoutes[0]] = { data: void 0 };
|
|
247
|
-
return {
|
|
248
|
-
status: res.status,
|
|
249
|
-
data: { routes }
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
invariant(res.body, "No response body to decode");
|
|
253
|
-
try {
|
|
254
|
-
let decoded = await decodeViaTurboStream(res.body, window);
|
|
255
|
-
let data;
|
|
226
|
+
function fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin) {
|
|
227
|
+
return async (args, targetRoutes) => {
|
|
228
|
+
let { request } = args;
|
|
229
|
+
let url = singleFetchUrl(request.url, "data", serverOrigin);
|
|
256
230
|
if (request.method === "GET") {
|
|
257
|
-
|
|
258
|
-
if (
|
|
259
|
-
else data = { routes: typed };
|
|
260
|
-
} else {
|
|
261
|
-
let typed = decoded.value;
|
|
262
|
-
let routeId = targetRoutes?.[0];
|
|
263
|
-
invariant(routeId, "No routeId found for single fetch call decoding");
|
|
264
|
-
if ("redirect" in typed) data = { redirect: typed };
|
|
265
|
-
else data = { routes: { [routeId]: typed } };
|
|
231
|
+
url = stripIndexParam(url);
|
|
232
|
+
if (targetRoutes) url.searchParams.set("_routes", targetRoutes.join(","));
|
|
266
233
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
234
|
+
let req = new Request(url, await createRequestInit(request));
|
|
235
|
+
invariant(args.unstable_initiator !== "static", "Static data strategy initiator used for a client data request");
|
|
236
|
+
let fetchContext;
|
|
237
|
+
if (args.unstable_initiator === "navigation") {
|
|
238
|
+
invariant(args.unstable_navigationType !== null, "Missing navigation type for a navigation data request");
|
|
239
|
+
fetchContext = {
|
|
240
|
+
type: "navigation",
|
|
241
|
+
fetcherKey: args.fetcherKey,
|
|
242
|
+
navigationType: args.unstable_navigationType
|
|
243
|
+
};
|
|
244
|
+
} else fetchContext = {
|
|
245
|
+
type: args.unstable_initiator,
|
|
246
|
+
fetcherKey: args.fetcherKey,
|
|
247
|
+
navigationType: null
|
|
270
248
|
};
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
249
|
+
let res = await fetchImplementation(req, fetchContext);
|
|
250
|
+
if (res.status >= 400 && !res.headers.has("X-Remix-Response")) throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
|
|
251
|
+
if (res.status === 204 && res.headers.has("X-Remix-Redirect")) return {
|
|
252
|
+
status: 202,
|
|
253
|
+
data: { redirect: {
|
|
254
|
+
redirect: res.headers.get("X-Remix-Redirect"),
|
|
255
|
+
status: Number(res.headers.get("X-Remix-Status") || "302"),
|
|
256
|
+
revalidate: res.headers.get("X-Remix-Revalidate") === "true",
|
|
257
|
+
reload: res.headers.get("X-Remix-Reload-Document") === "true",
|
|
258
|
+
replace: res.headers.get("X-Remix-Replace") === "true"
|
|
259
|
+
} }
|
|
260
|
+
};
|
|
261
|
+
if (NO_BODY_STATUS_CODES.has(res.status)) {
|
|
262
|
+
let routes = {};
|
|
263
|
+
if (targetRoutes && request.method !== "GET") routes[targetRoutes[0]] = { data: void 0 };
|
|
264
|
+
return {
|
|
265
|
+
status: res.status,
|
|
266
|
+
data: { routes }
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
invariant(res.body, "No response body to decode");
|
|
270
|
+
try {
|
|
271
|
+
let decoded = await decodeViaTurboStream(res.body, window);
|
|
272
|
+
let data;
|
|
273
|
+
if (request.method === "GET") {
|
|
274
|
+
let typed = decoded.value;
|
|
275
|
+
if (SingleFetchRedirectSymbol in typed) data = { redirect: typed[SingleFetchRedirectSymbol] };
|
|
276
|
+
else data = { routes: typed };
|
|
277
|
+
} else {
|
|
278
|
+
let typed = decoded.value;
|
|
279
|
+
let routeId = targetRoutes?.[0];
|
|
280
|
+
invariant(routeId, "No routeId found for single fetch call decoding");
|
|
281
|
+
if ("redirect" in typed) data = { redirect: typed };
|
|
282
|
+
else data = { routes: { [routeId]: typed } };
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
status: res.status,
|
|
286
|
+
data
|
|
287
|
+
};
|
|
288
|
+
} catch (cause) {
|
|
289
|
+
throw new Error("Unable to decode turbo-stream response", { cause });
|
|
290
|
+
}
|
|
291
|
+
};
|
|
274
292
|
}
|
|
275
293
|
function decodeViaTurboStream(body, global) {
|
|
276
294
|
return decode(body, { plugins: [(type, ...rest) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import { RouterFetch } from "../dom/ssr/single-fetch.js";
|
|
2
3
|
import { ClientInstrumentation } from "../router/instrumentation.js";
|
|
3
4
|
import * as React$1 from "react";
|
|
4
5
|
import { ClientOnErrorFunction, RouterInit } from "react-router";
|
|
@@ -107,6 +108,32 @@ interface HydratedRouterProps {
|
|
|
107
108
|
* For more information, please see the [docs](../../explanation/react-transitions).
|
|
108
109
|
*/
|
|
109
110
|
useTransitions?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* <docs-warning>This prop is experimental and subject to breaking
|
|
113
|
+
* changes.</docs-warning>
|
|
114
|
+
*
|
|
115
|
+
* Provide a custom implementation for `fetch`, which will be used to perform
|
|
116
|
+
* JavaScript-issued manifest and data requests. The context identifies the
|
|
117
|
+
* operation that initiated each request. Defaults to `window.fetch`.
|
|
118
|
+
*
|
|
119
|
+
* This prop is read when the singleton router is created. Changing it after
|
|
120
|
+
* router initialization has no effect. To use changing values such as auth
|
|
121
|
+
* tokens, read current application state inside the function rather than
|
|
122
|
+
* capturing values from a component render.
|
|
123
|
+
*
|
|
124
|
+
* See the [Custom Fetch guide](../../how-to/custom-fetch) for examples of
|
|
125
|
+
* authentication headers, cross-origin credentials, traversal caching, and
|
|
126
|
+
* retries.
|
|
127
|
+
*
|
|
128
|
+
* <docs-info>
|
|
129
|
+
* Browser-managed data prefetches from {@link Link}, {@link NavLink}, or
|
|
130
|
+
* {@link PrefetchPageLinks} use native `<link rel="prefetch">` elements
|
|
131
|
+
* and do not call this function. If your data requests require custom headers
|
|
132
|
+
* or other request transformations, use `prefetch="none"` on links and avoid
|
|
133
|
+
* rendering {@link PrefetchPageLinks}.
|
|
134
|
+
* </docs-info>
|
|
135
|
+
*/
|
|
136
|
+
unstable_fetch?: RouterFetch;
|
|
110
137
|
}
|
|
111
138
|
/**
|
|
112
139
|
* Framework-mode router component to be used to hydrate a router from a
|
|
@@ -118,6 +145,7 @@ interface HydratedRouterProps {
|
|
|
118
145
|
* @param props Props
|
|
119
146
|
* @param {dom.HydratedRouterProps.getContext} props.getContext n/a
|
|
120
147
|
* @param {dom.HydratedRouterProps.onError} props.onError n/a
|
|
148
|
+
* @param {dom.HydratedRouterProps.unstable_fetch} props.unstable_fetch n/a
|
|
121
149
|
* @returns A React element that represents the hydrated application.
|
|
122
150
|
*/
|
|
123
151
|
declare function HydratedRouter(props: HydratedRouterProps): React$1.JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.5.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
import { CRITICAL_CSS_DATA_ATTRIBUTE } from "../dom/ssr/components.js";
|
|
12
12
|
import { RouterProvider as RouterProvider$1 } from "./dom-router-provider.js";
|
|
13
13
|
import * as React$1 from "react";
|
|
14
|
-
import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useFogOFWarDiscovery } from "react-router";
|
|
14
|
+
import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_RouteDiscoveryRuntime, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getCustomPatchRoutesOnNavigationFunction, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useCustomRouteDiscovery, UNSAFE_useFogOFWarDiscovery } from "react-router";
|
|
15
15
|
//#region lib/dom-export/hydrated-router.tsx
|
|
16
16
|
let ssrInfo = null;
|
|
17
17
|
let router = null;
|
|
18
|
+
let fetchImplementation = (request) => window.fetch(request);
|
|
18
19
|
function initSsrInfo() {
|
|
19
20
|
if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) {
|
|
20
21
|
if (window.__reactRouterManifest.sri === true) {
|
|
@@ -31,14 +32,17 @@ function initSsrInfo() {
|
|
|
31
32
|
routeModules: window.__reactRouterRouteModules,
|
|
32
33
|
stateDecodingPromise: void 0,
|
|
33
34
|
router: void 0,
|
|
35
|
+
routeDiscoveryRuntime: void 0,
|
|
34
36
|
routerInitialized: false
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
function createHydratedRouter({ getContext, instrumentations }) {
|
|
40
|
+
function createHydratedRouter({ getContext, instrumentations, fetch: fetchImplementation }) {
|
|
39
41
|
initSsrInfo();
|
|
40
42
|
if (!ssrInfo) throw new Error("You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`");
|
|
41
43
|
let localSsrInfo = ssrInfo;
|
|
44
|
+
let isApiOnly = ssrInfo.context.unstable_apiOnly === true;
|
|
45
|
+
let ssr = ssrInfo.context.ssr;
|
|
42
46
|
if (!ssrInfo.stateDecodingPromise) {
|
|
43
47
|
let stream = ssrInfo.context.stream;
|
|
44
48
|
UNSAFE_invariant(stream, "No stream found for single fetch decoding");
|
|
@@ -52,7 +56,7 @@ function createHydratedRouter({ getContext, instrumentations }) {
|
|
|
52
56
|
}
|
|
53
57
|
if (ssrInfo.stateDecodingPromise.error) throw ssrInfo.stateDecodingPromise.error;
|
|
54
58
|
if (!ssrInfo.stateDecodingPromise.value) throw ssrInfo.stateDecodingPromise;
|
|
55
|
-
let routes = UNSAFE_createClientRoutes(ssrInfo.manifest.routes, ssrInfo.routeModules, ssrInfo.context.state,
|
|
59
|
+
let routes = UNSAFE_createClientRoutes(ssrInfo.manifest.routes, ssrInfo.routeModules, ssrInfo.context.state, ssr, ssrInfo.context.isSpaMode, "", void 0, void 0, isApiOnly);
|
|
56
60
|
let hydrationData = void 0;
|
|
57
61
|
if (ssrInfo.context.isSpaMode) {
|
|
58
62
|
let { loaderData } = ssrInfo.context.state;
|
|
@@ -74,19 +78,22 @@ function createHydratedRouter({ getContext, instrumentations }) {
|
|
|
74
78
|
...window.history.state,
|
|
75
79
|
masked: void 0
|
|
76
80
|
}, "");
|
|
81
|
+
let discoveryRuntime = ssrInfo.context.future.unstable_customRouteDiscovery ? new UNSAFE_RouteDiscoveryRuntime(ssrInfo, { fetch: fetchImplementation }) : void 0;
|
|
77
82
|
let router = UNSAFE_createRouter({
|
|
78
83
|
routes,
|
|
79
84
|
history: UNSAFE_createBrowserHistory(),
|
|
85
|
+
future: { unstable_customRouteDiscovery: ssrInfo.context.future.unstable_customRouteDiscovery },
|
|
80
86
|
basename: ssrInfo.context.basename,
|
|
81
87
|
getContext,
|
|
82
88
|
hydrationData,
|
|
83
89
|
mapRouteProperties: UNSAFE_defaultMapRouteProperties,
|
|
84
90
|
hydrationRouteProperties: UNSAFE_hydrationRouteProperties,
|
|
85
91
|
instrumentations,
|
|
86
|
-
dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssrInfo.context.
|
|
87
|
-
patchRoutesOnNavigation: UNSAFE_getPatchRoutesOnNavigationFunction(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssrInfo.context.
|
|
92
|
+
dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, fetchImplementation, ssrInfo.context.unstable_apiOnly === true, ssrInfo.context.unstable_apiServerOrigin),
|
|
93
|
+
patchRoutesOnNavigation: discoveryRuntime ? UNSAFE_getCustomPatchRoutesOnNavigationFunction(() => router, discoveryRuntime) : UNSAFE_getPatchRoutesOnNavigationFunction(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, ssrInfo.context.basename, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, isApiOnly)
|
|
88
94
|
});
|
|
89
95
|
ssrInfo.router = router;
|
|
96
|
+
ssrInfo.routeDiscoveryRuntime = discoveryRuntime;
|
|
90
97
|
if (router.state.initialized) {
|
|
91
98
|
ssrInfo.routerInitialized = true;
|
|
92
99
|
router.initialize();
|
|
@@ -105,13 +112,18 @@ function createHydratedRouter({ getContext, instrumentations }) {
|
|
|
105
112
|
* @param props Props
|
|
106
113
|
* @param {dom.HydratedRouterProps.getContext} props.getContext n/a
|
|
107
114
|
* @param {dom.HydratedRouterProps.onError} props.onError n/a
|
|
115
|
+
* @param {dom.HydratedRouterProps.unstable_fetch} props.unstable_fetch n/a
|
|
108
116
|
* @returns A React element that represents the hydrated application.
|
|
109
117
|
*/
|
|
110
118
|
function HydratedRouter(props) {
|
|
111
|
-
if (!router)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
if (!router) {
|
|
120
|
+
router = createHydratedRouter({
|
|
121
|
+
getContext: props.getContext,
|
|
122
|
+
instrumentations: props.instrumentations,
|
|
123
|
+
fetch: props.unstable_fetch ?? fetchImplementation
|
|
124
|
+
});
|
|
125
|
+
if (props.unstable_fetch) fetchImplementation = props.unstable_fetch;
|
|
126
|
+
}
|
|
115
127
|
let [criticalCss, setCriticalCss] = React$1.useState(process.env.NODE_ENV === "development" ? ssrInfo?.context.criticalCss : void 0);
|
|
116
128
|
React$1.useEffect(() => {
|
|
117
129
|
if (process.env.NODE_ENV === "development") setCriticalCss(void 0);
|
|
@@ -132,15 +144,23 @@ function HydratedRouter(props) {
|
|
|
132
144
|
});
|
|
133
145
|
}, [location]);
|
|
134
146
|
UNSAFE_invariant(ssrInfo, "ssrInfo unavailable for HydratedRouter");
|
|
135
|
-
|
|
147
|
+
let ssr = ssrInfo.context.ssr;
|
|
148
|
+
let discoveryRuntime = ssrInfo.routeDiscoveryRuntime;
|
|
149
|
+
let discoveryState;
|
|
150
|
+
if (discoveryRuntime) discoveryState = UNSAFE_useCustomRouteDiscovery(discoveryRuntime, props.onError);
|
|
151
|
+
else UNSAFE_useFogOFWarDiscovery(router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, ssrInfo.context.unstable_apiOnly === true);
|
|
136
152
|
return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, /* @__PURE__ */ React$1.createElement(UNSAFE_FrameworkContext.Provider, { value: {
|
|
153
|
+
routeDiscoveryRuntime: discoveryRuntime,
|
|
154
|
+
routeDiscoveryState: discoveryState,
|
|
137
155
|
manifest: ssrInfo.manifest,
|
|
138
156
|
routeModules: ssrInfo.routeModules,
|
|
139
157
|
future: ssrInfo.context.future,
|
|
140
158
|
criticalCss,
|
|
141
159
|
ssr: ssrInfo.context.ssr,
|
|
142
160
|
isSpaMode: ssrInfo.context.isSpaMode,
|
|
143
|
-
|
|
161
|
+
unstable_apiOnly: ssrInfo.context.unstable_apiOnly,
|
|
162
|
+
routeDiscovery: ssrInfo.context.routeDiscovery,
|
|
163
|
+
unstable_apiServerOrigin: ssrInfo.context.unstable_apiServerOrigin
|
|
144
164
|
} }, /* @__PURE__ */ React$1.createElement(UNSAFE_RemixErrorBoundary, { location }, /* @__PURE__ */ React$1.createElement(RouterProvider$1, {
|
|
145
165
|
router,
|
|
146
166
|
useTransitions: props.useTransitions,
|
|
@@ -3,8 +3,8 @@ import { Action, Location, Path, To } from "./router/history.js";
|
|
|
3
3
|
import { ParamParseKey, Params, PathMatch, PathPattern, RouteObject, UIMatch } from "./router/utils.js";
|
|
4
4
|
import { Blocker, BlockerFunction, NavigationStates, RelativeRoutingType, Router } from "./router/router.js";
|
|
5
5
|
import { NavigateOptions } from "./context.js";
|
|
6
|
-
import { RouteModules } from "./types/register.js";
|
|
7
6
|
import { GetActionData, GetLoaderData, SerializeFrom } from "./types/route-data.js";
|
|
7
|
+
import { RouteModules } from "./types/register.js";
|
|
8
8
|
import * as React$1 from "react";
|
|
9
9
|
|
|
10
10
|
//#region lib/hooks.d.ts
|
|
@@ -116,7 +116,7 @@ interface NavigateFunction {
|
|
|
116
116
|
* * These options only work in Framework and Data modes:
|
|
117
117
|
* * `flushSync`: Wrap the DOM updates in [`ReactDom.flushSync`](https://react.dev/reference/react-dom/flushSync)
|
|
118
118
|
* * `preventScrollReset`: Do not scroll back to the top of the page after navigation
|
|
119
|
-
* * `viewTransition`:
|
|
119
|
+
* * `viewTransition`: **Deprecated.** Use React's [`<ViewTransition>`](https://react.dev/reference/react/ViewTransition) component instead. See the [migration guide](../../how-to/view-transitions).
|
|
120
120
|
*
|
|
121
121
|
* @example
|
|
122
122
|
* import { useNavigate } from "react-router";
|
|
@@ -939,7 +939,7 @@ type unstable_RouterState = {
|
|
|
939
939
|
* @example
|
|
940
940
|
* import { unstable_useRouterState as useRouterState } from "react-router";
|
|
941
941
|
*
|
|
942
|
-
* let { active, pending } =
|
|
942
|
+
* let { active, pending } = useRouterState();
|
|
943
943
|
*
|
|
944
944
|
* // Active is always populated with the current location
|
|
945
945
|
* active.location; // replaces `useLocation()`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.5.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -136,7 +136,7 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
|
|
|
136
136
|
* * These options only work in Framework and Data modes:
|
|
137
137
|
* * `flushSync`: Wrap the DOM updates in [`ReactDom.flushSync`](https://react.dev/reference/react-dom/flushSync)
|
|
138
138
|
* * `preventScrollReset`: Do not scroll back to the top of the page after navigation
|
|
139
|
-
* * `viewTransition`:
|
|
139
|
+
* * `viewTransition`: **Deprecated.** Use React's [`<ViewTransition>`](https://react.dev/reference/react/ViewTransition) component instead. See the [migration guide](../../how-to/view-transitions).
|
|
140
140
|
*
|
|
141
141
|
* @example
|
|
142
142
|
* import { useNavigate } from "react-router";
|
|
@@ -1326,7 +1326,7 @@ function toRouterStateMatch(match) {
|
|
|
1326
1326
|
* @example
|
|
1327
1327
|
* import { unstable_useRouterState as useRouterState } from "react-router";
|
|
1328
1328
|
*
|
|
1329
|
-
* let { active, pending } =
|
|
1329
|
+
* let { active, pending } = useRouterState();
|
|
1330
1330
|
*
|
|
1331
1331
|
* // Active is always populated with the current location
|
|
1332
1332
|
* active.location; // replaces `useLocation()`
|
|
@@ -306,6 +306,8 @@ type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionData" | "e
|
|
|
306
306
|
* Future flags to toggle new feature behavior
|
|
307
307
|
*/
|
|
308
308
|
interface FutureConfig {
|
|
309
|
+
/** @internal Enables application-controlled Framework route discovery. */
|
|
310
|
+
unstable_customRouteDiscovery?: boolean;
|
|
309
311
|
/** Enables route-pattern matching after calling `unstable_preloadRoutePattern()`. */
|
|
310
312
|
unstable_routePatternMatching?: boolean;
|
|
311
313
|
}
|
|
@@ -452,6 +454,10 @@ type BaseNavigateOptions = BaseNavigateOrFetchOptions & {
|
|
|
452
454
|
replace?: boolean;
|
|
453
455
|
state?: any;
|
|
454
456
|
fromRouteId?: string;
|
|
457
|
+
/**
|
|
458
|
+
* @deprecated Use React's `<ViewTransition>` component instead. See the
|
|
459
|
+
* [migration guide](https://reactrouter.com/how-to/view-transitions).
|
|
460
|
+
*/
|
|
455
461
|
viewTransition?: boolean;
|
|
456
462
|
mask?: To;
|
|
457
463
|
};
|