react-router 8.1.0 → 8.3.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 +83 -0
- 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 +109 -19
- package/dist/development/index-react-server.js +176 -45
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +1 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.d.ts +24 -24
- package/dist/development/lib/dom/dom.js +25 -25
- package/dist/development/lib/dom/lib.d.ts +2 -1
- package/dist/development/lib/dom/lib.js +5 -4
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +1 -1
- package/dist/development/lib/dom/ssr/data.js +1 -1
- 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 +26 -21
- 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/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.d.ts +13 -0
- package/dist/development/lib/dom/ssr/routes-test-stub.js +14 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +1 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +33 -6
- package/dist/development/lib/hooks.js +34 -7
- package/dist/development/lib/href.d.ts +24 -8
- package/dist/development/lib/href.js +31 -11
- package/dist/development/lib/router/history.d.ts +6 -0
- package/dist/development/lib/router/history.js +7 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/router.js +2 -2
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +12 -0
- package/dist/development/lib/router/utils.js +61 -5
- package/dist/development/lib/rsc/browser.js +34 -24
- 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 +29 -10
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +8 -3
- package/dist/development/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/development/lib/rsc/server.ssr.js +27 -12
- package/dist/development/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/development/lib/server-runtime/cookies.js +17 -3
- 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.js +1 -1
- package/dist/development/lib/server-runtime/server.d.ts +12 -0
- package/dist/development/lib/server-runtime/server.js +13 -1
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/development/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/development/lib/server-runtime/sessions.js +20 -3
- 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/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.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +109 -19
- package/dist/production/index-react-server.js +176 -45
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +1 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.d.ts +24 -24
- package/dist/production/lib/dom/dom.js +25 -25
- package/dist/production/lib/dom/lib.d.ts +2 -1
- package/dist/production/lib/dom/lib.js +5 -4
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +1 -1
- package/dist/production/lib/dom/ssr/data.js +1 -1
- 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 +26 -21
- 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/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.d.ts +13 -0
- package/dist/production/lib/dom/ssr/routes-test-stub.js +14 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +1 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +33 -6
- package/dist/production/lib/hooks.js +34 -7
- package/dist/production/lib/href.d.ts +24 -8
- package/dist/production/lib/href.js +31 -11
- package/dist/production/lib/router/history.d.ts +6 -0
- package/dist/production/lib/router/history.js +7 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/router.js +2 -2
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +12 -0
- package/dist/production/lib/router/utils.js +61 -5
- package/dist/production/lib/rsc/browser.js +34 -24
- 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 +29 -10
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +8 -3
- package/dist/production/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/production/lib/rsc/server.ssr.js +27 -12
- package/dist/production/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/production/lib/server-runtime/cookies.js +17 -3
- 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.js +1 -1
- package/dist/production/lib/server-runtime/server.d.ts +12 -0
- package/dist/production/lib/server-runtime/server.js +13 -1
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/production/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/production/lib/server-runtime/sessions.js +20 -3
- 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/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/hot-module-replacement.md +1 -1
- package/docs/explanation/sessions-and-cookies.md +13 -13
- package/docs/explanation/state-management.md +2 -2
- package/docs/how-to/data-strategy.md +1 -1
- package/docs/how-to/presets.md +2 -2
- package/docs/how-to/react-server-components.md +53 -1
- package/docs/how-to/security.md +8 -1
- package/docs/how-to/server-bundles.md +2 -2
- package/docs/start/data/route-object.md +2 -2
- package/docs/start/data/routing.md +1 -1
- package/docs/start/framework/deploying.md +4 -0
- package/docs/start/framework/pending-ui.md +1 -1
- package/docs/start/framework/route-module.md +8 -8
- package/docs/start/framework/routing.md +1 -1
- package/docs/upgrading/component-routes.md +1 -1
- package/docs/upgrading/future.md +33 -0
- package/docs/upgrading/router-provider.md +5 -5
- package/docs/upgrading/v7.md +39 -22
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -110,6 +110,29 @@ function getManifestPath(_manifestPath, basename) {
|
|
|
110
110
|
return basename == null ? manifestPath : joinPaths([basename, manifestPath]);
|
|
111
111
|
}
|
|
112
112
|
const MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
|
|
113
|
+
async function handleClientVersionMismatch(needsReload, version, errorReloadPath) {
|
|
114
|
+
if (!needsReload) {
|
|
115
|
+
try {
|
|
116
|
+
sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
|
|
117
|
+
} catch {}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (!errorReloadPath) {
|
|
121
|
+
console.warn("Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest.");
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === version) {
|
|
126
|
+
console.error("Unable to discover routes due to manifest version mismatch.");
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, version);
|
|
130
|
+
} catch {}
|
|
131
|
+
window.location.href = errorReloadPath;
|
|
132
|
+
console.warn("Detected manifest version mismatch, reloading...");
|
|
133
|
+
await new Promise(() => {});
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
113
136
|
async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
|
|
114
137
|
paths = getPathsWithAncestors(paths);
|
|
115
138
|
const searchParams = new URLSearchParams();
|
|
@@ -125,25 +148,7 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
|
|
|
125
148
|
try {
|
|
126
149
|
let res = await fetch(url, { signal });
|
|
127
150
|
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
128
|
-
|
|
129
|
-
if (!errorReloadPath) {
|
|
130
|
-
console.warn("Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest.");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
|
|
135
|
-
console.error("Unable to discover routes due to manifest version mismatch.");
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
|
|
139
|
-
} catch {}
|
|
140
|
-
window.location.href = errorReloadPath;
|
|
141
|
-
console.warn("Detected manifest version mismatch, reloading...");
|
|
142
|
-
await new Promise(() => {});
|
|
143
|
-
} else if (res.status >= 400) throw new Error(await res.text());
|
|
144
|
-
try {
|
|
145
|
-
sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
|
|
146
|
-
} catch {}
|
|
151
|
+
if (await handleClientVersionMismatch(res.status === 204 && res.headers.has("X-Remix-Reload-Document"), manifest.version, errorReloadPath)) return;
|
|
147
152
|
serverPatches = await res.json();
|
|
148
153
|
} catch (e) {
|
|
149
154
|
if (signal?.aborted) return;
|
|
@@ -177,4 +182,4 @@ function debounce(callback, wait) {
|
|
|
177
182
|
};
|
|
178
183
|
}
|
|
179
184
|
//#endregion
|
|
180
|
-
export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, isFogOfWarEnabled, useFogOFWarDiscovery };
|
|
185
|
+
export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, useFogOFWarDiscovery };
|
|
@@ -50,7 +50,20 @@ interface RoutesTestStubProps {
|
|
|
50
50
|
future?: Partial<FutureConfig>;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
+
* Creates a React component that renders the provided routes in a test-friendly
|
|
54
|
+
* React Router context.
|
|
55
|
+
*
|
|
56
|
+
* Use this to unit test components that rely on router context, such as
|
|
57
|
+
* `loaderData`, `actionData`, and route matches.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
53
60
|
* @category Utils
|
|
61
|
+
* @mode framework
|
|
62
|
+
* @mode data
|
|
63
|
+
* @param routes The route objects to render in the test router.
|
|
64
|
+
* @param _context An optional {@link RouterContextProvider} for supplying
|
|
65
|
+
* application context values to route middleware, loaders, and actions.
|
|
66
|
+
* @returns A React component that renders the test router.
|
|
54
67
|
*/
|
|
55
68
|
declare function createRoutesStub(routes: StubRouteObject[], _context?: RouterContextProvider): ({
|
|
56
69
|
initialEntries,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -14,7 +14,20 @@ import { FrameworkContext } from "./components.js";
|
|
|
14
14
|
import * as React$1 from "react";
|
|
15
15
|
//#region lib/dom/ssr/routes-test-stub.tsx
|
|
16
16
|
/**
|
|
17
|
+
* Creates a React component that renders the provided routes in a test-friendly
|
|
18
|
+
* React Router context.
|
|
19
|
+
*
|
|
20
|
+
* Use this to unit test components that rely on router context, such as
|
|
21
|
+
* `loaderData`, `actionData`, and route matches.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
17
24
|
* @category Utils
|
|
25
|
+
* @mode framework
|
|
26
|
+
* @mode data
|
|
27
|
+
* @param routes The route objects to render in the test router.
|
|
28
|
+
* @param _context An optional {@link RouterContextProvider} for supplying
|
|
29
|
+
* application context values to route middleware, loaders, and actions.
|
|
30
|
+
* @returns A React component that renders the test router.
|
|
18
31
|
*/
|
|
19
32
|
function createRoutesStub(routes, _context) {
|
|
20
33
|
return function RoutesTestStub({ initialEntries, initialIndex, hydrationData, future }) {
|
|
@@ -143,12 +143,16 @@ interface NavigateFunction {
|
|
|
143
143
|
* All properties are optional.
|
|
144
144
|
*
|
|
145
145
|
* ```tsx
|
|
146
|
-
* navigate(
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
146
|
+
* navigate(
|
|
147
|
+
* {
|
|
148
|
+
* pathname: "/some/route",
|
|
149
|
+
* search: "?search=param",
|
|
150
|
+
* hash: "#hash",
|
|
151
|
+
* },
|
|
152
|
+
* {
|
|
153
|
+
* state: { some: "state" },
|
|
154
|
+
* },
|
|
155
|
+
* );
|
|
152
156
|
* ```
|
|
153
157
|
*
|
|
154
158
|
* If you use `state`, that will be available on the {@link Location} object on
|
|
@@ -576,6 +580,29 @@ declare function useRevalidator(): {
|
|
|
576
580
|
* parent/child routes or the route [`handle`](../../start/framework/route-module#handle)
|
|
577
581
|
* property
|
|
578
582
|
*
|
|
583
|
+
* Pairing the route `handle` with `useMatches` gets very powerful since you can put
|
|
584
|
+
* whatever you want on a route handle and have access to `useMatches` anywhere.
|
|
585
|
+
* Please see the [handle](../../how-to/using-handle) documentation for an example
|
|
586
|
+
* of breadcrumbs via `useMatches`/`handle`.
|
|
587
|
+
*
|
|
588
|
+
* ```tsx
|
|
589
|
+
* import { useMatches } from "react-router";
|
|
590
|
+
*
|
|
591
|
+
* function SomeComponent() {
|
|
592
|
+
* const matches = useMatches();
|
|
593
|
+
* // matches[i].id // route id
|
|
594
|
+
* // matches[i].pathname // the portion of the URL the route matched
|
|
595
|
+
* // matches[i].params // the parsed params from the URL
|
|
596
|
+
* // matches[i].loaderData // the data from the loader
|
|
597
|
+
* // matches[i].handle // the route handle with any app specific data
|
|
598
|
+
* }
|
|
599
|
+
* ```
|
|
600
|
+
*
|
|
601
|
+
* <docs-info>useMatches only works with a data router like `createBrowserRouter`,
|
|
602
|
+
* since they know the full route tree up front and can provide all of the current
|
|
603
|
+
* matches. Additionally, `useMatches` will not match down into any descendant route
|
|
604
|
+
* trees since the router isn't aware of the descendant routes.</docs-info>
|
|
605
|
+
*
|
|
579
606
|
* @public
|
|
580
607
|
* @category Hooks
|
|
581
608
|
* @mode framework
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -162,12 +162,16 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
|
|
|
162
162
|
* All properties are optional.
|
|
163
163
|
*
|
|
164
164
|
* ```tsx
|
|
165
|
-
* navigate(
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
165
|
+
* navigate(
|
|
166
|
+
* {
|
|
167
|
+
* pathname: "/some/route",
|
|
168
|
+
* search: "?search=param",
|
|
169
|
+
* hash: "#hash",
|
|
170
|
+
* },
|
|
171
|
+
* {
|
|
172
|
+
* state: { some: "state" },
|
|
173
|
+
* },
|
|
174
|
+
* );
|
|
171
175
|
* ```
|
|
172
176
|
*
|
|
173
177
|
* If you use `state`, that will be available on the {@link Location} object on
|
|
@@ -919,6 +923,29 @@ function useRevalidator() {
|
|
|
919
923
|
* parent/child routes or the route [`handle`](../../start/framework/route-module#handle)
|
|
920
924
|
* property
|
|
921
925
|
*
|
|
926
|
+
* Pairing the route `handle` with `useMatches` gets very powerful since you can put
|
|
927
|
+
* whatever you want on a route handle and have access to `useMatches` anywhere.
|
|
928
|
+
* Please see the [handle](../../how-to/using-handle) documentation for an example
|
|
929
|
+
* of breadcrumbs via `useMatches`/`handle`.
|
|
930
|
+
*
|
|
931
|
+
* ```tsx
|
|
932
|
+
* import { useMatches } from "react-router";
|
|
933
|
+
*
|
|
934
|
+
* function SomeComponent() {
|
|
935
|
+
* const matches = useMatches();
|
|
936
|
+
* // matches[i].id // route id
|
|
937
|
+
* // matches[i].pathname // the portion of the URL the route matched
|
|
938
|
+
* // matches[i].params // the parsed params from the URL
|
|
939
|
+
* // matches[i].loaderData // the data from the loader
|
|
940
|
+
* // matches[i].handle // the route handle with any app specific data
|
|
941
|
+
* }
|
|
942
|
+
* ```
|
|
943
|
+
*
|
|
944
|
+
* <docs-info>useMatches only works with a data router like `createBrowserRouter`,
|
|
945
|
+
* since they know the full route tree up front and can provide all of the current
|
|
946
|
+
* matches. Additionally, `useMatches` will not match down into any descendant route
|
|
947
|
+
* trees since the router isn't aware of the descendant routes.</docs-info>
|
|
948
|
+
*
|
|
922
949
|
* @public
|
|
923
950
|
* @category Hooks
|
|
924
951
|
* @mode framework
|
|
@@ -6,14 +6,30 @@ import { Pages } from "./types/register.js";
|
|
|
6
6
|
type Args = { [K in keyof Pages]: ToArgs<Pages[K]["params"]> };
|
|
7
7
|
type ToArgs<Params extends Record<string, string | undefined>> = Equal<Params, {}> extends true ? [] : Partial<Params> extends Params ? [Params] | [] : [Params];
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
* Returns a resolved URL path for the specified route.
|
|
10
|
+
*
|
|
11
|
+
* Param values are percent-encoded for use in a path segment: characters that
|
|
12
|
+
* would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
|
|
13
|
+
* are escaped, while characters that RFC 3986 allows literally in a path
|
|
14
|
+
* segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
|
|
15
|
+
* encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
|
|
16
|
+
* delimiters and must be escaped. Splat (`*`) values are encoded per segment,
|
|
17
|
+
* preserving `/` separators.
|
|
18
|
+
*
|
|
19
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const h = href("/:lang?/about", { lang: "en" })
|
|
23
|
+
* // -> `/en/about`
|
|
24
|
+
*
|
|
25
|
+
* <Link to={href("/products/:id", { id: "abc123" })} />
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @category Utils
|
|
29
|
+
* @mode framework
|
|
30
|
+
* @param path The route path to resolve
|
|
31
|
+
* @param args The route params to use when resolving the path
|
|
32
|
+
* @returns The resolved URL path
|
|
17
33
|
*/
|
|
18
34
|
declare function href<Path extends keyof Args>(path: Path, ...args: Args[Path]): string;
|
|
19
35
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,16 +8,36 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
+
import { encodePathParam } from "./router/utils.js";
|
|
11
12
|
//#region lib/href.ts
|
|
13
|
+
function stringify(p) {
|
|
14
|
+
return p == null ? "" : typeof p === "string" ? p : String(p);
|
|
15
|
+
}
|
|
12
16
|
/**
|
|
13
|
-
Returns a resolved URL path for the specified route.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
* Returns a resolved URL path for the specified route.
|
|
18
|
+
*
|
|
19
|
+
* Param values are percent-encoded for use in a path segment: characters that
|
|
20
|
+
* would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
|
|
21
|
+
* are escaped, while characters that RFC 3986 allows literally in a path
|
|
22
|
+
* segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
|
|
23
|
+
* encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
|
|
24
|
+
* delimiters and must be escaped. Splat (`*`) values are encoded per segment,
|
|
25
|
+
* preserving `/` separators.
|
|
26
|
+
*
|
|
27
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const h = href("/:lang?/about", { lang: "en" })
|
|
31
|
+
* // -> `/en/about`
|
|
32
|
+
*
|
|
33
|
+
* <Link to={href("/products/:id", { id: "abc123" })} />
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
* @category Utils
|
|
37
|
+
* @mode framework
|
|
38
|
+
* @param path The route path to resolve
|
|
39
|
+
* @param args The route params to use when resolving the path
|
|
40
|
+
* @returns The resolved URL path
|
|
21
41
|
*/
|
|
22
42
|
function href(path, ...args) {
|
|
23
43
|
let params = args[0];
|
|
@@ -25,11 +45,11 @@ function href(path, ...args) {
|
|
|
25
45
|
const isRequired = questionMark === void 0;
|
|
26
46
|
const value = params?.[param];
|
|
27
47
|
if (isRequired && value === void 0) throw new Error(`Path '${path}' requires param '${param}' but it was not provided`);
|
|
28
|
-
return value
|
|
48
|
+
return value == null ? "" : "/" + encodePathParam(stringify(value));
|
|
29
49
|
});
|
|
30
50
|
if (path.endsWith("*")) {
|
|
31
51
|
const value = params?.["*"];
|
|
32
|
-
if (value !== void 0) result += "/" + value;
|
|
52
|
+
if (value !== void 0) result += "/" + stringify(value).split("/").map(encodePathParam).join("/");
|
|
33
53
|
}
|
|
34
54
|
return result || "/";
|
|
35
55
|
}
|
|
@@ -236,7 +236,10 @@ declare function invariant<T>(value: T | null | undefined, message?: string): as
|
|
|
236
236
|
/**
|
|
237
237
|
* Creates a string URL path from the given pathname, search, and hash components.
|
|
238
238
|
*
|
|
239
|
+
* @public
|
|
239
240
|
* @category Utils
|
|
241
|
+
* @param path The pathname, search, and hash components to combine.
|
|
242
|
+
* @returns The combined URL path.
|
|
240
243
|
*/
|
|
241
244
|
declare function createPath({
|
|
242
245
|
pathname,
|
|
@@ -246,7 +249,10 @@ declare function createPath({
|
|
|
246
249
|
/**
|
|
247
250
|
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
248
251
|
*
|
|
252
|
+
* @public
|
|
249
253
|
* @category Utils
|
|
254
|
+
* @param path The URL path to parse.
|
|
255
|
+
* @returns The parsed pathname, search, and hash components.
|
|
250
256
|
*/
|
|
251
257
|
declare function parsePath(path: string): Partial<Path>;
|
|
252
258
|
interface UrlHistory extends History {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -231,7 +231,10 @@ function createLocation(current, to, state = null, key, mask) {
|
|
|
231
231
|
/**
|
|
232
232
|
* Creates a string URL path from the given pathname, search, and hash components.
|
|
233
233
|
*
|
|
234
|
+
* @public
|
|
234
235
|
* @category Utils
|
|
236
|
+
* @param path The pathname, search, and hash components to combine.
|
|
237
|
+
* @returns The combined URL path.
|
|
235
238
|
*/
|
|
236
239
|
function createPath({ pathname = "/", search = "", hash = "" }) {
|
|
237
240
|
if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
|
|
@@ -241,7 +244,10 @@ function createPath({ pathname = "/", search = "", hash = "" }) {
|
|
|
241
244
|
/**
|
|
242
245
|
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
243
246
|
*
|
|
247
|
+
* @public
|
|
244
248
|
* @category Utils
|
|
249
|
+
* @param path The URL path to parse.
|
|
250
|
+
* @returns The parsed pathname, search, and hash components.
|
|
245
251
|
*/
|
|
246
252
|
function parsePath(path) {
|
|
247
253
|
let parsedPath = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -341,7 +341,7 @@ function createRouter(init) {
|
|
|
341
341
|
else actionData = null;
|
|
342
342
|
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
|
|
343
343
|
let blockers = state.blockers;
|
|
344
|
-
if (blockers.size > 0) {
|
|
344
|
+
if (blockers.size > 0 && !isUninterruptedRevalidation) {
|
|
345
345
|
blockers = new Map(blockers);
|
|
346
346
|
blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));
|
|
347
347
|
}
|
|
@@ -686,10 +686,22 @@ interface RouteBranch<RouteObjectType extends RouteObject = RouteObject> {
|
|
|
686
686
|
/**
|
|
687
687
|
* Returns a path with params interpolated.
|
|
688
688
|
*
|
|
689
|
+
* Param values are percent-encoded for use in a path segment: characters that
|
|
690
|
+
* would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
|
|
691
|
+
* are escaped, while characters that RFC 3986 allows literally in a path
|
|
692
|
+
* segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
|
|
693
|
+
* encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
|
|
694
|
+
* delimiters and must be escaped. Splat (`*`) values are encoded per segment,
|
|
695
|
+
* preserving `/` separators.
|
|
696
|
+
*
|
|
697
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
|
|
698
|
+
*
|
|
689
699
|
* @example
|
|
690
700
|
* import { generatePath } from "react-router";
|
|
691
701
|
*
|
|
692
702
|
* generatePath("/users/:id", { id: "123" }); // "/users/123"
|
|
703
|
+
* generatePath("/files/:name", { name: "a b" }); // "/files/a%20b"
|
|
704
|
+
* generatePath("/releases/:v", { v: "1.0.0+1" }); // "/releases/1.0.0+1"
|
|
693
705
|
*
|
|
694
706
|
* @public
|
|
695
707
|
* @category Utils
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -323,6 +323,8 @@ function rankRouteBranches(branches) {
|
|
|
323
323
|
branches.sort((a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(a.routesMeta.map((meta) => meta.childrenIndex), b.routesMeta.map((meta) => meta.childrenIndex)));
|
|
324
324
|
}
|
|
325
325
|
const paramRe = /^:[\w-]+$/;
|
|
326
|
+
const partialParamRe = /^:[\w-]+/;
|
|
327
|
+
const partialDynamicSegmentValue = 3.5;
|
|
326
328
|
const dynamicSegmentValue = 3;
|
|
327
329
|
const indexRouteValue = 2;
|
|
328
330
|
const emptySegmentValue = 1;
|
|
@@ -334,7 +336,7 @@ function computeScore(path, index) {
|
|
|
334
336
|
let initialScore = segments.length;
|
|
335
337
|
if (segments.some(isSplat)) initialScore += splatPenalty;
|
|
336
338
|
if (index) initialScore += indexRouteValue;
|
|
337
|
-
return segments.filter((s) => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
|
|
339
|
+
return segments.filter((s) => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : partialParamRe.test(segment) ? partialDynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
|
|
338
340
|
}
|
|
339
341
|
function compareIndexes(a, b) {
|
|
340
342
|
return a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]) ? a[a.length - 1] - b[b.length - 1] : 0;
|
|
@@ -373,12 +375,66 @@ function matchRouteBranch(branch, pathname, allowPartial = false) {
|
|
|
373
375
|
return matches;
|
|
374
376
|
}
|
|
375
377
|
/**
|
|
378
|
+
* Characters that `encodeURIComponent` escapes but that are valid literally in
|
|
379
|
+
* a URL path segment. Per RFC 3986 §3.3, a path segment is made of `pchar`:
|
|
380
|
+
*
|
|
381
|
+
* ```
|
|
382
|
+
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
383
|
+
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
384
|
+
* ```
|
|
385
|
+
*
|
|
386
|
+
* `encodeURIComponent` targets query-string values, where `$ & + , ; = : @`
|
|
387
|
+
* are delimiters and must be escaped — but in a path segment they carry no
|
|
388
|
+
* special meaning, and browsers keep them literal in `location.pathname`.
|
|
389
|
+
* (`! ' ( ) *` and the unreserved set are already left alone by
|
|
390
|
+
* `encodeURIComponent`, so they need no restoring.)
|
|
391
|
+
*/
|
|
392
|
+
const PATH_PARAM_OVERESCAPED = {
|
|
393
|
+
"%24": "$",
|
|
394
|
+
"%26": "&",
|
|
395
|
+
"%2B": "+",
|
|
396
|
+
"%2C": ",",
|
|
397
|
+
"%3A": ":",
|
|
398
|
+
"%3B": ";",
|
|
399
|
+
"%3D": "=",
|
|
400
|
+
"%40": "@"
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Encodes a param value for interpolation into a single URL path segment.
|
|
404
|
+
*
|
|
405
|
+
* Escapes characters that would break the path (`/ ? # %`, whitespace,
|
|
406
|
+
* non-ASCII, …) while leaving characters that RFC 3986 permits literally in a
|
|
407
|
+
* path segment untouched. Escaping those would needlessly rewrite URLs — e.g.
|
|
408
|
+
* a semver build param `1.0.0+1` would become `1.0.0%2B1` even though browsers
|
|
409
|
+
* display and match the `+` literally in `location.pathname`.
|
|
410
|
+
*
|
|
411
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3))
|
|
412
|
+
*
|
|
413
|
+
* @param value The param value to encode.
|
|
414
|
+
* @returns The encoded value, safe for use as a single path segment.
|
|
415
|
+
*/
|
|
416
|
+
function encodePathParam(value) {
|
|
417
|
+
return encodeURIComponent(value).replace(/%(?:24|26|2B|2C|3A|3B|3D|40)/g, (match) => PATH_PARAM_OVERESCAPED[match]);
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
376
420
|
* Returns a path with params interpolated.
|
|
377
421
|
*
|
|
422
|
+
* Param values are percent-encoded for use in a path segment: characters that
|
|
423
|
+
* would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
|
|
424
|
+
* are escaped, while characters that RFC 3986 allows literally in a path
|
|
425
|
+
* segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
|
|
426
|
+
* encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
|
|
427
|
+
* delimiters and must be escaped. Splat (`*`) values are encoded per segment,
|
|
428
|
+
* preserving `/` separators.
|
|
429
|
+
*
|
|
430
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
|
|
431
|
+
*
|
|
378
432
|
* @example
|
|
379
433
|
* import { generatePath } from "react-router";
|
|
380
434
|
*
|
|
381
435
|
* generatePath("/users/:id", { id: "123" }); // "/users/123"
|
|
436
|
+
* generatePath("/files/:name", { name: "a b" }); // "/files/a%20b"
|
|
437
|
+
* generatePath("/releases/:v", { v: "1.0.0+1" }); // "/releases/1.0.0+1"
|
|
382
438
|
*
|
|
383
439
|
* @public
|
|
384
440
|
* @category Utils
|
|
@@ -401,7 +457,7 @@ function generatePath(originalPath, params = {}) {
|
|
|
401
457
|
const [, key, optional, suffix] = keyMatch;
|
|
402
458
|
let param = params[key];
|
|
403
459
|
invariant(optional === "?" || param != null, `Missing ":${key}" param`);
|
|
404
|
-
return
|
|
460
|
+
return encodePathParam(stringify(param)) + suffix;
|
|
405
461
|
}
|
|
406
462
|
return segment.replace(/\?$/g, "");
|
|
407
463
|
}).filter((segment) => !!segment).join("/");
|
|
@@ -465,7 +521,7 @@ function compilePath(path, caseSensitive = false, end = true) {
|
|
|
465
521
|
return "(?:/([^\\/]*))?";
|
|
466
522
|
}
|
|
467
523
|
return "/([^\\/]+)";
|
|
468
|
-
}).replace(/\/([\w-]+)\?(
|
|
524
|
+
}).replace(/\/([\w-]+)\?(?=\/|$|\()/g, "(?:/$1)?");
|
|
469
525
|
if (path.endsWith("*")) {
|
|
470
526
|
params.push({ paramName: "*" });
|
|
471
527
|
regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
|
|
@@ -822,4 +878,4 @@ function parseToInfo(_to, basename) {
|
|
|
822
878
|
};
|
|
823
879
|
}
|
|
824
880
|
//#endregion
|
|
825
|
-
export { ErrorResponseImpl, RouterContextProvider, SUPPORTED_ERROR_TYPES, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, createDataFunctionUrl, data, decodePath, defaultMapRouteProperties, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, removeTrailingSlash, replace, resolvePath, resolveTo, stripBasename };
|
|
881
|
+
export { ErrorResponseImpl, RouterContextProvider, SUPPORTED_ERROR_TYPES, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, createDataFunctionUrl, data, decodePath, defaultMapRouteProperties, encodePathParam, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, removeTrailingSlash, replace, resolvePath, resolveTo, stripBasename };
|