react-router 7.7.1 → 7.8.0-pre.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 +81 -5
- package/dist/development/browser-z32v5KVN.d.mts +46 -0
- package/dist/{production/chunk-K3SBCRK4.mjs → development/chunk-HSC5IU24.mjs} +177 -134
- package/dist/development/{chunk-K7YFBME3.js → chunk-IW6UADHO.js} +250 -187
- package/dist/development/{chunk-C37GKA54.mjs → chunk-SC4OUYO4.mjs} +232 -169
- package/dist/development/{chunk-R73PQUJU.js → chunk-Z4NNCWGU.js} +130 -130
- package/dist/development/{components-CjQijYga.d.mts → components-uUh0svuC.d.mts} +33 -21
- package/dist/{production/route-data-CqEmXQub.d.mts → development/context-DZWGFcKX.d.mts} +312 -524
- package/dist/development/dom-export.d.mts +16 -12
- package/dist/development/dom-export.d.ts +13 -8
- package/dist/development/dom-export.js +3 -3
- package/dist/development/dom-export.mjs +3 -3
- package/dist/{production/index-react-server-client-KLg-U4nr.d.mts → development/index-react-server-client-BUK-oRcG.d.mts} +327 -200
- package/dist/development/{index-react-server-client-Bi_fx8qz.d.ts → index-react-server-client-DSU6bZil.d.ts} +357 -219
- package/dist/development/index-react-server-client.d.mts +4 -3
- package/dist/development/index-react-server-client.d.ts +2 -2
- package/dist/development/index-react-server-client.js +4 -4
- package/dist/development/index-react-server-client.mjs +2 -2
- package/dist/development/index-react-server.d.mts +291 -70
- package/dist/development/index-react-server.d.ts +291 -70
- package/dist/development/index-react-server.js +174 -180
- package/dist/development/index-react-server.mjs +174 -180
- package/dist/development/index.d.mts +294 -86
- package/dist/development/index.d.ts +136 -105
- package/dist/development/index.js +258 -215
- package/dist/development/index.mjs +3 -3
- package/dist/development/lib/types/internal.d.mts +13 -2
- package/dist/development/lib/types/internal.d.ts +12 -2
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/lib/types/internal.mjs +1 -1
- package/dist/development/route-data-UTmTa8an.d.mts +473 -0
- package/dist/{production/routeModules-BR2FO0ix.d.ts → development/routeModules-D5bppTB2.d.ts} +325 -67
- package/dist/production/browser-z32v5KVN.d.mts +46 -0
- package/dist/production/{chunk-4DGLNKXF.js → chunk-BCLZG6QW.js} +130 -130
- package/dist/{development/chunk-KIUJAIYX.mjs → production/chunk-KQ5567DT.mjs} +177 -134
- package/dist/production/{chunk-IZ57JD2V.mjs → chunk-X2NPJMV2.mjs} +232 -169
- package/dist/production/{chunk-7OQROU2D.js → chunk-YC2ENCM3.js} +250 -187
- package/dist/production/{components-CjQijYga.d.mts → components-uUh0svuC.d.mts} +33 -21
- package/dist/{development/route-data-CqEmXQub.d.mts → production/context-DZWGFcKX.d.mts} +312 -524
- package/dist/production/dom-export.d.mts +16 -12
- package/dist/production/dom-export.d.ts +13 -8
- package/dist/production/dom-export.js +3 -3
- package/dist/production/dom-export.mjs +3 -3
- package/dist/{development/index-react-server-client-KLg-U4nr.d.mts → production/index-react-server-client-BUK-oRcG.d.mts} +327 -200
- package/dist/production/{index-react-server-client-Bi_fx8qz.d.ts → index-react-server-client-DSU6bZil.d.ts} +357 -219
- package/dist/production/index-react-server-client.d.mts +4 -3
- package/dist/production/index-react-server-client.d.ts +2 -2
- package/dist/production/index-react-server-client.js +4 -4
- package/dist/production/index-react-server-client.mjs +2 -2
- package/dist/production/index-react-server.d.mts +291 -70
- package/dist/production/index-react-server.d.ts +291 -70
- package/dist/production/index-react-server.js +174 -180
- package/dist/production/index-react-server.mjs +174 -180
- package/dist/production/index.d.mts +294 -86
- package/dist/production/index.d.ts +136 -105
- package/dist/production/index.js +258 -215
- package/dist/production/index.mjs +3 -3
- package/dist/production/lib/types/internal.d.mts +13 -2
- package/dist/production/lib/types/internal.d.ts +12 -2
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/lib/types/internal.mjs +1 -1
- package/dist/production/route-data-UTmTa8an.d.mts +473 -0
- package/dist/{development/routeModules-BR2FO0ix.d.ts → production/routeModules-D5bppTB2.d.ts} +325 -67
- package/package.json +1 -1
- package/dist/development/browser-7LYX59NK.d.mts +0 -226
- package/dist/production/browser-7LYX59NK.d.mts +0 -226
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
# `react-router`
|
|
2
2
|
|
|
3
|
+
## 7.8.0-pre.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add `nonce` prop to `Links` & `PrefetchPageLinks` ([#14048](https://github.com/remix-run/react-router/pull/14048))
|
|
8
|
+
- Add `loaderData` arguments/properties alongside existing `data` arguments/properties to provide consistency and clarity between `loaderData` and `actionData` across the board ([#14047](https://github.com/remix-run/react-router/pull/14047))
|
|
9
|
+
- Updated types: `Route.MetaArgs`, `Route.MetaMatch`, `MetaArgs`, `MetaMatch`, `Route.ComponentProps.matches`, `UIMatch`
|
|
10
|
+
- `@deprecated` warnings have been added to the existing `data` properties to point users to new `loaderData` properties, in preparation for removing the `data` properties in a future major release
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [UNSTABLE] Ensure resource route errors go through `handleError` w/middleware enabled ([#14078](https://github.com/remix-run/react-router/pull/14078))
|
|
15
|
+
- Prevent _"Did not find corresponding fetcher result"_ console error when navigating during a `fetcher.submit` revalidation ([#14114](https://github.com/remix-run/react-router/pull/14114))
|
|
16
|
+
- Switch Lazy Route Discovery manifest URL generation to usea standalone `URLSearchParams` instance instead of `URL.searchParams` to avoid a major performance bottleneck in Chrome ([#14084](https://github.com/remix-run/react-router/pull/14084))
|
|
17
|
+
- [UNSTABLE] Propagate returned Response from server middleware if next wasn't called ([#14093](https://github.com/remix-run/react-router/pull/14093))
|
|
18
|
+
- [UNSTABLE] Allow server middlewares to return `data()` values which will be converted into a `Response` ([#14093](https://github.com/remix-run/react-router/pull/14093))
|
|
19
|
+
- [UNSTABLE] Update middleware error handling so that the `next` function never throws and instead handles any middleware errors at the proper `ErrorBoundary` and returns the `Response` up through the ancestor `next` function ([#14118](https://github.com/remix-run/react-router/pull/14118))
|
|
20
|
+
- - [UNSTABLE] When middleware is enabled, make the `context` parameter read-only (via `Readonly<unstable_RouterContextProvider>`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097))
|
|
21
|
+
- [UNSTABLE] Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103))
|
|
22
|
+
- The API has been renamed to `unstable_generateMiddlewareResponse` for clarity
|
|
23
|
+
- The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling
|
|
24
|
+
- The `query` version of the API now has a signature of `(query: (r: Request) => Promise<StaticHandlerContext | Response>) => Promise<Response>`
|
|
25
|
+
- The `queryRoute` version of the API now has a signature of `(queryRoute: (r: Request) => Promise<Response>) => Promise<Response>`
|
|
26
|
+
- This allows for more advanced usages such as running logic before/after calling `query` and direct error handling of errors thrown from query
|
|
27
|
+
- ⚠️ This is a breaking change if you've adopted the `staticHandler` `unstable_respond` API
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
let response = await staticHandler.query(request, {
|
|
31
|
+
requestContext: new unstable_RouterContextProvider(),
|
|
32
|
+
async unstable_generateMiddlewareResponse(query) {
|
|
33
|
+
try {
|
|
34
|
+
// At this point we've run middleware top-down so we need to call the
|
|
35
|
+
// handlers and generate the Response to bubble back up the middleware
|
|
36
|
+
let result = await query(request);
|
|
37
|
+
if (isResponse(result)) {
|
|
38
|
+
return result; // Redirects, etc.
|
|
39
|
+
}
|
|
40
|
+
return await generateHtmlResponse(result);
|
|
41
|
+
} catch (error: unknown) {
|
|
42
|
+
return generateErrorResponse(error);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- [UNSTABLE] Convert internal middleware implementations to use the new `unstable_generateMiddlewareResponse` API ([#14103](https://github.com/remix-run/react-router/pull/14103))
|
|
49
|
+
- Adjust internal RSC usage of `React.use` to avoid Webpack compilation errors when using React 18 ([#14113](https://github.com/remix-run/react-router/pull/14113))
|
|
50
|
+
- [UNSTABLE] Change `getLoadContext` signature (`type GetLoadContextFunction`) when `future.unstable_middleware` is enabled so that it returns an `unstable_RouterContextProvider` instance instead of a `Map` used to contruct the instance internally ([#14097](https://github.com/remix-run/react-router/pull/14097))
|
|
51
|
+
- This also removes the `type unstable_InitialContext` export
|
|
52
|
+
- ⚠️ This is a breaking change if you have adopted middleware and are using a custom server with a `getLoadContext` function
|
|
53
|
+
|
|
54
|
+
- Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059))
|
|
55
|
+
- Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206))
|
|
56
|
+
- When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary
|
|
57
|
+
- The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered
|
|
58
|
+
- ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// app/root.tsx
|
|
62
|
+
export function loader() {
|
|
63
|
+
someFunctionThatThrows(); // ❌ Throws an Error
|
|
64
|
+
return { title: "My Title" };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function Layout({ children }: { children: React.ReactNode }) {
|
|
68
|
+
let matches = useMatches();
|
|
69
|
+
let rootMatch = matches[0] as UIMatch<Awaited<ReturnType<typeof loader>>>;
|
|
70
|
+
// ^ rootMatch.data is incorrectly typed here, so TypeScript does not
|
|
71
|
+
// complain if you do the following which throws an error at runtime:
|
|
72
|
+
let { title } = rootMatch.data; // 💥
|
|
73
|
+
|
|
74
|
+
return <html>...</html>;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- [UNSTABLE] Run client middleware on client navigations even if no loaders exist ([#14106](https://github.com/remix-run/react-router/pull/14106))
|
|
79
|
+
- [UNSTABLE] Change the `unstable_getContext` signature on `RouterProvider`/`HydratedRouter`/`unstable_RSCHydratedRouter` so that it returns an `unstable_RouterContextProvider` instance instead of a `Map` used to contruct the instance internally ([#14097](https://github.com/remix-run/react-router/pull/14097))
|
|
80
|
+
- ⚠️ This is a breaking change if you have adopted the `unstable_getContext` prop
|
|
81
|
+
|
|
82
|
+
- Fix RSC Data Mode issue where routes that return `false` from `shouldRevalidate` would be replaced by an `<Outlet />` ([#14071](https://github.com/remix-run/react-router/pull/14071))
|
|
83
|
+
|
|
3
84
|
## 7.7.1
|
|
4
85
|
|
|
5
86
|
### Patch Changes
|
|
@@ -604,7 +685,6 @@
|
|
|
604
685
|
```
|
|
605
686
|
|
|
606
687
|
Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app:
|
|
607
|
-
|
|
608
688
|
- Library mode - `createBrowserRouter(routes, { unstable_getContext })`
|
|
609
689
|
- Framework mode - `<HydratedRouter unstable_getContext>`
|
|
610
690
|
|
|
@@ -792,7 +872,6 @@ _No changes_
|
|
|
792
872
|
- Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697))
|
|
793
873
|
|
|
794
874
|
- For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837))
|
|
795
|
-
|
|
796
875
|
- `createCookie`
|
|
797
876
|
- `createCookieSessionStorage`
|
|
798
877
|
- `createMemorySessionStorage`
|
|
@@ -801,7 +880,6 @@ _No changes_
|
|
|
801
880
|
For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html)
|
|
802
881
|
|
|
803
882
|
Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed:
|
|
804
|
-
|
|
805
883
|
- `createCookieFactory`
|
|
806
884
|
- `createSessionStorageFactory`
|
|
807
885
|
- `createCookieSessionStorageFactory`
|
|
@@ -957,7 +1035,6 @@ _No changes_
|
|
|
957
1035
|
```
|
|
958
1036
|
|
|
959
1037
|
This initial implementation targets type inference for:
|
|
960
|
-
|
|
961
1038
|
- `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
|
|
962
1039
|
- `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
|
|
963
1040
|
- `ActionData` : Action data from `action` and/or `clientAction` within your route module
|
|
@@ -972,7 +1049,6 @@ _No changes_
|
|
|
972
1049
|
```
|
|
973
1050
|
|
|
974
1051
|
Check out our docs for more:
|
|
975
|
-
|
|
976
1052
|
- [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety)
|
|
977
1053
|
- [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety)
|
|
978
1054
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
__FLIGHT_DATA: any[];
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Get the prerendered [RSC](https://react.dev/reference/rsc/server-components)
|
|
8
|
+
* stream for hydration. Usually passed directly to your
|
|
9
|
+
* `react-server-dom-xyz/client`'s `createFromReadableStream`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* import { startTransition, StrictMode } from "react";
|
|
13
|
+
* import { hydrateRoot } from "react-dom/client";
|
|
14
|
+
* import {
|
|
15
|
+
* unstable_getRSCStream as getRSCStream,
|
|
16
|
+
* unstable_RSCHydratedRouter as RSCHydratedRouter,
|
|
17
|
+
* } from "react-router";
|
|
18
|
+
* import type { unstable_RSCPayload as RSCPayload } from "react-router";
|
|
19
|
+
*
|
|
20
|
+
* createFromReadableStream(getRSCStream()).then(
|
|
21
|
+
* (payload: RSCServerPayload) => {
|
|
22
|
+
* startTransition(async () => {
|
|
23
|
+
* hydrateRoot(
|
|
24
|
+
* document,
|
|
25
|
+
* <StrictMode>
|
|
26
|
+
* <RSCHydratedRouter {...props} />
|
|
27
|
+
* </StrictMode>,
|
|
28
|
+
* {
|
|
29
|
+
* // Options
|
|
30
|
+
* }
|
|
31
|
+
* );
|
|
32
|
+
* });
|
|
33
|
+
* }
|
|
34
|
+
* );
|
|
35
|
+
*
|
|
36
|
+
* @name unstable_getRSCStream
|
|
37
|
+
* @public
|
|
38
|
+
* @category RSC
|
|
39
|
+
* @mode data
|
|
40
|
+
* @returns A [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
|
|
41
|
+
* that contains the [RSC](https://react.dev/reference/rsc/server-components)
|
|
42
|
+
* data for hydration.
|
|
43
|
+
*/
|
|
44
|
+
declare function getRSCStream(): ReadableStream;
|
|
45
|
+
|
|
46
|
+
export { getRSCStream as g };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v7.
|
|
2
|
+
* react-router v7.8.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
withComponentProps,
|
|
58
58
|
withErrorBoundaryProps,
|
|
59
59
|
withHydrateFallbackProps
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-SC4OUYO4.mjs";
|
|
61
61
|
|
|
62
62
|
// lib/dom/ssr/server.tsx
|
|
63
63
|
import * as React from "react";
|
|
@@ -772,42 +772,6 @@ var SERVER_NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
|
772
772
|
]);
|
|
773
773
|
async function singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
|
|
774
774
|
try {
|
|
775
|
-
let respond2 = function(context) {
|
|
776
|
-
let headers = getDocumentHeaders(context, build);
|
|
777
|
-
if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
|
|
778
|
-
return generateSingleFetchResponse(request, build, serverMode, {
|
|
779
|
-
result: getSingleFetchRedirect(
|
|
780
|
-
context.statusCode,
|
|
781
|
-
headers,
|
|
782
|
-
build.basename
|
|
783
|
-
),
|
|
784
|
-
headers,
|
|
785
|
-
status: SINGLE_FETCH_REDIRECT_STATUS
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
if (context.errors) {
|
|
789
|
-
Object.values(context.errors).forEach((err) => {
|
|
790
|
-
if (!isRouteErrorResponse(err) || err.error) {
|
|
791
|
-
handleError(err);
|
|
792
|
-
}
|
|
793
|
-
});
|
|
794
|
-
context.errors = sanitizeErrors(context.errors, serverMode);
|
|
795
|
-
}
|
|
796
|
-
let singleFetchResult;
|
|
797
|
-
if (context.errors) {
|
|
798
|
-
singleFetchResult = { error: Object.values(context.errors)[0] };
|
|
799
|
-
} else {
|
|
800
|
-
singleFetchResult = {
|
|
801
|
-
data: Object.values(context.actionData || {})[0]
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
return generateSingleFetchResponse(request, build, serverMode, {
|
|
805
|
-
result: singleFetchResult,
|
|
806
|
-
headers,
|
|
807
|
-
status: context.statusCode
|
|
808
|
-
});
|
|
809
|
-
};
|
|
810
|
-
var respond = respond2;
|
|
811
775
|
let handlerRequest = new Request(handlerUrl, {
|
|
812
776
|
method: request.method,
|
|
813
777
|
body: request.body,
|
|
@@ -819,10 +783,22 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
|
|
|
819
783
|
requestContext: loadContext,
|
|
820
784
|
skipLoaderErrorBubbling: true,
|
|
821
785
|
skipRevalidation: true,
|
|
822
|
-
|
|
786
|
+
unstable_generateMiddlewareResponse: build.future.unstable_middleware ? async (query) => {
|
|
787
|
+
try {
|
|
788
|
+
let innerResult = await query(handlerRequest);
|
|
789
|
+
return handleQueryResult(innerResult);
|
|
790
|
+
} catch (error) {
|
|
791
|
+
return handleQueryError(error);
|
|
792
|
+
}
|
|
793
|
+
} : void 0
|
|
823
794
|
});
|
|
795
|
+
return handleQueryResult(result);
|
|
796
|
+
} catch (error) {
|
|
797
|
+
return handleQueryError(error);
|
|
798
|
+
}
|
|
799
|
+
function handleQueryResult(result) {
|
|
824
800
|
if (!isResponse(result)) {
|
|
825
|
-
result =
|
|
801
|
+
result = staticContextToResponse(result);
|
|
826
802
|
}
|
|
827
803
|
if (isRedirectResponse(result)) {
|
|
828
804
|
return generateSingleFetchResponse(request, build, serverMode, {
|
|
@@ -836,7 +812,8 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
|
|
|
836
812
|
});
|
|
837
813
|
}
|
|
838
814
|
return result;
|
|
839
|
-
}
|
|
815
|
+
}
|
|
816
|
+
function handleQueryError(error) {
|
|
840
817
|
handleError(error);
|
|
841
818
|
return generateSingleFetchResponse(request, build, serverMode, {
|
|
842
819
|
result: { error },
|
|
@@ -844,92 +821,137 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
|
|
|
844
821
|
status: 500
|
|
845
822
|
});
|
|
846
823
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
let respond2 = function(context) {
|
|
851
|
-
let headers = getDocumentHeaders(context, build);
|
|
852
|
-
if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
|
|
853
|
-
return generateSingleFetchResponse(request, build, serverMode, {
|
|
854
|
-
result: {
|
|
855
|
-
[SingleFetchRedirectSymbol]: getSingleFetchRedirect(
|
|
856
|
-
context.statusCode,
|
|
857
|
-
headers,
|
|
858
|
-
build.basename
|
|
859
|
-
)
|
|
860
|
-
},
|
|
861
|
-
headers,
|
|
862
|
-
status: SINGLE_FETCH_REDIRECT_STATUS
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
if (context.errors) {
|
|
866
|
-
Object.values(context.errors).forEach((err) => {
|
|
867
|
-
if (!isRouteErrorResponse(err) || err.error) {
|
|
868
|
-
handleError(err);
|
|
869
|
-
}
|
|
870
|
-
});
|
|
871
|
-
context.errors = sanitizeErrors(context.errors, serverMode);
|
|
872
|
-
}
|
|
873
|
-
let results = {};
|
|
874
|
-
let loadedMatches = new Set(
|
|
875
|
-
context.matches.filter(
|
|
876
|
-
(m) => loadRouteIds ? loadRouteIds.has(m.route.id) : m.route.loader != null
|
|
877
|
-
).map((m) => m.route.id)
|
|
878
|
-
);
|
|
879
|
-
if (context.errors) {
|
|
880
|
-
for (let [id, error] of Object.entries(context.errors)) {
|
|
881
|
-
results[id] = { error };
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
for (let [id, data2] of Object.entries(context.loaderData)) {
|
|
885
|
-
if (!(id in results) && loadedMatches.has(id)) {
|
|
886
|
-
results[id] = { data: data2 };
|
|
887
|
-
}
|
|
888
|
-
}
|
|
824
|
+
function staticContextToResponse(context) {
|
|
825
|
+
let headers = getDocumentHeaders(context, build);
|
|
826
|
+
if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
|
|
889
827
|
return generateSingleFetchResponse(request, build, serverMode, {
|
|
890
|
-
result:
|
|
828
|
+
result: getSingleFetchRedirect(
|
|
829
|
+
context.statusCode,
|
|
830
|
+
headers,
|
|
831
|
+
build.basename
|
|
832
|
+
),
|
|
891
833
|
headers,
|
|
892
|
-
status:
|
|
834
|
+
status: SINGLE_FETCH_REDIRECT_STATUS
|
|
893
835
|
});
|
|
894
|
-
}
|
|
895
|
-
|
|
836
|
+
}
|
|
837
|
+
if (context.errors) {
|
|
838
|
+
Object.values(context.errors).forEach((err) => {
|
|
839
|
+
if (!isRouteErrorResponse(err) || err.error) {
|
|
840
|
+
handleError(err);
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
context.errors = sanitizeErrors(context.errors, serverMode);
|
|
844
|
+
}
|
|
845
|
+
let singleFetchResult;
|
|
846
|
+
if (context.errors) {
|
|
847
|
+
singleFetchResult = { error: Object.values(context.errors)[0] };
|
|
848
|
+
} else {
|
|
849
|
+
singleFetchResult = {
|
|
850
|
+
data: Object.values(context.actionData || {})[0]
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
return generateSingleFetchResponse(request, build, serverMode, {
|
|
854
|
+
result: singleFetchResult,
|
|
855
|
+
headers,
|
|
856
|
+
status: context.statusCode
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
async function singleFetchLoaders(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
|
|
861
|
+
let routesParam = new URL(request.url).searchParams.get("_routes");
|
|
862
|
+
let loadRouteIds = routesParam ? new Set(routesParam.split(",")) : null;
|
|
863
|
+
try {
|
|
896
864
|
let handlerRequest = new Request(handlerUrl, {
|
|
897
865
|
headers: request.headers,
|
|
898
866
|
signal: request.signal
|
|
899
867
|
});
|
|
900
|
-
let routesParam = new URL(request.url).searchParams.get("_routes");
|
|
901
|
-
let loadRouteIds = routesParam ? new Set(routesParam.split(",")) : null;
|
|
902
868
|
let result = await staticHandler.query(handlerRequest, {
|
|
903
869
|
requestContext: loadContext,
|
|
904
870
|
filterMatchesToLoad: (m) => !loadRouteIds || loadRouteIds.has(m.route.id),
|
|
905
871
|
skipLoaderErrorBubbling: true,
|
|
906
|
-
|
|
872
|
+
unstable_generateMiddlewareResponse: build.future.unstable_middleware ? async (query) => {
|
|
873
|
+
try {
|
|
874
|
+
let innerResult = await query(handlerRequest);
|
|
875
|
+
return handleQueryResult(innerResult);
|
|
876
|
+
} catch (error) {
|
|
877
|
+
return handleQueryError(error);
|
|
878
|
+
}
|
|
879
|
+
} : void 0
|
|
907
880
|
});
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
881
|
+
return handleQueryResult(result);
|
|
882
|
+
} catch (error) {
|
|
883
|
+
return handleQueryError(error);
|
|
884
|
+
}
|
|
885
|
+
function handleQueryResult(result) {
|
|
886
|
+
let response = isResponse(result) ? result : staticContextToResponse(result);
|
|
887
|
+
if (isRedirectResponse(response)) {
|
|
912
888
|
return generateSingleFetchResponse(request, build, serverMode, {
|
|
913
889
|
result: {
|
|
914
890
|
[SingleFetchRedirectSymbol]: getSingleFetchRedirect(
|
|
915
|
-
|
|
916
|
-
|
|
891
|
+
response.status,
|
|
892
|
+
response.headers,
|
|
917
893
|
build.basename
|
|
918
894
|
)
|
|
919
895
|
},
|
|
920
|
-
headers:
|
|
896
|
+
headers: response.headers,
|
|
921
897
|
status: SINGLE_FETCH_REDIRECT_STATUS
|
|
922
898
|
});
|
|
923
899
|
}
|
|
924
|
-
return
|
|
925
|
-
}
|
|
900
|
+
return response;
|
|
901
|
+
}
|
|
902
|
+
function handleQueryError(error) {
|
|
926
903
|
handleError(error);
|
|
927
904
|
return generateSingleFetchResponse(request, build, serverMode, {
|
|
928
|
-
result: {
|
|
905
|
+
result: { error },
|
|
929
906
|
headers: new Headers(),
|
|
930
907
|
status: 500
|
|
931
908
|
});
|
|
932
909
|
}
|
|
910
|
+
function staticContextToResponse(context) {
|
|
911
|
+
let headers = getDocumentHeaders(context, build);
|
|
912
|
+
if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
|
|
913
|
+
return generateSingleFetchResponse(request, build, serverMode, {
|
|
914
|
+
result: {
|
|
915
|
+
[SingleFetchRedirectSymbol]: getSingleFetchRedirect(
|
|
916
|
+
context.statusCode,
|
|
917
|
+
headers,
|
|
918
|
+
build.basename
|
|
919
|
+
)
|
|
920
|
+
},
|
|
921
|
+
headers,
|
|
922
|
+
status: SINGLE_FETCH_REDIRECT_STATUS
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
if (context.errors) {
|
|
926
|
+
Object.values(context.errors).forEach((err) => {
|
|
927
|
+
if (!isRouteErrorResponse(err) || err.error) {
|
|
928
|
+
handleError(err);
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
context.errors = sanitizeErrors(context.errors, serverMode);
|
|
932
|
+
}
|
|
933
|
+
let results = {};
|
|
934
|
+
let loadedMatches = new Set(
|
|
935
|
+
context.matches.filter(
|
|
936
|
+
(m) => loadRouteIds ? loadRouteIds.has(m.route.id) : m.route.loader != null
|
|
937
|
+
).map((m) => m.route.id)
|
|
938
|
+
);
|
|
939
|
+
if (context.errors) {
|
|
940
|
+
for (let [id, error] of Object.entries(context.errors)) {
|
|
941
|
+
results[id] = { error };
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
for (let [id, data2] of Object.entries(context.loaderData)) {
|
|
945
|
+
if (!(id in results) && loadedMatches.has(id)) {
|
|
946
|
+
results[id] = { data: data2 };
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return generateSingleFetchResponse(request, build, serverMode, {
|
|
950
|
+
result: results,
|
|
951
|
+
headers,
|
|
952
|
+
status: context.statusCode
|
|
953
|
+
});
|
|
954
|
+
}
|
|
933
955
|
}
|
|
934
956
|
function generateSingleFetchResponse(request, build, serverMode, {
|
|
935
957
|
result,
|
|
@@ -1074,23 +1096,14 @@ var createRequestHandler = (build, mode) => {
|
|
|
1074
1096
|
});
|
|
1075
1097
|
};
|
|
1076
1098
|
if (_build.future.unstable_middleware) {
|
|
1077
|
-
if (initialContext
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
);
|
|
1084
|
-
} catch (e) {
|
|
1085
|
-
let error = new Error(
|
|
1086
|
-
`Unable to create initial \`unstable_RouterContextProvider\` instance. Please confirm you are returning an instance of \`Map<unstable_routerContext, unknown>\` from your \`getLoadContext\` function.
|
|
1087
|
-
|
|
1088
|
-
Error: ${e instanceof Error ? e.toString() : e}`
|
|
1089
|
-
);
|
|
1090
|
-
handleError(error);
|
|
1091
|
-
return returnLastResortErrorResponse(error, serverMode);
|
|
1092
|
-
}
|
|
1099
|
+
if (initialContext && !(initialContext instanceof unstable_RouterContextProvider)) {
|
|
1100
|
+
let error = new Error(
|
|
1101
|
+
"Invalid `context` value provided to `handleRequest`. When middleware is enabled you must return an instance of `unstable_RouterContextProvider` from your `getLoadContext` function."
|
|
1102
|
+
);
|
|
1103
|
+
handleError(error);
|
|
1104
|
+
return returnLastResortErrorResponse(error, serverMode);
|
|
1093
1105
|
}
|
|
1106
|
+
loadContext = initialContext || new unstable_RouterContextProvider();
|
|
1094
1107
|
} else {
|
|
1095
1108
|
loadContext = initialContext || {};
|
|
1096
1109
|
}
|
|
@@ -1304,19 +1317,30 @@ async function handleSingleFetchRequest(serverMode, build, staticHandler, reques
|
|
|
1304
1317
|
}
|
|
1305
1318
|
async function handleDocumentRequest(serverMode, build, staticHandler, request, loadContext, handleError, isSpaMode, criticalCss) {
|
|
1306
1319
|
try {
|
|
1307
|
-
let
|
|
1320
|
+
let result = await staticHandler.query(request, {
|
|
1308
1321
|
requestContext: loadContext,
|
|
1309
|
-
|
|
1322
|
+
unstable_generateMiddlewareResponse: build.future.unstable_middleware ? async (query) => {
|
|
1323
|
+
try {
|
|
1324
|
+
let innerResult = await query(request);
|
|
1325
|
+
if (!isResponse(innerResult)) {
|
|
1326
|
+
innerResult = await renderHtml(innerResult, isSpaMode);
|
|
1327
|
+
}
|
|
1328
|
+
return innerResult;
|
|
1329
|
+
} catch (error) {
|
|
1330
|
+
handleError(error);
|
|
1331
|
+
return new Response(null, { status: 500 });
|
|
1332
|
+
}
|
|
1333
|
+
} : void 0
|
|
1310
1334
|
});
|
|
1311
|
-
|
|
1335
|
+
if (!isResponse(result)) {
|
|
1336
|
+
result = await renderHtml(result, isSpaMode);
|
|
1337
|
+
}
|
|
1338
|
+
return result;
|
|
1312
1339
|
} catch (error) {
|
|
1313
1340
|
handleError(error);
|
|
1314
1341
|
return new Response(null, { status: 500 });
|
|
1315
1342
|
}
|
|
1316
1343
|
async function renderHtml(context, isSpaMode2) {
|
|
1317
|
-
if (isResponse(context)) {
|
|
1318
|
-
return context;
|
|
1319
|
-
}
|
|
1320
1344
|
let headers = getDocumentHeaders(context, build);
|
|
1321
1345
|
if (SERVER_NO_BODY_STATUS_CODES.has(context.statusCode)) {
|
|
1322
1346
|
return new Response(null, { status: context.statusCode, headers });
|
|
@@ -1428,27 +1452,38 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
|
|
|
1428
1452
|
}
|
|
1429
1453
|
async function handleResourceRequest(serverMode, build, staticHandler, routeId, request, loadContext, handleError) {
|
|
1430
1454
|
try {
|
|
1431
|
-
let
|
|
1455
|
+
let result = await staticHandler.queryRoute(request, {
|
|
1432
1456
|
routeId,
|
|
1433
1457
|
requestContext: loadContext,
|
|
1434
|
-
|
|
1458
|
+
unstable_generateMiddlewareResponse: build.future.unstable_middleware ? async (queryRoute) => {
|
|
1459
|
+
try {
|
|
1460
|
+
let innerResult = await queryRoute(request);
|
|
1461
|
+
return handleQueryRouteResult(innerResult);
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
return handleQueryRouteError(error);
|
|
1464
|
+
}
|
|
1465
|
+
} : void 0
|
|
1435
1466
|
});
|
|
1436
|
-
|
|
1437
|
-
|
|
1467
|
+
return handleQueryRouteResult(result);
|
|
1468
|
+
} catch (error) {
|
|
1469
|
+
return handleQueryRouteError(error);
|
|
1470
|
+
}
|
|
1471
|
+
function handleQueryRouteResult(result) {
|
|
1472
|
+
if (isResponse(result)) {
|
|
1473
|
+
return result;
|
|
1438
1474
|
}
|
|
1439
|
-
if (typeof
|
|
1440
|
-
return new Response(
|
|
1475
|
+
if (typeof result === "string") {
|
|
1476
|
+
return new Response(result);
|
|
1441
1477
|
}
|
|
1442
|
-
return Response.json(
|
|
1443
|
-
}
|
|
1478
|
+
return Response.json(result);
|
|
1479
|
+
}
|
|
1480
|
+
function handleQueryRouteError(error) {
|
|
1444
1481
|
if (isResponse(error)) {
|
|
1445
1482
|
error.headers.set("X-Remix-Catch", "yes");
|
|
1446
1483
|
return error;
|
|
1447
1484
|
}
|
|
1448
1485
|
if (isRouteErrorResponse(error)) {
|
|
1449
|
-
|
|
1450
|
-
handleError(error);
|
|
1451
|
-
}
|
|
1486
|
+
handleError(error);
|
|
1452
1487
|
return errorResponseToJson(error, serverMode);
|
|
1453
1488
|
}
|
|
1454
1489
|
if (error instanceof Error && error.message === "Expected a response from queryRoute") {
|
|
@@ -2440,6 +2475,14 @@ function escapeScript(script) {
|
|
|
2440
2475
|
}
|
|
2441
2476
|
|
|
2442
2477
|
// lib/rsc/server.ssr.tsx
|
|
2478
|
+
var REACT_USE = "use";
|
|
2479
|
+
var useImpl = React5[REACT_USE];
|
|
2480
|
+
function useSafe(promise) {
|
|
2481
|
+
if (useImpl) {
|
|
2482
|
+
return useImpl(promise);
|
|
2483
|
+
}
|
|
2484
|
+
throw new Error("React Router v7 requires React 19+ for RSC features.");
|
|
2485
|
+
}
|
|
2443
2486
|
async function routeRSCServerRequest({
|
|
2444
2487
|
request,
|
|
2445
2488
|
fetchServer,
|
|
@@ -2494,7 +2537,7 @@ async function routeRSCServerRequest({
|
|
|
2494
2537
|
}
|
|
2495
2538
|
}
|
|
2496
2539
|
function RSCStaticRouter({ getPayload }) {
|
|
2497
|
-
const payload =
|
|
2540
|
+
const payload = useSafe(getPayload());
|
|
2498
2541
|
if (payload.type === "redirect") {
|
|
2499
2542
|
throw new Response(null, {
|
|
2500
2543
|
status: payload.status,
|