react-router 7.9.1 → 7.9.2-pre.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 (58) hide show
  1. package/CHANGELOG.md +25 -9
  2. package/dist/development/{chunk-B7RQU5TL.mjs → chunk-I4PRIPRX.mjs} +178 -26
  3. package/dist/{production/chunk-RCAZODXZ.mjs → development/chunk-ITFVGECV.mjs} +155 -65
  4. package/dist/development/{chunk-PW3F6ATG.js → chunk-MVCD4EFU.js} +102 -70
  5. package/dist/{production/chunk-3SXVZXGI.js → development/chunk-XCFBICS6.js} +277 -157
  6. package/dist/development/{context-CIdFp11b.d.mts → context-BqL5Eckq.d.mts} +20 -0
  7. package/dist/development/dom-export.d.mts +1 -1
  8. package/dist/development/dom-export.js +3 -3
  9. package/dist/development/dom-export.mjs +3 -3
  10. package/dist/development/{index-react-server-client-BeVfPpWg.d.mts → index-react-server-client-2EDmGlsZ.d.mts} +40 -24
  11. package/dist/{production/index-react-server-client-BYr9g50r.d.ts → development/index-react-server-client-DKvU8YRr.d.ts} +39 -23
  12. package/dist/development/index-react-server-client.d.mts +3 -3
  13. package/dist/development/index-react-server-client.d.ts +2 -2
  14. package/dist/development/index-react-server-client.js +4 -4
  15. package/dist/development/index-react-server-client.mjs +2 -2
  16. package/dist/development/index-react-server.d.mts +10 -0
  17. package/dist/development/index-react-server.d.ts +10 -0
  18. package/dist/development/index-react-server.js +3 -3
  19. package/dist/development/index-react-server.mjs +3 -3
  20. package/dist/development/index.d.mts +16 -12
  21. package/dist/development/index.d.ts +14 -10
  22. package/dist/development/index.js +250 -160
  23. package/dist/development/index.mjs +3 -3
  24. package/dist/development/lib/types/internal.d.mts +2 -2
  25. package/dist/development/lib/types/internal.d.ts +1 -1
  26. package/dist/development/lib/types/internal.js +1 -1
  27. package/dist/development/lib/types/internal.mjs +1 -1
  28. package/dist/development/{route-data-Bpm4liR_.d.mts → route-data-CDwqkzPE.d.mts} +1 -1
  29. package/dist/{production/routeModules-DnUHijGz.d.ts → development/routeModules-BmVo7q9e.d.ts} +20 -0
  30. package/dist/production/{chunk-HMYSPRGR.js → chunk-4FAGWJMT.js} +102 -70
  31. package/dist/{development/chunk-LWNHKVDL.js → production/chunk-MKNSEQLS.js} +277 -157
  32. package/dist/{development/chunk-SKNKB5VI.mjs → production/chunk-RXSRHQUT.mjs} +155 -65
  33. package/dist/production/{chunk-P25HWPOZ.mjs → chunk-SKKC22F5.mjs} +178 -26
  34. package/dist/production/{context-CIdFp11b.d.mts → context-BqL5Eckq.d.mts} +20 -0
  35. package/dist/production/dom-export.d.mts +1 -1
  36. package/dist/production/dom-export.js +3 -3
  37. package/dist/production/dom-export.mjs +3 -3
  38. package/dist/production/{index-react-server-client-BeVfPpWg.d.mts → index-react-server-client-2EDmGlsZ.d.mts} +40 -24
  39. package/dist/{development/index-react-server-client-BYr9g50r.d.ts → production/index-react-server-client-DKvU8YRr.d.ts} +39 -23
  40. package/dist/production/index-react-server-client.d.mts +3 -3
  41. package/dist/production/index-react-server-client.d.ts +2 -2
  42. package/dist/production/index-react-server-client.js +4 -4
  43. package/dist/production/index-react-server-client.mjs +2 -2
  44. package/dist/production/index-react-server.d.mts +10 -0
  45. package/dist/production/index-react-server.d.ts +10 -0
  46. package/dist/production/index-react-server.js +3 -3
  47. package/dist/production/index-react-server.mjs +3 -3
  48. package/dist/production/index.d.mts +16 -12
  49. package/dist/production/index.d.ts +14 -10
  50. package/dist/production/index.js +250 -160
  51. package/dist/production/index.mjs +3 -3
  52. package/dist/production/lib/types/internal.d.mts +2 -2
  53. package/dist/production/lib/types/internal.d.ts +1 -1
  54. package/dist/production/lib/types/internal.js +1 -1
  55. package/dist/production/lib/types/internal.mjs +1 -1
  56. package/dist/production/{route-data-Bpm4liR_.d.mts → route-data-CDwqkzPE.d.mts} +1 -1
  57. package/dist/{development/routeModules-DnUHijGz.d.ts → production/routeModules-BmVo7q9e.d.ts} +20 -0
  58. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # `react-router`
2
2
 
3
+ ## 7.9.2-pre.1
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: enable full transition support for the rsc router ([#14362](https://github.com/remix-run/react-router/pull/14362))
8
+
9
+ ## 7.9.2-pre.0
10
+
11
+ ### Patch Changes
12
+
13
+ - - Update client-side router to run client `middleware` on initial load even if no loaders exist ([#14348](https://github.com/remix-run/react-router/pull/14348))
14
+ - Update `createRoutesStub` to run route middleware
15
+ - You will need to set the `<RoutesStub future={{ v8_middleware: true }} />` flag to enable the proper `context` type
16
+ - Update Lazy Route Discovery manifest requests to use a singular comma-separated `paths` query param instead of repeated `p` query params ([#14321](https://github.com/remix-run/react-router/pull/14321))
17
+ - This is because Cloudflare has a hard limit of 100 URL search param key/value pairs when used as a key for caching purposes
18
+ - If more that 100 paths were included, the cache key would be incomplete and could produce false-positive cache hits
19
+
20
+ - [UNSTABLE] Add `fetcher.unstable_reset()` API ([#14206](https://github.com/remix-run/react-router/pull/14206))
21
+ - Made useOutlet element reference have stable identity in-between route chages ([#13382](https://github.com/remix-run/react-router/pull/13382))
22
+ - In RSC Data Mode, handle SSR'd client errors and re-try in the browser ([#14342](https://github.com/remix-run/react-router/pull/14342))
23
+ - Support `middleware` prop on `<Route>` for usage with a data router via `createRoutesFromElements` ([#14357](https://github.com/remix-run/react-router/pull/14357))
24
+ - Handle encoded question mark and hash characters in ancestor splat routes ([#14249](https://github.com/remix-run/react-router/pull/14249))
25
+ - Fail gracefully on manifest version mismatch logic if `sessionStorage` access is blocked ([#14335](https://github.com/remix-run/react-router/pull/14335))
26
+
3
27
  ## 7.9.1
4
28
 
5
29
  ### Patch Changes
@@ -13,7 +37,6 @@
13
37
  - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215))
14
38
 
15
39
  We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use:
16
-
17
40
  - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider)
18
41
  - [`createContext`](https://reactrouter.com/api/utils/createContext)
19
42
  - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option
@@ -40,7 +63,7 @@
40
63
 
41
64
  - \[UNSTABLE] Add `<RouterProvider unstable_onError>`/`<HydratedRouter unstable_onError>` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162))
42
65
 
43
- - server action revalidation opt out via $SKIP\_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154))
66
+ - server action revalidation opt out via $SKIP_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154))
44
67
 
45
68
  - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530))
46
69
 
@@ -89,7 +112,6 @@
89
112
  - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059))
90
113
 
91
114
  - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206))
92
-
93
115
  - When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary
94
116
  - The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered
95
117
  - ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios.
@@ -123,7 +145,6 @@
123
145
  - \[UNSTABLE] When middleware is enabled, make the `context` parameter read-only (via `Readonly<unstable_RouterContextProvider>`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097))
124
146
 
125
147
  - \[UNSTABLE] Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103))
126
-
127
148
  - The API has been renamed to `unstable_generateMiddlewareResponse` for clarity
128
149
  - The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling
129
150
  - The `query` version of the API now has a signature of `(query: (r: Request) => Promise<StaticHandlerContext | Response>) => Promise<Response>`
@@ -769,7 +790,6 @@
769
790
  ```
770
791
 
771
792
  Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app:
772
-
773
793
  - Library mode - `createBrowserRouter(routes, { unstable_getContext })`
774
794
  - Framework mode - `<HydratedRouter unstable_getContext>`
775
795
 
@@ -957,7 +977,6 @@ _No changes_
957
977
  - Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697))
958
978
 
959
979
  - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837))
960
-
961
980
  - `createCookie`
962
981
  - `createCookieSessionStorage`
963
982
  - `createMemorySessionStorage`
@@ -966,7 +985,6 @@ _No changes_
966
985
  For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html)
967
986
 
968
987
  Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed:
969
-
970
988
  - `createCookieFactory`
971
989
  - `createSessionStorageFactory`
972
990
  - `createCookieSessionStorageFactory`
@@ -1122,7 +1140,6 @@ _No changes_
1122
1140
  ```
1123
1141
 
1124
1142
  This initial implementation targets type inference for:
1125
-
1126
1143
  - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
1127
1144
  - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
1128
1145
  - `ActionData` : Action data from `action` and/or `clientAction` within your route module
@@ -1137,7 +1154,6 @@ _No changes_
1137
1154
  ```
1138
1155
 
1139
1156
  Check out our docs for more:
1140
-
1141
1157
  - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety)
1142
1158
  - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety)
1143
1159
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.9.1
2
+ * react-router v7.9.2-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1054,7 +1054,7 @@ function createRouter(init) {
1054
1054
  }
1055
1055
  } else if (initialMatches.some((m) => m.route.lazy)) {
1056
1056
  initialized = false;
1057
- } else if (!initialMatches.some((m) => m.route.loader)) {
1057
+ } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) {
1058
1058
  initialized = true;
1059
1059
  } else {
1060
1060
  let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
@@ -1756,7 +1756,9 @@ function createRouter(init) {
1756
1756
  pendingActionResult
1757
1757
  );
1758
1758
  pendingNavigationLoadId = ++incrementingLoadId;
1759
- if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some((m) => m.route.middleware) && revalidatingFetchers.length === 0) {
1759
+ if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some(
1760
+ (m) => m.route.middleware && m.route.middleware.length > 0
1761
+ ) && revalidatingFetchers.length === 0) {
1760
1762
  let updatedFetchers2 = markFetchRedirectsDone();
1761
1763
  completeNavigation(
1762
1764
  location,
@@ -2437,6 +2439,10 @@ function createRouter(init) {
2437
2439
  }
2438
2440
  return state.fetchers.get(key) || IDLE_FETCHER;
2439
2441
  }
2442
+ function resetFetcher(key, opts) {
2443
+ abortFetcher(key, opts?.reason);
2444
+ updateFetcherState(key, getDoneFetcher(null));
2445
+ }
2440
2446
  function deleteFetcher(key) {
2441
2447
  let fetcher = state.fetchers.get(key);
2442
2448
  if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) {
@@ -2459,10 +2465,10 @@ function createRouter(init) {
2459
2465
  }
2460
2466
  updateState({ fetchers: new Map(state.fetchers) });
2461
2467
  }
2462
- function abortFetcher(key) {
2468
+ function abortFetcher(key, reason) {
2463
2469
  let controller = fetchControllers.get(key);
2464
2470
  if (controller) {
2465
- controller.abort();
2471
+ controller.abort(reason);
2466
2472
  fetchControllers.delete(key);
2467
2473
  }
2468
2474
  }
@@ -2726,6 +2732,7 @@ function createRouter(init) {
2726
2732
  createHref: (to) => init.history.createHref(to),
2727
2733
  encodeLocation: (to) => init.history.encodeLocation(to),
2728
2734
  getFetcher,
2735
+ resetFetcher,
2729
2736
  deleteFetcher: queueFetcherForDeletion,
2730
2737
  dispose,
2731
2738
  getBlocker,
@@ -3541,7 +3548,7 @@ function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest,
3541
3548
  forceShouldLoad = false;
3542
3549
  } else if (route.lazy) {
3543
3550
  forceShouldLoad = true;
3544
- } else if (route.loader == null) {
3551
+ } else if (!routeHasLoaderOrMiddleware(route)) {
3545
3552
  forceShouldLoad = false;
3546
3553
  } else if (initialHydration) {
3547
3554
  forceShouldLoad = shouldLoadRouteOnHydration(
@@ -3673,11 +3680,14 @@ function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest,
3673
3680
  });
3674
3681
  return { dsMatches, revalidatingFetchers };
3675
3682
  }
3683
+ function routeHasLoaderOrMiddleware(route) {
3684
+ return route.loader != null || route.middleware != null && route.middleware.length > 0;
3685
+ }
3676
3686
  function shouldLoadRouteOnHydration(route, loaderData, errors) {
3677
3687
  if (route.lazy) {
3678
3688
  return true;
3679
3689
  }
3680
- if (!route.loader) {
3690
+ if (!routeHasLoaderOrMiddleware(route)) {
3681
3691
  return false;
3682
3692
  }
3683
3693
  let hasData = loaderData != null && route.id in loaderData;
@@ -4006,9 +4016,15 @@ function runClientMiddlewarePipeline(args, handler) {
4006
4016
  let { matches } = args;
4007
4017
  let maxBoundaryIdx = Math.min(
4008
4018
  // Throwing route
4009
- matches.findIndex((m) => m.route.id === routeId) || 0,
4019
+ Math.max(
4020
+ matches.findIndex((m) => m.route.id === routeId),
4021
+ 0
4022
+ ),
4010
4023
  // or the shallowest route that needs to load data
4011
- matches.findIndex((m) => m.unstable_shouldCallHandler()) || 0
4024
+ Math.max(
4025
+ matches.findIndex((m) => m.unstable_shouldCallHandler()),
4026
+ 0
4027
+ )
4012
4028
  );
4013
4029
  let boundaryRouteId = findNearestBoundary(
4014
4030
  matches,
@@ -5056,10 +5072,10 @@ function useOutletContext() {
5056
5072
  }
5057
5073
  function useOutlet(context) {
5058
5074
  let outlet = React2.useContext(RouteContext).outlet;
5059
- if (outlet) {
5060
- return /* @__PURE__ */ React2.createElement(OutletContext.Provider, { value: context }, outlet);
5061
- }
5062
- return outlet;
5075
+ return React2.useMemo(
5076
+ () => outlet && /* @__PURE__ */ React2.createElement(OutletContext.Provider, { value: context }, outlet),
5077
+ [outlet, context]
5078
+ );
5063
5079
  }
5064
5080
  function useParams() {
5065
5081
  let { matches } = React2.useContext(RouteContext);
@@ -5143,13 +5159,23 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
5143
5159
  params: Object.assign({}, parentParams, match.params),
5144
5160
  pathname: joinPaths([
5145
5161
  parentPathnameBase,
5146
- // Re-encode pathnames that were decoded inside matchRoutes
5147
- navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname
5162
+ // Re-encode pathnames that were decoded inside matchRoutes.
5163
+ // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
5164
+ // `new URL()` internally and we need to prevent it from treating
5165
+ // them as separators
5166
+ navigator.encodeLocation ? navigator.encodeLocation(
5167
+ match.pathname.replace(/\?/g, "%3F").replace(/#/g, "%23")
5168
+ ).pathname : match.pathname
5148
5169
  ]),
5149
5170
  pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([
5150
5171
  parentPathnameBase,
5151
5172
  // Re-encode pathnames that were decoded inside matchRoutes
5152
- navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase
5173
+ // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
5174
+ // `new URL()` internally and we need to prevent it from treating
5175
+ // them as separators
5176
+ navigator.encodeLocation ? navigator.encodeLocation(
5177
+ match.pathnameBase.replace(/\?/g, "%3F").replace(/#/g, "%23")
5178
+ ).pathname : match.pathnameBase
5153
5179
  ])
5154
5180
  })
5155
5181
  ),
@@ -5627,6 +5653,119 @@ var Deferred = class {
5627
5653
  });
5628
5654
  }
5629
5655
  };
5656
+ function shallowDiff(a, b) {
5657
+ if (a === b) {
5658
+ return false;
5659
+ }
5660
+ let aKeys = Object.keys(a);
5661
+ let bKeys = Object.keys(b);
5662
+ if (aKeys.length !== bKeys.length) {
5663
+ return true;
5664
+ }
5665
+ for (let key of aKeys) {
5666
+ if (a[key] !== b[key]) {
5667
+ return true;
5668
+ }
5669
+ }
5670
+ return false;
5671
+ }
5672
+ function UNSTABLE_TransitionEnabledRouterProvider({
5673
+ router,
5674
+ flushSync: reactDomFlushSyncImpl,
5675
+ unstable_onError
5676
+ }) {
5677
+ let fetcherData = React3.useRef(/* @__PURE__ */ new Map());
5678
+ let [revalidating, startRevalidation] = React3.useTransition();
5679
+ let [state, setState] = React3.useState(router.state);
5680
+ router.__setPendingRerender = (promise) => startRevalidation(
5681
+ // @ts-expect-error - need react 19 types for this to be async
5682
+ async () => {
5683
+ const rerender = await promise;
5684
+ startRevalidation(() => {
5685
+ rerender();
5686
+ });
5687
+ }
5688
+ );
5689
+ let navigator = React3.useMemo(() => {
5690
+ return {
5691
+ createHref: router.createHref,
5692
+ encodeLocation: router.encodeLocation,
5693
+ go: (n) => router.navigate(n),
5694
+ push: (to, state2, opts) => router.navigate(to, {
5695
+ state: state2,
5696
+ preventScrollReset: opts?.preventScrollReset
5697
+ }),
5698
+ replace: (to, state2, opts) => router.navigate(to, {
5699
+ replace: true,
5700
+ state: state2,
5701
+ preventScrollReset: opts?.preventScrollReset
5702
+ })
5703
+ };
5704
+ }, [router]);
5705
+ let basename = router.basename || "/";
5706
+ let dataRouterContext = React3.useMemo(
5707
+ () => ({
5708
+ router,
5709
+ navigator,
5710
+ static: false,
5711
+ basename,
5712
+ unstable_onError
5713
+ }),
5714
+ [router, navigator, basename, unstable_onError]
5715
+ );
5716
+ React3.useLayoutEffect(() => {
5717
+ return router.subscribe(
5718
+ (newState, { deletedFetchers, flushSync, viewTransitionOpts }) => {
5719
+ newState.fetchers.forEach((fetcher, key) => {
5720
+ if (fetcher.data !== void 0) {
5721
+ fetcherData.current.set(key, fetcher.data);
5722
+ }
5723
+ });
5724
+ deletedFetchers.forEach((key) => fetcherData.current.delete(key));
5725
+ const diff = shallowDiff(state, newState);
5726
+ if (!diff) return;
5727
+ if (flushSync) {
5728
+ if (reactDomFlushSyncImpl) {
5729
+ reactDomFlushSyncImpl(() => setState(newState));
5730
+ } else {
5731
+ setState(newState);
5732
+ }
5733
+ } else {
5734
+ React3.startTransition(() => {
5735
+ setState(newState);
5736
+ });
5737
+ }
5738
+ }
5739
+ );
5740
+ }, [router, reactDomFlushSyncImpl, state]);
5741
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React3.createElement(
5742
+ DataRouterStateContext.Provider,
5743
+ {
5744
+ value: {
5745
+ ...state,
5746
+ revalidation: revalidating ? "loading" : state.revalidation
5747
+ }
5748
+ },
5749
+ /* @__PURE__ */ React3.createElement(FetchersContext.Provider, { value: fetcherData.current }, /* @__PURE__ */ React3.createElement(
5750
+ Router,
5751
+ {
5752
+ basename,
5753
+ location: state.location,
5754
+ navigationType: state.historyAction,
5755
+ navigator
5756
+ },
5757
+ /* @__PURE__ */ React3.createElement(
5758
+ MemoizedDataRoutes,
5759
+ {
5760
+ routes: router.routes,
5761
+ future: router.future,
5762
+ state,
5763
+ unstable_onError
5764
+ }
5765
+ )
5766
+ ))
5767
+ )), null);
5768
+ }
5630
5769
  function RouterProvider({
5631
5770
  router,
5632
5771
  flushSync: reactDomFlushSyncImpl,
@@ -6083,6 +6222,7 @@ function createRoutesFromChildren(children, parentPath = []) {
6083
6222
  Component: element.props.Component,
6084
6223
  index: element.props.index,
6085
6224
  path: element.props.path,
6225
+ middleware: element.props.middleware,
6086
6226
  loader: element.props.loader,
6087
6227
  action: element.props.action,
6088
6228
  hydrateFallbackElement: element.props.hydrateFallbackElement,
@@ -8262,7 +8402,7 @@ function getManifestPath(_manifestPath, basename) {
8262
8402
  var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
8263
8403
  async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
8264
8404
  const searchParams = new URLSearchParams();
8265
- paths.sort().forEach((path) => searchParams.append("p", path));
8405
+ searchParams.set("paths", paths.sort().join(","));
8266
8406
  searchParams.set("version", manifest.version);
8267
8407
  let url = new URL(
8268
8408
  getManifestPath(manifestPath, basename),
@@ -8285,13 +8425,16 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
8285
8425
  );
8286
8426
  return;
8287
8427
  }
8288
- if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
8289
- console.error(
8290
- "Unable to discover routes due to manifest version mismatch."
8291
- );
8292
- return;
8428
+ try {
8429
+ if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
8430
+ console.error(
8431
+ "Unable to discover routes due to manifest version mismatch."
8432
+ );
8433
+ return;
8434
+ }
8435
+ sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
8436
+ } catch {
8293
8437
  }
8294
- sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
8295
8438
  window.location.href = errorReloadPath;
8296
8439
  console.warn("Detected manifest version mismatch, reloading...");
8297
8440
  await new Promise(() => {
@@ -8299,7 +8442,10 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
8299
8442
  } else if (res.status >= 400) {
8300
8443
  throw new Error(await res.text());
8301
8444
  }
8302
- sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
8445
+ try {
8446
+ sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
8447
+ } catch {
8448
+ }
8303
8449
  serverPatches = await res.json();
8304
8450
  } catch (e) {
8305
8451
  if (signal?.aborted) return;
@@ -8964,7 +9110,7 @@ var isBrowser = typeof window !== "undefined" && typeof window.document !== "und
8964
9110
  try {
8965
9111
  if (isBrowser) {
8966
9112
  window.__reactRouterVersion = // @ts-expect-error
8967
- "7.9.1";
9113
+ "7.9.2-pre.1";
8968
9114
  }
8969
9115
  } catch (e) {
8970
9116
  }
@@ -9578,6 +9724,7 @@ function useFetcher({
9578
9724
  },
9579
9725
  [fetcherKey, submitImpl]
9580
9726
  );
9727
+ let unstable_reset = React10.useCallback((opts) => router.resetFetcher(fetcherKey, opts), [router, fetcherKey]);
9581
9728
  let FetcherForm = React10.useMemo(() => {
9582
9729
  let FetcherForm2 = React10.forwardRef(
9583
9730
  (props, ref) => {
@@ -9594,10 +9741,11 @@ function useFetcher({
9594
9741
  Form: FetcherForm,
9595
9742
  submit,
9596
9743
  load,
9744
+ unstable_reset,
9597
9745
  ...fetcher,
9598
9746
  data: data2
9599
9747
  }),
9600
- [FetcherForm, submit, load, fetcher, data2]
9748
+ [FetcherForm, submit, load, unstable_reset, fetcher, data2]
9601
9749
  );
9602
9750
  return fetcherWithComponents;
9603
9751
  }
@@ -10008,6 +10156,9 @@ function createStaticRouter(routes, context, opts = {}) {
10008
10156
  deleteFetcher() {
10009
10157
  throw msg("deleteFetcher");
10010
10158
  },
10159
+ resetFetcher() {
10160
+ throw msg("resetFetcher");
10161
+ },
10011
10162
  dispose() {
10012
10163
  throw msg("dispose");
10013
10164
  },
@@ -10121,6 +10272,7 @@ export {
10121
10272
  mapRouteProperties,
10122
10273
  hydrationRouteProperties,
10123
10274
  createMemoryRouter,
10275
+ UNSTABLE_TransitionEnabledRouterProvider,
10124
10276
  RouterProvider,
10125
10277
  MemoryRouter,
10126
10278
  Navigate,