react-router 7.14.0 → 7.14.2

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 (72) hide show
  1. package/CHANGELOG.md +63 -24
  2. package/dist/development/{browser-C9Ar1yxG.d.ts → browser-C-UvoYvi.d.ts} +2 -2
  3. package/dist/development/{browser-vtIR1Kpe.d.mts → browser-I6n6wVSO.d.mts} +2 -2
  4. package/dist/development/{chunk-QFMPRPBF.mjs → chunk-EVOBXE3Y.mjs} +45 -19
  5. package/dist/development/{chunk-WAVMRYR2.js → chunk-PZFPF4X7.js} +7 -7
  6. package/dist/{production/chunk-X5LK27NZ.mjs → development/chunk-YQSHRJWW.mjs} +3 -3
  7. package/dist/{production/chunk-FPT5DLVJ.js → development/chunk-YZKCRDTN.js} +99 -99
  8. package/dist/development/{chunk-IK6APEEG.js → chunk-ZZNWZ5Q3.js} +82 -56
  9. package/dist/{production/context-phCt_zmH.d.mts → development/context-DGGUoDIu.d.mts} +1 -1
  10. package/dist/development/dom-export.d.mts +4 -4
  11. package/dist/development/dom-export.d.ts +4 -4
  12. package/dist/development/dom-export.js +27 -27
  13. package/dist/development/dom-export.mjs +3 -3
  14. package/dist/development/{index-react-server-client-luDbagNU.d.ts → index-react-server-client-BBd0A0TL.d.ts} +2 -2
  15. package/dist/{production/index-react-server-client-BwWaHAr3.d.mts → development/index-react-server-client-BjhKIe3u.d.mts} +2 -2
  16. package/dist/development/index-react-server-client.d.mts +3 -3
  17. package/dist/development/index-react-server-client.d.ts +3 -3
  18. package/dist/development/index-react-server-client.js +4 -4
  19. package/dist/development/index-react-server-client.mjs +2 -2
  20. package/dist/development/index-react-server.d.mts +6 -0
  21. package/dist/development/index-react-server.d.ts +6 -0
  22. package/dist/development/index-react-server.js +9 -6
  23. package/dist/development/index-react-server.mjs +9 -6
  24. package/dist/development/index.d.mts +11 -11
  25. package/dist/development/index.d.ts +11 -11
  26. package/dist/development/index.js +96 -96
  27. package/dist/development/index.mjs +3 -3
  28. package/dist/{production/instrumentation-BYr6ff5D.d.ts → development/instrumentation-g0dG8UL0.d.ts} +1 -1
  29. package/dist/development/lib/types/internal.d.mts +2 -2
  30. package/dist/development/lib/types/internal.d.ts +2 -2
  31. package/dist/development/lib/types/internal.js +1 -1
  32. package/dist/development/lib/types/internal.mjs +1 -1
  33. package/dist/development/{register-CTxsJBKQ.d.mts → register-D9d2sMQ7.d.mts} +1 -1
  34. package/dist/development/{register-CkcGwv27.d.ts → register-DcBltf5q.d.ts} +1 -1
  35. package/dist/development/{routeModules-CA7kSxJJ.d.ts → routeModules-7rtk67cd.d.ts} +32 -11
  36. package/dist/development/{routeModules-BRrCYrSL.d.mts → routeModules-BW4a8k3I.d.mts} +32 -11
  37. package/dist/production/{browser-C9Ar1yxG.d.ts → browser-C-UvoYvi.d.ts} +2 -2
  38. package/dist/production/{browser-vtIR1Kpe.d.mts → browser-I6n6wVSO.d.mts} +2 -2
  39. package/dist/{development/chunk-2UH5WJXA.mjs → production/chunk-2WLZNCK5.mjs} +3 -3
  40. package/dist/production/{chunk-HZQGQD2X.mjs → chunk-LK6U7ULH.mjs} +45 -19
  41. package/dist/production/{chunk-355DUZMC.js → chunk-PQL4HLVQ.js} +7 -7
  42. package/dist/{development/chunk-NXTEWSJO.js → production/chunk-UJQ4OJF4.js} +99 -99
  43. package/dist/production/{chunk-4TJ7T2OQ.js → chunk-X5SKXJ4A.js} +82 -56
  44. package/dist/{development/context-phCt_zmH.d.mts → production/context-DGGUoDIu.d.mts} +1 -1
  45. package/dist/production/dom-export.d.mts +4 -4
  46. package/dist/production/dom-export.d.ts +4 -4
  47. package/dist/production/dom-export.js +27 -27
  48. package/dist/production/dom-export.mjs +3 -3
  49. package/dist/production/{index-react-server-client-luDbagNU.d.ts → index-react-server-client-BBd0A0TL.d.ts} +2 -2
  50. package/dist/{development/index-react-server-client-BwWaHAr3.d.mts → production/index-react-server-client-BjhKIe3u.d.mts} +2 -2
  51. package/dist/production/index-react-server-client.d.mts +3 -3
  52. package/dist/production/index-react-server-client.d.ts +3 -3
  53. package/dist/production/index-react-server-client.js +4 -4
  54. package/dist/production/index-react-server-client.mjs +2 -2
  55. package/dist/production/index-react-server.d.mts +6 -0
  56. package/dist/production/index-react-server.d.ts +6 -0
  57. package/dist/production/index-react-server.js +9 -6
  58. package/dist/production/index-react-server.mjs +9 -6
  59. package/dist/production/index.d.mts +11 -11
  60. package/dist/production/index.d.ts +11 -11
  61. package/dist/production/index.js +96 -96
  62. package/dist/production/index.mjs +3 -3
  63. package/dist/{development/instrumentation-BYr6ff5D.d.ts → production/instrumentation-g0dG8UL0.d.ts} +1 -1
  64. package/dist/production/lib/types/internal.d.mts +2 -2
  65. package/dist/production/lib/types/internal.d.ts +2 -2
  66. package/dist/production/lib/types/internal.js +1 -1
  67. package/dist/production/lib/types/internal.mjs +1 -1
  68. package/dist/production/{register-CTxsJBKQ.d.mts → register-D9d2sMQ7.d.mts} +1 -1
  69. package/dist/production/{register-CkcGwv27.d.ts → register-DcBltf5q.d.ts} +1 -1
  70. package/dist/production/{routeModules-CA7kSxJJ.d.ts → routeModules-7rtk67cd.d.ts} +32 -11
  71. package/dist/production/{routeModules-BRrCYrSL.d.mts → routeModules-BW4a8k3I.d.mts} +32 -11
  72. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # `react-router`
2
2
 
3
+ ## v7.14.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Remove the un-documented custom error serialization logic from the internal turbo-stream implementation. React Router only automatically handles serialization of `Error` and it's standard subtypes (`SyntaxError`, `TypeError`, etc.). ([[aabf4a1](https://github.com/remix-run/react-router/commit/aabf4a1))
8
+
9
+ - Properly handle parent middleware redirects during `fetcher.load` ([[aabf4a1](https://github.com/remix-run/react-router/commit/aabf4a1))
10
+
11
+ - Remove redundant `Omit<RouterProviderProps, "flushSync">` from `react-router/dom` `RouterProvider` ([[aabf4a1](https://github.com/remix-run/react-router/commit/aabf4a1))
12
+
13
+ - Improved types for `generatePath`'s `param` arg ([[aabf4a1](https://github.com/remix-run/react-router/commit/aabf4a1))
14
+
15
+ Type errors when required params are omitted:
16
+
17
+ ```ts
18
+ // Before
19
+ // Passes type checks, but throws at runtime 💥
20
+ generatePath(":required", { required: null });
21
+
22
+ // After
23
+ generatePath(":required", { required: null });
24
+ // ^^^^^^^^ Type 'null' is not assignable to type 'string'.ts(2322)
25
+ ```
26
+
27
+ Allow omission of optional params:
28
+
29
+ ```ts
30
+ // Before
31
+ generatePath(":optional?", {});
32
+ // ^^ Property 'optional' is missing in type '{}' but required in type '{ optional: string | null | undefined; }'.ts(2741)
33
+
34
+ // After
35
+ generatePath(":optional?", {});
36
+ ```
37
+
38
+ Allows extra keys:
39
+
40
+ ```ts
41
+ // Before
42
+ generatePath(":a", { a: "1", b: "2" });
43
+ // ^ Object literal may only specify known properties, and 'b' does not exist in type '{ a: string; }'.ts(2353)
44
+
45
+ // After
46
+ generatePath(":a", { a: "1", b: "2" });
47
+ ```
48
+
49
+ ## v7.14.1
50
+
51
+ ### Patch Changes
52
+
53
+ - Fix a potential race condition that can occur when rendering a `HydrateFallback` and initial loaders land before the `router.subscribe` call happens in the `RouterProvider` layout effect
54
+ - Normalize double-slashes in redirect paths
55
+
3
56
  ## 7.14.0
4
57
 
5
58
  ### Patch Changes
@@ -82,7 +135,6 @@
82
135
  By default, React Router normalizes the `request.url` passed to your `loader`, `action`, and `middleware` functions by removing React Router's internal implementation details (`.data` suffixes, `index` + `_routes` query params).
83
136
 
84
137
  Enabling this flag removes that normalization and passes the raw HTTP `request` instance to your handlers. This provides a few benefits:
85
-
86
138
  - Reduces server-side overhead by eliminating multiple `new Request()` calls on the critical path
87
139
  - Allows you to distinguish document from data requests in your handlers base don the presence of a `.data` suffix (useful for observability purposes)
88
140
 
@@ -132,9 +184,9 @@
132
184
 
133
185
  - Fix matchPath optional params matching without a "/" separator. ([#14689](https://github.com/remix-run/react-router/pull/14689))
134
186
  - matchPath("/users/:id?", "/usersblah") now returns null.
135
- - matchPath("/test\_route/:part?", "/test\_route\_more") now returns null.
187
+ - matchPath("/test_route/:part?", "/test_route_more") now returns null.
136
188
 
137
- - add RSC unstable\_getRequest ([#14758](https://github.com/remix-run/react-router/pull/14758))
189
+ - add RSC unstable_getRequest ([#14758](https://github.com/remix-run/react-router/pull/14758))
138
190
 
139
191
  - Fix `HydrateFallback` rendering during initial lazy route discovery with matching splat route ([#14740](https://github.com/remix-run/react-router/pull/14740))
140
192
 
@@ -180,7 +232,6 @@
180
232
  ```
181
233
 
182
234
  Notes:
183
-
184
235
  - The masked location, if present, will be available on `useLocation().unstable_mask` so you can detect whether you are currently masked or not.
185
236
  - Masked URLs only work for SPA use cases, and will be removed from `history.state` during SSR.
186
237
  - This provides a first-class API to mask URLs in Data Mode to achieve the same behavior you could do in Declarative Mode via [manual `backgroundLocation` management](https://github.com/remix-run/react-router/tree/main/examples/modal).
@@ -226,25 +277,25 @@
226
277
 
227
278
  | URL `/a/b/c` | **HTTP pathname** | **`request` pathname\`** |
228
279
  | ------------ | ----------------- | ------------------------ |
229
- | **Document** | `/a/b/c` | `/a/b/c` ✅ |
230
- | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
280
+ | **Document** | `/a/b/c` | `/a/b/c` ✅ |
281
+ | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
231
282
 
232
283
  | URL `/a/b/c/` | **HTTP pathname** | **`request` pathname\`** |
233
284
  | ------------- | ----------------- | ------------------------ |
234
- | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
285
+ | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
235
286
  | **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
236
287
 
237
288
  With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
238
289
 
239
290
  | URL `/a/b/c` | **HTTP pathname** | **`request` pathname\`** |
240
291
  | ------------ | ----------------- | ------------------------ |
241
- | **Document** | `/a/b/c` | `/a/b/c` ✅ |
242
- | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
292
+ | **Document** | `/a/b/c` | `/a/b/c` ✅ |
293
+ | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
243
294
 
244
295
  | URL `/a/b/c/` | **HTTP pathname** | **`request` pathname\`** |
245
296
  | ------------- | ------------------ | ------------------------ |
246
- | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
247
- | **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
297
+ | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
298
+ | **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
248
299
 
249
300
  This a bug fix but we are putting it behind an opt-in flag because it has the potential to be a "breaking bug fix" if you are relying on the URL format for any other application or caching logic.
250
301
 
@@ -271,14 +322,12 @@
271
322
  - \[UNSTABLE] Add a new `unstable_defaultShouldRevalidate` flag to various APIs to allow opt-ing out of standard revalidation behaviors. ([#14542](https://github.com/remix-run/react-router/pull/14542))
272
323
 
273
324
  If active routes include a `shouldRevalidate` function, then your value will be passed as `defaultShouldRevalidate` in those function so that the route always has the final revalidation determination.
274
-
275
325
  - `<Form method="post" unstable_defaultShouldRevalidate={false}>`
276
326
  - `submit(data, { method: "post", unstable_defaultShouldRevalidate: false })`
277
327
  - `<fetcher.Form method="post" unstable_defaultShouldRevalidate={false}>`
278
328
  - `fetcher.submit(data, { method: "post", unstable_defaultShouldRevalidate: false })`
279
329
 
280
330
  This is also available on non-submission APIs that may trigger revalidations due to changing search params:
281
-
282
331
  - `<Link to="/" unstable_defaultShouldRevalidate={false}>`
283
332
  - `navigate("/?foo=bar", { unstable_defaultShouldRevalidate: false })`
284
333
  - `setSearchParams(params, { unstable_defaultShouldRevalidate: false })`
@@ -301,7 +350,6 @@
301
350
  - ⚠️ This is a breaking change if you have begun using `fetcher.unstable_reset()`
302
351
 
303
352
  - Stabilize the `dataStrategy` `match.shouldRevalidateArgs`/`match.shouldCallHandler()` APIs. ([#14592](https://github.com/remix-run/react-router/pull/14592))
304
-
305
353
  - The `match.shouldLoad` API is now marked deprecated in favor of these more powerful alternatives
306
354
 
307
355
  - If you're using this API in a custom `dataStrategy` today, you can swap to the new API at your convenience:
@@ -430,7 +478,6 @@
430
478
  - Ensure action handlers run for routes with middleware even if no loader is present ([#14443](https://github.com/remix-run/react-router/pull/14443))
431
479
 
432
480
  - Add `unstable_instrumentations` API to allow users to add observablity to their apps by instrumenting route loaders, actions, middlewares, lazy, as well as server-side request handlers and client side navigations/fetches ([#14412](https://github.com/remix-run/react-router/pull/14412))
433
-
434
481
  - Framework Mode:
435
482
  - `entry.server.tsx`: `export const unstable_instrumentations = [...]`
436
483
  - `entry.client.tsx`: `<HydratedRouter unstable_instrumentations={[...]} />`
@@ -592,7 +639,6 @@
592
639
  - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215))
593
640
 
594
641
  We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use:
595
-
596
642
  - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider)
597
643
  - [`createContext`](https://reactrouter.com/api/utils/createContext)
598
644
  - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option
@@ -619,7 +665,7 @@
619
665
 
620
666
  - \[UNSTABLE] Add `<RouterProvider unstable_onError>`/`<HydratedRouter unstable_onError>` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162))
621
667
 
622
- - server action revalidation opt out via $SKIP\_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154))
668
+ - server action revalidation opt out via $SKIP_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154))
623
669
 
624
670
  - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530))
625
671
 
@@ -668,7 +714,6 @@
668
714
  - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059))
669
715
 
670
716
  - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206))
671
-
672
717
  - 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
673
718
  - 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
674
719
  - ⚠️ 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.
@@ -702,7 +747,6 @@
702
747
  - \[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))
703
748
 
704
749
  - \[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))
705
-
706
750
  - The API has been renamed to `unstable_generateMiddlewareResponse` for clarity
707
751
  - 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
708
752
  - The `query` version of the API now has a signature of `(query: (r: Request) => Promise<StaticHandlerContext | Response>) => Promise<Response>`
@@ -1348,7 +1392,6 @@
1348
1392
  ```
1349
1393
 
1350
1394
  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:
1351
-
1352
1395
  - Library mode - `createBrowserRouter(routes, { unstable_getContext })`
1353
1396
  - Framework mode - `<HydratedRouter unstable_getContext>`
1354
1397
 
@@ -1536,7 +1579,6 @@ _No changes_
1536
1579
  - Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697))
1537
1580
 
1538
1581
  - 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))
1539
-
1540
1582
  - `createCookie`
1541
1583
  - `createCookieSessionStorage`
1542
1584
  - `createMemorySessionStorage`
@@ -1545,7 +1587,6 @@ _No changes_
1545
1587
  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)
1546
1588
 
1547
1589
  Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed:
1548
-
1549
1590
  - `createCookieFactory`
1550
1591
  - `createSessionStorageFactory`
1551
1592
  - `createCookieSessionStorageFactory`
@@ -1701,7 +1742,6 @@ _No changes_
1701
1742
  ```
1702
1743
 
1703
1744
  This initial implementation targets type inference for:
1704
-
1705
1745
  - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
1706
1746
  - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
1707
1747
  - `ActionData` : Action data from `action` and/or `clientAction` within your route module
@@ -1716,7 +1756,6 @@ _No changes_
1716
1756
  ```
1717
1757
 
1718
1758
  Check out our docs for more:
1719
-
1720
1759
  - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety)
1721
1760
  - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety)
1722
1761
 
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { R as RouterInit } from './instrumentation-BYr6ff5D.js';
3
- import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './routeModules-CA7kSxJJ.js';
2
+ import { R as RouterInit } from './instrumentation-g0dG8UL0.js';
3
+ import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './routeModules-7rtk67cd.js';
4
4
 
5
5
  declare function getRequest(): Request;
6
6
  type RSCRouteConfigEntryBase = {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { R as RouterInit } from './context-phCt_zmH.mjs';
3
- import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './routeModules-BRrCYrSL.mjs';
2
+ import { R as RouterInit } from './context-DGGUoDIu.mjs';
3
+ import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './routeModules-BW4a8k3I.mjs';
4
4
 
5
5
  declare function getRequest(): Request;
6
6
  type RSCRouteConfigEntryBase = {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.14.0
2
+ * react-router v7.14.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -723,8 +723,7 @@ function generatePath(originalPath, params = {}) {
723
723
  const segments = path.split(/\/+/).map((segment, index, array) => {
724
724
  const isLastSegment = index === array.length - 1;
725
725
  if (isLastSegment && segment === "*") {
726
- const star = "*";
727
- return stringify2(params[star]);
726
+ return stringify2(params["*"]);
728
727
  }
729
728
  const keyMatch = segment.match(/^:([\w-]+)(\??)(.*)/);
730
729
  if (keyMatch) {
@@ -845,7 +844,7 @@ function resolvePath(to, fromPathname = "/") {
845
844
  } = typeof to === "string" ? parsePath(to) : to;
846
845
  let pathname;
847
846
  if (toPathname) {
848
- toPathname = toPathname.replace(/\/\/+/g, "/");
847
+ toPathname = removeDoubleSlashes(toPathname);
849
848
  if (toPathname.startsWith("/")) {
850
849
  pathname = resolvePathname(toPathname.substring(1), "/");
851
850
  } else {
@@ -861,7 +860,7 @@ function resolvePath(to, fromPathname = "/") {
861
860
  };
862
861
  }
863
862
  function resolvePathname(relativePath, fromPathname) {
864
- let segments = fromPathname.replace(/\/+$/, "").split("/");
863
+ let segments = removeTrailingSlash(fromPathname).split("/");
865
864
  let relativeSegments = relativePath.split("/");
866
865
  relativeSegments.forEach((segment) => {
867
866
  if (segment === "..") {
@@ -932,8 +931,10 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = fal
932
931
  }
933
932
  return path;
934
933
  }
935
- var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/");
936
- var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
934
+ var removeDoubleSlashes = (path) => path.replace(/\/\/+/g, "/");
935
+ var joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
936
+ var removeTrailingSlash = (path) => path.replace(/\/+$/, "");
937
+ var normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/");
937
938
  var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
938
939
  var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
939
940
  var DataWithResponseInit = class {
@@ -987,7 +988,8 @@ function isRouteErrorResponse(error) {
987
988
  return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
988
989
  }
989
990
  function getRoutePattern(matches) {
990
- return matches.map((m) => m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/";
991
+ let parts = matches.map((m) => m.route.path).filter(Boolean);
992
+ return joinPaths(parts) || "/";
991
993
  }
992
994
  var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
993
995
  function parseToInfo(_to, basename) {
@@ -2656,6 +2658,14 @@ function createRouter(init) {
2656
2658
  key
2657
2659
  );
2658
2660
  let result = results[match.route.id];
2661
+ if (!result) {
2662
+ for (let match2 of matches) {
2663
+ if (results[match2.route.id]) {
2664
+ result = results[match2.route.id];
2665
+ break;
2666
+ }
2667
+ }
2668
+ }
2659
2669
  if (fetchControllers.get(key) === abortController) {
2660
2670
  fetchControllers.delete(key);
2661
2671
  }
@@ -5022,7 +5032,7 @@ function normalizeRedirectLocation(location, currentUrl, basename, historyInstan
5022
5032
  }
5023
5033
  let isSameBasename = stripBasename(url.pathname, basename) != null;
5024
5034
  if (url.origin === currentUrl.origin && isSameBasename) {
5025
- return url.pathname + url.search + url.hash;
5035
+ return removeDoubleSlashes(url.pathname) + url.search + url.hash;
5026
5036
  }
5027
5037
  }
5028
5038
  try {
@@ -5732,7 +5742,7 @@ function useOutlet(context) {
5732
5742
  function useParams() {
5733
5743
  let { matches } = React2.useContext(RouteContext);
5734
5744
  let routeMatch = matches[matches.length - 1];
5735
- return routeMatch ? routeMatch.params : {};
5745
+ return routeMatch?.params ?? {};
5736
5746
  }
5737
5747
  function useResolvedPath(to, { relative } = {}) {
5738
5748
  let { matches } = React2.useContext(RouteContext);
@@ -6503,6 +6513,16 @@ function RouterProvider({
6503
6513
  ]
6504
6514
  );
6505
6515
  React3.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
6516
+ let initialized = state.initialized;
6517
+ React3.useLayoutEffect(() => {
6518
+ if (!initialized && router.state.initialized) {
6519
+ setState(router.state, {
6520
+ deletedFetchers: [],
6521
+ flushSync: false,
6522
+ newErrors: null
6523
+ });
6524
+ }
6525
+ }, [initialized, setState, router.state]);
6506
6526
  React3.useEffect(() => {
6507
6527
  if (vtContext.isTransitioning && !vtContext.flushSync) {
6508
6528
  setRenderDfd(new Deferred());
@@ -7152,6 +7172,14 @@ var TYPE_SET = "S";
7152
7172
  var TYPE_SYMBOL = "Y";
7153
7173
  var TYPE_URL = "U";
7154
7174
  var TYPE_PREVIOUS_RESOLVED = "Z";
7175
+ var SUPPORTED_ERROR_TYPES = [
7176
+ "EvalError",
7177
+ "RangeError",
7178
+ "ReferenceError",
7179
+ "SyntaxError",
7180
+ "TypeError",
7181
+ "URIError"
7182
+ ];
7155
7183
  var Deferred2 = class {
7156
7184
  constructor() {
7157
7185
  this.promise = new Promise((resolve, reject) => {
@@ -7513,7 +7541,7 @@ function hydrate(index) {
7513
7541
  continue;
7514
7542
  case TYPE_ERROR:
7515
7543
  const [, message, errorType] = value;
7516
- let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message);
7544
+ let error = errorType && globalObj && SUPPORTED_ERROR_TYPES.includes(errorType) && errorType in globalObj && typeof globalObj[errorType] === "function" ? new globalObj[errorType](message) : new Error(message);
7517
7545
  hydrated[index2] = error;
7518
7546
  set(error);
7519
7547
  continue;
@@ -8219,9 +8247,9 @@ function singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) {
8219
8247
  if (url.pathname === "/") {
8220
8248
  url.pathname = `_root.${extension}`;
8221
8249
  } else if (basename && stripBasename(url.pathname, basename) === "/") {
8222
- url.pathname = `${basename.replace(/\/$/, "")}/_root.${extension}`;
8250
+ url.pathname = `${removeTrailingSlash(basename)}/_root.${extension}`;
8223
8251
  } else {
8224
- url.pathname = `${url.pathname.replace(/\/$/, "")}.${extension}`;
8252
+ url.pathname = `${removeTrailingSlash(url.pathname)}.${extension}`;
8225
8253
  }
8226
8254
  }
8227
8255
  return url;
@@ -8296,7 +8324,8 @@ function decodeViaTurboStream(body, global) {
8296
8324
  if (type === "SanitizedError") {
8297
8325
  let [name, message, stack] = rest;
8298
8326
  let Constructor = Error;
8299
- if (name && name in global && typeof global[name] === "function") {
8327
+ if (name && SUPPORTED_ERROR_TYPES.includes(name) && name in global && // @ts-expect-error
8328
+ typeof global[name] === "function") {
8300
8329
  Constructor = global[name];
8301
8330
  }
8302
8331
  let error = new Constructor(message);
@@ -9177,10 +9206,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscover
9177
9206
  }
9178
9207
  function getManifestPath(_manifestPath, basename) {
9179
9208
  let manifestPath = _manifestPath || "/__manifest";
9180
- if (basename == null) {
9181
- return manifestPath;
9182
- }
9183
- return `${basename}${manifestPath}`.replace(/\/+/g, "/");
9209
+ return basename == null ? manifestPath : joinPaths([basename, manifestPath]);
9184
9210
  }
9185
9211
  var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
9186
9212
  async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
@@ -9970,7 +9996,7 @@ var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "un
9970
9996
  try {
9971
9997
  if (isBrowser2) {
9972
9998
  window.__reactRouterVersion = // @ts-expect-error
9973
- "7.14.0";
9999
+ "7.14.2";
9974
10000
  }
9975
10001
  } catch (e) {
9976
10002
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }/**
2
- * react-router v7.14.0
2
+ * react-router v7.14.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
 
17
- var _chunkIK6APEEGjs = require('./chunk-IK6APEEG.js');
17
+ var _chunkZZNWZ5Q3js = require('./chunk-ZZNWZ5Q3.js');
18
18
 
19
19
  // lib/dom/ssr/hydration.tsx
20
20
  function getHydrationData({
@@ -29,12 +29,12 @@ function getHydrationData({
29
29
  ...state,
30
30
  loaderData: { ...state.loaderData }
31
31
  };
32
- let initialMatches = _chunkIK6APEEGjs.matchRoutes.call(void 0, routes, location, basename);
32
+ let initialMatches = _chunkZZNWZ5Q3js.matchRoutes.call(void 0, routes, location, basename);
33
33
  if (initialMatches) {
34
34
  for (let match of initialMatches) {
35
35
  let routeId = match.route.id;
36
36
  let routeInfo = getRouteInfo(routeId);
37
- if (_chunkIK6APEEGjs.shouldHydrateRouteLoader.call(void 0,
37
+ if (_chunkZZNWZ5Q3js.shouldHydrateRouteLoader.call(void 0,
38
38
  routeId,
39
39
  routeInfo.clientLoader,
40
40
  routeInfo.hasLoader,
@@ -112,7 +112,7 @@ function RSCDefaultRootErrorBoundaryImpl({
112
112
  }
113
113
  }
114
114
  );
115
- if (_chunkIK6APEEGjs.isRouteErrorResponse.call(void 0, error)) {
115
+ if (_chunkZZNWZ5Q3js.isRouteErrorResponse.call(void 0, error)) {
116
116
  return /* @__PURE__ */ _react2.default.createElement(
117
117
  ErrorWrapper,
118
118
  {
@@ -120,7 +120,7 @@ function RSCDefaultRootErrorBoundaryImpl({
120
120
  title: "Unhandled Thrown Response!"
121
121
  },
122
122
  /* @__PURE__ */ _react2.default.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText),
123
- _chunkIK6APEEGjs.ENABLE_DEV_WARNINGS ? heyDeveloper : null
123
+ _chunkZZNWZ5Q3js.ENABLE_DEV_WARNINGS ? heyDeveloper : null
124
124
  );
125
125
  }
126
126
  let errorInstance;
@@ -146,7 +146,7 @@ function RSCDefaultRootErrorBoundaryImpl({
146
146
  function RSCDefaultRootErrorBoundary({
147
147
  hasRootLayout
148
148
  }) {
149
- let error = _chunkIK6APEEGjs.useRouteError.call(void 0, );
149
+ let error = _chunkZZNWZ5Q3js.useRouteError.call(void 0, );
150
150
  if (hasRootLayout === void 0) {
151
151
  throw new Error("Missing 'hasRootLayout' prop");
152
152
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.14.0
2
+ * react-router v7.14.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -51,7 +51,7 @@ import {
51
51
  withComponentProps,
52
52
  withErrorBoundaryProps,
53
53
  withHydrateFallbackProps
54
- } from "./chunk-HZQGQD2X.mjs";
54
+ } from "./chunk-EVOBXE3Y.mjs";
55
55
 
56
56
  // lib/dom/ssr/server.tsx
57
57
  import * as React from "react";
@@ -579,7 +579,7 @@ function getDevServerHooks() {
579
579
  function getBuildTimeHeader(request, headerName) {
580
580
  if (typeof process !== "undefined") {
581
581
  try {
582
- if (process.env?.IS_RR_BUILD_REQUEST === "yes") {
582
+ if (process.env.hasOwnProperty("IS_RR_BUILD_REQUEST") && process.env.IS_RR_BUILD_REQUEST === "yes") {
583
583
  return request.headers.get(headerName);
584
584
  }
585
585
  } catch (e) {