react-router 8.3.0 → 8.4.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 +46 -2
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +1 -1
- package/dist/development/index-react-server.d.ts +50 -48
- package/dist/development/index-react-server.js +96 -43
- package/dist/development/index.d.ts +2 -2
- package/dist/development/index.js +3 -3
- package/dist/development/lib/actions.js +10 -5
- package/dist/development/lib/components.js +50 -10
- package/dist/development/lib/context.d.ts +14 -5
- package/dist/development/lib/context.js +11 -3
- package/dist/development/lib/dom/dom.js +2 -2
- package/dist/development/lib/dom/lib.js +33 -36
- package/dist/development/lib/dom/server.d.ts +6 -1
- package/dist/development/lib/dom/server.js +40 -14
- package/dist/development/lib/dom/ssr/components.js +16 -24
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/entry.d.ts +4 -0
- 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.js +34 -12
- package/dist/development/lib/dom/ssr/hydration.d.ts +3 -1
- package/dist/development/lib/dom/ssr/hydration.js +6 -4
- 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 +5 -2
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +2 -2
- package/dist/development/lib/dom/ssr/single-fetch.js +13 -22
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +2 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.js +54 -46
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +2 -2
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.d.ts +2 -0
- package/dist/development/lib/router/matcher-route-pattern.js +216 -0
- package/dist/development/lib/router/matcher-route-pattern.preload.d.ts +20 -0
- package/dist/development/lib/router/matcher-route-pattern.preload.js +36 -0
- package/dist/development/lib/router/matcher.d.ts +2 -0
- package/dist/development/lib/router/matcher.js +29 -0
- package/dist/development/lib/router/navigation.js +45 -0
- package/dist/development/lib/router/router.d.ts +21 -7
- package/dist/development/lib/router/router.js +111 -82
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +6 -1
- package/dist/development/lib/router/utils.js +15 -9
- package/dist/development/lib/rsc/browser.js +5 -1
- 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 +3 -5
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +7 -0
- package/dist/development/lib/rsc/server.ssr.js +26 -22
- package/dist/development/lib/server-runtime/cookies.js +2 -2
- package/dist/development/lib/server-runtime/crypto.js +2 -2
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +2 -2
- 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 +3 -4
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +8 -7
- 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 +2 -2
- 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/route-pattern.d.ts +3 -0
- package/dist/development/route-pattern.js +12 -0
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +4 -4
- 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.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +50 -48
- package/dist/production/index-react-server.js +96 -43
- package/dist/production/index.d.ts +2 -2
- package/dist/production/index.js +3 -3
- package/dist/production/lib/actions.js +10 -5
- package/dist/production/lib/components.js +50 -10
- package/dist/production/lib/context.d.ts +14 -5
- package/dist/production/lib/context.js +11 -3
- package/dist/production/lib/dom/dom.js +2 -2
- package/dist/production/lib/dom/lib.js +33 -36
- package/dist/production/lib/dom/server.d.ts +6 -1
- package/dist/production/lib/dom/server.js +40 -14
- package/dist/production/lib/dom/ssr/components.js +16 -24
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/entry.d.ts +4 -0
- 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.js +34 -12
- package/dist/production/lib/dom/ssr/hydration.d.ts +3 -1
- package/dist/production/lib/dom/ssr/hydration.js +6 -4
- 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 +5 -2
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +2 -2
- package/dist/production/lib/dom/ssr/single-fetch.js +13 -22
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +2 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.js +54 -46
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +2 -2
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.d.ts +2 -0
- package/dist/production/lib/router/matcher-route-pattern.js +216 -0
- package/dist/production/lib/router/matcher-route-pattern.preload.d.ts +20 -0
- package/dist/production/lib/router/matcher-route-pattern.preload.js +36 -0
- package/dist/production/lib/router/matcher.d.ts +2 -0
- package/dist/production/lib/router/matcher.js +29 -0
- package/dist/production/lib/router/navigation.js +45 -0
- package/dist/production/lib/router/router.d.ts +21 -7
- package/dist/production/lib/router/router.js +111 -82
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +6 -1
- package/dist/production/lib/router/utils.js +15 -9
- package/dist/production/lib/rsc/browser.js +5 -1
- 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 +3 -5
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +7 -0
- package/dist/production/lib/rsc/server.ssr.js +26 -22
- package/dist/production/lib/server-runtime/cookies.js +2 -2
- package/dist/production/lib/server-runtime/crypto.js +2 -2
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +2 -2
- 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 +3 -4
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +8 -7
- 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 +2 -2
- 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/route-pattern.d.ts +3 -0
- package/dist/production/route-pattern.js +12 -0
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +4 -4
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/how-to/fetchers.md +6 -1
- package/docs/how-to/middleware.md +3 -1
- package/docs/how-to/optimize-revalidation.md +178 -5
- package/docs/how-to/react-server-components.md +26 -3
- package/docs/how-to/resource-routes.md +3 -0
- package/docs/start/data/actions.md +2 -1
- package/docs/start/data/route-object.md +21 -6
- package/docs/start/framework/actions.md +4 -2
- package/docs/start/framework/route-module.md +32 -5
- package/docs/upgrading/future.md +68 -0
- package/package.json +11 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { Path } from "../../router/history.js";
|
|
3
3
|
import { DataRouteObject } from "../../router/utils.js";
|
|
4
|
-
import { HydrationState, Router } from "../../router/router.js";
|
|
4
|
+
import { FutureConfig, HydrationState, Router } from "../../router/router.js";
|
|
5
5
|
import { ClientLoaderFunction } from "./routeModules.js";
|
|
6
6
|
|
|
7
7
|
//#region lib/dom/ssr/hydration.d.ts
|
|
@@ -11,6 +11,7 @@ declare function getHydrationData({
|
|
|
11
11
|
getRouteInfo,
|
|
12
12
|
location,
|
|
13
13
|
basename,
|
|
14
|
+
future,
|
|
14
15
|
isSpaMode
|
|
15
16
|
}: {
|
|
16
17
|
state: {
|
|
@@ -26,6 +27,7 @@ declare function getHydrationData({
|
|
|
26
27
|
};
|
|
27
28
|
location: Path;
|
|
28
29
|
basename: string | undefined;
|
|
30
|
+
future: FutureConfig;
|
|
29
31
|
isSpaMode: boolean;
|
|
30
32
|
}): HydrationState;
|
|
31
33
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,15 +8,17 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { createDataRouteMatcher } from "../../router/router.js";
|
|
12
12
|
import { shouldHydrateRouteLoader } from "./routes.js";
|
|
13
13
|
//#region lib/dom/ssr/hydration.tsx
|
|
14
|
-
function getHydrationData({ state, routes, getRouteInfo, location, basename, isSpaMode }) {
|
|
14
|
+
function getHydrationData({ state, routes, getRouteInfo, location, basename, future, isSpaMode }) {
|
|
15
15
|
let hydrationData = {
|
|
16
16
|
...state,
|
|
17
17
|
loaderData: { ...state.loaderData }
|
|
18
18
|
};
|
|
19
|
-
let
|
|
19
|
+
let dataRouteMatcher = createDataRouteMatcher(future, basename || "/");
|
|
20
|
+
dataRouteMatcher.update(routes);
|
|
21
|
+
let initialMatches = dataRouteMatcher.match(location);
|
|
20
22
|
if (initialMatches) for (let match of initialMatches) {
|
|
21
23
|
let routeId = match.route.id;
|
|
22
24
|
let routeInfo = getRouteInfo(routeId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -20,5 +20,8 @@ const ESCAPE_REGEX = /[&><\u2028\u2029]/g;
|
|
|
20
20
|
function escapeHtml(html) {
|
|
21
21
|
return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
|
|
22
22
|
}
|
|
23
|
+
function escapeAttribute(value) {
|
|
24
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
25
|
+
}
|
|
23
26
|
//#endregion
|
|
24
|
-
export { escapeHtml };
|
|
27
|
+
export { escapeAttribute, escapeHtml };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -40,7 +40,7 @@ function ServerRouter({ context, url, nonce }) {
|
|
|
40
40
|
let manifestRoute = context.manifest.routes[routeId];
|
|
41
41
|
if (route && manifestRoute && shouldHydrateRouteLoader(routeId, route.clientLoader, manifestRoute.hasLoader, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) delete context.staticHandlerContext.loaderData[routeId];
|
|
42
42
|
}
|
|
43
|
-
let router = createStaticRouter(routes, context.staticHandlerContext, {
|
|
43
|
+
let router = createStaticRouter(routes, context.staticHandlerContext, { future: context.future });
|
|
44
44
|
return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, /* @__PURE__ */ React$1.createElement(FrameworkContext.Provider, { value: {
|
|
45
45
|
manifest,
|
|
46
46
|
routeModules,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -101,25 +101,16 @@ async function singleFetchActionStrategy(args, fetchAndDecode) {
|
|
|
101
101
|
async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode) {
|
|
102
102
|
let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler());
|
|
103
103
|
let results = {};
|
|
104
|
-
await Promise.all(matchesToLoad.map(
|
|
105
|
-
|
|
104
|
+
await Promise.all(matchesToLoad.map(async (m) => {
|
|
105
|
+
let routeId = m.route.id;
|
|
106
|
+
results[routeId] = await m.resolve(async (handler) => {
|
|
106
107
|
let { hasClientLoader } = getRouteInfo(m);
|
|
107
|
-
|
|
108
|
-
let result = hasClientLoader ? await handler(async () => {
|
|
108
|
+
return hasClientLoader ? handler(async () => {
|
|
109
109
|
let { data } = await fetchAndDecode(args, [routeId]);
|
|
110
110
|
return unwrapSingleFetchResult(data, routeId);
|
|
111
|
-
}) :
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
result
|
|
115
|
-
};
|
|
116
|
-
} catch (e) {
|
|
117
|
-
results[m.route.id] = {
|
|
118
|
-
type: "error",
|
|
119
|
-
result: e
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
})));
|
|
111
|
+
}) : handler();
|
|
112
|
+
});
|
|
113
|
+
}));
|
|
123
114
|
return results;
|
|
124
115
|
}
|
|
125
116
|
async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true) {
|
|
@@ -205,7 +196,7 @@ async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams,
|
|
|
205
196
|
if (middlewareError !== void 0) Array.from(routesParams.values()).forEach((routeId) => {
|
|
206
197
|
if (results[routeId].result instanceof SingleFetchNoResultError) results[routeId].result = middlewareError;
|
|
207
198
|
});
|
|
208
|
-
} catch
|
|
199
|
+
} catch {}
|
|
209
200
|
}
|
|
210
201
|
async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode) {
|
|
211
202
|
let fetcherMatch = args.matches.find((m) => m.shouldCallHandler());
|
|
@@ -277,8 +268,8 @@ async function fetchAndDecodeViaTurboStream(args, targetRoutes) {
|
|
|
277
268
|
status: res.status,
|
|
278
269
|
data
|
|
279
270
|
};
|
|
280
|
-
} catch (
|
|
281
|
-
throw new Error("Unable to decode turbo-stream response");
|
|
271
|
+
} catch (cause) {
|
|
272
|
+
throw new Error("Unable to decode turbo-stream response", { cause });
|
|
282
273
|
}
|
|
283
274
|
}
|
|
284
275
|
function decodeViaTurboStream(body, global) {
|
|
@@ -326,13 +317,13 @@ function createDeferred() {
|
|
|
326
317
|
res(val);
|
|
327
318
|
try {
|
|
328
319
|
await promise;
|
|
329
|
-
} catch
|
|
320
|
+
} catch {}
|
|
330
321
|
};
|
|
331
322
|
reject = async (error) => {
|
|
332
323
|
rej(error);
|
|
333
324
|
try {
|
|
334
325
|
await promise;
|
|
335
|
-
} catch
|
|
326
|
+
} catch {}
|
|
336
327
|
};
|
|
337
328
|
});
|
|
338
329
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -67,6 +67,7 @@ function createHydratedRouter({ getContext, instrumentations }) {
|
|
|
67
67
|
}),
|
|
68
68
|
location: window.location,
|
|
69
69
|
basename: window.__reactRouterContext?.basename,
|
|
70
|
+
future: ssrInfo.context.future,
|
|
70
71
|
isSpaMode: ssrInfo.context.isSpaMode
|
|
71
72
|
});
|
|
72
73
|
if (window.history.state && window.history.state.masked) window.history.replaceState({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import { invariant, parsePath, warning } from "./router/history.js";
|
|
11
|
+
import { createPath, invariant, parsePath, warning } from "./router/history.js";
|
|
12
12
|
import { convertRouteMatchToUiMatch, decodePath, getResolveToMatches, getRoutePattern, isBrowser, isRouteErrorResponse, joinPaths, matchPath, matchRoutes, parseToInfo, resolveTo, stripBasename } from "./router/utils.js";
|
|
13
|
+
import { getNavigatorCurrentUrl, validateNavigationTarget } from "./router/navigation.js";
|
|
13
14
|
import { IDLE_BLOCKER, hasInvalidProtocol } from "./router/router.js";
|
|
14
|
-
import { AwaitContext, DataRouterContext, DataRouterStateContext, LocationContext, NavigationContext, RSCRouterContext, RouteContext, RouteErrorContext } from "./context.js";
|
|
15
|
+
import { AwaitContext, DataRouterContext, DataRouterDataContext, DataRouterNavigationContext, DataRouterStateContext, FetchersContext, IsDataRouteContext, LocationContext, NavigationContext, RSCRouterContext, RouteContext, RouteErrorContext, RouteIdContext } from "./context.js";
|
|
15
16
|
import { decodeRedirectErrorDigest, decodeRouteErrorResponseDigest } from "./errors.js";
|
|
16
17
|
import * as React$1 from "react";
|
|
17
18
|
//#region lib/hooks.tsx
|
|
@@ -268,8 +269,7 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
|
|
|
268
269
|
* @returns A navigate function for programmatic navigation
|
|
269
270
|
*/
|
|
270
271
|
function useNavigate() {
|
|
271
|
-
|
|
272
|
-
return isDataRoute ? useNavigateStable() : useNavigateUnstable();
|
|
272
|
+
return React$1.useContext(IsDataRouteContext) ? useNavigateStable() : useNavigateUnstable();
|
|
273
273
|
}
|
|
274
274
|
function useNavigateUnstable() {
|
|
275
275
|
invariant(useInRouterContext(), `useNavigate() may be used only in the context of a <Router> component.`);
|
|
@@ -291,6 +291,7 @@ function useNavigateUnstable() {
|
|
|
291
291
|
}
|
|
292
292
|
let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
|
|
293
293
|
if (dataRouterContext == null && basename !== "/") path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
|
|
294
|
+
validateNavigationTarget(typeof to === "string" ? to : createPath(to), navigator.createHref(path), getNavigatorCurrentUrl(navigator), "reject");
|
|
294
295
|
(!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
|
|
295
296
|
}, [
|
|
296
297
|
basename,
|
|
@@ -601,7 +602,10 @@ function useRoutesImpl(routes, locationArg, dataRouterOpts) {
|
|
|
601
602
|
let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
|
|
602
603
|
remainingPathname = "/" + pathname.replace(/^\//, "").split("/").slice(parentSegments.length).join("/");
|
|
603
604
|
}
|
|
604
|
-
let matches
|
|
605
|
+
let matches;
|
|
606
|
+
if (dataRouterOpts) if (dataRouterOpts.state.matches.length) matches = dataRouterOpts.state.matches.map((m) => Object.assign(m, { route: dataRouterOpts.manifest[m.route.id] || m.route }));
|
|
607
|
+
else matches = dataRouterOpts.router.match(dataRouterOpts.state.location);
|
|
608
|
+
else matches = matchRoutes(routes, { pathname: remainingPathname });
|
|
605
609
|
warning(parentRoute || matches != null, `No routes matched location "${location.pathname}${location.search}${location.hash}" `);
|
|
606
610
|
warning(matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0, `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);
|
|
607
611
|
let renderedMatches = _renderMatches(matches && matches.map((match) => Object.assign({}, match, {
|
|
@@ -677,17 +681,17 @@ var RenderErrorBoundary = class extends React$1.Component {
|
|
|
677
681
|
const decoded = decodeRouteErrorResponseDigest(error.digest);
|
|
678
682
|
if (decoded) error = decoded;
|
|
679
683
|
}
|
|
680
|
-
let result = error !== void 0 ? /* @__PURE__ */ React$1.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React$1.createElement(RouteErrorContext.Provider, {
|
|
684
|
+
let result = error !== void 0 ? /* @__PURE__ */ React$1.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React$1.createElement(IsDataRouteContext.Provider, { value: this.props.routeContext.isDataRoute }, /* @__PURE__ */ React$1.createElement(RouteIdContext.Provider, { value: this.props.routeContext.matches[this.props.routeContext.matches.length - 1]?.route.id }, /* @__PURE__ */ React$1.createElement(RouteErrorContext.Provider, {
|
|
681
685
|
value: error,
|
|
682
686
|
children: this.props.component
|
|
683
|
-
})) : this.props.children;
|
|
687
|
+
})))) : this.props.children;
|
|
684
688
|
if (this.context) return /* @__PURE__ */ React$1.createElement(RSCErrorHandler, { error }, result);
|
|
685
689
|
return result;
|
|
686
690
|
}
|
|
687
691
|
};
|
|
688
692
|
const errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();
|
|
689
693
|
function RSCErrorHandler({ children, error }) {
|
|
690
|
-
let { basename } = React$1.useContext(NavigationContext);
|
|
694
|
+
let { basename, navigator } = React$1.useContext(NavigationContext);
|
|
691
695
|
if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
|
|
692
696
|
let redirect = decodeRedirectErrorDigest(error.digest);
|
|
693
697
|
if (redirect) {
|
|
@@ -695,6 +699,7 @@ function RSCErrorHandler({ children, error }) {
|
|
|
695
699
|
if (existingRedirect) throw existingRedirect;
|
|
696
700
|
let parsed = parseToInfo(redirect.location, basename);
|
|
697
701
|
let target = parsed.absoluteURL || parsed.to;
|
|
702
|
+
validateNavigationTarget(redirect.location, target, getNavigatorCurrentUrl(navigator), "allow-explicit");
|
|
698
703
|
if (hasInvalidProtocol(target)) throw new Error("Invalid redirect location");
|
|
699
704
|
if (isBrowser && !errorRedirectHandledMap.get(error)) if (parsed.isExternal || redirect.reloadDocument) window.location.href = target;
|
|
700
705
|
else {
|
|
@@ -713,7 +718,7 @@ function RSCErrorHandler({ children, error }) {
|
|
|
713
718
|
function RenderedRoute({ routeContext, match, children }) {
|
|
714
719
|
let dataRouterContext = React$1.useContext(DataRouterContext);
|
|
715
720
|
if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
|
|
716
|
-
return /* @__PURE__ */ React$1.createElement(RouteContext.Provider, { value: routeContext }, children);
|
|
721
|
+
return /* @__PURE__ */ React$1.createElement(RouteContext.Provider, { value: routeContext }, /* @__PURE__ */ React$1.createElement(IsDataRouteContext.Provider, { value: routeContext.isDataRoute }, /* @__PURE__ */ React$1.createElement(RouteIdContext.Provider, { value: match.route.id }, children)));
|
|
717
722
|
}
|
|
718
723
|
function _renderMatches(matches, parentMatches = [], dataRouterOpts) {
|
|
719
724
|
let dataRouterState = dataRouterOpts?.state;
|
|
@@ -823,25 +828,25 @@ function useDataRouterState(hookName) {
|
|
|
823
828
|
invariant(state, getDataRouterConsoleError(hookName));
|
|
824
829
|
return state;
|
|
825
830
|
}
|
|
826
|
-
function
|
|
827
|
-
let
|
|
828
|
-
invariant(
|
|
829
|
-
return
|
|
831
|
+
function useDataRouterFetchers(hookName) {
|
|
832
|
+
let fetchers = React$1.useContext(FetchersContext);
|
|
833
|
+
invariant(fetchers, getDataRouterConsoleError(hookName));
|
|
834
|
+
return fetchers;
|
|
830
835
|
}
|
|
831
|
-
function
|
|
832
|
-
let
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
return thisRoute.route.id;
|
|
836
|
+
function useDataRouterData(hookName) {
|
|
837
|
+
let data = React$1.useContext(DataRouterDataContext);
|
|
838
|
+
invariant(data, getDataRouterConsoleError(hookName));
|
|
839
|
+
return data;
|
|
836
840
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
841
|
+
function useDataRouterNavigation(hookName) {
|
|
842
|
+
let navigation = React$1.useContext(DataRouterNavigationContext);
|
|
843
|
+
invariant(navigation, getDataRouterConsoleError(hookName));
|
|
844
|
+
return navigation;
|
|
845
|
+
}
|
|
846
|
+
function useCurrentRouteId(hookName) {
|
|
847
|
+
let routeId = React$1.useContext(RouteIdContext);
|
|
848
|
+
invariant(routeId, `${hookName} can only be used on routes that contain a unique "id"`);
|
|
849
|
+
return routeId;
|
|
845
850
|
}
|
|
846
851
|
/**
|
|
847
852
|
* Returns the current {@link Navigation}, defaulting to an "idle" navigation
|
|
@@ -866,11 +871,11 @@ function useRouteId() {
|
|
|
866
871
|
* @returns The current {@link Navigation} object
|
|
867
872
|
*/
|
|
868
873
|
function useNavigation() {
|
|
869
|
-
let
|
|
874
|
+
let { navigation } = useDataRouterNavigation("useNavigation");
|
|
870
875
|
return React$1.useMemo(() => {
|
|
871
|
-
let { matches, historyAction, ...rest } =
|
|
876
|
+
let { matches, historyAction, ...rest } = navigation;
|
|
872
877
|
return rest;
|
|
873
|
-
}, [
|
|
878
|
+
}, [navigation]);
|
|
874
879
|
}
|
|
875
880
|
/**
|
|
876
881
|
* Revalidate the data on the page for reasons outside of normal data mutations
|
|
@@ -909,14 +914,14 @@ function useNavigation() {
|
|
|
909
914
|
*/
|
|
910
915
|
function useRevalidator() {
|
|
911
916
|
let dataRouterContext = useDataRouterContext("useRevalidator");
|
|
912
|
-
let
|
|
917
|
+
let { revalidation } = useDataRouterNavigation("useRevalidator");
|
|
913
918
|
let revalidate = React$1.useCallback(async () => {
|
|
914
919
|
await dataRouterContext.router.revalidate();
|
|
915
920
|
}, [dataRouterContext.router]);
|
|
916
921
|
return React$1.useMemo(() => ({
|
|
917
922
|
revalidate,
|
|
918
|
-
state:
|
|
919
|
-
}), [revalidate,
|
|
923
|
+
state: revalidation
|
|
924
|
+
}), [revalidate, revalidation]);
|
|
920
925
|
}
|
|
921
926
|
/**
|
|
922
927
|
* Returns the active route matches, useful for accessing `loaderData` for
|
|
@@ -953,7 +958,8 @@ function useRevalidator() {
|
|
|
953
958
|
* @returns An array of {@link UIMatch | UI matches} for the current route hierarchy
|
|
954
959
|
*/
|
|
955
960
|
function useMatches() {
|
|
956
|
-
let { matches
|
|
961
|
+
let { matches } = useDataRouterState("useMatches");
|
|
962
|
+
let { loaderData } = useDataRouterData("useMatches");
|
|
957
963
|
return React$1.useMemo(() => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);
|
|
958
964
|
}
|
|
959
965
|
/**
|
|
@@ -980,9 +986,9 @@ function useMatches() {
|
|
|
980
986
|
* @returns The data returned from the route's [`loader`](../../start/framework/route-module#loader) or [`clientLoader`](../../start/framework/route-module#clientloader) function
|
|
981
987
|
*/
|
|
982
988
|
function useLoaderData() {
|
|
983
|
-
let
|
|
989
|
+
let data = useDataRouterData("useLoaderData");
|
|
984
990
|
let routeId = useCurrentRouteId("useLoaderData");
|
|
985
|
-
return
|
|
991
|
+
return data.loaderData[routeId];
|
|
986
992
|
}
|
|
987
993
|
/**
|
|
988
994
|
* Returns the [`loader`](../../start/framework/route-module#loader) data for a
|
|
@@ -1017,7 +1023,7 @@ function useLoaderData() {
|
|
|
1017
1023
|
* function, or `undefined` if not found
|
|
1018
1024
|
*/
|
|
1019
1025
|
function useRouteLoaderData(routeId) {
|
|
1020
|
-
return
|
|
1026
|
+
return useDataRouterData("useRouteLoaderData").loaderData[routeId];
|
|
1021
1027
|
}
|
|
1022
1028
|
/**
|
|
1023
1029
|
* Returns the [`action`](../../start/framework/route-module#action) data from
|
|
@@ -1052,9 +1058,9 @@ function useRouteLoaderData(routeId) {
|
|
|
1052
1058
|
* has been called
|
|
1053
1059
|
*/
|
|
1054
1060
|
function useActionData() {
|
|
1055
|
-
let
|
|
1056
|
-
let routeId = useCurrentRouteId("
|
|
1057
|
-
return
|
|
1061
|
+
let data = useDataRouterData("useActionData");
|
|
1062
|
+
let routeId = useCurrentRouteId("useActionData");
|
|
1063
|
+
return data.actionData ? data.actionData[routeId] : void 0;
|
|
1058
1064
|
}
|
|
1059
1065
|
/**
|
|
1060
1066
|
* Accesses the error thrown during an
|
|
@@ -1078,10 +1084,10 @@ function useActionData() {
|
|
|
1078
1084
|
*/
|
|
1079
1085
|
function useRouteError() {
|
|
1080
1086
|
let error = React$1.useContext(RouteErrorContext);
|
|
1081
|
-
let
|
|
1087
|
+
let data = useDataRouterData("useRouteError");
|
|
1082
1088
|
let routeId = useCurrentRouteId("useRouteError");
|
|
1083
1089
|
if (error !== void 0) return error;
|
|
1084
|
-
return
|
|
1090
|
+
return data.errors?.[routeId];
|
|
1085
1091
|
}
|
|
1086
1092
|
/**
|
|
1087
1093
|
* Returns the resolved promise value from the closest {@link Await | `<Await>`}.
|
|
@@ -1306,12 +1312,13 @@ function useRoute(...args) {
|
|
|
1306
1312
|
const currentRouteId = useCurrentRouteId("useRoute");
|
|
1307
1313
|
const id = args[0] ?? currentRouteId;
|
|
1308
1314
|
const state = useDataRouterState("useRoute");
|
|
1315
|
+
const data = useDataRouterData("useRoute");
|
|
1309
1316
|
const route = state.matches.find(({ route }) => route.id === id);
|
|
1310
1317
|
if (route === void 0) return void 0;
|
|
1311
1318
|
return {
|
|
1312
1319
|
handle: route.route.handle,
|
|
1313
|
-
loaderData:
|
|
1314
|
-
actionData:
|
|
1320
|
+
loaderData: data.loaderData[id],
|
|
1321
|
+
actionData: data.actionData?.[id]
|
|
1315
1322
|
};
|
|
1316
1323
|
}
|
|
1317
1324
|
function toRouterStateMatch(match) {
|
|
@@ -1365,7 +1372,8 @@ function toRouterStateMatch(match) {
|
|
|
1365
1372
|
* @returns The current router state with `active` and `pending` variants
|
|
1366
1373
|
*/
|
|
1367
1374
|
function useRouterState() {
|
|
1368
|
-
let { location, historyAction: type, matches
|
|
1375
|
+
let { location, historyAction: type, matches } = useDataRouterState("unstable_useRouterState");
|
|
1376
|
+
let { navigation } = useDataRouterNavigation("unstable_useRouterState");
|
|
1369
1377
|
let active = React$1.useMemo(() => ({
|
|
1370
1378
|
type,
|
|
1371
1379
|
location,
|
|
@@ -1412,4 +1420,4 @@ function useRouterState() {
|
|
|
1412
1420
|
}), [active, pending]);
|
|
1413
1421
|
}
|
|
1414
1422
|
//#endregion
|
|
1415
|
-
export { _renderMatches, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRoute, useRouteError,
|
|
1423
|
+
export { _renderMatches, useActionData, useAsyncError, useAsyncValue, useBlocker, useCurrentRouteId, useDataRouterContext, useDataRouterData, useDataRouterFetchers, useDataRouterState, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRoute, useRouteError, useRouteLoaderData, useRouterState, useRoutes, useRoutesImpl };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.4.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -193,7 +193,7 @@ function warning(cond, message) {
|
|
|
193
193
|
if (typeof console !== "undefined") console.warn(message);
|
|
194
194
|
try {
|
|
195
195
|
throw new Error(message);
|
|
196
|
-
} catch
|
|
196
|
+
} catch {}
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
function createKey() {
|