react-router 8.4.0 → 8.5.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 (198) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/dist/development/dom-export.d.ts +2 -1
  3. package/dist/development/dom-export.js +1 -1
  4. package/dist/development/index-react-server-client.js +2 -2
  5. package/dist/development/index-react-server.d.ts +583 -165
  6. package/dist/development/index-react-server.js +27 -19
  7. package/dist/development/index.d.ts +9 -8
  8. package/dist/development/index.js +5 -4
  9. package/dist/development/lib/actions.js +1 -1
  10. package/dist/development/lib/components.js +22 -3
  11. package/dist/development/lib/context.d.ts +6 -1
  12. package/dist/development/lib/context.js +1 -1
  13. package/dist/development/lib/dom/dom.d.ts +3 -0
  14. package/dist/development/lib/dom/dom.js +1 -1
  15. package/dist/development/lib/dom/global.d.ts +35 -0
  16. package/dist/development/lib/dom/lib.d.ts +34 -9
  17. package/dist/development/lib/dom/lib.js +17 -6
  18. package/dist/development/lib/dom/server.js +2 -2
  19. package/dist/development/lib/dom/ssr/components.js +12 -9
  20. package/dist/development/lib/dom/ssr/data.js +1 -1
  21. package/dist/development/lib/dom/ssr/entry.d.ts +9 -2
  22. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  23. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  24. package/dist/development/lib/dom/ssr/fog-of-war.d.ts +3 -2
  25. package/dist/development/lib/dom/ssr/fog-of-war.js +14 -11
  26. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  27. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  28. package/dist/development/lib/dom/ssr/links.js +1 -1
  29. package/dist/development/lib/dom/ssr/markup.js +1 -1
  30. package/dist/development/lib/dom/ssr/route-discovery.d.ts +120 -0
  31. package/dist/development/lib/dom/ssr/route-discovery.js +415 -0
  32. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  33. package/dist/development/lib/dom/ssr/routes-test-stub.js +2 -2
  34. package/dist/development/lib/dom/ssr/routes.d.ts +2 -2
  35. package/dist/development/lib/dom/ssr/routes.js +8 -8
  36. package/dist/development/lib/dom/ssr/server.js +3 -1
  37. package/dist/development/lib/dom/ssr/single-fetch.d.ts +28 -2
  38. package/dist/development/lib/dom/ssr/single-fetch.js +73 -55
  39. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  40. package/dist/development/lib/dom-export/hydrated-router.d.ts +28 -0
  41. package/dist/development/lib/dom-export/hydrated-router.js +32 -12
  42. package/dist/development/lib/errors.js +1 -1
  43. package/dist/development/lib/hooks.d.ts +3 -3
  44. package/dist/development/lib/hooks.js +4 -4
  45. package/dist/development/lib/href.js +1 -1
  46. package/dist/development/lib/router/history.js +1 -1
  47. package/dist/development/lib/router/instrumentation.js +1 -1
  48. package/dist/development/lib/router/matcher-route-pattern.js +1 -1
  49. package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
  50. package/dist/development/lib/router/matcher.js +1 -1
  51. package/dist/development/lib/router/navigation.js +1 -1
  52. package/dist/development/lib/router/router.d.ts +6 -0
  53. package/dist/development/lib/router/router.js +157 -65
  54. package/dist/development/lib/router/url.js +1 -1
  55. package/dist/development/lib/router/utils.d.ts +24 -4
  56. package/dist/development/lib/router/utils.js +4 -3
  57. package/dist/development/lib/rsc/browser.js +2 -2
  58. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  59. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  60. package/dist/development/lib/rsc/html-stream/server.js +24 -12
  61. package/dist/development/lib/rsc/route-modules.js +1 -1
  62. package/dist/development/lib/rsc/server.rsc.d.ts +3 -2
  63. package/dist/development/lib/rsc/server.ssr.js +1 -1
  64. package/dist/development/lib/server-runtime/build.d.ts +14 -0
  65. package/dist/development/lib/server-runtime/cookies.js +1 -1
  66. package/dist/development/lib/server-runtime/crypto.js +1 -1
  67. package/dist/development/lib/server-runtime/data.js +1 -1
  68. package/dist/development/lib/server-runtime/dev.js +1 -1
  69. package/dist/development/lib/server-runtime/entry.js +1 -1
  70. package/dist/development/lib/server-runtime/errors.js +1 -1
  71. package/dist/development/lib/server-runtime/headers.js +1 -1
  72. package/dist/development/lib/server-runtime/invariant.js +1 -1
  73. package/dist/development/lib/server-runtime/mode.js +1 -1
  74. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  75. package/dist/development/lib/server-runtime/routes.d.ts +1 -1
  76. package/dist/development/lib/server-runtime/routes.js +1 -1
  77. package/dist/development/lib/server-runtime/server.js +12 -4
  78. package/dist/development/lib/server-runtime/serverHandoff.d.ts +17 -0
  79. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  80. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  81. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  82. package/dist/development/lib/server-runtime/sessions.js +1 -1
  83. package/dist/development/lib/server-runtime/single-fetch.js +1 -1
  84. package/dist/development/lib/server-runtime/urls.js +1 -1
  85. package/dist/development/lib/server-runtime/warnings.js +1 -1
  86. package/dist/development/lib/types/internal.js +1 -1
  87. package/dist/development/lib/types/route-data.d.ts +2 -2
  88. package/dist/development/lib/types/route-module-annotations.d.ts +1 -1
  89. package/dist/development/route-pattern.js +1 -1
  90. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  91. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  92. package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
  93. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  94. package/dist/production/dom-export.d.ts +2 -1
  95. package/dist/production/dom-export.js +1 -1
  96. package/dist/production/index-react-server-client.js +2 -2
  97. package/dist/production/index-react-server.d.ts +583 -165
  98. package/dist/production/index-react-server.js +27 -19
  99. package/dist/production/index.d.ts +9 -8
  100. package/dist/production/index.js +5 -4
  101. package/dist/production/lib/actions.js +1 -1
  102. package/dist/production/lib/components.js +22 -3
  103. package/dist/production/lib/context.d.ts +6 -1
  104. package/dist/production/lib/context.js +1 -1
  105. package/dist/production/lib/dom/dom.d.ts +3 -0
  106. package/dist/production/lib/dom/dom.js +1 -1
  107. package/dist/production/lib/dom/global.d.ts +35 -0
  108. package/dist/production/lib/dom/lib.d.ts +34 -9
  109. package/dist/production/lib/dom/lib.js +17 -6
  110. package/dist/production/lib/dom/server.js +2 -2
  111. package/dist/production/lib/dom/ssr/components.js +12 -9
  112. package/dist/production/lib/dom/ssr/data.js +1 -1
  113. package/dist/production/lib/dom/ssr/entry.d.ts +9 -2
  114. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  115. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  116. package/dist/production/lib/dom/ssr/fog-of-war.d.ts +3 -2
  117. package/dist/production/lib/dom/ssr/fog-of-war.js +14 -11
  118. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  119. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  120. package/dist/production/lib/dom/ssr/links.js +1 -1
  121. package/dist/production/lib/dom/ssr/markup.js +1 -1
  122. package/dist/production/lib/dom/ssr/route-discovery.d.ts +120 -0
  123. package/dist/production/lib/dom/ssr/route-discovery.js +415 -0
  124. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  125. package/dist/production/lib/dom/ssr/routes-test-stub.js +2 -2
  126. package/dist/production/lib/dom/ssr/routes.d.ts +2 -2
  127. package/dist/production/lib/dom/ssr/routes.js +8 -8
  128. package/dist/production/lib/dom/ssr/server.js +3 -1
  129. package/dist/production/lib/dom/ssr/single-fetch.d.ts +28 -2
  130. package/dist/production/lib/dom/ssr/single-fetch.js +73 -55
  131. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  132. package/dist/production/lib/dom-export/hydrated-router.d.ts +28 -0
  133. package/dist/production/lib/dom-export/hydrated-router.js +32 -12
  134. package/dist/production/lib/errors.js +1 -1
  135. package/dist/production/lib/hooks.d.ts +3 -3
  136. package/dist/production/lib/hooks.js +3 -3
  137. package/dist/production/lib/href.js +1 -1
  138. package/dist/production/lib/router/history.js +1 -1
  139. package/dist/production/lib/router/instrumentation.js +1 -1
  140. package/dist/production/lib/router/matcher-route-pattern.js +1 -1
  141. package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
  142. package/dist/production/lib/router/matcher.js +1 -1
  143. package/dist/production/lib/router/navigation.js +1 -1
  144. package/dist/production/lib/router/router.d.ts +6 -0
  145. package/dist/production/lib/router/router.js +157 -65
  146. package/dist/production/lib/router/url.js +1 -1
  147. package/dist/production/lib/router/utils.d.ts +24 -4
  148. package/dist/production/lib/router/utils.js +4 -3
  149. package/dist/production/lib/rsc/browser.js +2 -2
  150. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  151. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  152. package/dist/production/lib/rsc/html-stream/server.js +24 -12
  153. package/dist/production/lib/rsc/route-modules.js +1 -1
  154. package/dist/production/lib/rsc/server.rsc.d.ts +3 -2
  155. package/dist/production/lib/rsc/server.ssr.js +1 -1
  156. package/dist/production/lib/server-runtime/build.d.ts +14 -0
  157. package/dist/production/lib/server-runtime/cookies.js +1 -1
  158. package/dist/production/lib/server-runtime/crypto.js +1 -1
  159. package/dist/production/lib/server-runtime/data.js +1 -1
  160. package/dist/production/lib/server-runtime/dev.js +1 -1
  161. package/dist/production/lib/server-runtime/entry.js +1 -1
  162. package/dist/production/lib/server-runtime/errors.js +1 -1
  163. package/dist/production/lib/server-runtime/headers.js +1 -1
  164. package/dist/production/lib/server-runtime/invariant.js +1 -1
  165. package/dist/production/lib/server-runtime/mode.js +1 -1
  166. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  167. package/dist/production/lib/server-runtime/routes.d.ts +1 -1
  168. package/dist/production/lib/server-runtime/routes.js +1 -1
  169. package/dist/production/lib/server-runtime/server.js +12 -4
  170. package/dist/production/lib/server-runtime/serverHandoff.d.ts +17 -0
  171. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  172. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  173. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  174. package/dist/production/lib/server-runtime/sessions.js +1 -1
  175. package/dist/production/lib/server-runtime/single-fetch.js +1 -1
  176. package/dist/production/lib/server-runtime/urls.js +1 -1
  177. package/dist/production/lib/server-runtime/warnings.js +1 -1
  178. package/dist/production/lib/types/internal.js +1 -1
  179. package/dist/production/lib/types/route-data.d.ts +2 -2
  180. package/dist/production/lib/types/route-module-annotations.d.ts +1 -1
  181. package/dist/production/route-pattern.js +1 -1
  182. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  183. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  184. package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
  185. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  186. package/docs/explanation/lazy-route-discovery.md +4 -0
  187. package/docs/explanation/sessions-and-cookies.md +108 -4
  188. package/docs/how-to/custom-fetch.md +218 -0
  189. package/docs/how-to/data-strategy.md +23 -1
  190. package/docs/how-to/middleware.md +1 -0
  191. package/docs/how-to/optimize-revalidation.md +2 -2
  192. package/docs/how-to/pre-rendering.md +23 -1
  193. package/docs/how-to/route-discovery.md +145 -0
  194. package/docs/how-to/spa.md +2 -0
  195. package/docs/how-to/view-transitions.md +80 -13
  196. package/docs/start/framework/navigating.md +5 -9
  197. package/docs/start/framework/rendering.md +37 -0
  198. package/package.json +9 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
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) {
59
+ function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, fetchImplementation = (request) => fetch(request), isApiOnly = false, serverOrigin) {
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, ssr);
67
+ }, fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin), ssr, void 0, isApiOnly);
68
68
  return async (args) => args.runClientMiddleware(dataStrategy);
69
69
  }
70
- function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true) {
70
+ function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = 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);
81
+ return singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut, isApiOnly);
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) {
116
+ async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, shouldAllowOptOut = () => true, isApiOnly = 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" || routesParams.size === 0) && !window.__reactRouterHdrActive) singleFetchDfd.resolve({ routes: {} });
165
+ if ((!router.state.initialized && router.state.navigation.state === "idle" && !isApiOnly || 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 {
@@ -216,61 +216,79 @@ function stripIndexParam(url) {
216
216
  for (let toKeep of indexValuesToKeep) url.searchParams.append("index", toKeep);
217
217
  return url;
218
218
  }
219
- function singleFetchUrl(reqUrl, extension) {
220
- let url = typeof reqUrl === "string" ? new URL(reqUrl, typeof window === "undefined" ? "server://singlefetch/" : window.location.origin) : reqUrl;
219
+ function singleFetchUrl(reqUrl, extension, serverOrigin) {
220
+ let url = typeof reqUrl === "string" ? new URL(reqUrl, serverOrigin ?? (typeof window === "undefined" ? "server://singlefetch/" : window.location.origin)) : new URL(reqUrl);
221
+ if (serverOrigin && url.origin !== serverOrigin) url = new URL(url.pathname + url.search + url.hash, serverOrigin);
221
222
  if (url.pathname.endsWith("/")) url.pathname = `${url.pathname}_.${extension}`;
222
223
  else url.pathname = `${url.pathname}.${extension}`;
223
224
  return url;
224
225
  }
225
- async function fetchAndDecodeViaTurboStream(args, targetRoutes) {
226
- let { request } = args;
227
- let url = singleFetchUrl(request.url, "data");
228
- if (request.method === "GET") {
229
- url = stripIndexParam(url);
230
- if (targetRoutes) url.searchParams.set("_routes", targetRoutes.join(","));
231
- }
232
- let res = await fetch(url, await createRequestInit(request));
233
- if (res.status >= 400 && !res.headers.has("X-Remix-Response")) throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
234
- if (res.status === 204 && res.headers.has("X-Remix-Redirect")) return {
235
- status: 202,
236
- data: { redirect: {
237
- redirect: res.headers.get("X-Remix-Redirect"),
238
- status: Number(res.headers.get("X-Remix-Status") || "302"),
239
- revalidate: res.headers.get("X-Remix-Revalidate") === "true",
240
- reload: res.headers.get("X-Remix-Reload-Document") === "true",
241
- replace: res.headers.get("X-Remix-Replace") === "true"
242
- } }
243
- };
244
- if (NO_BODY_STATUS_CODES.has(res.status)) {
245
- let routes = {};
246
- if (targetRoutes && request.method !== "GET") routes[targetRoutes[0]] = { data: void 0 };
247
- return {
248
- status: res.status,
249
- data: { routes }
250
- };
251
- }
252
- invariant(res.body, "No response body to decode");
253
- try {
254
- let decoded = await decodeViaTurboStream(res.body, window);
255
- let data;
226
+ function fetchAndDecodeViaTurboStream(fetchImplementation, serverOrigin) {
227
+ return async (args, targetRoutes) => {
228
+ let { request } = args;
229
+ let url = singleFetchUrl(request.url, "data", serverOrigin);
256
230
  if (request.method === "GET") {
257
- let typed = decoded.value;
258
- if (SingleFetchRedirectSymbol in typed) data = { redirect: typed[SingleFetchRedirectSymbol] };
259
- else data = { routes: typed };
260
- } else {
261
- let typed = decoded.value;
262
- let routeId = targetRoutes?.[0];
263
- invariant(routeId, "No routeId found for single fetch call decoding");
264
- if ("redirect" in typed) data = { redirect: typed };
265
- else data = { routes: { [routeId]: typed } };
231
+ url = stripIndexParam(url);
232
+ if (targetRoutes) url.searchParams.set("_routes", targetRoutes.join(","));
266
233
  }
267
- return {
268
- status: res.status,
269
- data
234
+ let req = new Request(url, await createRequestInit(request));
235
+ invariant(args.unstable_initiator !== "static", "Static data strategy initiator used for a client data request");
236
+ let fetchContext;
237
+ if (args.unstable_initiator === "navigation") {
238
+ invariant(args.unstable_navigationType !== null, "Missing navigation type for a navigation data request");
239
+ fetchContext = {
240
+ type: "navigation",
241
+ fetcherKey: args.fetcherKey,
242
+ navigationType: args.unstable_navigationType
243
+ };
244
+ } else fetchContext = {
245
+ type: args.unstable_initiator,
246
+ fetcherKey: args.fetcherKey,
247
+ navigationType: null
270
248
  };
271
- } catch (cause) {
272
- throw new Error("Unable to decode turbo-stream response", { cause });
273
- }
249
+ let res = await fetchImplementation(req, fetchContext);
250
+ if (res.status >= 400 && !res.headers.has("X-Remix-Response")) throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
251
+ if (res.status === 204 && res.headers.has("X-Remix-Redirect")) return {
252
+ status: 202,
253
+ data: { redirect: {
254
+ redirect: res.headers.get("X-Remix-Redirect"),
255
+ status: Number(res.headers.get("X-Remix-Status") || "302"),
256
+ revalidate: res.headers.get("X-Remix-Revalidate") === "true",
257
+ reload: res.headers.get("X-Remix-Reload-Document") === "true",
258
+ replace: res.headers.get("X-Remix-Replace") === "true"
259
+ } }
260
+ };
261
+ if (NO_BODY_STATUS_CODES.has(res.status)) {
262
+ let routes = {};
263
+ if (targetRoutes && request.method !== "GET") routes[targetRoutes[0]] = { data: void 0 };
264
+ return {
265
+ status: res.status,
266
+ data: { routes }
267
+ };
268
+ }
269
+ invariant(res.body, "No response body to decode");
270
+ try {
271
+ let decoded = await decodeViaTurboStream(res.body, window);
272
+ let data;
273
+ if (request.method === "GET") {
274
+ let typed = decoded.value;
275
+ if (SingleFetchRedirectSymbol in typed) data = { redirect: typed[SingleFetchRedirectSymbol] };
276
+ else data = { routes: typed };
277
+ } else {
278
+ let typed = decoded.value;
279
+ let routeId = targetRoutes?.[0];
280
+ invariant(routeId, "No routeId found for single fetch call decoding");
281
+ if ("redirect" in typed) data = { redirect: typed };
282
+ else data = { routes: { [routeId]: typed } };
283
+ }
284
+ return {
285
+ status: res.status,
286
+ data
287
+ };
288
+ } catch (cause) {
289
+ throw new Error("Unable to decode turbo-stream response", { cause });
290
+ }
291
+ };
274
292
  }
275
293
  function decodeViaTurboStream(body, global) {
276
294
  return decode(body, { plugins: [(type, ...rest) => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,4 +1,5 @@
1
1
 
2
+ import { RouterFetch } from "../dom/ssr/single-fetch.js";
2
3
  import { ClientInstrumentation } from "../router/instrumentation.js";
3
4
  import * as React$1 from "react";
4
5
  import { ClientOnErrorFunction, RouterInit } from "react-router";
@@ -107,6 +108,32 @@ interface HydratedRouterProps {
107
108
  * For more information, please see the [docs](../../explanation/react-transitions).
108
109
  */
109
110
  useTransitions?: boolean;
111
+ /**
112
+ * <docs-warning>This prop is experimental and subject to breaking
113
+ * changes.</docs-warning>
114
+ *
115
+ * Provide a custom implementation for `fetch`, which will be used to perform
116
+ * JavaScript-issued manifest and data requests. The context identifies the
117
+ * operation that initiated each request. Defaults to `window.fetch`.
118
+ *
119
+ * This prop is read when the singleton router is created. Changing it after
120
+ * router initialization has no effect. To use changing values such as auth
121
+ * tokens, read current application state inside the function rather than
122
+ * capturing values from a component render.
123
+ *
124
+ * See the [Custom Fetch guide](../../how-to/custom-fetch) for examples of
125
+ * authentication headers, cross-origin credentials, traversal caching, and
126
+ * retries.
127
+ *
128
+ * <docs-info>
129
+ * Browser-managed data prefetches from {@link Link}, {@link NavLink}, or
130
+ * {@link PrefetchPageLinks} use native `<link rel="prefetch">` elements
131
+ * and do not call this function. If your data requests require custom headers
132
+ * or other request transformations, use `prefetch="none"` on links and avoid
133
+ * rendering {@link PrefetchPageLinks}.
134
+ * </docs-info>
135
+ */
136
+ unstable_fetch?: RouterFetch;
110
137
  }
111
138
  /**
112
139
  * Framework-mode router component to be used to hydrate a router from a
@@ -118,6 +145,7 @@ interface HydratedRouterProps {
118
145
  * @param props Props
119
146
  * @param {dom.HydratedRouterProps.getContext} props.getContext n/a
120
147
  * @param {dom.HydratedRouterProps.onError} props.onError n/a
148
+ * @param {dom.HydratedRouterProps.unstable_fetch} props.unstable_fetch n/a
121
149
  * @returns A React element that represents the hydrated application.
122
150
  */
123
151
  declare function HydratedRouter(props: HydratedRouterProps): React$1.JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -11,10 +11,11 @@
11
11
  import { CRITICAL_CSS_DATA_ATTRIBUTE } from "../dom/ssr/components.js";
12
12
  import { RouterProvider as RouterProvider$1 } from "./dom-router-provider.js";
13
13
  import * as React$1 from "react";
14
- import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useFogOFWarDiscovery } from "react-router";
14
+ import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_RouteDiscoveryRuntime, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getCustomPatchRoutesOnNavigationFunction, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useCustomRouteDiscovery, UNSAFE_useFogOFWarDiscovery } from "react-router";
15
15
  //#region lib/dom-export/hydrated-router.tsx
16
16
  let ssrInfo = null;
17
17
  let router = null;
18
+ let fetchImplementation = (request) => window.fetch(request);
18
19
  function initSsrInfo() {
19
20
  if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) {
20
21
  if (window.__reactRouterManifest.sri === true) {
@@ -31,14 +32,17 @@ function initSsrInfo() {
31
32
  routeModules: window.__reactRouterRouteModules,
32
33
  stateDecodingPromise: void 0,
33
34
  router: void 0,
35
+ routeDiscoveryRuntime: void 0,
34
36
  routerInitialized: false
35
37
  };
36
38
  }
37
39
  }
38
- function createHydratedRouter({ getContext, instrumentations }) {
40
+ function createHydratedRouter({ getContext, instrumentations, fetch: fetchImplementation }) {
39
41
  initSsrInfo();
40
42
  if (!ssrInfo) throw new Error("You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`");
41
43
  let localSsrInfo = ssrInfo;
44
+ let isApiOnly = ssrInfo.context.unstable_apiOnly === true;
45
+ let ssr = ssrInfo.context.ssr;
42
46
  if (!ssrInfo.stateDecodingPromise) {
43
47
  let stream = ssrInfo.context.stream;
44
48
  UNSAFE_invariant(stream, "No stream found for single fetch decoding");
@@ -52,7 +56,7 @@ function createHydratedRouter({ getContext, instrumentations }) {
52
56
  }
53
57
  if (ssrInfo.stateDecodingPromise.error) throw ssrInfo.stateDecodingPromise.error;
54
58
  if (!ssrInfo.stateDecodingPromise.value) throw ssrInfo.stateDecodingPromise;
55
- let routes = UNSAFE_createClientRoutes(ssrInfo.manifest.routes, ssrInfo.routeModules, ssrInfo.context.state, ssrInfo.context.ssr, ssrInfo.context.isSpaMode);
59
+ let routes = UNSAFE_createClientRoutes(ssrInfo.manifest.routes, ssrInfo.routeModules, ssrInfo.context.state, ssr, ssrInfo.context.isSpaMode, "", void 0, void 0, isApiOnly);
56
60
  let hydrationData = void 0;
57
61
  if (ssrInfo.context.isSpaMode) {
58
62
  let { loaderData } = ssrInfo.context.state;
@@ -74,19 +78,22 @@ function createHydratedRouter({ getContext, instrumentations }) {
74
78
  ...window.history.state,
75
79
  masked: void 0
76
80
  }, "");
81
+ let discoveryRuntime = ssrInfo.context.future.unstable_customRouteDiscovery ? new UNSAFE_RouteDiscoveryRuntime(ssrInfo, { fetch: fetchImplementation }) : void 0;
77
82
  let router = UNSAFE_createRouter({
78
83
  routes,
79
84
  history: UNSAFE_createBrowserHistory(),
85
+ future: { unstable_customRouteDiscovery: ssrInfo.context.future.unstable_customRouteDiscovery },
80
86
  basename: ssrInfo.context.basename,
81
87
  getContext,
82
88
  hydrationData,
83
89
  mapRouteProperties: UNSAFE_defaultMapRouteProperties,
84
90
  hydrationRouteProperties: UNSAFE_hydrationRouteProperties,
85
91
  instrumentations,
86
- dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssrInfo.context.ssr),
87
- patchRoutesOnNavigation: UNSAFE_getPatchRoutesOnNavigationFunction(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssrInfo.context.ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, ssrInfo.context.basename)
92
+ dataStrategy: UNSAFE_getTurboStreamSingleFetchDataStrategy(() => router, ssrInfo.manifest, ssrInfo.routeModules, ssr, fetchImplementation, ssrInfo.context.unstable_apiOnly === true, ssrInfo.context.unstable_apiServerOrigin),
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)
88
94
  });
89
95
  ssrInfo.router = router;
96
+ ssrInfo.routeDiscoveryRuntime = discoveryRuntime;
90
97
  if (router.state.initialized) {
91
98
  ssrInfo.routerInitialized = true;
92
99
  router.initialize();
@@ -105,13 +112,18 @@ function createHydratedRouter({ getContext, instrumentations }) {
105
112
  * @param props Props
106
113
  * @param {dom.HydratedRouterProps.getContext} props.getContext n/a
107
114
  * @param {dom.HydratedRouterProps.onError} props.onError n/a
115
+ * @param {dom.HydratedRouterProps.unstable_fetch} props.unstable_fetch n/a
108
116
  * @returns A React element that represents the hydrated application.
109
117
  */
110
118
  function HydratedRouter(props) {
111
- if (!router) router = createHydratedRouter({
112
- getContext: props.getContext,
113
- instrumentations: props.instrumentations
114
- });
119
+ if (!router) {
120
+ router = createHydratedRouter({
121
+ getContext: props.getContext,
122
+ instrumentations: props.instrumentations,
123
+ fetch: props.unstable_fetch ?? fetchImplementation
124
+ });
125
+ if (props.unstable_fetch) fetchImplementation = props.unstable_fetch;
126
+ }
115
127
  let [criticalCss, setCriticalCss] = React$1.useState(process.env.NODE_ENV === "development" ? ssrInfo?.context.criticalCss : void 0);
116
128
  React$1.useEffect(() => {
117
129
  if (process.env.NODE_ENV === "development") setCriticalCss(void 0);
@@ -132,15 +144,23 @@ function HydratedRouter(props) {
132
144
  });
133
145
  }, [location]);
134
146
  UNSAFE_invariant(ssrInfo, "ssrInfo unavailable for HydratedRouter");
135
- UNSAFE_useFogOFWarDiscovery(router, ssrInfo.manifest, ssrInfo.routeModules, ssrInfo.context.ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode);
147
+ let ssr = ssrInfo.context.ssr;
148
+ let discoveryRuntime = ssrInfo.routeDiscoveryRuntime;
149
+ let discoveryState;
150
+ if (discoveryRuntime) discoveryState = UNSAFE_useCustomRouteDiscovery(discoveryRuntime, props.onError);
151
+ else UNSAFE_useFogOFWarDiscovery(router, ssrInfo.manifest, ssrInfo.routeModules, ssr, ssrInfo.context.routeDiscovery, ssrInfo.context.isSpaMode, fetchImplementation, ssrInfo.context.unstable_apiServerOrigin, ssrInfo.context.unstable_apiOnly === true);
136
152
  return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, /* @__PURE__ */ React$1.createElement(UNSAFE_FrameworkContext.Provider, { value: {
153
+ routeDiscoveryRuntime: discoveryRuntime,
154
+ routeDiscoveryState: discoveryState,
137
155
  manifest: ssrInfo.manifest,
138
156
  routeModules: ssrInfo.routeModules,
139
157
  future: ssrInfo.context.future,
140
158
  criticalCss,
141
159
  ssr: ssrInfo.context.ssr,
142
160
  isSpaMode: ssrInfo.context.isSpaMode,
143
- routeDiscovery: ssrInfo.context.routeDiscovery
161
+ unstable_apiOnly: ssrInfo.context.unstable_apiOnly,
162
+ routeDiscovery: ssrInfo.context.routeDiscovery,
163
+ unstable_apiServerOrigin: ssrInfo.context.unstable_apiServerOrigin
144
164
  } }, /* @__PURE__ */ React$1.createElement(UNSAFE_RemixErrorBoundary, { location }, /* @__PURE__ */ React$1.createElement(RouterProvider$1, {
145
165
  router,
146
166
  useTransitions: props.useTransitions,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -3,8 +3,8 @@ import { Action, Location, Path, To } from "./router/history.js";
3
3
  import { ParamParseKey, Params, PathMatch, PathPattern, RouteObject, UIMatch } from "./router/utils.js";
4
4
  import { Blocker, BlockerFunction, NavigationStates, RelativeRoutingType, Router } from "./router/router.js";
5
5
  import { NavigateOptions } from "./context.js";
6
- import { RouteModules } from "./types/register.js";
7
6
  import { GetActionData, GetLoaderData, SerializeFrom } from "./types/route-data.js";
7
+ import { RouteModules } from "./types/register.js";
8
8
  import * as React$1 from "react";
9
9
 
10
10
  //#region lib/hooks.d.ts
@@ -116,7 +116,7 @@ interface NavigateFunction {
116
116
  * * These options only work in Framework and Data modes:
117
117
  * * `flushSync`: Wrap the DOM updates in [`ReactDom.flushSync`](https://react.dev/reference/react-dom/flushSync)
118
118
  * * `preventScrollReset`: Do not scroll back to the top of the page after navigation
119
- * * `viewTransition`: Enable [`document.startViewTransition`](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) for this navigation
119
+ * * `viewTransition`: **Deprecated.** Use React's [`<ViewTransition>`](https://react.dev/reference/react/ViewTransition) component instead. See the [migration guide](../../how-to/view-transitions).
120
120
  *
121
121
  * @example
122
122
  * import { useNavigate } from "react-router";
@@ -939,7 +939,7 @@ type unstable_RouterState = {
939
939
  * @example
940
940
  * import { unstable_useRouterState as useRouterState } from "react-router";
941
941
  *
942
- * let { active, pending } = unstable_useRouterState();
942
+ * let { active, pending } = useRouterState();
943
943
  *
944
944
  * // Active is always populated with the current location
945
945
  * active.location; // replaces `useLocation()`
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -136,7 +136,7 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
136
136
  * * These options only work in Framework and Data modes:
137
137
  * * `flushSync`: Wrap the DOM updates in [`ReactDom.flushSync`](https://react.dev/reference/react-dom/flushSync)
138
138
  * * `preventScrollReset`: Do not scroll back to the top of the page after navigation
139
- * * `viewTransition`: Enable [`document.startViewTransition`](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) for this navigation
139
+ * * `viewTransition`: **Deprecated.** Use React's [`<ViewTransition>`](https://react.dev/reference/react/ViewTransition) component instead. See the [migration guide](../../how-to/view-transitions).
140
140
  *
141
141
  * @example
142
142
  * import { useNavigate } from "react-router";
@@ -1326,7 +1326,7 @@ function toRouterStateMatch(match) {
1326
1326
  * @example
1327
1327
  * import { unstable_useRouterState as useRouterState } from "react-router";
1328
1328
  *
1329
- * let { active, pending } = unstable_useRouterState();
1329
+ * let { active, pending } = useRouterState();
1330
1330
  *
1331
1331
  * // Active is always populated with the current location
1332
1332
  * active.location; // replaces `useLocation()`
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.4.0
2
+ * react-router v8.5.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -306,6 +306,8 @@ type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionData" | "e
306
306
  * Future flags to toggle new feature behavior
307
307
  */
308
308
  interface FutureConfig {
309
+ /** @internal Enables application-controlled Framework route discovery. */
310
+ unstable_customRouteDiscovery?: boolean;
309
311
  /** Enables route-pattern matching after calling `unstable_preloadRoutePattern()`. */
310
312
  unstable_routePatternMatching?: boolean;
311
313
  }
@@ -452,6 +454,10 @@ type BaseNavigateOptions = BaseNavigateOrFetchOptions & {
452
454
  replace?: boolean;
453
455
  state?: any;
454
456
  fromRouteId?: string;
457
+ /**
458
+ * @deprecated Use React's `<ViewTransition>` component instead. See the
459
+ * [migration guide](https://reactrouter.com/how-to/view-transitions).
460
+ */
455
461
  viewTransition?: boolean;
456
462
  mask?: To;
457
463
  };