react-router 8.2.0 → 8.3.1
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 +78 -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 +114 -17
- package/dist/development/index-react-server.js +189 -54
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +10 -5
- package/dist/development/lib/components.js +6 -3
- package/dist/development/lib/context.d.ts +1 -0
- 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 +26 -26
- package/dist/development/lib/dom/lib.d.ts +2 -1
- package/dist/development/lib/dom/lib.js +23 -7
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +2 -2
- 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 +27 -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 +5 -5
- 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.js +6 -3
- package/dist/development/lib/href.d.ts +24 -8
- package/dist/development/lib/href.js +28 -11
- package/dist/development/lib/router/history.d.ts +6 -0
- package/dist/development/lib/router/history.js +8 -2
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/navigation.js +45 -0
- package/dist/development/lib/router/router.d.ts +8 -0
- package/dist/development/lib/router/router.js +31 -17
- 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 +66 -8
- package/dist/development/lib/rsc/browser.js +37 -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 +30 -11
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/development/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/development/lib/rsc/server.ssr.js +28 -13
- package/dist/development/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/development/lib/server-runtime/cookies.js +18 -4
- 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 +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 +14 -2
- 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 +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/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 +114 -17
- package/dist/production/index-react-server.js +189 -54
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +10 -5
- package/dist/production/lib/components.js +6 -3
- package/dist/production/lib/context.d.ts +1 -0
- 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 +26 -26
- package/dist/production/lib/dom/lib.d.ts +2 -1
- package/dist/production/lib/dom/lib.js +23 -7
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +2 -2
- 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 +27 -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 +5 -5
- 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.js +6 -3
- package/dist/production/lib/href.d.ts +24 -8
- package/dist/production/lib/href.js +28 -11
- package/dist/production/lib/router/history.d.ts +6 -0
- package/dist/production/lib/router/history.js +8 -2
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/navigation.js +45 -0
- package/dist/production/lib/router/router.d.ts +8 -0
- package/dist/production/lib/router/router.js +31 -17
- 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 +66 -8
- package/dist/production/lib/rsc/browser.js +37 -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 +30 -11
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/production/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/production/lib/rsc/server.ssr.js +28 -13
- package/dist/production/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/production/lib/server-runtime/cookies.js +18 -4
- 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 +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 +14 -2
- 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 +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/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/explanation/sessions-and-cookies.md +13 -13
- package/docs/explanation/state-management.md +2 -2
- 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/pending-ui.md +1 -1
- package/docs/start/framework/route-module.md +8 -8
- package/docs/start/framework/routing.md +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -30,30 +30,30 @@ function shouldProcessLinkClick(event, target) {
|
|
|
30
30
|
return event.button === 0 && (!target || target === "_self") && !isModifiedEvent(event);
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
Creates a URLSearchParams object using the given initializer.
|
|
34
|
-
|
|
35
|
-
This is identical to `new URLSearchParams(init)` except it also
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
33
|
+
* Creates a URLSearchParams object using the given initializer.
|
|
34
|
+
*
|
|
35
|
+
* This is identical to `new URLSearchParams(init)` except it also supports
|
|
36
|
+
* arrays as values in the object form of the initializer instead of just
|
|
37
|
+
* strings. This is convenient when you need multiple values for a given key,
|
|
38
|
+
* but don't want to use an array initializer.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Instead of:
|
|
42
|
+
* let searchParams = new URLSearchParams([
|
|
43
|
+
* ["sort", "name"],
|
|
44
|
+
* ["sort", "price"],
|
|
45
|
+
* ]);
|
|
46
|
+
*
|
|
47
|
+
* // You can do:
|
|
48
|
+
* let searchParams = createSearchParams({
|
|
49
|
+
* sort: ["name", "price"],
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* @public
|
|
53
|
+
* @category Utils
|
|
54
|
+
* @param init The value used to initialize the URL search parameters.
|
|
55
|
+
* @returns A URLSearchParams object containing the initialized search
|
|
56
|
+
* parameters.
|
|
57
57
|
*/
|
|
58
58
|
function createSearchParams(init = "") {
|
|
59
59
|
return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
|
|
@@ -75,7 +75,7 @@ function isFormDataSubmitterSupported() {
|
|
|
75
75
|
if (_formDataSupportsSubmitter === null) try {
|
|
76
76
|
new FormData(document.createElement("form"), 0);
|
|
77
77
|
_formDataSupportsSubmitter = false;
|
|
78
|
-
} catch
|
|
78
|
+
} catch {
|
|
79
79
|
_formDataSupportsSubmitter = true;
|
|
80
80
|
}
|
|
81
81
|
return _formDataSupportsSubmitter;
|
|
@@ -1409,7 +1409,8 @@ declare namespace ScrollRestoration {
|
|
|
1409
1409
|
* for this navigation. To apply specific styles during the transition, see
|
|
1410
1410
|
* {@link useViewTransitionState}. Defaults to `false`.
|
|
1411
1411
|
* @param options.defaultShouldRevalidate Specify the default revalidation
|
|
1412
|
-
* behavior for the navigation.
|
|
1412
|
+
* behavior for the navigation. When not specified, loaders revalidate
|
|
1413
|
+
* according to the router's standard revalidation behavior.
|
|
1413
1414
|
* @param options.mask Masked location to display in the browser instead
|
|
1414
1415
|
* of the router location. Defaults to `undefined`.
|
|
1415
1416
|
* @param options.useTransitions Wraps the navigation in
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -22,8 +22,8 @@ import * as React$1 from "react";
|
|
|
22
22
|
//#region lib/dom/lib.tsx
|
|
23
23
|
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
24
24
|
try {
|
|
25
|
-
if (isBrowser) window.__reactRouterVersion = "8
|
|
26
|
-
} catch
|
|
25
|
+
if (isBrowser) window.__reactRouterVersion = "8";
|
|
26
|
+
} catch {}
|
|
27
27
|
/**
|
|
28
28
|
* Create a new {@link DataRouter| data router} that manages the application
|
|
29
29
|
* path via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)
|
|
@@ -123,7 +123,7 @@ function deserializeErrors(errors) {
|
|
|
123
123
|
let error = new ErrorConstructor(val.message);
|
|
124
124
|
error.stack = "";
|
|
125
125
|
serialized[key] = error;
|
|
126
|
-
} catch
|
|
126
|
+
} catch {}
|
|
127
127
|
}
|
|
128
128
|
if (serialized[key] == null) {
|
|
129
129
|
let error = new Error(val.message);
|
|
@@ -386,7 +386,7 @@ const NavLink = React$1.forwardRef(function NavLinkWithRef({ "aria-current": ari
|
|
|
386
386
|
if (nextLocationPathname && basename) nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
|
|
387
387
|
const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
|
|
388
388
|
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
|
|
389
|
-
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(
|
|
389
|
+
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(endSlashPosition) === "/");
|
|
390
390
|
let renderProps = {
|
|
391
391
|
isActive,
|
|
392
392
|
isPending,
|
|
@@ -609,7 +609,8 @@ function useDataRouterState(hookName) {
|
|
|
609
609
|
* for this navigation. To apply specific styles during the transition, see
|
|
610
610
|
* {@link useViewTransitionState}. Defaults to `false`.
|
|
611
611
|
* @param options.defaultShouldRevalidate Specify the default revalidation
|
|
612
|
-
* behavior for the navigation.
|
|
612
|
+
* behavior for the navigation. When not specified, loaders revalidate
|
|
613
|
+
* according to the router's standard revalidation behavior.
|
|
613
614
|
* @param options.mask Masked location to display in the browser instead
|
|
614
615
|
* of the router location. Defaults to `undefined`.
|
|
615
616
|
* @param options.useTransitions Wraps the navigation in
|
|
@@ -795,6 +796,7 @@ function useSubmit() {
|
|
|
795
796
|
if (options.navigate === false) await routerFetch(options.fetcherKey || getUniqueFetcherId(), currentRouteId, options.action || action, {
|
|
796
797
|
defaultShouldRevalidate: options.defaultShouldRevalidate,
|
|
797
798
|
preventScrollReset: options.preventScrollReset,
|
|
799
|
+
relative: options.relative,
|
|
798
800
|
formData,
|
|
799
801
|
body,
|
|
800
802
|
formMethod: options.method || method,
|
|
@@ -804,6 +806,7 @@ function useSubmit() {
|
|
|
804
806
|
else await routerNavigate(options.action || action, {
|
|
805
807
|
defaultShouldRevalidate: options.defaultShouldRevalidate,
|
|
806
808
|
preventScrollReset: options.preventScrollReset,
|
|
809
|
+
relative: options.relative,
|
|
807
810
|
formData,
|
|
808
811
|
body,
|
|
809
812
|
formMethod: options.method || method,
|
|
@@ -1086,6 +1089,9 @@ function useScrollRestoration({ getKey, storageKey } = {}) {
|
|
|
1086
1089
|
window.history.scrollRestoration = "auto";
|
|
1087
1090
|
};
|
|
1088
1091
|
}, []);
|
|
1092
|
+
usePageShow(React$1.useCallback((event) => {
|
|
1093
|
+
if (event.persisted) window.history.scrollRestoration = "manual";
|
|
1094
|
+
}, []));
|
|
1089
1095
|
usePageHide(React$1.useCallback(() => {
|
|
1090
1096
|
if (navigation.state === "idle") {
|
|
1091
1097
|
let key = getScrollRestorationKey(location, matches, basename, getKey);
|
|
@@ -1110,7 +1116,7 @@ function useScrollRestoration({ getKey, storageKey } = {}) {
|
|
|
1110
1116
|
try {
|
|
1111
1117
|
let sessionPositions = sessionStorage.getItem(storageKey || SCROLL_RESTORATION_STORAGE_KEY);
|
|
1112
1118
|
if (sessionPositions) savedScrollPositions = JSON.parse(sessionPositions);
|
|
1113
|
-
} catch
|
|
1119
|
+
} catch {}
|
|
1114
1120
|
}, [storageKey]);
|
|
1115
1121
|
React$1.useLayoutEffect(() => {
|
|
1116
1122
|
let disableScrollRestoration = router?.enableScrollRestoration(savedScrollPositions, () => window.scrollY, getKey ? (location, matches) => getScrollRestorationKey(location, matches, basename, getKey) : void 0);
|
|
@@ -1178,6 +1184,16 @@ function usePageHide(callback, options) {
|
|
|
1178
1184
|
};
|
|
1179
1185
|
}, [callback, capture]);
|
|
1180
1186
|
}
|
|
1187
|
+
function usePageShow(callback, options) {
|
|
1188
|
+
let { capture } = options || {};
|
|
1189
|
+
React$1.useEffect(() => {
|
|
1190
|
+
let opts = capture != null ? { capture } : void 0;
|
|
1191
|
+
window.addEventListener("pageshow", callback, opts);
|
|
1192
|
+
return () => {
|
|
1193
|
+
window.removeEventListener("pageshow", callback, opts);
|
|
1194
|
+
};
|
|
1195
|
+
}, [callback, capture]);
|
|
1196
|
+
}
|
|
1181
1197
|
/**
|
|
1182
1198
|
* Wrapper around {@link useBlocker} to show a [`window.confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
|
|
1183
1199
|
* prompt to users instead of building a custom UI with {@link useBlocker}.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -425,7 +425,7 @@ function Meta() {
|
|
|
425
425
|
type: "application/ld+json",
|
|
426
426
|
dangerouslySetInnerHTML: { __html: escapeHtml(json) }
|
|
427
427
|
});
|
|
428
|
-
} catch
|
|
428
|
+
} catch {
|
|
429
429
|
return null;
|
|
430
430
|
}
|
|
431
431
|
return /* @__PURE__ */ React$1.createElement("meta", {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
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,30 +148,13 @@ 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;
|
|
150
155
|
throw e;
|
|
151
156
|
}
|
|
157
|
+
if (signal?.aborted) return;
|
|
152
158
|
let knownRoutes = new Set(Object.keys(manifest.routes));
|
|
153
159
|
let patches = Object.values(serverPatches).reduce((acc, route) => {
|
|
154
160
|
if (route && !knownRoutes.has(route.id)) acc[route.id] = route;
|
|
@@ -177,4 +183,4 @@ function debounce(callback, wait) {
|
|
|
177
183
|
};
|
|
178
184
|
}
|
|
179
185
|
//#endregion
|
|
180
|
-
export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, isFogOfWarEnabled, useFogOFWarDiscovery };
|
|
186
|
+
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.1
|
|
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 }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -205,7 +205,7 @@ async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams,
|
|
|
205
205
|
if (middlewareError !== void 0) Array.from(routesParams.values()).forEach((routeId) => {
|
|
206
206
|
if (results[routeId].result instanceof SingleFetchNoResultError) results[routeId].result = middlewareError;
|
|
207
207
|
});
|
|
208
|
-
} catch
|
|
208
|
+
} catch {}
|
|
209
209
|
}
|
|
210
210
|
async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode) {
|
|
211
211
|
let fetcherMatch = args.matches.find((m) => m.shouldCallHandler());
|
|
@@ -277,7 +277,7 @@ async function fetchAndDecodeViaTurboStream(args, targetRoutes) {
|
|
|
277
277
|
status: res.status,
|
|
278
278
|
data
|
|
279
279
|
};
|
|
280
|
-
} catch
|
|
280
|
+
} catch {
|
|
281
281
|
throw new Error("Unable to decode turbo-stream response");
|
|
282
282
|
}
|
|
283
283
|
}
|
|
@@ -326,13 +326,13 @@ function createDeferred() {
|
|
|
326
326
|
res(val);
|
|
327
327
|
try {
|
|
328
328
|
await promise;
|
|
329
|
-
} catch
|
|
329
|
+
} catch {}
|
|
330
330
|
};
|
|
331
331
|
reject = async (error) => {
|
|
332
332
|
rej(error);
|
|
333
333
|
try {
|
|
334
334
|
await promise;
|
|
335
|
-
} catch
|
|
335
|
+
} catch {}
|
|
336
336
|
};
|
|
337
337
|
});
|
|
338
338
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,8 +8,9 @@
|
|
|
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
15
|
import { AwaitContext, DataRouterContext, DataRouterStateContext, LocationContext, NavigationContext, RSCRouterContext, RouteContext, RouteErrorContext } from "./context.js";
|
|
15
16
|
import { decodeRedirectErrorDigest, decodeRouteErrorResponseDigest } from "./errors.js";
|
|
@@ -291,6 +292,7 @@ function useNavigateUnstable() {
|
|
|
291
292
|
}
|
|
292
293
|
let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
|
|
293
294
|
if (dataRouterContext == null && basename !== "/") path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
|
|
295
|
+
validateNavigationTarget(typeof to === "string" ? to : createPath(to), navigator.createHref(path), getNavigatorCurrentUrl(navigator), "reject");
|
|
294
296
|
(!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
|
|
295
297
|
}, [
|
|
296
298
|
basename,
|
|
@@ -687,7 +689,7 @@ var RenderErrorBoundary = class extends React$1.Component {
|
|
|
687
689
|
};
|
|
688
690
|
const errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();
|
|
689
691
|
function RSCErrorHandler({ children, error }) {
|
|
690
|
-
let { basename } = React$1.useContext(NavigationContext);
|
|
692
|
+
let { basename, navigator } = React$1.useContext(NavigationContext);
|
|
691
693
|
if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
|
|
692
694
|
let redirect = decodeRedirectErrorDigest(error.digest);
|
|
693
695
|
if (redirect) {
|
|
@@ -695,6 +697,7 @@ function RSCErrorHandler({ children, error }) {
|
|
|
695
697
|
if (existingRedirect) throw existingRedirect;
|
|
696
698
|
let parsed = parseToInfo(redirect.location, basename);
|
|
697
699
|
let target = parsed.absoluteURL || parsed.to;
|
|
700
|
+
validateNavigationTarget(redirect.location, target, getNavigatorCurrentUrl(navigator), "allow-explicit");
|
|
698
701
|
if (hasInvalidProtocol(target)) throw new Error("Invalid redirect location");
|
|
699
702
|
if (isBrowser && !errorRedirectHandledMap.get(error)) if (parsed.isExternal || redirect.reloadDocument) window.location.href = target;
|
|
700
703
|
else {
|
|
@@ -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.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,19 +8,36 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
+
import { encodePathParam } from "./router/utils.js";
|
|
11
12
|
//#region lib/href.ts
|
|
12
13
|
function stringify(p) {
|
|
13
14
|
return p == null ? "" : typeof p === "string" ? p : String(p);
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
|
-
Returns a resolved URL path for the specified route.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
24
41
|
*/
|
|
25
42
|
function href(path, ...args) {
|
|
26
43
|
let params = args[0];
|
|
@@ -28,11 +45,11 @@ function href(path, ...args) {
|
|
|
28
45
|
const isRequired = questionMark === void 0;
|
|
29
46
|
const value = params?.[param];
|
|
30
47
|
if (isRequired && value === void 0) throw new Error(`Path '${path}' requires param '${param}' but it was not provided`);
|
|
31
|
-
return value == null ? "" : "/" +
|
|
48
|
+
return value == null ? "" : "/" + encodePathParam(stringify(value));
|
|
32
49
|
});
|
|
33
50
|
if (path.endsWith("*")) {
|
|
34
51
|
const value = params?.["*"];
|
|
35
|
-
if (value !== void 0) result += "/" + stringify(value).split("/").map(
|
|
52
|
+
if (value !== void 0) result += "/" + stringify(value).split("/").map(encodePathParam).join("/");
|
|
36
53
|
}
|
|
37
54
|
return result || "/";
|
|
38
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 {}
|