react-router 8.5.0 → 8.5.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 +44 -1
- 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 -396
- package/dist/development/index-react-server.js +43 -15
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/await.js +58 -0
- package/dist/development/lib/components.d.ts +41 -5
- package/dist/development/lib/components.js +62 -4
- package/dist/development/lib/context.d.ts +2 -2
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.js +1 -1
- package/dist/development/lib/dom/lib.js +1 -1
- 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 +12 -3
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/route-discovery.d.ts +2 -2
- package/dist/development/lib/dom/ssr/route-discovery.js +3 -3
- 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 +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.d.ts +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +7 -7
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +2 -2
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +0 -3
- package/dist/development/lib/hooks.js +5 -6
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +1 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/development/lib/router/matcher.js +6 -1
- package/dist/development/lib/router/navigation.js +1 -1
- package/dist/development/lib/router/router.d.ts +2 -0
- package/dist/development/lib/router/router.js +58 -28
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +7 -0
- package/dist/development/lib/router/utils.js +1 -1
- package/dist/development/lib/rsc/browser.js +3 -3
- 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 +1 -1
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.ssr.js +1 -1
- package/dist/development/lib/server-runtime/cookies.js +1 -1
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +13 -5
- 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 +2 -2
- 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/route-pattern.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +23 -3
- 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 -396
- package/dist/production/index-react-server.js +43 -15
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/await.js +58 -0
- package/dist/production/lib/components.d.ts +41 -5
- package/dist/production/lib/components.js +62 -4
- package/dist/production/lib/context.d.ts +2 -2
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.js +1 -1
- package/dist/production/lib/dom/lib.js +1 -1
- 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 +12 -3
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/route-discovery.d.ts +2 -2
- package/dist/production/lib/dom/ssr/route-discovery.js +3 -3
- 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 +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.d.ts +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +7 -7
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +2 -2
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +0 -3
- package/dist/production/lib/hooks.js +5 -6
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +1 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/production/lib/router/matcher.js +6 -1
- package/dist/production/lib/router/navigation.js +1 -1
- package/dist/production/lib/router/router.d.ts +2 -0
- package/dist/production/lib/router/router.js +58 -28
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +7 -0
- package/dist/production/lib/router/utils.js +1 -1
- package/dist/production/lib/rsc/browser.js +3 -3
- 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 +1 -1
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.ssr.js +1 -1
- package/dist/production/lib/server-runtime/cookies.js +1 -1
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +13 -5
- 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 +2 -2
- 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/route-pattern.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +23 -3
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/backend-for-frontend.md +0 -3
- package/docs/explanation/code-splitting.md +0 -3
- package/docs/explanation/concurrency.md +0 -3
- package/docs/explanation/hot-module-replacement.md +0 -3
- package/docs/explanation/lazy-route-discovery.md +0 -3
- package/docs/explanation/progressive-enhancement.md +0 -3
- package/docs/explanation/race-conditions.md +0 -3
- package/docs/explanation/react-transitions.md +0 -3
- package/docs/explanation/sessions-and-cookies.md +1 -1
- package/docs/explanation/state-management.md +0 -3
- package/docs/explanation/styling.md +0 -3
- package/docs/explanation/type-safety.md +0 -3
- package/docs/how-to/accessibility.md +0 -6
- package/docs/how-to/client-data.md +0 -3
- package/docs/how-to/data-strategy.md +0 -3
- package/docs/how-to/error-boundary.md +0 -3
- package/docs/how-to/error-reporting.md +0 -3
- package/docs/how-to/fetchers.md +0 -3
- package/docs/how-to/file-route-conventions.md +0 -3
- package/docs/how-to/file-uploads.md +0 -3
- package/docs/how-to/form-validation.md +0 -3
- package/docs/how-to/headers.md +0 -3
- package/docs/how-to/instrumentation.md +0 -3
- package/docs/how-to/middleware.md +6 -3
- package/docs/how-to/navigation-blocking.md +0 -3
- package/docs/how-to/optimize-revalidation.md +0 -3
- package/docs/how-to/pre-rendering.md +0 -3
- package/docs/how-to/presets.md +0 -3
- package/docs/how-to/react-server-components.md +0 -3
- package/docs/how-to/resource-routes.md +0 -3
- package/docs/how-to/route-discovery.md +4 -2
- package/docs/how-to/route-module-type-safety.md +0 -3
- package/docs/how-to/security.md +0 -3
- package/docs/how-to/server-bundles.md +0 -3
- package/docs/how-to/spa.md +0 -3
- package/docs/how-to/status.md +0 -3
- package/docs/how-to/suspense.md +22 -6
- package/docs/how-to/using-handle.md +0 -3
- package/docs/how-to/view-transitions.md +0 -3
- package/docs/start/framework/data-loading.md +9 -0
- package/docs/upgrading/future.md +0 -12
- package/docs/upgrading/v7.md +3 -33
- package/package.json +1 -1
- package/dist/development/lib/dom/global.d.ts +0 -35
- package/dist/production/lib/dom/global.d.ts +0 -35
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.5.1
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
//#region lib/await.ts
|
|
12
|
+
function getPromiseResult(promise) {
|
|
13
|
+
if (promise.status === "fulfilled") return {
|
|
14
|
+
status: "fulfilled",
|
|
15
|
+
value: promise.value
|
|
16
|
+
};
|
|
17
|
+
if (promise.status === "rejected") return {
|
|
18
|
+
status: "rejected",
|
|
19
|
+
reason: promise.reason
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
let awaitPromises = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
function getAwaitPromise(source, onError) {
|
|
24
|
+
let cached = awaitPromises.get(source);
|
|
25
|
+
if (!cached) {
|
|
26
|
+
cached = {
|
|
27
|
+
promise: Promise.resolve(source).then((value) => settle({
|
|
28
|
+
status: "fulfilled",
|
|
29
|
+
value
|
|
30
|
+
}), (reason) => {
|
|
31
|
+
let result = settle({
|
|
32
|
+
status: "rejected",
|
|
33
|
+
reason
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
cached.onError(reason);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("<Await> caught the following error in onError", error);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}),
|
|
42
|
+
onError
|
|
43
|
+
};
|
|
44
|
+
awaitPromises.set(source, cached);
|
|
45
|
+
} else cached.onError = onError;
|
|
46
|
+
function settle(result) {
|
|
47
|
+
Object.assign(cached.promise, {
|
|
48
|
+
status: "fulfilled",
|
|
49
|
+
value: result
|
|
50
|
+
});
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
let result = getPromiseResult(source);
|
|
54
|
+
if (result) settle(result);
|
|
55
|
+
return cached.promise;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { getAwaitPromise, getPromiseResult };
|
|
@@ -768,6 +768,8 @@ interface AwaitResolveRenderFunction<Resolve = any> {
|
|
|
768
768
|
* @category Types
|
|
769
769
|
*/
|
|
770
770
|
interface AwaitProps<Resolve> {
|
|
771
|
+
/** Use either `resolve` or `unstable_promise`, never both. */
|
|
772
|
+
unstable_promise?: never;
|
|
771
773
|
/**
|
|
772
774
|
* When using a function, the resolved value is provided as the parameter.
|
|
773
775
|
*
|
|
@@ -869,11 +871,46 @@ interface AwaitProps<Resolve> {
|
|
|
869
871
|
*/
|
|
870
872
|
resolve: Resolve;
|
|
871
873
|
}
|
|
874
|
+
interface AwaitPromiseProps<Resolve> extends Omit<AwaitProps<Resolve>, "resolve" | "unstable_promise"> {
|
|
875
|
+
resolve?: never;
|
|
876
|
+
/**
|
|
877
|
+
* A promise (or value) to read using React's `use()` API in client components.
|
|
878
|
+
* Unlike `resolve` in client components, this accepts promise-like values
|
|
879
|
+
* without modifying the source promise.
|
|
880
|
+
*
|
|
881
|
+
* `errorElement` handles promise rejections. Errors thrown while rendering
|
|
882
|
+
* children bubble to the nearest React error boundary.
|
|
883
|
+
*
|
|
884
|
+
* ```tsx
|
|
885
|
+
* <Await unstable_promise={reviewsPromise} errorElement={<ReviewsError />}>
|
|
886
|
+
* {(reviews) => <Reviews items={reviews} />}
|
|
887
|
+
* </Await>
|
|
888
|
+
* ```
|
|
889
|
+
*
|
|
890
|
+
* Pass exactly one of `unstable_promise` or `resolve`.
|
|
891
|
+
*/
|
|
892
|
+
unstable_promise: Resolve;
|
|
893
|
+
}
|
|
872
894
|
/**
|
|
873
895
|
* Used to render promise values with automatic error handling.
|
|
874
896
|
*
|
|
875
897
|
* **Note:** `<Await>` expects to be rendered inside a [`<React.Suspense>`](https://react.dev/reference/react/Suspense)
|
|
876
898
|
*
|
|
899
|
+
* Pass `unstable_promise` instead of `resolve` to opt into React's
|
|
900
|
+
* [`use()`](https://react.dev/reference/react/use) implementation. With
|
|
901
|
+
* `unstable_promise`, `errorElement` handles promise rejections, while errors
|
|
902
|
+
* thrown by children bubble to the nearest React error boundary.
|
|
903
|
+
*
|
|
904
|
+
* In React Server Components, `resolve` already has this error-handling behavior:
|
|
905
|
+
* `errorElement` handles only input rejections, while child render errors
|
|
906
|
+
* propagate to the surrounding error boundary. Both props accept promise-like
|
|
907
|
+
* values without modifying the source promise. Both props treat a falsy
|
|
908
|
+
* `errorElement` as absent and propagate the rejection. Pass an empty fragment
|
|
909
|
+
* to handle a rejection without rendering any content.
|
|
910
|
+
*
|
|
911
|
+
* <docs-warning>The `unstable_promise` prop is experimental and may change in
|
|
912
|
+
* minor or patch releases.</docs-warning>
|
|
913
|
+
*
|
|
877
914
|
* @example
|
|
878
915
|
* import { Await, useLoaderData } from "react-router";
|
|
879
916
|
*
|
|
@@ -914,13 +951,12 @@ interface AwaitProps<Resolve> {
|
|
|
914
951
|
* @param {AwaitProps.children} props.children n/a
|
|
915
952
|
* @param {AwaitProps.errorElement} props.errorElement n/a
|
|
916
953
|
* @param {AwaitProps.resolve} props.resolve n/a
|
|
954
|
+
* @param props.unstable_promise A promise (or value) to read using React's `use()`
|
|
955
|
+
* API in client components. Accepts promise-like values without modifying the
|
|
956
|
+
* source promise. Pass exactly one of `unstable_promise` or `resolve`.
|
|
917
957
|
* @returns React element for the rendered awaited value
|
|
918
958
|
*/
|
|
919
|
-
declare function Await<Resolve>(
|
|
920
|
-
children,
|
|
921
|
-
errorElement,
|
|
922
|
-
resolve
|
|
923
|
-
}: AwaitProps<Resolve>): React$1.JSX.Element;
|
|
959
|
+
declare function Await<Resolve>(props: AwaitProps<Resolve> | AwaitPromiseProps<Resolve>): React$1.JSX.Element;
|
|
924
960
|
/**
|
|
925
961
|
* Creates a route config from a React "children" object, which is usually
|
|
926
962
|
* either a `<Route>` element or an array of them. Used internally by
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -13,6 +13,7 @@ import { defaultMapRouteProperties, getResolveToMatches, getRoutePattern, resolv
|
|
|
13
13
|
import { getNavigatorCurrentUrl, validateNavigationTarget } from "./router/navigation.js";
|
|
14
14
|
import { clientErrors, createRouter } from "./router/router.js";
|
|
15
15
|
import { AwaitContext, DataRouterContext, DataRouterDataContext, DataRouterNavigationContext, DataRouterStateContext, FetchersContext, LocationContext, NavigationContext, RouteContext, ViewTransitionContext, useIsRSCRouterContext } from "./context.js";
|
|
16
|
+
import { getAwaitPromise, getPromiseResult } from "./await.js";
|
|
16
17
|
import { _renderMatches, useActionData, useAsyncValue, useInRouterContext, useLoaderData, useLocation, useMatches, useNavigate, useOutlet, useParams, useRouteError, useRoutes, useRoutesImpl } from "./hooks.js";
|
|
17
18
|
import { warnOnce } from "./server-runtime/warnings.js";
|
|
18
19
|
import { FrameworkContext } from "./dom/ssr/components.js";
|
|
@@ -85,6 +86,11 @@ var Deferred = class {
|
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
};
|
|
89
|
+
function handleSkippedViewTransition(transition, document) {
|
|
90
|
+
transition.ready.catch((reason) => {
|
|
91
|
+
if (!(document.visibilityState === "hidden" || typeof reason === "object" && reason !== null && "name" in reason && reason.name === "AbortError")) throw reason;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
88
94
|
/**
|
|
89
95
|
* Render the UI for the given {@link DataRouter}. This component should
|
|
90
96
|
* typically be at the top of an app's element tree. The router prop should
|
|
@@ -172,6 +178,7 @@ function RouterProvider({ router, flushSync: reactDomFlushSyncImpl, onError, use
|
|
|
172
178
|
let t = router.window.document.startViewTransition(() => {
|
|
173
179
|
reactDomFlushSyncImpl(() => setStateImpl(newState));
|
|
174
180
|
});
|
|
181
|
+
handleSkippedViewTransition(t, router.window.document);
|
|
175
182
|
t.finished.finally(() => {
|
|
176
183
|
reactDomFlushSyncImpl(() => {
|
|
177
184
|
setRenderDfd(void 0);
|
|
@@ -234,6 +241,7 @@ function RouterProvider({ router, flushSync: reactDomFlushSyncImpl, onError, use
|
|
|
234
241
|
});
|
|
235
242
|
await renderPromise;
|
|
236
243
|
});
|
|
244
|
+
handleSkippedViewTransition(transition, router.window.document);
|
|
237
245
|
transition.finished.finally(() => {
|
|
238
246
|
setRenderDfd(void 0);
|
|
239
247
|
setTransition(void 0);
|
|
@@ -643,6 +651,21 @@ function Routes({ children, location }) {
|
|
|
643
651
|
*
|
|
644
652
|
* **Note:** `<Await>` expects to be rendered inside a [`<React.Suspense>`](https://react.dev/reference/react/Suspense)
|
|
645
653
|
*
|
|
654
|
+
* Pass `unstable_promise` instead of `resolve` to opt into React's
|
|
655
|
+
* [`use()`](https://react.dev/reference/react/use) implementation. With
|
|
656
|
+
* `unstable_promise`, `errorElement` handles promise rejections, while errors
|
|
657
|
+
* thrown by children bubble to the nearest React error boundary.
|
|
658
|
+
*
|
|
659
|
+
* In React Server Components, `resolve` already has this error-handling behavior:
|
|
660
|
+
* `errorElement` handles only input rejections, while child render errors
|
|
661
|
+
* propagate to the surrounding error boundary. Both props accept promise-like
|
|
662
|
+
* values without modifying the source promise. Both props treat a falsy
|
|
663
|
+
* `errorElement` as absent and propagate the rejection. Pass an empty fragment
|
|
664
|
+
* to handle a rejection without rendering any content.
|
|
665
|
+
*
|
|
666
|
+
* <docs-warning>The `unstable_promise` prop is experimental and may change in
|
|
667
|
+
* minor or patch releases.</docs-warning>
|
|
668
|
+
*
|
|
646
669
|
* @example
|
|
647
670
|
* import { Await, useLoaderData } from "react-router";
|
|
648
671
|
*
|
|
@@ -683,9 +706,14 @@ function Routes({ children, location }) {
|
|
|
683
706
|
* @param {AwaitProps.children} props.children n/a
|
|
684
707
|
* @param {AwaitProps.errorElement} props.errorElement n/a
|
|
685
708
|
* @param {AwaitProps.resolve} props.resolve n/a
|
|
709
|
+
* @param props.unstable_promise A promise (or value) to read using React's `use()`
|
|
710
|
+
* API in client components. Accepts promise-like values without modifying the
|
|
711
|
+
* source promise. Pass exactly one of `unstable_promise` or `resolve`.
|
|
686
712
|
* @returns React element for the rendered awaited value
|
|
687
713
|
*/
|
|
688
|
-
function Await(
|
|
714
|
+
function Await(props) {
|
|
715
|
+
invariant("resolve" in props !== "unstable_promise" in props, "<Await> requires exactly one of `resolve` or `unstable_promise`");
|
|
716
|
+
let { children, errorElement } = props;
|
|
689
717
|
let dataRouterContext = React$1.useContext(DataRouterContext);
|
|
690
718
|
let dataRouterStateContext = React$1.useContext(DataRouterStateContext);
|
|
691
719
|
let onError = React$1.useCallback((error, errorInfo) => {
|
|
@@ -696,12 +724,25 @@ function Await({ children, errorElement, resolve }) {
|
|
|
696
724
|
errorInfo
|
|
697
725
|
});
|
|
698
726
|
}, [dataRouterContext, dataRouterStateContext]);
|
|
727
|
+
if ("unstable_promise" in props) return /* @__PURE__ */ React$1.createElement(AwaitPromise, {
|
|
728
|
+
value: props.unstable_promise,
|
|
729
|
+
errorElement,
|
|
730
|
+
onError
|
|
731
|
+
}, children);
|
|
699
732
|
return /* @__PURE__ */ React$1.createElement(AwaitErrorBoundary, {
|
|
700
|
-
resolve,
|
|
733
|
+
resolve: props.resolve,
|
|
701
734
|
errorElement,
|
|
702
735
|
onError
|
|
703
736
|
}, /* @__PURE__ */ React$1.createElement(ResolveAwait, null, children));
|
|
704
737
|
}
|
|
738
|
+
function AwaitPromise({ value, children, errorElement, onError }) {
|
|
739
|
+
let result = value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function" ? React$1.use(getAwaitPromise(value, onError)) : {
|
|
740
|
+
status: "fulfilled",
|
|
741
|
+
value
|
|
742
|
+
};
|
|
743
|
+
if (result.status === "rejected" && !errorElement) throw result.reason;
|
|
744
|
+
return /* @__PURE__ */ React$1.createElement(AwaitContext.Provider, { value: result }, result.status === "rejected" ? errorElement : /* @__PURE__ */ React$1.createElement(ResolveAwait, null, children));
|
|
745
|
+
}
|
|
705
746
|
var AwaitErrorBoundary = class extends React$1.Component {
|
|
706
747
|
constructor(props) {
|
|
707
748
|
super(props);
|
|
@@ -735,7 +776,24 @@ var AwaitErrorBoundary = class extends React$1.Component {
|
|
|
735
776
|
} else {
|
|
736
777
|
status = 0;
|
|
737
778
|
Object.defineProperty(resolve, "_tracked", { get: () => true });
|
|
738
|
-
|
|
779
|
+
let result = getPromiseResult(resolve);
|
|
780
|
+
if (result) {
|
|
781
|
+
promise = resolve;
|
|
782
|
+
if (result.status === "fulfilled") {
|
|
783
|
+
status = 1;
|
|
784
|
+
Object.defineProperty(resolve, "_data", { get: () => result.value });
|
|
785
|
+
} else {
|
|
786
|
+
status = 2;
|
|
787
|
+
Object.defineProperty(resolve, "_error", { get: () => result.reason });
|
|
788
|
+
Promise.resolve(resolve).catch((reason) => {
|
|
789
|
+
try {
|
|
790
|
+
this.props.onError?.(reason);
|
|
791
|
+
} catch (error) {
|
|
792
|
+
console.error("<Await> caught the following error in onError", error);
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
} else promise = Promise.resolve(resolve).then((data) => Object.defineProperty(resolve, "_data", { get: () => data }), (error) => {
|
|
739
797
|
this.props.onError?.(error);
|
|
740
798
|
Object.defineProperty(resolve, "_error", { get: () => error });
|
|
741
799
|
});
|
|
@@ -32,8 +32,8 @@ type FetchersContextObject = {
|
|
|
32
32
|
fetcherData: Map<string, any>;
|
|
33
33
|
};
|
|
34
34
|
declare const FetchersContext: React$1.Context<FetchersContextObject | null>;
|
|
35
|
-
declare const AwaitContext: React$1.Context<TrackedPromise | null>;
|
|
36
|
-
declare const AwaitContextProvider: (props: React$1.ComponentProps<typeof AwaitContext.Provider>) => React$1.FunctionComponentElement<React$1.ProviderProps<TrackedPromise | null>>;
|
|
35
|
+
declare const AwaitContext: React$1.Context<TrackedPromise | PromiseSettledResult<unknown> | null>;
|
|
36
|
+
declare const AwaitContextProvider: (props: React$1.ComponentProps<typeof AwaitContext.Provider>) => React$1.FunctionComponentElement<React$1.ProviderProps<TrackedPromise | PromiseSettledResult<unknown> | null>>;
|
|
37
37
|
interface NavigateOptions {
|
|
38
38
|
/** Replace the current entry in the history stack instead of pushing a new one */
|
|
39
39
|
replace?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -29,6 +29,12 @@ function getPathsWithAncestors(paths) {
|
|
|
29
29
|
function isFogOfWarEnabled(routeDiscovery, ssr) {
|
|
30
30
|
return routeDiscovery.mode === "lazy" && ssr;
|
|
31
31
|
}
|
|
32
|
+
const MANIFEST_MATCH_COST_LIMIT = 5e4;
|
|
33
|
+
const MANIFEST_MATCH_COST_SEGMENT_THRESHOLD = 10;
|
|
34
|
+
function shouldUseInitialRouteDiscovery(pathname, matchCost = 0) {
|
|
35
|
+
let segmentCount = pathname.split("/").length - 1;
|
|
36
|
+
return Math.max(segmentCount - 1, 0) * pathname.length + 1 > 7680 || segmentCount > MANIFEST_MATCH_COST_SEGMENT_THRESHOLD && segmentCount * matchCost > MANIFEST_MATCH_COST_LIMIT;
|
|
37
|
+
}
|
|
32
38
|
function getPartialManifest({ sri, ...manifest }, router) {
|
|
33
39
|
let routeIds = new Set(router.state.matches.map((m) => m.route.id));
|
|
34
40
|
let segments = router.state.location.pathname.split("/").filter(Boolean);
|
|
@@ -108,6 +114,9 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscover
|
|
|
108
114
|
isApiOnly
|
|
109
115
|
]);
|
|
110
116
|
}
|
|
117
|
+
function getManifestPathsParam(paths) {
|
|
118
|
+
return paths.slice().sort().map((path) => path.replace(/,/g, "%2C")).join(",");
|
|
119
|
+
}
|
|
111
120
|
function getManifestPath(_manifestPath, basename) {
|
|
112
121
|
let manifestPath = _manifestPath || "/__manifest";
|
|
113
122
|
return basename == null ? manifestPath : joinPaths([basename, manifestPath]);
|
|
@@ -160,7 +169,7 @@ async function handleClientVersionMismatch(needsReload, version, errorReloadPath
|
|
|
160
169
|
async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal, fetchImplementation = (request) => fetch(request), serverOrigin, isApiOnly = false) {
|
|
161
170
|
paths = getPathsWithAncestors(paths);
|
|
162
171
|
const searchParams = new URLSearchParams();
|
|
163
|
-
searchParams.set("paths", paths
|
|
172
|
+
searchParams.set("paths", getManifestPathsParam(paths));
|
|
164
173
|
searchParams.set("version", manifest.version);
|
|
165
174
|
let url = new URL(getManifestPath(manifestPath, basename), serverOrigin ?? window.location.origin);
|
|
166
175
|
url.search = searchParams.toString();
|
|
@@ -207,4 +216,4 @@ function debounce(callback, wait) {
|
|
|
207
216
|
};
|
|
208
217
|
}
|
|
209
218
|
//#endregion
|
|
210
|
-
export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, useFogOFWarDiscovery };
|
|
219
|
+
export { URL_LIMIT, getManifestPath, getManifestPathsParam, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled, shouldUseInitialRouteDiscovery, useFogOFWarDiscovery };
|
|
@@ -4,7 +4,7 @@ import { Router } from "../../router/router.js";
|
|
|
4
4
|
import { ClientOnErrorFunction } from "../../components.js";
|
|
5
5
|
import { RouteModules } from "./routeModules.js";
|
|
6
6
|
import { RouterFetch } from "./single-fetch.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ServerHandoff } from "../../server-runtime/serverHandoff.js";
|
|
8
8
|
import { AssetsManifest } from "./entry.js";
|
|
9
9
|
|
|
10
10
|
//#region lib/dom/ssr/route-discovery.d.ts
|
|
@@ -37,7 +37,7 @@ type RouteDiscoverySsrInfo = {
|
|
|
37
37
|
manifest: AssetsManifest;
|
|
38
38
|
routeModules: RouteModules;
|
|
39
39
|
router: Router | undefined;
|
|
40
|
-
context: Pick<
|
|
40
|
+
context: Pick<ServerHandoff, "ssr" | "routeDiscovery" | "isSpaMode" | "basename" | "unstable_apiServerOrigin" | "unstable_apiOnly">;
|
|
41
41
|
};
|
|
42
42
|
declare class RouteDiscoveryRuntime {
|
|
43
43
|
private ssrInfo;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { createPath, invariant } from "../../router/history.js";
|
|
12
12
|
import { DiscoveryCancelledError, getRoutePattern, prependBasename } from "../../router/utils.js";
|
|
13
13
|
import { createClientRoutes } from "./routes.js";
|
|
14
|
-
import { getManifestPath, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled } from "./fog-of-war.js";
|
|
14
|
+
import { getManifestPath, getManifestPathsParam, getPathsWithAncestors, handleClientVersionMismatch, isFogOfWarEnabled } from "./fog-of-war.js";
|
|
15
15
|
import { useFrameworkContext } from "./components.js";
|
|
16
16
|
import * as React$1 from "react";
|
|
17
17
|
//#region lib/dom/ssr/route-discovery.ts
|
|
@@ -158,7 +158,7 @@ var RouteDiscoveryRuntime = class {
|
|
|
158
158
|
requestUrl(paths) {
|
|
159
159
|
let { manifest, context } = this.ssrInfo;
|
|
160
160
|
let params = new URLSearchParams();
|
|
161
|
-
params.set("paths", paths
|
|
161
|
+
params.set("paths", getManifestPathsParam(paths));
|
|
162
162
|
params.set("version", manifest.version);
|
|
163
163
|
let url = new URL(getManifestPath(context.routeDiscovery.manifestPath, context.basename), context.unstable_apiServerOrigin ?? window.location.origin);
|
|
164
164
|
url.search = params.toString();
|
|
@@ -31,7 +31,7 @@ type RouterFetchContext = {
|
|
|
31
31
|
navigationType: null;
|
|
32
32
|
};
|
|
33
33
|
type RouterFetch = (request: Request, context: RouterFetchContext) => Promise<Response>;
|
|
34
|
-
declare function getTurboStreamSingleFetchDataStrategy(getRouter: () => Router, manifest: AssetsManifest, routeModules: RouteModules, ssr: boolean, fetchImplementation?: RouterFetch, isApiOnly?: boolean, serverOrigin?: string): DataStrategyFunction;
|
|
34
|
+
declare function getTurboStreamSingleFetchDataStrategy(getRouter: () => Router, manifest: AssetsManifest, routeModules: RouteModules, ssr: boolean, fetchImplementation?: RouterFetch, isApiOnly?: boolean, serverOrigin?: string, isSpaMode?: boolean): DataStrategyFunction;
|
|
35
35
|
declare function decodeViaTurboStream(body: ReadableStream<Uint8Array>, global: Window | typeof globalThis): Promise<{
|
|
36
36
|
done: Promise<void>;
|
|
37
37
|
value: unknown;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -56,7 +56,7 @@ function StreamTransfer({ context, identifier, reader, textDecoder, nonce }) {
|
|
|
56
56
|
nonce
|
|
57
57
|
})));
|
|
58
58
|
}
|
|
59
|
-
function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, fetchImplementation = (request) => fetch(request), isApiOnly = false, serverOrigin) {
|
|
59
|
+
function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, fetchImplementation = (request) => fetch(request), isApiOnly = false, serverOrigin, isSpaMode = false) {
|
|
60
60
|
let dataStrategy = getSingleFetchDataStrategyImpl(getRouter, (match) => {
|
|
61
61
|
let manifestRoute = manifest.routes[match.route.id];
|
|
62
62
|
invariant(manifestRoute, "Route not found in manifest");
|
|
@@ -64,10 +64,10 @@ function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules
|
|
|
64
64
|
hasLoader: manifestRoute.hasLoader,
|
|
65
65
|
hasClientLoader: manifestRoute.hasClientLoader
|
|
66
66
|
};
|
|
67
|
-
}, fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin), ssr, void 0, isApiOnly);
|
|
67
|
+
}, fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin), ssr, void 0, isApiOnly, isSpaMode);
|
|
68
68
|
return async (args) => args.runClientMiddleware(dataStrategy);
|
|
69
69
|
}
|
|
70
|
-
function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false) {
|
|
70
|
+
function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false, isSpaMode = false) {
|
|
71
71
|
return async (args) => {
|
|
72
72
|
let { request, matches, fetcherKey } = args;
|
|
73
73
|
let router = getRouter();
|
|
@@ -78,7 +78,7 @@ function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode,
|
|
|
78
78
|
});
|
|
79
79
|
if (!ssr && !foundRevalidatingServerLoader) return nonSsrStrategy(args, getRouteInfo, fetchAndDecode);
|
|
80
80
|
if (fetcherKey) return singleFetchLoaderFetcherStrategy(args, fetchAndDecode);
|
|
81
|
-
return singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut, isApiOnly);
|
|
81
|
+
return singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut, isApiOnly, isSpaMode);
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
async function singleFetchActionStrategy(args, fetchAndDecode) {
|
|
@@ -113,7 +113,7 @@ async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode) {
|
|
|
113
113
|
}));
|
|
114
114
|
return results;
|
|
115
115
|
}
|
|
116
|
-
async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false) {
|
|
116
|
+
async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = false, isSpaMode = false) {
|
|
117
117
|
let routesParams = /* @__PURE__ */ new Set();
|
|
118
118
|
let foundOptOutRoute = false;
|
|
119
119
|
let routeDfds = args.matches.map(() => createDeferred());
|
|
@@ -162,7 +162,7 @@ async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, f
|
|
|
162
162
|
}
|
|
163
163
|
})));
|
|
164
164
|
await Promise.all(routeDfds.map((d) => d.promise));
|
|
165
|
-
if ((!router.state.initialized && router.state.navigation.state === "idle" && !isApiOnly || routesParams.size === 0) && !window.__reactRouterHdrActive) singleFetchDfd.resolve({ routes: {} });
|
|
165
|
+
if ((!router.state.initialized && router.state.navigation.state === "idle" && !isApiOnly && !isSpaMode || routesParams.size === 0) && !window.__reactRouterHdrActive) singleFetchDfd.resolve({ routes: {} });
|
|
166
166
|
else {
|
|
167
167
|
let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;
|
|
168
168
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -89,7 +89,7 @@ function createHydratedRouter({ getContext, instrumentations, fetch: fetchImplem
|
|
|
89
89
|
mapRouteProperties: UNSAFE_defaultMapRouteProperties,
|
|
90
90
|
hydrationRouteProperties: UNSAFE_hydrationRouteProperties,
|
|
91
91
|
instrumentations,
|
|
92
|
-
dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, fetchImplementation, ssrInfo.context.unstable_apiOnly === true, ssrInfo.context.unstable_apiServerOrigin),
|
|
92
|
+
dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, fetchImplementation, ssrInfo.context.unstable_apiOnly === true, ssrInfo.context.unstable_apiServerOrigin, ssrInfo.context.isSpaMode),
|
|
93
93
|
patchRoutesOnNavigation: discoveryRuntime ? UNSAFE_getCustomPatchRoutesOnNavigationFunction(() => router, discoveryRuntime) : UNSAFE_getPatchRoutesOnNavigationFunction(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, ssrInfo.context.basename, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, isApiOnly)
|
|
94
94
|
});
|
|
95
95
|
ssrInfo.router = router;
|
|
@@ -192,9 +192,6 @@ interface NavigateFunction {
|
|
|
192
192
|
*
|
|
193
193
|
* [MODES: framework, data]
|
|
194
194
|
*
|
|
195
|
-
* <br/>
|
|
196
|
-
* <br/>
|
|
197
|
-
*
|
|
198
195
|
* To prevent {@link ScrollRestoration | `<ScrollRestoration>`} from resetting
|
|
199
196
|
* the scroll position, use the `preventScrollReset` option.
|
|
200
197
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.5.
|
|
2
|
+
* react-router v8.5.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -212,9 +212,6 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
|
|
|
212
212
|
*
|
|
213
213
|
* [MODES: framework, data]
|
|
214
214
|
*
|
|
215
|
-
* <br/>
|
|
216
|
-
* <br/>
|
|
217
|
-
*
|
|
218
215
|
* To prevent {@link ScrollRestoration | `<ScrollRestoration>`} from resetting
|
|
219
216
|
* the scroll position, use the `preventScrollReset` option.
|
|
220
217
|
*
|
|
@@ -1095,7 +1092,8 @@ function useRouteError() {
|
|
|
1095
1092
|
* @returns The resolved value from the nearest {@link Await} component
|
|
1096
1093
|
*/
|
|
1097
1094
|
function useAsyncValue() {
|
|
1098
|
-
|
|
1095
|
+
let value = React$1.useContext(AwaitContext);
|
|
1096
|
+
return value && "status" in value && !("_tracked" in value) ? value.status === "fulfilled" ? value.value : void 0 : value?._data;
|
|
1099
1097
|
}
|
|
1100
1098
|
/**
|
|
1101
1099
|
* Returns the rejection value from the closest {@link Await | `<Await>`}.
|
|
@@ -1123,7 +1121,8 @@ function useAsyncValue() {
|
|
|
1123
1121
|
* @returns The error that was thrown in the nearest {@link Await} component
|
|
1124
1122
|
*/
|
|
1125
1123
|
function useAsyncError() {
|
|
1126
|
-
|
|
1124
|
+
let value = React$1.useContext(AwaitContext);
|
|
1125
|
+
return value && "status" in value && !("_tracked" in value) ? value.status === "rejected" ? value.reason : void 0 : value?._error;
|
|
1127
1126
|
}
|
|
1128
1127
|
let blockerId = 0;
|
|
1129
1128
|
/**
|