react-router 7.13.2 → 7.14.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/development/{browser-Bfn3xw9E.d.ts → browser-C9Ar1yxG.d.ts} +13 -10
  3. package/dist/development/{browser-Di6-vSl-.d.mts → browser-vtIR1Kpe.d.mts} +13 -10
  4. package/dist/development/{chunk-UALY5CBT.mjs → chunk-2UH5WJXA.mjs} +21 -7
  5. package/dist/development/{chunk-GO74ODU3.js → chunk-IK6APEEG.js} +191 -118
  6. package/dist/development/{chunk-HPFFRPKK.js → chunk-NXTEWSJO.js} +99 -99
  7. package/dist/development/{chunk-UVKPFVEO.mjs → chunk-QFMPRPBF.mjs} +192 -119
  8. package/dist/development/{chunk-LLP6DRWX.js → chunk-WAVMRYR2.js} +7 -7
  9. package/dist/development/dom-export.d.mts +1 -1
  10. package/dist/development/dom-export.d.ts +1 -1
  11. package/dist/development/dom-export.js +65 -54
  12. package/dist/development/dom-export.mjs +34 -23
  13. package/dist/{production/index-react-server-client-BcrVT7Dd.d.mts → development/index-react-server-client-BwWaHAr3.d.mts} +7 -5
  14. package/dist/development/{index-react-server-client-CCwMoQIT.d.ts → index-react-server-client-luDbagNU.d.ts} +7 -5
  15. package/dist/development/index-react-server-client.d.mts +1 -1
  16. package/dist/development/index-react-server-client.d.ts +1 -1
  17. package/dist/development/index-react-server-client.js +4 -4
  18. package/dist/development/index-react-server-client.mjs +2 -2
  19. package/dist/development/index-react-server.d.mts +12 -3
  20. package/dist/development/index-react-server.d.ts +12 -3
  21. package/dist/development/index-react-server.js +58 -18
  22. package/dist/development/index-react-server.mjs +58 -18
  23. package/dist/development/index.d.mts +4 -4
  24. package/dist/development/index.d.ts +4 -4
  25. package/dist/development/index.js +101 -87
  26. package/dist/development/index.mjs +3 -3
  27. package/dist/development/lib/types/internal.d.mts +10 -10
  28. package/dist/development/lib/types/internal.d.ts +10 -10
  29. package/dist/development/lib/types/internal.js +1 -1
  30. package/dist/development/lib/types/internal.mjs +1 -1
  31. package/dist/production/{browser-Bfn3xw9E.d.ts → browser-C9Ar1yxG.d.ts} +13 -10
  32. package/dist/production/{browser-Di6-vSl-.d.mts → browser-vtIR1Kpe.d.mts} +13 -10
  33. package/dist/production/{chunk-CAFVLUDY.js → chunk-355DUZMC.js} +7 -7
  34. package/dist/production/{chunk-LKUVSIBA.js → chunk-4TJ7T2OQ.js} +191 -118
  35. package/dist/production/{chunk-XAAX7KIK.js → chunk-FPT5DLVJ.js} +99 -99
  36. package/dist/production/{chunk-2BDJPJTA.mjs → chunk-HZQGQD2X.mjs} +192 -119
  37. package/dist/production/{chunk-PY35PE22.mjs → chunk-X5LK27NZ.mjs} +21 -7
  38. package/dist/production/dom-export.d.mts +1 -1
  39. package/dist/production/dom-export.d.ts +1 -1
  40. package/dist/production/dom-export.js +65 -54
  41. package/dist/production/dom-export.mjs +34 -23
  42. package/dist/{development/index-react-server-client-BcrVT7Dd.d.mts → production/index-react-server-client-BwWaHAr3.d.mts} +7 -5
  43. package/dist/production/{index-react-server-client-CCwMoQIT.d.ts → index-react-server-client-luDbagNU.d.ts} +7 -5
  44. package/dist/production/index-react-server-client.d.mts +1 -1
  45. package/dist/production/index-react-server-client.d.ts +1 -1
  46. package/dist/production/index-react-server-client.js +4 -4
  47. package/dist/production/index-react-server-client.mjs +2 -2
  48. package/dist/production/index-react-server.d.mts +12 -3
  49. package/dist/production/index-react-server.d.ts +12 -3
  50. package/dist/production/index-react-server.js +58 -18
  51. package/dist/production/index-react-server.mjs +58 -18
  52. package/dist/production/index.d.mts +4 -4
  53. package/dist/production/index.d.ts +4 -4
  54. package/dist/production/index.js +101 -87
  55. package/dist/production/index.mjs +3 -3
  56. package/dist/production/lib/types/internal.d.mts +10 -10
  57. package/dist/production/lib/types/internal.d.ts +10 -10
  58. package/dist/production/lib/types/internal.js +1 -1
  59. package/dist/production/lib/types/internal.mjs +1 -1
  60. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # `react-router`
2
2
 
3
+ ## 7.14.0
4
+
5
+ ### Patch Changes
6
+
7
+ - UNSTABLE RSC FRAMEWORK MODE BREAKING CHANGE - Existing route module exports remain unchanged from stable v7 non-RSC mode, but new exports are added for RSC mode. If you want to use RSC features, you will need to update your route modules to export the new annotations. ([#14901](https://github.com/remix-run/react-router/pull/14901))
8
+
9
+ If you are using RSC framework mode currently, you will need to update your route modules to the new conventions. The following route module components have their own mutually exclusive server component counterparts:
10
+
11
+ | Server Component Export | Client Component |
12
+ | ----------------------- | ----------------- |
13
+ | `ServerComponent` | `default` |
14
+ | `ServerErrorBoundary` | `ErrorBoundary` |
15
+ | `ServerLayout` | `Layout` |
16
+ | `ServerHydrateFallback` | `HydrateFallback` |
17
+
18
+ If you were previously exporting a `ServerComponent`, your `ErrorBoundary`, `Layout`, and `HydrateFallback` were also server components. If you want to keep those as server components, you can rename them and prefix them with `Server`. If you were previously importing the implementations of those components from a client module, you can simply inline them.
19
+
20
+ Example:
21
+
22
+ Before
23
+
24
+ ```tsx
25
+ import { ErrorBoundary as ClientErrorBoundary } from "./client";
26
+
27
+ export function ServerComponent() {
28
+ // ...
29
+ }
30
+
31
+ export function ErrorBoundary() {
32
+ return <ClientErrorBoundary />;
33
+ }
34
+
35
+ export function Layout() {
36
+ // ...
37
+ }
38
+
39
+ export function HydrateFallback() {
40
+ // ...
41
+ }
42
+ ```
43
+
44
+ After
45
+
46
+ ```tsx
47
+ export function ServerComponent() {
48
+ // ...
49
+ }
50
+
51
+ export function ErrorBoundary() {
52
+ // previous implementation of ClientErrorBoundary, this is now a client component
53
+ }
54
+
55
+ export function ServerLayout() {
56
+ // rename previous Layout export to ServerLayout to make it a server component
57
+ }
58
+
59
+ export function ServerHydrateFallback() {
60
+ // rename previous HydrateFallback export to ServerHydrateFallback to make it a server component
61
+ }
62
+ ```
63
+
64
+ - rsc Link prefetch ([#14902](https://github.com/remix-run/react-router/pull/14902))
65
+
66
+ - Remove recursion from turbo-stream v2 allowing for encoding / decoding of massive payloads. ([#14838](https://github.com/remix-run/react-router/pull/14838))
67
+
68
+ - encodeViaTurboStream leaked memory via unremoved AbortSignal listener ([#14900](https://github.com/remix-run/react-router/pull/14900))
69
+
3
70
  ## 7.13.2
4
71
 
5
72
  ### Patch Changes
@@ -65,14 +65,15 @@ type RSCRenderPayload = {
65
65
  errors: Record<string, any> | null;
66
66
  loaderData: Record<string, any>;
67
67
  location: Location;
68
+ routeDiscovery: RouteDiscovery;
68
69
  matches: RSCRouteMatch[];
69
- patches?: RSCRouteManifest[];
70
+ patches?: Promise<RSCRouteManifest[]>;
70
71
  nonce?: string;
71
72
  formState?: unknown;
72
73
  };
73
74
  type RSCManifestPayload = {
74
75
  type: "manifest";
75
- patches: RSCRouteManifest[];
76
+ patches: Promise<RSCRouteManifest[]>;
76
77
  };
77
78
  type RSCActionPayload = {
78
79
  type: "action";
@@ -99,6 +100,12 @@ type DecodeReplyFunction = (reply: FormData | string, options: {
99
100
  temporaryReferences: unknown;
100
101
  }) => Promise<unknown[]>;
101
102
  type LoadServerActionFunction = (id: string) => Promise<Function>;
103
+ type RouteDiscovery = {
104
+ mode: "lazy";
105
+ manifestPath?: string | undefined;
106
+ } | {
107
+ mode: "initial";
108
+ };
102
109
  /**
103
110
  * Matches the given routes to a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
104
111
  * and returns an [RSC](https://react.dev/reference/rsc/server-components)
@@ -165,12 +172,13 @@ type LoadServerActionFunction = (id: string) => Promise<Function>;
165
172
  * @param opts.requestContext An instance of {@link RouterContextProvider}
166
173
  * that should be created per request, to be passed to [`action`](../../start/data/route-object#action)s,
167
174
  * [`loader`](../../start/data/route-object#loader)s and [middleware](../../how-to/middleware).
175
+ * @param opts.routeDiscovery The route discovery configuration, used to determine how the router should discover new routes during navigations.
168
176
  * @param opts.routes Your {@link unstable_RSCRouteConfigEntry | route definitions}.
169
177
  * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
170
178
  * that contains the [RSC](https://react.dev/reference/rsc/server-components)
171
179
  * data for hydration.
172
180
  */
173
- declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, request, routes, generateResponse, }: {
181
+ declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, routeDiscovery, loadServerAction, decodeAction, decodeFormState, onError, request, routes, generateResponse, }: {
174
182
  allowedActionOrigins?: string[];
175
183
  createTemporaryReferenceSet: () => unknown;
176
184
  basename?: string;
@@ -182,6 +190,7 @@ declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryRe
182
190
  onError?: (error: unknown) => void;
183
191
  request: Request;
184
192
  routes: RSCRouteConfigEntry[];
193
+ routeDiscovery?: RouteDiscovery;
185
194
  generateResponse: (match: RSCMatch, { onError, temporaryReferences, }: {
186
195
  onError(error: unknown): string | undefined;
187
196
  temporaryReferences: unknown;
@@ -256,11 +265,6 @@ interface RSCHydratedRouterProps {
256
265
  * The decoded {@link unstable_RSCPayload} to hydrate.
257
266
  */
258
267
  payload: RSCPayload;
259
- /**
260
- * `"eager"` or `"lazy"` - Determines if links are eagerly discovered, or
261
- * delayed until clicked.
262
- */
263
- routeDiscovery?: "eager" | "lazy";
264
268
  /**
265
269
  * A function that returns an {@link RouterContextProvider} instance
266
270
  * which is provided as the `context` argument to client [`action`](../../start/data/route-object#action)s,
@@ -306,10 +310,9 @@ interface RSCHydratedRouterProps {
306
310
  * @param {unstable_RSCHydratedRouterProps.fetch} props.fetch n/a
307
311
  * @param {unstable_RSCHydratedRouterProps.getContext} props.getContext n/a
308
312
  * @param {unstable_RSCHydratedRouterProps.payload} props.payload n/a
309
- * @param {unstable_RSCHydratedRouterProps.routeDiscovery} props.routeDiscovery n/a
310
313
  * @returns A hydrated {@link DataRouter} that can be used to navigate and
311
314
  * render routes.
312
315
  */
313
- declare function RSCHydratedRouter({ createFromReadableStream, fetch: fetchImplementation, payload, routeDiscovery, getContext, }: RSCHydratedRouterProps): React.JSX.Element;
316
+ declare function RSCHydratedRouter({ createFromReadableStream, fetch: fetchImplementation, payload, getContext, }: RSCHydratedRouterProps): React.JSX.Element;
314
317
 
315
318
  export { type BrowserCreateFromReadableStreamFunction as B, type DecodeActionFunction as D, type EncodeReplyFunction as E, type LoadServerActionFunction as L, RSCHydratedRouter as R, type DecodeFormStateFunction as a, type DecodeReplyFunction as b, createCallServer as c, type RSCManifestPayload as d, type RSCPayload as e, type RSCRenderPayload as f, getRequest as g, type RSCHydratedRouterProps as h, type RSCMatch as i, type RSCRouteManifest as j, type RSCRouteMatch as k, type RSCRouteConfigEntry as l, matchRSCServerRequest as m, type RSCRouteConfig as n };
@@ -65,14 +65,15 @@ type RSCRenderPayload = {
65
65
  errors: Record<string, any> | null;
66
66
  loaderData: Record<string, any>;
67
67
  location: Location;
68
+ routeDiscovery: RouteDiscovery;
68
69
  matches: RSCRouteMatch[];
69
- patches?: RSCRouteManifest[];
70
+ patches?: Promise<RSCRouteManifest[]>;
70
71
  nonce?: string;
71
72
  formState?: unknown;
72
73
  };
73
74
  type RSCManifestPayload = {
74
75
  type: "manifest";
75
- patches: RSCRouteManifest[];
76
+ patches: Promise<RSCRouteManifest[]>;
76
77
  };
77
78
  type RSCActionPayload = {
78
79
  type: "action";
@@ -99,6 +100,12 @@ type DecodeReplyFunction = (reply: FormData | string, options: {
99
100
  temporaryReferences: unknown;
100
101
  }) => Promise<unknown[]>;
101
102
  type LoadServerActionFunction = (id: string) => Promise<Function>;
103
+ type RouteDiscovery = {
104
+ mode: "lazy";
105
+ manifestPath?: string | undefined;
106
+ } | {
107
+ mode: "initial";
108
+ };
102
109
  /**
103
110
  * Matches the given routes to a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
104
111
  * and returns an [RSC](https://react.dev/reference/rsc/server-components)
@@ -165,12 +172,13 @@ type LoadServerActionFunction = (id: string) => Promise<Function>;
165
172
  * @param opts.requestContext An instance of {@link RouterContextProvider}
166
173
  * that should be created per request, to be passed to [`action`](../../start/data/route-object#action)s,
167
174
  * [`loader`](../../start/data/route-object#loader)s and [middleware](../../how-to/middleware).
175
+ * @param opts.routeDiscovery The route discovery configuration, used to determine how the router should discover new routes during navigations.
168
176
  * @param opts.routes Your {@link unstable_RSCRouteConfigEntry | route definitions}.
169
177
  * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
170
178
  * that contains the [RSC](https://react.dev/reference/rsc/server-components)
171
179
  * data for hydration.
172
180
  */
173
- declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, request, routes, generateResponse, }: {
181
+ declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, routeDiscovery, loadServerAction, decodeAction, decodeFormState, onError, request, routes, generateResponse, }: {
174
182
  allowedActionOrigins?: string[];
175
183
  createTemporaryReferenceSet: () => unknown;
176
184
  basename?: string;
@@ -182,6 +190,7 @@ declare function matchRSCServerRequest({ allowedActionOrigins, createTemporaryRe
182
190
  onError?: (error: unknown) => void;
183
191
  request: Request;
184
192
  routes: RSCRouteConfigEntry[];
193
+ routeDiscovery?: RouteDiscovery;
185
194
  generateResponse: (match: RSCMatch, { onError, temporaryReferences, }: {
186
195
  onError(error: unknown): string | undefined;
187
196
  temporaryReferences: unknown;
@@ -256,11 +265,6 @@ interface RSCHydratedRouterProps {
256
265
  * The decoded {@link unstable_RSCPayload} to hydrate.
257
266
  */
258
267
  payload: RSCPayload;
259
- /**
260
- * `"eager"` or `"lazy"` - Determines if links are eagerly discovered, or
261
- * delayed until clicked.
262
- */
263
- routeDiscovery?: "eager" | "lazy";
264
268
  /**
265
269
  * A function that returns an {@link RouterContextProvider} instance
266
270
  * which is provided as the `context` argument to client [`action`](../../start/data/route-object#action)s,
@@ -306,10 +310,9 @@ interface RSCHydratedRouterProps {
306
310
  * @param {unstable_RSCHydratedRouterProps.fetch} props.fetch n/a
307
311
  * @param {unstable_RSCHydratedRouterProps.getContext} props.getContext n/a
308
312
  * @param {unstable_RSCHydratedRouterProps.payload} props.payload n/a
309
- * @param {unstable_RSCHydratedRouterProps.routeDiscovery} props.routeDiscovery n/a
310
313
  * @returns A hydrated {@link DataRouter} that can be used to navigate and
311
314
  * render routes.
312
315
  */
313
- declare function RSCHydratedRouter({ createFromReadableStream, fetch: fetchImplementation, payload, routeDiscovery, getContext, }: RSCHydratedRouterProps): React.JSX.Element;
316
+ declare function RSCHydratedRouter({ createFromReadableStream, fetch: fetchImplementation, payload, getContext, }: RSCHydratedRouterProps): React.JSX.Element;
314
317
 
315
318
  export { type BrowserCreateFromReadableStreamFunction as B, type DecodeActionFunction as D, type EncodeReplyFunction as E, type LoadServerActionFunction as L, RSCHydratedRouter as R, type DecodeFormStateFunction as a, type DecodeReplyFunction as b, createCallServer as c, type RSCManifestPayload as d, type RSCPayload as e, type RSCRenderPayload as f, getRequest as g, type RSCHydratedRouterProps as h, type RSCMatch as i, type RSCRouteManifest as j, type RSCRouteMatch as k, type RSCRouteConfigEntry as l, matchRSCServerRequest as m, type RSCRouteConfig as n };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.13.2
2
+ * react-router v7.14.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -51,7 +51,7 @@ import {
51
51
  withComponentProps,
52
52
  withErrorBoundaryProps,
53
53
  withHydrateFallbackProps
54
- } from "./chunk-UVKPFVEO.mjs";
54
+ } from "./chunk-QFMPRPBF.mjs";
55
55
 
56
56
  // lib/dom/ssr/server.tsx
57
57
  import * as React from "react";
@@ -1096,14 +1096,24 @@ function getSingleFetchRedirect(status, headers, basename) {
1096
1096
  function encodeViaTurboStream(data2, requestSignal, streamTimeout, serverMode) {
1097
1097
  let controller = new AbortController();
1098
1098
  let timeoutId = setTimeout(
1099
- () => controller.abort(new Error("Server Timeout")),
1099
+ () => {
1100
+ controller.abort(new Error("Server Timeout"));
1101
+ cleanupCallbacks();
1102
+ },
1100
1103
  typeof streamTimeout === "number" ? streamTimeout : 4950
1101
1104
  );
1102
- let clearStreamTimeout = () => clearTimeout(timeoutId);
1103
- requestSignal.addEventListener("abort", clearStreamTimeout);
1105
+ let abortControllerOnRequestAbort = () => {
1106
+ controller.abort(requestSignal.reason);
1107
+ cleanupCallbacks();
1108
+ };
1109
+ requestSignal.addEventListener("abort", abortControllerOnRequestAbort);
1110
+ let cleanupCallbacks = () => {
1111
+ clearTimeout(timeoutId);
1112
+ requestSignal.removeEventListener("abort", abortControllerOnRequestAbort);
1113
+ };
1104
1114
  return encode(data2, {
1105
1115
  signal: controller.signal,
1106
- onComplete: clearStreamTimeout,
1116
+ onComplete: cleanupCallbacks,
1107
1117
  plugins: [
1108
1118
  (value) => {
1109
1119
  if (value instanceof Error) {
@@ -2057,6 +2067,7 @@ function populateRSCRouteModules(routeModules, matches) {
2057
2067
  var noopComponent = () => null;
2058
2068
 
2059
2069
  // lib/rsc/server.ssr.tsx
2070
+ var defaultManifestPath = "/__manifest";
2060
2071
  var REACT_USE = "use";
2061
2072
  var useImpl = React4[REACT_USE];
2062
2073
  function useSafe(promise) {
@@ -2437,7 +2448,10 @@ function RSCStaticRouter({ getPayload }) {
2437
2448
  imports: []
2438
2449
  }
2439
2450
  },
2440
- routeDiscovery: { mode: "lazy", manifestPath: "/__manifest" },
2451
+ routeDiscovery: payload.routeDiscovery.mode === "initial" ? { mode: "initial", manifestPath: defaultManifestPath } : {
2452
+ mode: "lazy",
2453
+ manifestPath: payload.routeDiscovery.manifestPath || defaultManifestPath
2454
+ },
2441
2455
  routeModules: createRSCRouteModules(payload)
2442
2456
  };
2443
2457
  return /* @__PURE__ */ React4.createElement(RSCRouterContext.Provider, { value: true }, /* @__PURE__ */ React4.createElement(RSCRouterGlobalErrorBoundary, { location: payload.location }, /* @__PURE__ */ React4.createElement(FrameworkContext.Provider, { value: frameworkContext }, /* @__PURE__ */ React4.createElement(