react-router 8.5.0 → 8.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/dist/development/dom-export.js +1 -1
  3. package/dist/development/index-react-server-client.js +1 -1
  4. package/dist/development/index-react-server.d.ts +50 -396
  5. package/dist/development/index-react-server.js +43 -15
  6. package/dist/development/index.js +1 -1
  7. package/dist/development/lib/actions.js +1 -1
  8. package/dist/development/lib/await.js +58 -0
  9. package/dist/development/lib/components.d.ts +41 -5
  10. package/dist/development/lib/components.js +62 -4
  11. package/dist/development/lib/context.d.ts +2 -2
  12. package/dist/development/lib/context.js +1 -1
  13. package/dist/development/lib/dom/dom.js +1 -1
  14. package/dist/development/lib/dom/lib.js +1 -1
  15. package/dist/development/lib/dom/server.js +1 -1
  16. package/dist/development/lib/dom/ssr/components.js +1 -1
  17. package/dist/development/lib/dom/ssr/data.js +1 -1
  18. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  19. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  20. package/dist/development/lib/dom/ssr/fog-of-war.js +12 -3
  21. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  22. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  23. package/dist/development/lib/dom/ssr/links.js +1 -1
  24. package/dist/development/lib/dom/ssr/markup.js +1 -1
  25. package/dist/development/lib/dom/ssr/route-discovery.d.ts +2 -2
  26. package/dist/development/lib/dom/ssr/route-discovery.js +3 -3
  27. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  28. package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
  29. package/dist/development/lib/dom/ssr/routes.js +1 -1
  30. package/dist/development/lib/dom/ssr/server.js +1 -1
  31. package/dist/development/lib/dom/ssr/single-fetch.d.ts +1 -1
  32. package/dist/development/lib/dom/ssr/single-fetch.js +7 -7
  33. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  34. package/dist/development/lib/dom-export/hydrated-router.js +2 -2
  35. package/dist/development/lib/errors.js +1 -1
  36. package/dist/development/lib/hooks.d.ts +0 -3
  37. package/dist/development/lib/hooks.js +5 -6
  38. package/dist/development/lib/href.js +1 -1
  39. package/dist/development/lib/router/history.js +1 -1
  40. package/dist/development/lib/router/instrumentation.js +1 -1
  41. package/dist/development/lib/router/matcher-route-pattern.js +1 -1
  42. package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
  43. package/dist/development/lib/router/matcher.js +6 -1
  44. package/dist/development/lib/router/navigation.js +1 -1
  45. package/dist/development/lib/router/router.d.ts +2 -0
  46. package/dist/development/lib/router/router.js +58 -28
  47. package/dist/development/lib/router/url.js +1 -1
  48. package/dist/development/lib/router/utils.d.ts +7 -0
  49. package/dist/development/lib/router/utils.js +1 -1
  50. package/dist/development/lib/rsc/browser.js +3 -3
  51. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  52. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  53. package/dist/development/lib/rsc/html-stream/server.js +1 -1
  54. package/dist/development/lib/rsc/route-modules.js +1 -1
  55. package/dist/development/lib/rsc/server.ssr.js +1 -1
  56. package/dist/development/lib/server-runtime/cookies.js +1 -1
  57. package/dist/development/lib/server-runtime/crypto.js +1 -1
  58. package/dist/development/lib/server-runtime/data.js +1 -1
  59. package/dist/development/lib/server-runtime/dev.js +1 -1
  60. package/dist/development/lib/server-runtime/entry.js +1 -1
  61. package/dist/development/lib/server-runtime/errors.js +1 -1
  62. package/dist/development/lib/server-runtime/headers.js +1 -1
  63. package/dist/development/lib/server-runtime/invariant.js +1 -1
  64. package/dist/development/lib/server-runtime/mode.js +1 -1
  65. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  66. package/dist/development/lib/server-runtime/routes.js +1 -1
  67. package/dist/development/lib/server-runtime/server.js +13 -5
  68. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  69. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  70. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  71. package/dist/development/lib/server-runtime/sessions.js +2 -2
  72. package/dist/development/lib/server-runtime/single-fetch.js +1 -1
  73. package/dist/development/lib/server-runtime/urls.js +1 -1
  74. package/dist/development/lib/server-runtime/warnings.js +1 -1
  75. package/dist/development/lib/types/internal.js +1 -1
  76. package/dist/development/route-pattern.js +1 -1
  77. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  78. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  79. package/dist/development/vendor/turbo-stream-v2/unflatten.js +23 -3
  80. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  81. package/dist/production/dom-export.js +1 -1
  82. package/dist/production/index-react-server-client.js +1 -1
  83. package/dist/production/index-react-server.d.ts +50 -396
  84. package/dist/production/index-react-server.js +43 -15
  85. package/dist/production/index.js +1 -1
  86. package/dist/production/lib/actions.js +1 -1
  87. package/dist/production/lib/await.js +58 -0
  88. package/dist/production/lib/components.d.ts +41 -5
  89. package/dist/production/lib/components.js +62 -4
  90. package/dist/production/lib/context.d.ts +2 -2
  91. package/dist/production/lib/context.js +1 -1
  92. package/dist/production/lib/dom/dom.js +1 -1
  93. package/dist/production/lib/dom/lib.js +1 -1
  94. package/dist/production/lib/dom/server.js +1 -1
  95. package/dist/production/lib/dom/ssr/components.js +1 -1
  96. package/dist/production/lib/dom/ssr/data.js +1 -1
  97. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  98. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  99. package/dist/production/lib/dom/ssr/fog-of-war.js +12 -3
  100. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  101. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  102. package/dist/production/lib/dom/ssr/links.js +1 -1
  103. package/dist/production/lib/dom/ssr/markup.js +1 -1
  104. package/dist/production/lib/dom/ssr/route-discovery.d.ts +2 -2
  105. package/dist/production/lib/dom/ssr/route-discovery.js +3 -3
  106. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  107. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  108. package/dist/production/lib/dom/ssr/routes.js +1 -1
  109. package/dist/production/lib/dom/ssr/server.js +1 -1
  110. package/dist/production/lib/dom/ssr/single-fetch.d.ts +1 -1
  111. package/dist/production/lib/dom/ssr/single-fetch.js +7 -7
  112. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  113. package/dist/production/lib/dom-export/hydrated-router.js +2 -2
  114. package/dist/production/lib/errors.js +1 -1
  115. package/dist/production/lib/hooks.d.ts +0 -3
  116. package/dist/production/lib/hooks.js +5 -6
  117. package/dist/production/lib/href.js +1 -1
  118. package/dist/production/lib/router/history.js +1 -1
  119. package/dist/production/lib/router/instrumentation.js +1 -1
  120. package/dist/production/lib/router/matcher-route-pattern.js +1 -1
  121. package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
  122. package/dist/production/lib/router/matcher.js +6 -1
  123. package/dist/production/lib/router/navigation.js +1 -1
  124. package/dist/production/lib/router/router.d.ts +2 -0
  125. package/dist/production/lib/router/router.js +58 -28
  126. package/dist/production/lib/router/url.js +1 -1
  127. package/dist/production/lib/router/utils.d.ts +7 -0
  128. package/dist/production/lib/router/utils.js +1 -1
  129. package/dist/production/lib/rsc/browser.js +3 -3
  130. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  131. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  132. package/dist/production/lib/rsc/html-stream/server.js +1 -1
  133. package/dist/production/lib/rsc/route-modules.js +1 -1
  134. package/dist/production/lib/rsc/server.ssr.js +1 -1
  135. package/dist/production/lib/server-runtime/cookies.js +1 -1
  136. package/dist/production/lib/server-runtime/crypto.js +1 -1
  137. package/dist/production/lib/server-runtime/data.js +1 -1
  138. package/dist/production/lib/server-runtime/dev.js +1 -1
  139. package/dist/production/lib/server-runtime/entry.js +1 -1
  140. package/dist/production/lib/server-runtime/errors.js +1 -1
  141. package/dist/production/lib/server-runtime/headers.js +1 -1
  142. package/dist/production/lib/server-runtime/invariant.js +1 -1
  143. package/dist/production/lib/server-runtime/mode.js +1 -1
  144. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  145. package/dist/production/lib/server-runtime/routes.js +1 -1
  146. package/dist/production/lib/server-runtime/server.js +13 -5
  147. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  148. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  149. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  150. package/dist/production/lib/server-runtime/sessions.js +2 -2
  151. package/dist/production/lib/server-runtime/single-fetch.js +1 -1
  152. package/dist/production/lib/server-runtime/urls.js +1 -1
  153. package/dist/production/lib/server-runtime/warnings.js +1 -1
  154. package/dist/production/lib/types/internal.js +1 -1
  155. package/dist/production/route-pattern.js +1 -1
  156. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  157. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  158. package/dist/production/vendor/turbo-stream-v2/unflatten.js +23 -3
  159. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  160. package/docs/explanation/backend-for-frontend.md +0 -3
  161. package/docs/explanation/code-splitting.md +0 -3
  162. package/docs/explanation/concurrency.md +0 -3
  163. package/docs/explanation/hot-module-replacement.md +0 -3
  164. package/docs/explanation/lazy-route-discovery.md +0 -3
  165. package/docs/explanation/progressive-enhancement.md +0 -3
  166. package/docs/explanation/race-conditions.md +0 -3
  167. package/docs/explanation/react-transitions.md +0 -3
  168. package/docs/explanation/sessions-and-cookies.md +1 -1
  169. package/docs/explanation/state-management.md +0 -3
  170. package/docs/explanation/styling.md +0 -3
  171. package/docs/explanation/type-safety.md +0 -3
  172. package/docs/how-to/accessibility.md +0 -6
  173. package/docs/how-to/client-data.md +0 -3
  174. package/docs/how-to/data-strategy.md +0 -3
  175. package/docs/how-to/error-boundary.md +0 -3
  176. package/docs/how-to/error-reporting.md +0 -3
  177. package/docs/how-to/fetchers.md +0 -3
  178. package/docs/how-to/file-route-conventions.md +0 -3
  179. package/docs/how-to/file-uploads.md +0 -3
  180. package/docs/how-to/form-validation.md +0 -3
  181. package/docs/how-to/headers.md +0 -3
  182. package/docs/how-to/instrumentation.md +0 -3
  183. package/docs/how-to/middleware.md +6 -3
  184. package/docs/how-to/navigation-blocking.md +0 -3
  185. package/docs/how-to/optimize-revalidation.md +0 -3
  186. package/docs/how-to/pre-rendering.md +0 -3
  187. package/docs/how-to/presets.md +0 -3
  188. package/docs/how-to/react-server-components.md +0 -3
  189. package/docs/how-to/resource-routes.md +0 -3
  190. package/docs/how-to/route-discovery.md +4 -2
  191. package/docs/how-to/route-module-type-safety.md +0 -3
  192. package/docs/how-to/security.md +0 -3
  193. package/docs/how-to/server-bundles.md +0 -3
  194. package/docs/how-to/spa.md +0 -3
  195. package/docs/how-to/status.md +0 -3
  196. package/docs/how-to/suspense.md +22 -6
  197. package/docs/how-to/using-handle.md +0 -3
  198. package/docs/how-to/view-transitions.md +0 -3
  199. package/docs/start/framework/data-loading.md +9 -0
  200. package/docs/upgrading/future.md +0 -12
  201. package/docs/upgrading/v7.md +3 -33
  202. package/package.json +1 -1
  203. package/dist/development/lib/dom/global.d.ts +0 -35
  204. package/dist/production/lib/dom/global.d.ts +0 -35
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -14,12 +14,17 @@ var V6RegExMatcher = class {
14
14
  #routes = [];
15
15
  #branches = [];
16
16
  #basename;
17
+ #matchCost = 0;
17
18
  constructor(basename) {
18
19
  this.#basename = basename;
19
20
  }
20
21
  update(routes) {
21
22
  this.#routes = routes;
22
23
  this.#branches = flattenAndRankRoutes(routes);
24
+ this.#matchCost = this.#branches.reduce((total, branch) => total + branch.routesMeta.length, 0);
25
+ }
26
+ get matchCost() {
27
+ return this.#matchCost;
23
28
  }
24
29
  match(locationArg, allowPartial = false) {
25
30
  return matchRoutesImpl(this.#routes, locationArg, this.#basename, allowPartial, this.#branches);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -353,6 +353,8 @@ interface StaticHandler {
353
353
  * The set of data routes managed by this handler
354
354
  */
355
355
  dataRoutes: DataRouteObject[];
356
+ /** @private Estimated route metadata visits per regex match. */
357
+ readonly _matchCost?: number;
356
358
  /**
357
359
  * @private
358
360
  * PRIVATE - DO NOT USE
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -408,7 +408,7 @@ function createRouter(init) {
408
408
  pendingPreventScrollReset = false;
409
409
  pendingViewTransitionEnabled = false;
410
410
  isUninterruptedRevalidation = false;
411
- isRevalidationRequired = false;
411
+ isRevalidationRequired = fetchReloadIds.size > 0;
412
412
  }
413
413
  async function navigate(to, opts) {
414
414
  if (pendingDiscoveryCancellation) await pendingDiscoveryCancellation;
@@ -446,8 +446,9 @@ function createRouter(init) {
446
446
  validateNavigationTarget(to == null ? init.history.createHref(state.location) : typeof to === "string" ? to : createPath(to), init.history.createHref(nextLocation.mask || nextLocation), init.history.createURL("/"), "reject");
447
447
  let userReplace = opts && opts.replace != null ? opts.replace : void 0;
448
448
  let historyAction = "PUSH";
449
+ let currentPath = state.location.pathname + state.location.search;
449
450
  if (userReplace === true) historyAction = "REPLACE";
450
- else if (userReplace === false) {} else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) historyAction = "REPLACE";
451
+ else if (userReplace === false) {} else if (submission != null && isMutationMethod(submission.formMethod) && (submission.formAction === currentPath || nextLocation.pathname + nextLocation.search === currentPath)) historyAction = "REPLACE";
451
452
  let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : void 0;
452
453
  let flushSync = (opts && opts.flushSync) === true;
453
454
  let blockerKey = shouldBlockNavigation({
@@ -789,12 +790,16 @@ function createRouter(init) {
789
790
  abortFetcher(rf.key);
790
791
  if (rf.controller) fetchControllers.set(rf.key, rf.controller);
791
792
  });
792
- let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));
793
+ let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => {
794
+ if (fetchControllers.get(rf.key) === rf.controller) abortFetcher(rf.key);
795
+ });
793
796
  if (pendingNavigationController) pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations);
794
797
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, request, location, scopedContext, dataStrategyInitiator, historyAction);
795
798
  if (request.signal.aborted) return { shortCircuited: true };
796
799
  if (pendingNavigationController) pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations);
797
- revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));
800
+ revalidatingFetchers.forEach((rf) => {
801
+ if (fetchControllers.get(rf.key) === rf.controller) fetchControllers.delete(rf.key);
802
+ });
798
803
  let redirect = findRedirect(loaderResults);
799
804
  if (redirect) {
800
805
  await startRedirectNavigation(request, redirect.result, true, dataStrategyInitiator, { replace });
@@ -923,30 +928,39 @@ function createRouter(init) {
923
928
  return;
924
929
  }
925
930
  if (fetchersQueuedForDeletion.has(key)) {
926
- if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {
931
+ if (isErrorResult(actionResult)) {
927
932
  updateFetcherState(key, getDoneFetcher(void 0));
928
933
  return;
929
934
  }
930
- } else {
931
935
  if (isRedirectResult(actionResult)) {
936
+ isRevalidationRequired = true;
937
+ actionResult = {
938
+ type: "data",
939
+ data: void 0
940
+ };
941
+ }
942
+ } else {
943
+ if (isRedirectResult(actionResult)) if (pendingNavigationLoadId > originatingLoadId) {
944
+ isRevalidationRequired = true;
945
+ actionResult = {
946
+ type: "data",
947
+ data: void 0
948
+ };
949
+ } else {
932
950
  fetchControllers.delete(key);
933
- if (pendingNavigationLoadId > originatingLoadId) {
934
- updateFetcherState(key, getDoneFetcher(void 0));
935
- return;
936
- } else {
937
- fetchRedirectIds.add(key);
938
- updateFetcherState(key, getLoadingFetcher(submission));
939
- return startRedirectNavigation(fetchRequest, actionResult, false, "fetcher", {
940
- fetcherSubmission: submission,
941
- preventScrollReset
942
- });
943
- }
951
+ fetchRedirectIds.add(key);
952
+ updateFetcherState(key, getLoadingFetcher(submission));
953
+ return startRedirectNavigation(fetchRequest, actionResult, false, "fetcher", {
954
+ fetcherSubmission: submission,
955
+ preventScrollReset
956
+ });
944
957
  }
945
958
  if (isErrorResult(actionResult)) {
946
959
  setFetcherError(key, routeId, actionResult.error);
947
960
  return;
948
961
  }
949
962
  }
963
+ isRevalidationRequired = true;
950
964
  let nextLocation = state.navigation.location || state.location;
951
965
  let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
952
966
  let matches = state.navigation.state !== "idle" ? dataRouteMatcher.match(state.navigation.location) : state.matches;
@@ -966,7 +980,9 @@ function createRouter(init) {
966
980
  if (rf.controller) fetchControllers.set(staleKey, rf.controller);
967
981
  });
968
982
  updateState({ fetchers: workingFetchers });
969
- let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));
983
+ let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => {
984
+ if (fetchControllers.get(rf.key) === rf.controller) abortFetcher(rf.key);
985
+ });
970
986
  abortController.signal.addEventListener("abort", abortPendingFetchRevalidations);
971
987
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, revalidationRequest, nextLocation, scopedContext, "fetcher");
972
988
  if (abortController.signal.aborted) {
@@ -976,7 +992,9 @@ function createRouter(init) {
976
992
  abortController.signal.removeEventListener("abort", abortPendingFetchRevalidations);
977
993
  fetchReloadIds.delete(key);
978
994
  fetchControllers.delete(key);
979
- revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));
995
+ revalidatingFetchers.forEach((r) => {
996
+ if (fetchControllers.get(r.key) === r.controller) fetchControllers.delete(r.key);
997
+ });
980
998
  let fetcherIsMounted = state.fetchers.has(key);
981
999
  let getRedirectStateWithDoneFetcher = (s) => {
982
1000
  if (!fetcherIsMounted) return s;
@@ -1005,6 +1023,7 @@ function createRouter(init) {
1005
1023
  if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) {
1006
1024
  invariant(pendingAction, "Expected pending action");
1007
1025
  pendingNavigationController && pendingNavigationController.abort();
1026
+ markFetchRedirectsDone(finalFetchers);
1008
1027
  completeNavigation(state.navigation.location, {
1009
1028
  matches,
1010
1029
  loaderData,
@@ -1017,7 +1036,7 @@ function createRouter(init) {
1017
1036
  loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors),
1018
1037
  fetchers: finalFetchers
1019
1038
  });
1020
- isRevalidationRequired = false;
1039
+ isRevalidationRequired = fetchReloadIds.size > 0;
1021
1040
  }
1022
1041
  }
1023
1042
  async function handleFetcherLoader(key, loadMatch, matches, scopedContext, flushSync, preventScrollReset, submission) {
@@ -1877,6 +1896,9 @@ function createStaticHandler(routes, opts) {
1877
1896
  }
1878
1897
  return {
1879
1898
  dataRoutes,
1899
+ get _matchCost() {
1900
+ return dataRouteMatcher instanceof V6RegExMatcher ? dataRouteMatcher.matchCost : void 0;
1901
+ },
1880
1902
  match,
1881
1903
  query,
1882
1904
  queryRoute
@@ -2262,6 +2284,9 @@ const loadLazyRouteProperty = ({ key, route, manifest, mapRouteProperties }) =>
2262
2284
  }
2263
2285
  })();
2264
2286
  cache[key] = propertyPromise;
2287
+ propertyPromise.catch(() => {
2288
+ if (cache[key] === propertyPromise) delete cache[key];
2289
+ });
2265
2290
  return propertyPromise;
2266
2291
  };
2267
2292
  const lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
@@ -2303,7 +2328,9 @@ function loadLazyRoute(route, type, manifest, mapRouteProperties, lazyRoutePrope
2303
2328
  });
2304
2329
  })();
2305
2330
  lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise);
2306
- lazyRoutePromise.catch(() => {});
2331
+ lazyRoutePromise.catch(() => {
2332
+ if (lazyRouteFunctionCache.get(routeToUpdate) === lazyRoutePromise) lazyRouteFunctionCache.delete(routeToUpdate);
2333
+ });
2307
2334
  return {
2308
2335
  lazyRoutePromise,
2309
2336
  lazyHandlerPromise: lazyRoutePromise
@@ -2595,10 +2622,13 @@ async function callLoaderOrAction({ request, path, pattern, match, lazyHandlerPr
2595
2622
  pathname,
2596
2623
  routeId: match.route.id
2597
2624
  });
2598
- } else return {
2599
- type: "data",
2600
- result: void 0
2601
- };
2625
+ } else {
2626
+ await lazyRoutePromise;
2627
+ return {
2628
+ type: "data",
2629
+ result: void 0
2630
+ };
2631
+ }
2602
2632
  }
2603
2633
  else if (!handler) {
2604
2634
  let url = new URL(request.url);
@@ -2793,12 +2823,12 @@ function processRouteLoaderData(matches, results, pendingActionResult, isStaticH
2793
2823
  function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults, workingFetchers) {
2794
2824
  let { loaderData, errors } = processRouteLoaderData(matches, results, pendingActionResult);
2795
2825
  revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {
2796
- let { key, match, controller } = rf;
2826
+ let { key, routeId, controller } = rf;
2797
2827
  if (controller && controller.signal.aborted) return;
2798
2828
  let result = fetcherResults[key];
2799
2829
  invariant(result, "Did not find corresponding fetcher result");
2800
2830
  if (isErrorResult(result)) {
2801
- let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);
2831
+ let boundaryMatch = findNearestBoundary(state.matches, routeId);
2802
2832
  if (!(errors && errors[boundaryMatch.route.id])) errors = {
2803
2833
  ...errors,
2804
2834
  [boundaryMatch.route.id]: result.error
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -185,6 +185,13 @@ interface DataFunctionArgs<Context> {
185
185
  * In Framework mode, this is a normalized URL with React-Router-specific
186
186
  * implementation details removed (`.data` suffixes, `index`/`_routes` search
187
187
  * params). For the raw incoming URL, use `request.url`.
188
+ *
189
+ * This normalization preserves standard URL pathname encoding and casing.
190
+ * For example, a request to `/%61dmin.data` produces a `url.pathname` of
191
+ * `/%61dmin`. This is not a canonical representation of the matched route.
192
+ * For authorization, attach {@link https://reactrouter.com/how-to/middleware#authentication server middleware}
193
+ * to the protected route or a common ancestor instead of relying on literal
194
+ * pathname-prefix comparisons.
188
195
  */
189
196
  url: URL;
190
197
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -17,7 +17,7 @@ import { RSCRouterContext } from "../context.js";
17
17
  import { createRequestInit } from "../dom/ssr/data.js";
18
18
  import { getSingleFetchDataStrategyImpl, singleFetchUrl, stripIndexParam } from "../dom/ssr/single-fetch.js";
19
19
  import { noActionDefinedError, shouldHydrateRouteLoader } from "../dom/ssr/routes.js";
20
- import { getPathsWithAncestors, handleClientVersionMismatch } from "../dom/ssr/fog-of-war.js";
20
+ import { getManifestPathsParam, getPathsWithAncestors, handleClientVersionMismatch } from "../dom/ssr/fog-of-war.js";
21
21
  import { FrameworkContext, setIsHydrated } from "../dom/ssr/components.js";
22
22
  import { RouterProvider } from "../components.js";
23
23
  import { RSCRouterGlobalErrorBoundary } from "./errorBoundaries.js";
@@ -539,7 +539,7 @@ function getManifestUrl(paths, clientVersion) {
539
539
  else {
540
540
  let basename = (window.__reactRouterDataRouter.basename ?? "").replace(/^\/|\/$/g, "");
541
541
  url = new URL(`${basename}/.manifest`, window.location.origin);
542
- url.searchParams.set("paths", paths.sort().join(","));
542
+ url.searchParams.set("paths", getManifestPathsParam(paths));
543
543
  }
544
544
  if (clientVersion !== void 0) url.searchParams.set("version", clientVersion);
545
545
  return url;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -11,7 +11,7 @@
11
11
  import { ErrorResponseImpl, RouterContextProvider, createDataFunctionUrl, defaultMapRouteProperties, getRoutePattern, isRouteErrorResponse, removeTrailingSlash, stripBasename } from "../router/utils.js";
12
12
  import { instrumentHandler, instrumentationResultMetaContext } from "../router/instrumentation.js";
13
13
  import { createStaticHandler, getStaticContextFromError, isMutationMethod, isRedirectResponse, isResponse } from "../router/router.js";
14
- import { getManifestPath } from "../dom/ssr/fog-of-war.js";
14
+ import { getManifestPath, isFogOfWarEnabled, shouldUseInitialRouteDiscovery } from "../dom/ssr/fog-of-war.js";
15
15
  import { createEntryRouteModules } from "./entry.js";
16
16
  import { isServerMode } from "./mode.js";
17
17
  import { sanitizeErrors, serializeError } from "./errors.js";
@@ -59,7 +59,10 @@ function derive(build, mode) {
59
59
  let normalizedPathname = normalizedPath.pathname;
60
60
  let isSpaMode = getBuildTimeHeader(request, "X-React-Router-SPA-Mode") === "yes";
61
61
  if (!build.ssr || build.unstable_apiOnly) {
62
- let decodedPath = decodeURI(normalizedPathname);
62
+ let decodedPath = normalizedPathname;
63
+ try {
64
+ decodedPath = decodeURI(normalizedPathname);
65
+ } catch {}
63
66
  if (build.basename && build.basename !== "/") {
64
67
  let strippedPath = stripBasename(decodedPath, build.basename);
65
68
  if (strippedPath == null) {
@@ -251,10 +254,15 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
251
254
  actionData: context.actionData,
252
255
  errors: context.errors
253
256
  };
257
+ let routeDiscovery = build.routeDiscovery;
258
+ if (isFogOfWarEnabled(routeDiscovery, build.ssr) && shouldUseInitialRouteDiscovery(context.location.pathname, staticHandler._matchCost)) routeDiscovery = {
259
+ ...routeDiscovery,
260
+ mode: "initial"
261
+ };
254
262
  let baseServerHandoff = {
255
263
  basename: build.basename,
256
264
  future: build.future,
257
- routeDiscovery: build.routeDiscovery,
265
+ routeDiscovery,
258
266
  ssr: build.ssr,
259
267
  isSpaMode,
260
268
  unstable_apiOnly: build.unstable_apiOnly,
@@ -274,7 +282,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
274
282
  renderMeta: {},
275
283
  future: build.future,
276
284
  ssr: build.ssr,
277
- routeDiscovery: build.routeDiscovery,
285
+ routeDiscovery,
278
286
  isSpaMode,
279
287
  unstable_apiOnly: build.unstable_apiOnly,
280
288
  unstable_apiServerOrigin: build.unstable_apiServerOrigin,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -99,7 +99,7 @@ function createSessionStorage({ cookie: cookieArg, createData, readData, updateD
99
99
  return cookie.serialize(id, options);
100
100
  },
101
101
  async destroySession(session, options) {
102
- await deleteData(session.id);
102
+ if (session.id) await deleteData(session.id);
103
103
  return cookie.serialize("", {
104
104
  ...options,
105
105
  maxAge: void 0,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *