diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000..056a6c681a Binary files /dev/null and b/.DS_Store differ diff --git a/node_modules/@remix-run/router/CHANGELOG.md b/node_modules/@remix-run/router/CHANGELOG.md new file mode 100644 index 0000000000..2b7c0cb831 --- /dev/null +++ b/node_modules/@remix-run/router/CHANGELOG.md @@ -0,0 +1,769 @@ +# `@remix-run/router` + +## 1.18.0 + +### Minor Changes + +- Stabilize `future.unstable_skipActionErrorRevalidation` as `future.v7_skipActionErrorRevalidation` ([#11769](https://github.com/remix-run/react-router/pull/11769)) + + - When this flag is enabled, actions will not automatically trigger a revalidation if they return/throw a `Response` with a `4xx`/`5xx` status code + - You may still opt-into revalidation via `shouldRevalidate` + - This also changes `shouldRevalidate`'s `unstable_actionStatus` parameter to `actionStatus` + +### Patch Changes + +- Fix bubbling of errors thrown from `unstable_patchRoutesOnMiss` ([#11786](https://github.com/remix-run/react-router/pull/11786)) +- Fix hydration in SSR apps using `unstable_patchRoutesOnMiss` that matched a splat route on the server ([#11790](https://github.com/remix-run/react-router/pull/11790)) + +## 1.17.1 + +### Patch Changes + +- Fog of War (unstable): Trigger a new `router.routes` identity/reflow during route patching ([#11740](https://github.com/remix-run/react-router/pull/11740)) +- Fog of War (unstable): Fix initial matching when a splat route matches ([#11759](https://github.com/remix-run/react-router/pull/11759)) + +## 1.17.0 + +### Minor Changes + +- Add support for Lazy Route Discovery (a.k.a. Fog of War) ([#11626](https://github.com/remix-run/react-router/pull/11626)) + + - RFC: + - `unstable_patchRoutesOnMiss` docs: + +## 1.16.1 + +### Patch Changes + +- Support `unstable_dataStrategy` on `staticHandler.queryRoute` ([#11515](https://github.com/remix-run/react-router/pull/11515)) + +## 1.16.0 + +### Minor Changes + +- Add a new `unstable_dataStrategy` configuration option ([#11098](https://github.com/remix-run/react-router/pull/11098)) + - This option allows Data Router applications to take control over the approach for executing route loaders and actions + - The default implementation is today's behavior, to fetch all loaders in parallel, but this option allows users to implement more advanced data flows including Remix single-fetch, middleware/context APIs, automatic loader caching, and more +- Move `unstable_dataStrategy` from `createStaticHandler` to `staticHandler.query` so it can be request-specific for use with the `ResponseStub` approach in Remix. It's not really applicable to `queryRoute` for now since that's a singular handler call anyway so any pre-processing/post/processing could be done there manually. ([#11377](https://github.com/remix-run/react-router/pull/11377)) +- Add a new `future.unstable_skipActionRevalidation` future flag ([#11098](https://github.com/remix-run/react-router/pull/11098)) + - Currently, active loaders revalidate after any action, regardless of the result + - With this flag enabled, actions that return/throw a 4xx/5xx response status will no longer automatically revalidate + - This should reduce load on your server since it's rare that a 4xx/5xx should actually mutate any data + - If you need to revalidate after a 4xx/5xx result with this flag enabled, you can still do that via returning `true` from `shouldRevalidate` + - `shouldRevalidate` now also receives a new `unstable_actionStatus` argument alongside `actionResult` so you can make decision based on the status of the `action` response without having to encode it into the action data +- Added a `skipLoaderErrorBubbling` flag to `staticHandler.query` to disable error bubbling on loader executions for single-fetch scenarios where the client-side router will handle the bubbling ([#11098](https://github.com/remix-run/react-router/pull/11098)) + +## 1.15.3 + +### Patch Changes + +- Fix a `future.v7_partialHydration` bug that would re-run loaders below the boundary on hydration if SSR loader errors bubbled to a parent boundary ([#11324](https://github.com/remix-run/react-router/pull/11324)) +- Fix a `future.v7_partialHydration` bug that would consider the router uninitialized if a route did not have a loader ([#11325](https://github.com/remix-run/react-router/pull/11325)) + +## 1.15.2 + +### Patch Changes + +- Preserve hydrated errors during partial hydration runs ([#11305](https://github.com/remix-run/react-router/pull/11305)) + +## 1.15.1 + +### Patch Changes + +- Fix encoding/decoding issues with pre-encoded dynamic parameter values ([#11199](https://github.com/remix-run/react-router/pull/11199)) + +## 1.15.0 + +### Minor Changes + +- Add a `createStaticHandler` `future.v7_throwAbortReason` flag to throw `request.signal.reason` (defaults to a `DOMException`) when a request is aborted instead of an `Error` such as `new Error("query() call aborted: GET /path")` ([#11104](https://github.com/remix-run/react-router/pull/11104)) + + - Please note that `DOMException` was added in Node v17 so you will not get a `DOMException` on Node 16 and below. + +### Patch Changes + +- Respect the `ErrorResponse` status code if passed to `getStaticContextFormError` ([#11213](https://github.com/remix-run/react-router/pull/11213)) + +## 1.14.2 + +### Patch Changes + +- Fix bug where dashes were not picked up in dynamic parameter names ([#11160](https://github.com/remix-run/react-router/pull/11160)) +- Do not attempt to deserialize empty JSON responses ([#11164](https://github.com/remix-run/react-router/pull/11164)) + +## 1.14.1 + +### Patch Changes + +- Fix bug with `route.lazy` not working correctly on initial SPA load when `v7_partialHydration` is specified ([#11121](https://github.com/remix-run/react-router/pull/11121)) +- Fix bug preventing revalidation from occurring for persisted fetchers unmounted during the `submitting` phase ([#11102](https://github.com/remix-run/react-router/pull/11102)) +- De-dup relative path logic in `resolveTo` ([#11097](https://github.com/remix-run/react-router/pull/11097)) + +## 1.14.0 + +### Minor Changes + +- Added a new `future.v7_partialHydration` future flag that enables partial hydration of a data router when Server-Side Rendering. This allows you to provide `hydrationData.loaderData` that has values for _some_ initially matched route loaders, but not all. When this flag is enabled, the router will call `loader` functions for routes that do not have hydration loader data during `router.initialize()`, and it will render down to the deepest provided `HydrateFallback` (up to the first route without hydration data) while it executes the unhydrated routes. ([#11033](https://github.com/remix-run/react-router/pull/11033)) + + For example, the following router has a `root` and `index` route, but only provided `hydrationData.loaderData` for the `root` route. Because the `index` route has a `loader`, we need to run that during initialization. With `future.v7_partialHydration` specified, `` will render the `RootComponent` (because it has data) and then the `IndexFallback` (since it does not have data). Once `indexLoader` finishes, application will update and display `IndexComponent`. + + ```jsx + let router = createBrowserRouter( + [ + { + id: "root", + path: "/", + loader: rootLoader, + Component: RootComponent, + Fallback: RootFallback, + children: [ + { + id: "index", + index: true, + loader: indexLoader, + Component: IndexComponent, + HydrateFallback: IndexFallback, + }, + ], + }, + ], + { + future: { + v7_partialHydration: true, + }, + hydrationData: { + loaderData: { + root: { message: "Hydrated from Root!" }, + }, + }, + } + ); + ``` + + If the above example did not have an `IndexFallback`, then `RouterProvider` would instead render the `RootFallback` while it executed the `indexLoader`. + + **Note:** When `future.v7_partialHydration` is provided, the `` prop is ignored since you can move it to a `Fallback` on your top-most route. The `fallbackElement` prop will be removed in React Router v7 when `v7_partialHydration` behavior becomes the standard behavior. + +- Add a new `future.v7_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. ([#11087](https://github.com/remix-run/react-router/pull/11087)) + + This fix was originally added in [#10983](https://github.com/remix-run/react-router/issues/10983) and was later reverted in [#11078](https://github.com/remix-run/react-router/pull/11078) because it was determined that a large number of existing applications were relying on the buggy behavior (see [#11052](https://github.com/remix-run/react-router/issues/11052)) + + **The Bug** + The buggy behavior is that without this flag, the default behavior when resolving relative paths is to _ignore_ any splat (`*`) portion of the current route path. + + **The Background** + This decision was originally made thinking that it would make the concept of nested different sections of your apps in `` easier if relative routing would _replace_ the current splat: + + ```jsx + + + } /> + } /> + + + ``` + + Any paths like `/dashboard`, `/dashboard/team`, `/dashboard/projects` will match the `Dashboard` route. The dashboard component itself can then render nested ``: + + ```jsx + function Dashboard() { + return ( +
+

Dashboard

+ + + + } /> + } /> + } /> + +
+ ); + } + ``` + + Now, all links and route paths are relative to the router above them. This makes code splitting and compartmentalizing your app really easy. You could render the `Dashboard` as its own independent app, or embed it into your large app without making any changes to it. + + **The Problem** + + The problem is that this concept of ignoring part of a path breaks a lot of other assumptions in React Router - namely that `"."` always means the current location pathname for that route. When we ignore the splat portion, we start getting invalid paths when using `"."`: + + ```jsx + // If we are on URL /dashboard/team, and we want to link to /dashboard/team: + function DashboardTeam() { + // ❌ This is broken and results in + return A broken link to the Current URL; + + // ✅ This is fixed but super unintuitive since we're already at /dashboard/team! + return A broken link to the Current URL; + } + ``` + + We've also introduced an issue that we can no longer move our `DashboardTeam` component around our route hierarchy easily - since it behaves differently if we're underneath a non-splat route, such as `/dashboard/:widget`. Now, our `"."` links will, properly point to ourself _inclusive of the dynamic param value_ so behavior will break from it's corresponding usage in a `/dashboard/*` route. + + Even worse, consider a nested splat route configuration: + + ```jsx + + + + } /> + + + + ``` + + Now, a `` and a `` inside the `Dashboard` component go to the same place! That is definitely not correct! + + Another common issue arose in Data Routers (and Remix) where any `
` should post to it's own route `action` if you the user doesn't specify a form action: + + ```jsx + let router = createBrowserRouter({ + path: "/dashboard", + children: [ + { + path: "*", + action: dashboardAction, + Component() { + // ❌ This form is broken! It throws a 405 error when it submits because + // it tries to submit to /dashboard (without the splat value) and the parent + // `/dashboard` route doesn't have an action + return ...
; + }, + }, + ], + }); + ``` + + This is just a compounded issue from the above because the default location for a `Form` to submit to is itself (`"."`) - and if we ignore the splat portion, that now resolves to the parent route. + + **The Solution** + If you are leveraging this behavior, it's recommended to enable the future flag, move your splat to it's own route, and leverage `../` for any links to "sibling" pages: + + ```jsx + + + + } /> + + + + + function Dashboard() { + return ( +
+

Dashboard

+ + + + } /> + } /> + } /> + +
+ ); + } + ``` + + This way, `.` means "the full current pathname for my route" in all cases (including static, dynamic, and splat routes) and `..` always means "my parents pathname". + +### Patch Changes + +- Catch and bubble errors thrown when trying to unwrap responses from `loader`/`action` functions ([#11061](https://github.com/remix-run/react-router/pull/11061)) +- Fix `relative="path"` issue when rendering `Link`/`NavLink` outside of matched routes ([#11062](https://github.com/remix-run/react-router/pull/11062)) + +## 1.13.1 + +### Patch Changes + +- Revert the `useResolvedPath` fix for splat routes due to a large number of applications that were relying on the buggy behavior (see ). We plan to re-introduce this fix behind a future flag in the next minor version. ([#11078](https://github.com/remix-run/react-router/pull/11078)) + +## 1.13.0 + +### Minor Changes + +- Export the `PathParam` type from the public API ([#10719](https://github.com/remix-run/react-router/pull/10719)) + +### Patch Changes + +- Fix bug with `resolveTo` in splat routes ([#11045](https://github.com/remix-run/react-router/pull/11045)) + - This is a follow up to [#10983](https://github.com/remix-run/react-router/pull/10983) to handle the few other code paths using `getPathContributingMatches` + - This removes the `UNSAFE_getPathContributingMatches` export from `@remix-run/router` since we no longer need this in the `react-router`/`react-router-dom` layers +- Do not revalidate unmounted fetchers when `v7_fetcherPersist` is enabled ([#11044](https://github.com/remix-run/react-router/pull/11044)) + +## 1.12.0 + +### Minor Changes + +- Add `unstable_flushSync` option to `router.navigate` and `router.fetch` to tell the React Router layer to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#11005](https://github.com/remix-run/react-router/pull/11005)) + +### Patch Changes + +- Fix `relative="path"` bug where relative path calculations started from the full location pathname, instead of from the current contextual route pathname. ([#11006](https://github.com/remix-run/react-router/pull/11006)) + + ```jsx + + }> + + + ; + + function Component() { + return ( + <> + {/* This is now correctly relative to /a/b, not /a/b/c */} + + + + ); + } + ``` + +## 1.11.0 + +### Minor Changes + +- Add a new `future.v7_fetcherPersist` flag to the `@remix-run/router` to change the persistence behavior of fetchers when `router.deleteFetcher` is called. Instead of being immediately cleaned up, fetchers will persist until they return to an `idle` state ([RFC](https://github.com/remix-run/remix/discussions/7698)) ([#10962](https://github.com/remix-run/react-router/pull/10962)) + + - This is sort of a long-standing bug fix as the `useFetchers()` API was always supposed to only reflect **in-flight** fetcher information for pending/optimistic UI -- it was not intended to reflect fetcher data or hang onto fetchers after they returned to an `idle` state + - Keep an eye out for the following specific behavioral changes when opting into this flag and check your app for compatibility: + - Fetchers that complete _while still mounted_ will no longer appear in `useFetchers()`. They served effectively no purpose in there since you can access the data via `useFetcher().data`). + - Fetchers that previously unmounted _while in-flight_ will not be immediately aborted and will instead be cleaned up once they return to an `idle` state. They will remain exposed via `useFetchers` while in-flight so you can still access pending/optimistic data after unmount. + +- When `v7_fetcherPersist` is enabled, the router now performs ref-counting on fetcher keys via `getFetcher`/`deleteFetcher` so it knows when a given fetcher is totally unmounted from the UI ([#10977](https://github.com/remix-run/react-router/pull/10977)) + + - Once a fetcher has been totally unmounted, we can ignore post-processing of a persisted fetcher result such as a redirect or an error + - The router will also pass a new `deletedFetchers` array to the subscriber callbacks so that the UI layer can remove associated fetcher data + +- Add support for optional path segments in `matchPath` ([#10768](https://github.com/remix-run/react-router/pull/10768)) + +### Patch Changes + +- Fix `router.getFetcher`/`router.deleteFetcher` type definitions which incorrectly specified `key` as an optional parameter ([#10960](https://github.com/remix-run/react-router/pull/10960)) + +## 1.10.0 + +### Minor Changes + +- Add experimental support for the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition) by allowing users to opt-into view transitions on navigations via the new `unstable_viewTransition` option to `router.navigate` ([#10916](https://github.com/remix-run/react-router/pull/10916)) + +### Patch Changes + +- Allow 404 detection to leverage root route error boundary if path contains a URL segment ([#10852](https://github.com/remix-run/react-router/pull/10852)) +- Fix `ErrorResponse` type to avoid leaking internal field ([#10876](https://github.com/remix-run/react-router/pull/10876)) + +## 1.9.0 + +### Minor Changes + +- In order to move towards stricter TypeScript support in the future, we're aiming to replace current usages of `any` with `unknown` on exposed typings for user-provided data. To do this in Remix v2 without introducing breaking changes in React Router v6, we have added generics to a number of shared types. These continue to default to `any` in React Router and are overridden with `unknown` in Remix. In React Router v7 we plan to move these to `unknown` as a breaking change. ([#10843](https://github.com/remix-run/react-router/pull/10843)) + - `Location` now accepts a generic for the `location.state` value + - `ActionFunctionArgs`/`ActionFunction`/`LoaderFunctionArgs`/`LoaderFunction` now accept a generic for the `context` parameter (only used in SSR usages via `createStaticHandler`) + - The return type of `useMatches` (now exported as `UIMatch`) accepts generics for `match.data` and `match.handle` - both of which were already set to `unknown` +- Move the `@private` class export `ErrorResponse` to an `UNSAFE_ErrorResponseImpl` export since it is an implementation detail and there should be no construction of `ErrorResponse` instances in userland. This frees us up to export a `type ErrorResponse` which correlates to an instance of the class via `InstanceType`. Userland code should only ever be using `ErrorResponse` as a type and should be type-narrowing via `isRouteErrorResponse`. ([#10811](https://github.com/remix-run/react-router/pull/10811)) +- Export `ShouldRevalidateFunctionArgs` interface ([#10797](https://github.com/remix-run/react-router/pull/10797)) +- Removed private/internal APIs only required for the Remix v1 backwards compatibility layer and no longer needed in Remix v2 (`_isFetchActionRedirect`, `_hasFetcherDoneAnything`) ([#10715](https://github.com/remix-run/react-router/pull/10715)) + +### Patch Changes + +- Add method/url to error message on aborted `query`/`queryRoute` calls ([#10793](https://github.com/remix-run/react-router/pull/10793)) +- Fix a race-condition with loader/action-thrown errors on `route.lazy` routes ([#10778](https://github.com/remix-run/react-router/pull/10778)) +- Fix type for `actionResult` on the arguments object passed to `shouldRevalidate` ([#10779](https://github.com/remix-run/react-router/pull/10779)) + +## 1.8.0 + +### Minor Changes + +- Add's a new `redirectDocument()` function which allows users to specify that a redirect from a `loader`/`action` should trigger a document reload (via `window.location`) instead of attempting to navigate to the redirected location via React Router ([#10705](https://github.com/remix-run/react-router/pull/10705)) + +### Patch Changes + +- Fix an issue in `queryRoute` that was not always identifying thrown `Response` instances ([#10717](https://github.com/remix-run/react-router/pull/10717)) +- Ensure hash history always includes a leading slash on hash pathnames ([#10753](https://github.com/remix-run/react-router/pull/10753)) + +## 1.7.2 + +### Patch Changes + +- Trigger an error if a `defer` promise resolves/rejects with `undefined` in order to match the behavior of loaders and actions which must return a value or `null` ([#10690](https://github.com/remix-run/react-router/pull/10690)) +- Properly handle fetcher redirects interrupted by normal navigations ([#10674](https://github.com/remix-run/react-router/pull/10674), [#10709](https://github.com/remix-run/react-router/pull/10709)) +- Initial-load fetchers should not automatically revalidate on GET navigations ([#10688](https://github.com/remix-run/react-router/pull/10688)) +- Enhance the return type of `Route.lazy` to prohibit returning an empty object ([#10634](https://github.com/remix-run/react-router/pull/10634)) + +## 1.7.1 + +### Patch Changes + +- Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656)) + +## 1.7.0 + +### Minor Changes + +- Add support for `application/json` and `text/plain` encodings for `router.navigate`/`router.fetch` submissions. To leverage these encodings, pass your data in a `body` parameter and specify the desired `formEncType`: ([#10413](https://github.com/remix-run/react-router/pull/10413)) + + ```js + // By default, the encoding is "application/x-www-form-urlencoded" + router.navigate("/", { + formMethod: "post", + body: { key: "value" }, + }); + + async function action({ request }) { + // await request.formData() => FormData instance with entry [key=value] + } + ``` + + ```js + // Pass `formEncType` to opt-into a different encoding (json) + router.navigate("/", { + formMethod: "post", + formEncType: "application/json", + body: { key: "value" }, + }); + + async function action({ request }) { + // await request.json() => { key: "value" } + } + ``` + + ```js + // Pass `formEncType` to opt-into a different encoding (text) + router.navigate("/", { + formMethod: "post", + formEncType: "text/plain", + body: "Text submission", + }); + + async function action({ request }) { + // await request.text() => "Text submission" + } + ``` + +### Patch Changes + +- Call `window.history.pushState/replaceState` before updating React Router state (instead of after) so that `window.location` matches `useLocation` during synchronous React 17 rendering ([#10448](https://github.com/remix-run/react-router/pull/10448)) + - ⚠️ However, generally apps should not be relying on `window.location` and should always reference `useLocation` when possible, as `window.location` will not be in sync 100% of the time (due to `popstate` events, concurrent mode, etc.) +- Strip `basename` from the `location` provided to `` to match the `useLocation` behavior ([#10550](https://github.com/remix-run/react-router/pull/10550)) +- Avoid calling `shouldRevalidate` for fetchers that have not yet completed a data load ([#10623](https://github.com/remix-run/react-router/pull/10623)) +- Fix `unstable_useBlocker` key issues in `StrictMode` ([#10573](https://github.com/remix-run/react-router/pull/10573)) +- Upgrade `typescript` to 5.1 ([#10581](https://github.com/remix-run/react-router/pull/10581)) + +## 1.6.3 + +### Patch Changes + +- Allow fetcher revalidations to complete if submitting fetcher is deleted ([#10535](https://github.com/remix-run/react-router/pull/10535)) +- Re-throw `DOMException` (`DataCloneError`) when attempting to perform a `PUSH` navigation with non-serializable state. ([#10427](https://github.com/remix-run/react-router/pull/10427)) +- Ensure revalidations happen when hash is present ([#10516](https://github.com/remix-run/react-router/pull/10516)) +- upgrade jest and jsdom ([#10453](https://github.com/remix-run/react-router/pull/10453)) + +## 1.6.2 + +### Patch Changes + +- Fix HMR-driven error boundaries by properly reconstructing new routes and `manifest` in `\_internalSetRoutes` ([#10437](https://github.com/remix-run/react-router/pull/10437)) +- Fix bug where initial data load would not kick off when hash is present ([#10493](https://github.com/remix-run/react-router/pull/10493)) + +## 1.6.1 + +### Patch Changes + +- Fix `basename` handling when navigating without a path ([#10433](https://github.com/remix-run/react-router/pull/10433)) +- "Same hash" navigations no longer re-run loaders to match browser behavior (i.e. `/path#hash -> /path#hash`) ([#10408](https://github.com/remix-run/react-router/pull/10408)) + +## 1.6.0 + +### Minor Changes + +- Enable relative routing in the `@remix-run/router` when providing a source route ID from which the path is relative to: ([#10336](https://github.com/remix-run/react-router/pull/10336)) + + - Example: `router.navigate("../path", { fromRouteId: "some-route" })`. + - This also applies to `router.fetch` which already receives a source route ID + +- Introduce a new `@remix-run/router` `future.v7_prependBasename` flag to enable `basename` prefixing to all paths coming into `router.navigate` and `router.fetch`. + + - Previously the `basename` was prepended in the React Router layer, but now that relative routing is being handled by the router we need prepend the `basename` _after_ resolving any relative paths + - This also enables `basename` support in `useFetcher` as well + +### Patch Changes + +- Enhance `LoaderFunction`/`ActionFunction` return type to prevent `undefined` from being a valid return value ([#10267](https://github.com/remix-run/react-router/pull/10267)) +- Ensure proper 404 error on `fetcher.load` call to a route without a `loader` ([#10345](https://github.com/remix-run/react-router/pull/10345)) +- Deprecate the `createRouter` `detectErrorBoundary` option in favor of the new `mapRouteProperties` option for converting a framework-agnostic route to a framework-aware route. This allows us to set more than just the `hasErrorBoundary` property during route pre-processing, and is now used for mapping `Component -> element` and `ErrorBoundary -> errorElement` in `react-router`. ([#10287](https://github.com/remix-run/react-router/pull/10287)) +- Fixed a bug where fetchers were incorrectly attempting to revalidate on search params changes or routing to the same URL (using the same logic for route `loader` revalidations). However, since fetchers have a static href, they should only revalidate on `action` submissions or `router.revalidate` calls. ([#10344](https://github.com/remix-run/react-router/pull/10344)) +- Decouple `AbortController` usage between revalidating fetchers and the thing that triggered them such that the unmount/deletion of a revalidating fetcher doesn't impact the ongoing triggering navigation/revalidation ([#10271](https://github.com/remix-run/react-router/pull/10271)) + +## 1.5.0 + +### Minor Changes + +- Added support for [**Future Flags**](https://reactrouter.com/en/main/guides/api-development-strategy) in React Router. The first flag being introduced is `future.v7_normalizeFormMethod` which will normalize the exposed `useNavigation()/useFetcher()` `formMethod` fields as uppercase HTTP methods to align with the `fetch()` behavior. ([#10207](https://github.com/remix-run/react-router/pull/10207)) + + - When `future.v7_normalizeFormMethod === false` (default v6 behavior), + - `useNavigation().formMethod` is lowercase + - `useFetcher().formMethod` is lowercase + - When `future.v7_normalizeFormMethod === true`: + - `useNavigation().formMethod` is uppercase + - `useFetcher().formMethod` is uppercase + +### Patch Changes + +- Provide fetcher submission to `shouldRevalidate` if the fetcher action redirects ([#10208](https://github.com/remix-run/react-router/pull/10208)) +- Properly handle `lazy()` errors during router initialization ([#10201](https://github.com/remix-run/react-router/pull/10201)) +- Remove `instanceof` check for `DeferredData` to be resilient to ESM/CJS boundaries in SSR bundling scenarios ([#10247](https://github.com/remix-run/react-router/pull/10247)) +- Update to latest `@remix-run/web-fetch@4.3.3` ([#10216](https://github.com/remix-run/react-router/pull/10216)) + +## 1.4.0 + +### Minor Changes + +- **Introducing Lazy Route Modules!** ([#10045](https://github.com/remix-run/react-router/pull/10045)) + + In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new `lazy()` route property. This is an async function that resolves the non-route-matching portions of your route definition (`loader`, `action`, `element`/`Component`, `errorElement`/`ErrorBoundary`, `shouldRevalidate`, `handle`). + + Lazy routes are resolved on initial load and during the `loading` or `submitting` phase of a navigation or fetcher call. You cannot lazily define route-matching properties (`path`, `index`, `children`) since we only execute your lazy route functions after we've matched known routes. + + Your `lazy` functions will typically return the result of a dynamic import. + + ```jsx + // In this example, we assume most folks land on the homepage so we include that + // in our critical-path bundle, but then we lazily load modules for /a and /b so + // they don't load until the user navigates to those routes + let routes = createRoutesFromElements( + }> + } /> + import("./a")} /> + import("./b")} /> + + ); + ``` + + Then in your lazy route modules, export the properties you want defined for the route: + + ```jsx + export async function loader({ request }) { + let data = await fetchData(request); + return json(data); + } + + // Export a `Component` directly instead of needing to create a React Element from it + export function Component() { + let data = useLoaderData(); + + return ( + <> +

You made it!

+

{data}

+ + ); + } + + // Export an `ErrorBoundary` directly instead of needing to create a React Element from it + export function ErrorBoundary() { + let error = useRouteError(); + return isRouteErrorResponse(error) ? ( +

+ {error.status} {error.statusText} +

+ ) : ( +

{error.message || error}

+ ); + } + ``` + + An example of this in action can be found in the [`examples/lazy-loading-router-provider`](https://github.com/remix-run/react-router/tree/main/examples/lazy-loading-router-provider) directory of the repository. + + 🙌 Huge thanks to @rossipedia for the [Initial Proposal](https://github.com/remix-run/react-router/discussions/9826) and [POC Implementation](https://github.com/remix-run/react-router/pull/9830). + +### Patch Changes + +- Fix `generatePath` incorrectly applying parameters in some cases ([#10078](https://github.com/remix-run/react-router/pull/10078)) + +## 1.3.3 + +### Patch Changes + +- Correctly perform a hard redirect for same-origin absolute URLs outside of the router `basename` ([#10076](https://github.com/remix-run/react-router/pull/10076)) +- Ensure status code and headers are maintained for `defer` loader responses in `createStaticHandler`'s `query()` method ([#10077](https://github.com/remix-run/react-router/pull/10077)) +- Change `invariant` to an `UNSAFE_invariant` export since it's only intended for internal use ([#10066](https://github.com/remix-run/react-router/pull/10066)) +- Add internal API for custom HMR implementations ([#9996](https://github.com/remix-run/react-router/pull/9996)) + +## 1.3.2 + +### Patch Changes + +- Remove inaccurate console warning for POP navigations and update active blocker logic ([#10030](https://github.com/remix-run/react-router/pull/10030)) +- Only check for differing origin on absolute URL redirects ([#10033](https://github.com/remix-run/react-router/pull/10033)) + +## 1.3.1 + +### Patch Changes + +- Fixes 2 separate issues for revalidating fetcher `shouldRevalidate` calls ([#9948](https://github.com/remix-run/react-router/pull/9948)) + - The `shouldRevalidate` function was only being called for _explicit_ revalidation scenarios (after a mutation, manual `useRevalidator` call, or an `X-Remix-Revalidate` header used for cookie setting in Remix). It was not properly being called on _implicit_ revalidation scenarios that also apply to navigation `loader` revalidation, such as a change in search params or clicking a link for the page we're already on. It's now correctly called in those additional scenarios. + - The parameters being passed were incorrect and inconsistent with one another since the `current*`/`next*` parameters reflected the static `fetcher.load` URL (and thus were identical). Instead, they should have reflected the the navigation that triggered the revalidation (as the `form*` parameters did). These parameters now correctly reflect the triggering navigation. +- Respect `preventScrollReset` on `` ([#9963](https://github.com/remix-run/react-router/pull/9963)) +- Do not short circuit on hash change only mutation submissions ([#9944](https://github.com/remix-run/react-router/pull/9944)) +- Remove `instanceof` check from `isRouteErrorResponse` to avoid bundling issues on the server ([#9930](https://github.com/remix-run/react-router/pull/9930)) +- Fix navigation for hash routers on manual URL changes ([#9980](https://github.com/remix-run/react-router/pull/9980)) +- Detect when a `defer` call only contains critical data and remove the `AbortController` ([#9965](https://github.com/remix-run/react-router/pull/9965)) +- Send the name as the value when url-encoding `File` `FormData` entries ([#9867](https://github.com/remix-run/react-router/pull/9867)) + +## 1.3.0 + +### Minor Changes + +- Added support for navigation blocking APIs ([#9709](https://github.com/remix-run/react-router/pull/9709)) +- Expose deferred information from `createStaticHandler` ([#9760](https://github.com/remix-run/react-router/pull/9760)) + +### Patch Changes + +- Improved absolute redirect url detection in actions/loaders ([#9829](https://github.com/remix-run/react-router/pull/9829)) +- Fix URL creation with memory histories ([#9814](https://github.com/remix-run/react-router/pull/9814)) +- Fix `generatePath` when optional params are present ([#9764](https://github.com/remix-run/react-router/pull/9764)) +- Fix scroll reset if a submission redirects ([#9886](https://github.com/remix-run/react-router/pull/9886)) +- Fix 404 bug with same-origin absolute redirects ([#9913](https://github.com/remix-run/react-router/pull/9913)) +- Support `OPTIONS` requests in `staticHandler.queryRoute` ([#9914](https://github.com/remix-run/react-router/pull/9914)) + +## 1.2.1 + +### Patch Changes + +- Include submission info in `shouldRevalidate` on action redirects ([#9777](https://github.com/remix-run/react-router/pull/9777), [#9782](https://github.com/remix-run/react-router/pull/9782)) +- Reset `actionData` on action redirect to current location ([#9772](https://github.com/remix-run/react-router/pull/9772)) + +## 1.2.0 + +### Minor Changes + +- Remove `unstable_` prefix from `createStaticHandler`/`createStaticRouter`/`StaticRouterProvider` ([#9738](https://github.com/remix-run/react-router/pull/9738)) + +### Patch Changes + +- Fix explicit `replace` on submissions and `PUSH` on submission to new paths ([#9734](https://github.com/remix-run/react-router/pull/9734)) +- Fix a few bugs where loader/action data wasn't properly cleared on errors ([#9735](https://github.com/remix-run/react-router/pull/9735)) +- Prevent `useLoaderData` usage in `errorElement` ([#9735](https://github.com/remix-run/react-router/pull/9735)) +- Skip initial scroll restoration for SSR apps with `hydrationData` ([#9664](https://github.com/remix-run/react-router/pull/9664)) + +## 1.1.0 + +This release introduces support for [Optional Route Segments](https://github.com/remix-run/react-router/issues/9546). Now, adding a `?` to the end of any path segment will make that entire segment optional. This works for both static segments and dynamic parameters. + +**Optional Params Examples** + +- Path `lang?/about` will match: + - `/:lang/about` + - `/about` +- Path `/multistep/:widget1?/widget2?/widget3?` will match: + - `/multistep` + - `/multistep/:widget1` + - `/multistep/:widget1/:widget2` + - `/multistep/:widget1/:widget2/:widget3` + +**Optional Static Segment Example** + +- Path `/home?` will match: + - `/` + - `/home` +- Path `/fr?/about` will match: + - `/about` + - `/fr/about` + +### Minor Changes + +- Allows optional routes and optional static segments ([#9650](https://github.com/remix-run/react-router/pull/9650)) + +### Patch Changes + +- Stop incorrectly matching on partial named parameters, i.e. ``, to align with how splat parameters work. If you were previously relying on this behavior then it's recommended to extract the static portion of the path at the `useParams` call site: ([#9506](https://github.com/remix-run/react-router/pull/9506)) + +```jsx +// Old behavior at URL /prefix-123 + }> + +function Comp() { + let params = useParams(); // { id: '123' } + let id = params.id; // "123" + ... +} + +// New behavior at URL /prefix-123 + }> + +function Comp() { + let params = useParams(); // { id: 'prefix-123' } + let id = params.id.replace(/^prefix-/, ''); // "123" + ... +} +``` + +- Persist `headers` on `loader` `request`'s after SSR document `action` request ([#9721](https://github.com/remix-run/react-router/pull/9721)) +- Fix requests sent to revalidating loaders so they reflect a GET request ([#9660](https://github.com/remix-run/react-router/pull/9660)) +- Fix issue with deeply nested optional segments ([#9727](https://github.com/remix-run/react-router/pull/9727)) +- GET forms now expose a submission on the loading navigation ([#9695](https://github.com/remix-run/react-router/pull/9695)) +- Fix error boundary tracking for multiple errors bubbling to the same boundary ([#9702](https://github.com/remix-run/react-router/pull/9702)) + +## 1.0.5 + +### Patch Changes + +- Fix requests sent to revalidating loaders so they reflect a `GET` request ([#9680](https://github.com/remix-run/react-router/pull/9680)) +- Remove `instanceof Response` checks in favor of `isResponse` ([#9690](https://github.com/remix-run/react-router/pull/9690)) +- Fix `URL` creation in Cloudflare Pages or other non-browser-environments ([#9682](https://github.com/remix-run/react-router/pull/9682), [#9689](https://github.com/remix-run/react-router/pull/9689)) +- Add `requestContext` support to static handler `query`/`queryRoute` ([#9696](https://github.com/remix-run/react-router/pull/9696)) + - Note that the unstable API of `queryRoute(path, routeId)` has been changed to `queryRoute(path, { routeId, requestContext })` + +## 1.0.4 + +### Patch Changes + +- Throw an error if an `action`/`loader` function returns `undefined` as revalidations need to know whether the loader has previously been executed. `undefined` also causes issues during SSR stringification for hydration. You should always ensure you `loader`/`action` returns a value, and you may return `null` if you don't wish to return anything. ([#9511](https://github.com/remix-run/react-router/pull/9511)) +- Properly handle redirects to external domains ([#9590](https://github.com/remix-run/react-router/pull/9590), [#9654](https://github.com/remix-run/react-router/pull/9654)) +- Preserve the HTTP method on 307/308 redirects ([#9597](https://github.com/remix-run/react-router/pull/9597)) +- Support `basename` in static data routers ([#9591](https://github.com/remix-run/react-router/pull/9591)) +- Enhanced `ErrorResponse` bodies to contain more descriptive text in internal 403/404/405 scenarios + +## 1.0.3 + +### Patch Changes + +- Fix hrefs generated when using `createHashRouter` ([#9409](https://github.com/remix-run/react-router/pull/9409)) +- fix encoding/matching issues with special chars ([#9477](https://github.com/remix-run/react-router/pull/9477), [#9496](https://github.com/remix-run/react-router/pull/9496)) +- Support `basename` and relative routing in `loader`/`action` redirects ([#9447](https://github.com/remix-run/react-router/pull/9447)) +- Ignore pathless layout routes when looking for proper submission `action` function ([#9455](https://github.com/remix-run/react-router/pull/9455)) +- properly support `index` routes with a `path` in `useResolvedPath` ([#9486](https://github.com/remix-run/react-router/pull/9486)) +- Add UMD build for `@remix-run/router` ([#9446](https://github.com/remix-run/react-router/pull/9446)) +- fix `createURL` in local file execution in Firefox ([#9464](https://github.com/remix-run/react-router/pull/9464)) +- Updates to `unstable_createStaticHandler` for incorporating into Remix ([#9482](https://github.com/remix-run/react-router/pull/9482), [#9465](https://github.com/remix-run/react-router/pull/9465)) + +## 1.0.2 + +### Patch Changes + +- Reset `actionData` after a successful action redirect ([#9334](https://github.com/remix-run/react-router/pull/9334)) +- Update `matchPath` to avoid false positives on dash-separated segments ([#9300](https://github.com/remix-run/react-router/pull/9300)) +- If an index route has children, it will result in a runtime error. We have strengthened our `RouteObject`/`RouteProps` types to surface the error in TypeScript. ([#9366](https://github.com/remix-run/react-router/pull/9366)) + +## 1.0.1 + +### Patch Changes + +- Preserve state from `initialEntries` ([#9288](https://github.com/remix-run/react-router/pull/9288)) +- Preserve `?index` for fetcher get submissions to index routes ([#9312](https://github.com/remix-run/react-router/pull/9312)) + +## 1.0.0 + +This is the first stable release of `@remix-run/router`, which provides all the underlying routing and data loading/mutation logic for `react-router`. You should _not_ be using this package directly unless you are authoring a routing library similar to `react-router`. + +For an overview of the features provided by `react-router`, we recommend you go check out the [docs](https://reactrouter.com), especially the [feature overview](https://reactrouter.com/start/overview) and the [tutorial](https://reactrouter.com/start/tutorial). + +For an overview of the features provided by `@remix-run/router`, please check out the [`README`](./README.md). diff --git a/node_modules/@remix-run/router/LICENSE.md b/node_modules/@remix-run/router/LICENSE.md new file mode 100644 index 0000000000..7d0a32c385 --- /dev/null +++ b/node_modules/@remix-run/router/LICENSE.md @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) React Training LLC 2015-2019 +Copyright (c) Remix Software Inc. 2020-2021 +Copyright (c) Shopify Inc. 2022-2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@remix-run/router/README.md b/node_modules/@remix-run/router/README.md new file mode 100644 index 0000000000..1c8536de0d --- /dev/null +++ b/node_modules/@remix-run/router/README.md @@ -0,0 +1,135 @@ +# Remix Router + +The `@remix-run/router` package is a framework-agnostic routing package (sometimes referred to as a browser-emulator) that serves as the heart of [React Router][react-router] and [Remix][remix] and provides all the core functionality for routing coupled with data loading and data mutations. It comes with built-in handling of errors, race-conditions, interruptions, cancellations, lazy-loading data, and much, much more. + +If you're using React Router, you should never `import` anything directly from the `@remix-run/router` - you should have everything you need in `react-router-dom` (or `react-router`/`react-router-native` if you're not rendering in the browser). All of those packages should re-export everything you would otherwise need from `@remix-run/router`. + +> [!WARNING] +> +> This router is a low-level package intended to be consumed by UI layer routing libraries. You should very likely not be using this package directly unless you are authoring a routing library such as [`react-router-dom`][react-router-repo] or one of it's other [UI ports][remix-routers-repo]. + +## API + +A Router instance can be created using `createRouter`: + +```js +// Create and initialize a router. "initialize" contains all side effects +// including history listeners and kicking off the initial data fetch +let router = createRouter({ + // Required properties + routes: [{ + path: '/', + loader: ({ request, params }) => { /* ... */ }, + children: [{ + path: 'home', + loader: ({ request, params }) => { /* ... */ }, + }] + }, + history: createBrowserHistory(), + + // Optional properties + basename, // Base path + mapRouteProperties, // Map framework-agnostic routes to framework-aware routes + future, // Future flags + hydrationData, // Hydration data if using server-side-rendering +}).initialize(); +``` + +Internally, the Router represents the state in an object of the following format, which is available through `router.state`. You can also register a subscriber of the signature `(state: RouterState) => void` to execute when the state updates via `router.subscribe()`; + +```ts +interface RouterState { + // False during the initial data load, true once we have our initial data + initialized: boolean; + // The `history` action of the most recently completed navigation + historyAction: Action; + // The current location of the router. During a navigation this reflects + // the "old" location and is updated upon completion of the navigation + location: Location; + // The current set of route matches + matches: DataRouteMatch[]; + // The state of the current navigation + navigation: Navigation; + // The state of any in-progress router.revalidate() calls + revalidation: RevalidationState; + // Data from the loaders for the current matches + loaderData: RouteData; + // Data from the action for the current matches + actionData: RouteData | null; + // Errors thrown from loaders/actions for the current matches + errors: RouteData | null; + // Map of all active fetchers + fetchers: Map; + // Scroll position to restore to for the active Location, false if we + // should not restore, or null if we don't have a saved position + // Note: must be enabled via router.enableScrollRestoration() + restoreScrollPosition: number | false | null; + // Proxied `preventScrollReset` value passed to router.navigate() + preventScrollReset: boolean; +} +``` + +### Navigations + +All navigations are done through the `router.navigate` API which is overloaded to support different types of navigations: + +```js +// Link navigation (pushes onto the history stack by default) +router.navigate("/page"); + +// Link navigation (replacing the history stack) +router.navigate("/page", { replace: true }); + +// Pop navigation (moving backward/forward in the history stack) +router.navigate(-1); + +// Form submission navigation +let formData = new FormData(); +formData.append(key, value); +router.navigate("/page", { + formMethod: "post", + formData, +}); + +// Relative routing from a source routeId +router.navigate("../../somewhere", { + fromRouteId: "active-route-id", +}); +``` + +### Fetchers + +Fetchers are a mechanism to call loaders/actions without triggering a navigation, and are done through the `router.fetch()` API. All fetch calls require a unique key to identify the fetcher. + +```js +// Execute the loader for /page +router.fetch("key", "/page"); + +// Submit to the action for /page +let formData = new FormData(); +formData.append(key, value); +router.fetch("key", "/page", { + formMethod: "post", + formData, +}); +``` + +### Revalidation + +By default, active loaders will revalidate after any navigation or fetcher mutation. If you need to kick off a revalidation for other use-cases, you can use `router.revalidate()` to re-execute all active loaders. + +### Future Flags + +We use _Future Flags_ in the router to help us introduce breaking changes in an opt-in fashion ahead of major releases. Please check out the [blog post][future-flags-post] and [React Router Docs][api-development-strategy] for more information on this process. The currently available future flags in `@remix-run/router` are: + +| Flag | Description | +| ------------------------ | ------------------------------------------------------------------------- | +| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method | +| `v7_prependBasename` | Prepend the `basename` to incoming `router.navigate`/`router.fetch` paths | + +[react-router]: https://reactrouter.com +[remix]: https://remix.run +[react-router-repo]: https://github.com/remix-run/react-router +[remix-routers-repo]: https://github.com/brophdawg11/remix-routers +[api-development-strategy]: https://reactrouter.com/en/main/guides/api-development-strategy +[future-flags-post]: https://remix.run/blog/future-flags diff --git a/node_modules/@remix-run/router/dist/history.d.ts b/node_modules/@remix-run/router/dist/history.d.ts new file mode 100644 index 0000000000..bda672225f --- /dev/null +++ b/node_modules/@remix-run/router/dist/history.d.ts @@ -0,0 +1,250 @@ +/** + * Actions represent the type of change to a location value. + */ +export declare enum Action { + /** + * A POP indicates a change to an arbitrary index in the history stack, such + * as a back or forward navigation. It does not describe the direction of the + * navigation, only that the current index changed. + * + * Note: This is the default action for newly created history objects. + */ + Pop = "POP", + /** + * A PUSH indicates a new entry being added to the history stack, such as when + * a link is clicked and a new page loads. When this happens, all subsequent + * entries in the stack are lost. + */ + Push = "PUSH", + /** + * A REPLACE indicates the entry at the current index in the history stack + * being replaced by a new one. + */ + Replace = "REPLACE" +} +/** + * The pathname, search, and hash values of a URL. + */ +export interface Path { + /** + * A URL pathname, beginning with a /. + */ + pathname: string; + /** + * A URL search string, beginning with a ?. + */ + search: string; + /** + * A URL fragment identifier, beginning with a #. + */ + hash: string; +} +/** + * An entry in a history stack. A location contains information about the + * URL path, as well as possibly some arbitrary state and a key. + */ +export interface Location extends Path { + /** + * A value of arbitrary data associated with this location. + */ + state: State; + /** + * A unique string associated with this location. May be used to safely store + * and retrieve data in some other storage API, like `localStorage`. + * + * Note: This value is always "default" on the initial location. + */ + key: string; +} +/** + * A change to the current location. + */ +export interface Update { + /** + * The action that triggered the change. + */ + action: Action; + /** + * The new location. + */ + location: Location; + /** + * The delta between this location and the former location in the history stack + */ + delta: number | null; +} +/** + * A function that receives notifications about location changes. + */ +export interface Listener { + (update: Update): void; +} +/** + * Describes a location that is the destination of some navigation, either via + * `history.push` or `history.replace`. This may be either a URL or the pieces + * of a URL path. + */ +export type To = string | Partial; +/** + * A history is an interface to the navigation stack. The history serves as the + * source of truth for the current location, as well as provides a set of + * methods that may be used to change it. + * + * It is similar to the DOM's `window.history` object, but with a smaller, more + * focused API. + */ +export interface History { + /** + * The last action that modified the current location. This will always be + * Action.Pop when a history instance is first created. This value is mutable. + */ + readonly action: Action; + /** + * The current location. This value is mutable. + */ + readonly location: Location; + /** + * Returns a valid href for the given `to` value that may be used as + * the value of an
attribute. + * + * @param to - The destination URL + */ + createHref(to: To): string; + /** + * Returns a URL for the given `to` value + * + * @param to - The destination URL + */ + createURL(to: To): URL; + /** + * Encode a location the same way window.history would do (no-op for memory + * history) so we ensure our PUSH/REPLACE navigations for data routers + * behave the same as POP + * + * @param to Unencoded path + */ + encodeLocation(to: To): Path; + /** + * Pushes a new location onto the history stack, increasing its length by one. + * If there were any entries in the stack after the current one, they are + * lost. + * + * @param to - The new URL + * @param state - Data to associate with the new location + */ + push(to: To, state?: any): void; + /** + * Replaces the current location in the history stack with a new one. The + * location that was replaced will no longer be available. + * + * @param to - The new URL + * @param state - Data to associate with the new location + */ + replace(to: To, state?: any): void; + /** + * Navigates `n` entries backward/forward in the history stack relative to the + * current index. For example, a "back" navigation would use go(-1). + * + * @param delta - The delta in the stack index + */ + go(delta: number): void; + /** + * Sets up a listener that will be called whenever the current location + * changes. + * + * @param listener - A function that will be called when the location changes + * @returns unlisten - A function that may be used to stop listening + */ + listen(listener: Listener): () => void; +} +/** + * A user-supplied object that describes a location. Used when providing + * entries to `createMemoryHistory` via its `initialEntries` option. + */ +export type InitialEntry = string | Partial; +export type MemoryHistoryOptions = { + initialEntries?: InitialEntry[]; + initialIndex?: number; + v5Compat?: boolean; +}; +/** + * A memory history stores locations in memory. This is useful in stateful + * environments where there is no web browser, such as node tests or React + * Native. + */ +export interface MemoryHistory extends History { + /** + * The current index in the history stack. + */ + readonly index: number; +} +/** + * Memory history stores the current location in memory. It is designed for use + * in stateful non-browser environments like tests and React Native. + */ +export declare function createMemoryHistory(options?: MemoryHistoryOptions): MemoryHistory; +/** + * A browser history stores the current location in regular URLs in a web + * browser environment. This is the standard for most web apps and provides the + * cleanest URLs the browser's address bar. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory + */ +export interface BrowserHistory extends UrlHistory { +} +export type BrowserHistoryOptions = UrlHistoryOptions; +/** + * Browser history stores the location in regular URLs. This is the standard for + * most web apps, but it requires some configuration on the server to ensure you + * serve the same app at multiple URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory + */ +export declare function createBrowserHistory(options?: BrowserHistoryOptions): BrowserHistory; +/** + * A hash history stores the current location in the fragment identifier portion + * of the URL in a web browser environment. + * + * This is ideal for apps that do not control the server for some reason + * (because the fragment identifier is never sent to the server), including some + * shared hosting environments that do not provide fine-grained controls over + * which pages are served at which URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory + */ +export interface HashHistory extends UrlHistory { +} +export type HashHistoryOptions = UrlHistoryOptions; +/** + * Hash history stores the location in window.location.hash. This makes it ideal + * for situations where you don't want to send the location to the server for + * some reason, either because you do cannot configure it or the URL space is + * reserved for something else. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory + */ +export declare function createHashHistory(options?: HashHistoryOptions): HashHistory; +/** + * @private + */ +export declare function invariant(value: boolean, message?: string): asserts value; +export declare function invariant(value: T | null | undefined, message?: string): asserts value is T; +export declare function warning(cond: any, message: string): void; +/** + * Creates a Location object with a unique key from the given Path + */ +export declare function createLocation(current: string | Location, to: To, state?: any, key?: string): Readonly; +/** + * Creates a string URL path from the given pathname, search, and hash components. + */ +export declare function createPath({ pathname, search, hash, }: Partial): string; +/** + * Parses a string URL path into its separate pathname, search, and hash components. + */ +export declare function parsePath(path: string): Partial; +export interface UrlHistory extends History { +} +export type UrlHistoryOptions = { + window?: Window; + v5Compat?: boolean; +}; diff --git a/node_modules/@remix-run/router/dist/index.d.ts b/node_modules/@remix-run/router/dist/index.d.ts new file mode 100644 index 0000000000..ece1131729 --- /dev/null +++ b/node_modules/@remix-run/router/dist/index.d.ts @@ -0,0 +1,9 @@ +export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, DataStrategyFunction as unstable_DataStrategyFunction, DataStrategyFunctionArgs as unstable_DataStrategyFunctionArgs, DataStrategyMatch as unstable_DataStrategyMatch, ErrorResponse, FormEncType, FormMethod, HandlerResult as unstable_HandlerResult, HTMLFormMethod, JsonFunction, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, AgnosticPatchRoutesOnMissFunction as unstable_AgnosticPatchRoutesOnMissFunction, PathMatch, PathParam, PathPattern, RedirectFunction, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, TrackedPromise, UIMatch, V7_FormMethod, } from "./utils"; +export { AbortedDeferredError, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, redirectDocument, resolvePath, resolveTo, stripBasename, } from "./utils"; +export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history"; +export { Action, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, parsePath, } from "./history"; +export * from "./router"; +/** @internal */ +export type { RouteManifest as UNSAFE_RouteManifest } from "./utils"; +export { DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, decodePath as UNSAFE_decodePath, getResolveToMatches as UNSAFE_getResolveToMatches, } from "./utils"; +export { invariant as UNSAFE_invariant, warning as UNSAFE_warning, } from "./history"; diff --git a/node_modules/@remix-run/router/dist/router.cjs.js b/node_modules/@remix-run/router/dist/router.cjs.js new file mode 100644 index 0000000000..0fbf253e04 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.cjs.js @@ -0,0 +1,5440 @@ +/** + * @remix-run/router v1.18.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _extends() { + _extends = Object.assign ? Object.assign.bind() : function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); +} + +//////////////////////////////////////////////////////////////////////////////// +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// + +/** + * Actions represent the type of change to a location value. + */ +let Action = /*#__PURE__*/function (Action) { + Action["Pop"] = "POP"; + Action["Push"] = "PUSH"; + Action["Replace"] = "REPLACE"; + return Action; +}({}); + +/** + * The pathname, search, and hash values of a URL. + */ + +// TODO: (v7) Change the Location generic default from `any` to `unknown` and +// remove Remix `useLocation` wrapper. +/** + * An entry in a history stack. A location contains information about the + * URL path, as well as possibly some arbitrary state and a key. + */ +/** + * A change to the current location. + */ +/** + * A function that receives notifications about location changes. + */ +/** + * Describes a location that is the destination of some navigation, either via + * `history.push` or `history.replace`. This may be either a URL or the pieces + * of a URL path. + */ +/** + * A history is an interface to the navigation stack. The history serves as the + * source of truth for the current location, as well as provides a set of + * methods that may be used to change it. + * + * It is similar to the DOM's `window.history` object, but with a smaller, more + * focused API. + */ +const PopStateEventType = "popstate"; +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Memory History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A user-supplied object that describes a location. Used when providing + * entries to `createMemoryHistory` via its `initialEntries` option. + */ +/** + * A memory history stores locations in memory. This is useful in stateful + * environments where there is no web browser, such as node tests or React + * Native. + */ +/** + * Memory history stores the current location in memory. It is designed for use + * in stateful non-browser environments like tests and React Native. + */ +function createMemoryHistory(options) { + if (options === void 0) { + options = {}; + } + let { + initialEntries = ["/"], + initialIndex, + v5Compat = false + } = options; + let entries; // Declare so we can access from createMemoryLocation + entries = initialEntries.map((entry, index) => createMemoryLocation(entry, typeof entry === "string" ? null : entry.state, index === 0 ? "default" : undefined)); + let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex); + let action = Action.Pop; + let listener = null; + function clampIndex(n) { + return Math.min(Math.max(n, 0), entries.length - 1); + } + function getCurrentLocation() { + return entries[index]; + } + function createMemoryLocation(to, state, key) { + if (state === void 0) { + state = null; + } + let location = createLocation(entries ? getCurrentLocation().pathname : "/", to, state, key); + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in memory history: " + JSON.stringify(to)); + return location; + } + function createHref(to) { + return typeof to === "string" ? to : createPath(to); + } + let history = { + get index() { + return index; + }, + get action() { + return action; + }, + get location() { + return getCurrentLocation(); + }, + createHref, + createURL(to) { + return new URL(createHref(to), "http://localhost"); + }, + encodeLocation(to) { + let path = typeof to === "string" ? parsePath(to) : to; + return { + pathname: path.pathname || "", + search: path.search || "", + hash: path.hash || "" + }; + }, + push(to, state) { + action = Action.Push; + let nextLocation = createMemoryLocation(to, state); + index += 1; + entries.splice(index, entries.length, nextLocation); + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 1 + }); + } + }, + replace(to, state) { + action = Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 0 + }); + } + }, + go(delta) { + action = Action.Pop; + let nextIndex = clampIndex(index + delta); + let nextLocation = entries[nextIndex]; + index = nextIndex; + if (listener) { + listener({ + action, + location: nextLocation, + delta + }); + } + }, + listen(fn) { + listener = fn; + return () => { + listener = null; + }; + } + }; + return history; +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Browser History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A browser history stores the current location in regular URLs in a web + * browser environment. This is the standard for most web apps and provides the + * cleanest URLs the browser's address bar. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory + */ +/** + * Browser history stores the location in regular URLs. This is the standard for + * most web apps, but it requires some configuration on the server to ensure you + * serve the same app at multiple URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory + */ +function createBrowserHistory(options) { + if (options === void 0) { + options = {}; + } + function createBrowserLocation(window, globalHistory) { + let { + pathname, + search, + hash + } = window.location; + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createBrowserHref(window, to) { + return typeof to === "string" ? to : createPath(to); + } + return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options); +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Hash History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A hash history stores the current location in the fragment identifier portion + * of the URL in a web browser environment. + * + * This is ideal for apps that do not control the server for some reason + * (because the fragment identifier is never sent to the server), including some + * shared hosting environments that do not provide fine-grained controls over + * which pages are served at which URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory + */ +/** + * Hash history stores the location in window.location.hash. This makes it ideal + * for situations where you don't want to send the location to the server for + * some reason, either because you do cannot configure it or the URL space is + * reserved for something else. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory + */ +function createHashHistory(options) { + if (options === void 0) { + options = {}; + } + function createHashLocation(window, globalHistory) { + let { + pathname = "/", + search = "", + hash = "" + } = parsePath(window.location.hash.substr(1)); + + // Hash URL should always have a leading / just like window.location.pathname + // does, so if an app ends up at a route like /#something then we add a + // leading slash so all of our path-matching behaves the same as if it would + // in a browser router. This is particularly important when there exists a + // root splat route () since that matches internally against + // "/*" and we'd expect /#something to 404 in a hash router app. + if (!pathname.startsWith("/") && !pathname.startsWith(".")) { + pathname = "/" + pathname; + } + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createHashHref(window, to) { + let base = window.document.querySelector("base"); + let href = ""; + if (base && base.getAttribute("href")) { + let url = window.location.href; + let hashIndex = url.indexOf("#"); + href = hashIndex === -1 ? url : url.slice(0, hashIndex); + } + return href + "#" + (typeof to === "string" ? to : createPath(to)); + } + function validateHashLocation(location, to) { + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")"); + } + return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options); +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region UTILS +//////////////////////////////////////////////////////////////////////////////// + +/** + * @private + */ +function invariant(value, message) { + if (value === false || value === null || typeof value === "undefined") { + throw new Error(message); + } +} +function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + try { + // Welcome to debugging history! + // + // This error is thrown as a convenience, so you can more easily + // find the source for a warning that appears in the console by + // enabling "pause on exceptions" in your JavaScript debugger. + throw new Error(message); + // eslint-disable-next-line no-empty + } catch (e) {} + } +} +function createKey() { + return Math.random().toString(36).substr(2, 8); +} + +/** + * For browser-based histories, we combine the state and key into an object + */ +function getHistoryState(location, index) { + return { + usr: location.state, + key: location.key, + idx: index + }; +} + +/** + * Creates a Location object with a unique key from the given Path + */ +function createLocation(current, to, state, key) { + if (state === void 0) { + state = null; + } + let location = _extends({ + pathname: typeof current === "string" ? current : current.pathname, + search: "", + hash: "" + }, typeof to === "string" ? parsePath(to) : to, { + state, + // TODO: This could be cleaned up. push/replace should probably just take + // full Locations now and avoid the need to run through this flow at all + // But that's a pretty big refactor to the current test suite so going to + // keep as is for the time being and just let any incoming keys take precedence + key: to && to.key || key || createKey() + }); + return location; +} + +/** + * Creates a string URL path from the given pathname, search, and hash components. + */ +function createPath(_ref) { + let { + pathname = "/", + search = "", + hash = "" + } = _ref; + if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search; + if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash; + return pathname; +} + +/** + * Parses a string URL path into its separate pathname, search, and hash components. + */ +function parsePath(path) { + let parsedPath = {}; + if (path) { + let hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + parsedPath.hash = path.substr(hashIndex); + path = path.substr(0, hashIndex); + } + let searchIndex = path.indexOf("?"); + if (searchIndex >= 0) { + parsedPath.search = path.substr(searchIndex); + path = path.substr(0, searchIndex); + } + if (path) { + parsedPath.pathname = path; + } + } + return parsedPath; +} +function getUrlBasedHistory(getLocation, createHref, validateLocation, options) { + if (options === void 0) { + options = {}; + } + let { + window = document.defaultView, + v5Compat = false + } = options; + let globalHistory = window.history; + let action = Action.Pop; + let listener = null; + let index = getIndex(); + // Index should only be null when we initialize. If not, it's because the + // user called history.pushState or history.replaceState directly, in which + // case we should log a warning as it will result in bugs. + if (index == null) { + index = 0; + globalHistory.replaceState(_extends({}, globalHistory.state, { + idx: index + }), ""); + } + function getIndex() { + let state = globalHistory.state || { + idx: null + }; + return state.idx; + } + function handlePop() { + action = Action.Pop; + let nextIndex = getIndex(); + let delta = nextIndex == null ? null : nextIndex - index; + index = nextIndex; + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } + function push(to, state) { + action = Action.Push; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex() + 1; + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + + // try...catch because iOS limits us to 100 pushState calls :/ + try { + globalHistory.pushState(historyState, "", url); + } catch (error) { + // If the exception is because `state` can't be serialized, let that throw + // outwards just like a replace call would so the dev knows the cause + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + if (error instanceof DOMException && error.name === "DataCloneError") { + throw error; + } + // They are going to lose state here, but there is no real + // way to warn them about it since the page will refresh... + window.location.assign(url); + } + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 1 + }); + } + } + function replace(to, state) { + action = Action.Replace; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex(); + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + globalHistory.replaceState(historyState, "", url); + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 0 + }); + } + } + function createURL(to) { + // window.location.origin is "null" (the literal string value) in Firefox + // under certain conditions, notably when serving from a local HTML file + // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297 + let base = window.location.origin !== "null" ? window.location.origin : window.location.href; + let href = typeof to === "string" ? to : createPath(to); + // Treating this as a full URL will strip any trailing spaces so we need to + // pre-encode them since they might be part of a matching splat param from + // an ancestor route + href = href.replace(/ $/, "%20"); + invariant(base, "No window.location.(origin|href) available to create URL for href: " + href); + return new URL(href, base); + } + let history = { + get action() { + return action; + }, + get location() { + return getLocation(window, globalHistory); + }, + listen(fn) { + if (listener) { + throw new Error("A history only accepts one active listener"); + } + window.addEventListener(PopStateEventType, handlePop); + listener = fn; + return () => { + window.removeEventListener(PopStateEventType, handlePop); + listener = null; + }; + }, + createHref(to) { + return createHref(window, to); + }, + createURL, + encodeLocation(to) { + // Encode a Location the same way window.location would + let url = createURL(to); + return { + pathname: url.pathname, + search: url.search, + hash: url.hash + }; + }, + push, + replace, + go(n) { + return globalHistory.go(n); + } + }; + return history; +} + +//#endregion + +/** + * Map of routeId -> data returned from a loader/action/error + */ + +let ResultType = /*#__PURE__*/function (ResultType) { + ResultType["data"] = "data"; + ResultType["deferred"] = "deferred"; + ResultType["redirect"] = "redirect"; + ResultType["error"] = "error"; + return ResultType; +}({}); + +/** + * Successful result from a loader or action + */ + +/** + * Successful defer() result from a loader or action + */ + +/** + * Redirect result from a loader or action + */ + +/** + * Unsuccessful result from a loader or action + */ + +/** + * Result from a loader or action - potentially successful or unsuccessful + */ + +/** + * Result from a loader or action called via dataStrategy + */ + +/** + * Users can specify either lowercase or uppercase form methods on `
`, + * useSubmit(), ``, etc. + */ + +/** + * Active navigation/fetcher form methods are exposed in lowercase on the + * RouterState + */ + +/** + * In v7, active navigation/fetcher form methods are exposed in uppercase on the + * RouterState. This is to align with the normalization done via fetch(). + */ + +// Thanks https://github.com/sindresorhus/type-fest! + +/** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ + +/** + * @private + * Arguments passed to route loader/action functions. Same for now but we keep + * this as a private implementation detail in case they diverge in the future. + */ + +// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers: +// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs +// Also, make them a type alias instead of an interface +/** + * Arguments passed to loader functions + */ +/** + * Arguments passed to action functions + */ +/** + * Loaders and actions can return anything except `undefined` (`null` is a + * valid return value if there is no data to return). Responses are preferred + * and will ease any future migration to Remix + */ +/** + * Route loader function signature + */ +/** + * Route action function signature + */ +/** + * Arguments passed to shouldRevalidate function + */ +/** + * Route shouldRevalidate function signature. This runs after any submission + * (navigation or fetcher), so we flatten the navigation/fetcher submission + * onto the arguments. It shouldn't matter whether it came from a navigation + * or a fetcher, what really matters is the URLs and the formData since loaders + * have to re-run based on the data models that were potentially mutated. + */ +/** + * Function provided by the framework-aware layers to set `hasErrorBoundary` + * from the framework-aware `errorElement` prop + * + * @deprecated Use `mapRouteProperties` instead + */ +/** + * Function provided by the framework-aware layers to set any framework-specific + * properties from framework-agnostic properties + */ +/** + * Keys we cannot change from within a lazy() function. We spread all other keys + * onto the route. Either they're meaningful to the router, or they'll get + * ignored. + */ +const immutableRouteKeys = new Set(["lazy", "caseSensitive", "path", "id", "index", "children"]); + +/** + * lazy() function to load a route definition, which can add non-matching + * related properties to a route + */ + +/** + * Base RouteObject with common props shared by all types of routes + */ + +/** + * Index routes must not have children + */ + +/** + * Non-index routes may have children, but cannot have index + */ + +/** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ + +/** + * A data route object, which is just a RouteObject with a required unique ID + */ + +// Recursive helper for finding path parameters in the absence of wildcards + +/** + * Examples: + * "/a/b/*" -> "*" + * ":a" -> "a" + * "/a/:b" -> "b" + * "/a/blahblahblah:b" -> "b" + * "/:a/:b" -> "a" | "b" + * "/:a/b/:c/*" -> "a" | "c" | "*" + */ + +// Attempt to parse the given string segment. If it fails, then just return the +// plain string type as a default fallback. Otherwise, return the union of the +// parsed string literals that were referenced as dynamic segments in the route. +/** + * The parameters that were parsed from the URL path. + */ +/** + * A RouteMatch contains info about how a route matched a URL. + */ +function isIndexRoute(route) { + return route.index === true; +} + +// Walk the route tree generating unique IDs where necessary, so we are working +// solely with AgnosticDataRouteObject's within the Router +function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) { + if (parentPath === void 0) { + parentPath = []; + } + if (manifest === void 0) { + manifest = {}; + } + return routes.map((route, index) => { + let treePath = [...parentPath, String(index)]; + let id = typeof route.id === "string" ? route.id : treePath.join("-"); + invariant(route.index !== true || !route.children, "Cannot specify children on an index route"); + invariant(!manifest[id], "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, mapRouteProperties(route), { + id + }); + manifest[id] = indexRoute; + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, mapRouteProperties(route), { + id, + children: undefined + }); + manifest[id] = pathOrLayoutRoute; + if (route.children) { + pathOrLayoutRoute.children = convertRoutesToDataRoutes(route.children, mapRouteProperties, treePath, manifest); + } + return pathOrLayoutRoute; + } + }); +} + +/** + * Matches the given routes to a location and returns the match data. + * + * @see https://reactrouter.com/utils/match-routes + */ +function matchRoutes(routes, locationArg, basename) { + if (basename === void 0) { + basename = "/"; + } + return matchRoutesImpl(routes, locationArg, basename, false); +} +function matchRoutesImpl(routes, locationArg, basename, allowPartial) { + let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; + let pathname = stripBasename(location.pathname || "/", basename); + if (pathname == null) { + return null; + } + let branches = flattenRoutes(routes); + rankRouteBranches(branches); + let matches = null; + for (let i = 0; matches == null && i < branches.length; ++i) { + // Incoming pathnames are generally encoded from either window.location + // or from router.navigate, but we want to match against the unencoded + // paths in the route definitions. Memory router locations won't be + // encoded here but there also shouldn't be anything to decode so this + // should be a safe operation. This avoids needing matchRoutes to be + // history-aware. + let decoded = decodePath(pathname); + matches = matchRouteBranch(branches[i], decoded, allowPartial); + } + return matches; +} +function convertRouteMatchToUiMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; +} +function flattenRoutes(routes, branches, parentsMeta, parentPath) { + if (branches === void 0) { + branches = []; + } + if (parentsMeta === void 0) { + parentsMeta = []; + } + if (parentPath === void 0) { + parentPath = ""; + } + let flattenRoute = (route, index, relativePath) => { + let meta = { + relativePath: relativePath === undefined ? route.path || "" : relativePath, + caseSensitive: route.caseSensitive === true, + childrenIndex: index, + route + }; + if (meta.relativePath.startsWith("/")) { + invariant(meta.relativePath.startsWith(parentPath), "Absolute route path \"" + meta.relativePath + "\" nested under path " + ("\"" + parentPath + "\" is not valid. An absolute child route path ") + "must start with the combined path of all its parent routes."); + meta.relativePath = meta.relativePath.slice(parentPath.length); + } + let path = joinPaths([parentPath, meta.relativePath]); + let routesMeta = parentsMeta.concat(meta); + + // Add the children before adding this route to the array, so we traverse the + // route tree depth-first and child routes appear before their parents in + // the "flattened" version. + if (route.children && route.children.length > 0) { + invariant( + // Our types know better, but runtime JS may not! + // @ts-expect-error + route.index !== true, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")); + flattenRoutes(route.children, branches, routesMeta, path); + } + + // Routes without a path shouldn't ever match by themselves unless they are + // index routes, so don't add them to the list of possible branches. + if (route.path == null && !route.index) { + return; + } + branches.push({ + path, + score: computeScore(path, route.index), + routesMeta + }); + }; + routes.forEach((route, index) => { + var _route$path; + // coarse-grain check for optional params + if (route.path === "" || !((_route$path = route.path) != null && _route$path.includes("?"))) { + flattenRoute(route, index); + } else { + for (let exploded of explodeOptionalSegments(route.path)) { + flattenRoute(route, index, exploded); + } + } + }); + return branches; +} + +/** + * Computes all combinations of optional path segments for a given path, + * excluding combinations that are ambiguous and of lower priority. + * + * For example, `/one/:two?/three/:four?/:five?` explodes to: + * - `/one/three` + * - `/one/:two/three` + * - `/one/three/:four` + * - `/one/three/:five` + * - `/one/:two/three/:four` + * - `/one/:two/three/:five` + * - `/one/three/:four/:five` + * - `/one/:two/three/:four/:five` + */ +function explodeOptionalSegments(path) { + let segments = path.split("/"); + if (segments.length === 0) return []; + let [first, ...rest] = segments; + + // Optional path segments are denoted by a trailing `?` + let isOptional = first.endsWith("?"); + // Compute the corresponding required segment: `foo?` -> `foo` + let required = first.replace(/\?$/, ""); + if (rest.length === 0) { + // Intepret empty string as omitting an optional segment + // `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three` + return isOptional ? [required, ""] : [required]; + } + let restExploded = explodeOptionalSegments(rest.join("/")); + let result = []; + + // All child paths with the prefix. Do this for all children before the + // optional version for all children, so we get consistent ordering where the + // parent optional aspect is preferred as required. Otherwise, we can get + // child sections interspersed where deeper optional segments are higher than + // parent optional segments, where for example, /:two would explode _earlier_ + // then /:one. By always including the parent as required _for all children_ + // first, we avoid this issue + result.push(...restExploded.map(subpath => subpath === "" ? required : [required, subpath].join("/"))); + + // Then, if this is an optional value, add all child versions without + if (isOptional) { + result.push(...restExploded); + } + + // for absolute paths, ensure `/` instead of empty segment + return result.map(exploded => path.startsWith("/") && exploded === "" ? "/" : exploded); +} +function rankRouteBranches(branches) { + branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first + : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex))); +} +const paramRe = /^:[\w-]+$/; +const dynamicSegmentValue = 3; +const indexRouteValue = 2; +const emptySegmentValue = 1; +const staticSegmentValue = 10; +const splatPenalty = -2; +const isSplat = s => s === "*"; +function computeScore(path, index) { + let segments = path.split("/"); + let initialScore = segments.length; + if (segments.some(isSplat)) { + initialScore += splatPenalty; + } + if (index) { + initialScore += indexRouteValue; + } + return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore); +} +function compareIndexes(a, b) { + let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); + return siblings ? + // If two routes are siblings, we should try to match the earlier sibling + // first. This allows people to have fine-grained control over the matching + // behavior by simply putting routes with identical paths in the order they + // want them tried. + a[a.length - 1] - b[b.length - 1] : + // Otherwise, it doesn't really make sense to rank non-siblings by index, + // so they sort equally. + 0; +} +function matchRouteBranch(branch, pathname, allowPartial) { + if (allowPartial === void 0) { + allowPartial = false; + } + let { + routesMeta + } = branch; + let matchedParams = {}; + let matchedPathname = "/"; + let matches = []; + for (let i = 0; i < routesMeta.length; ++i) { + let meta = routesMeta[i]; + let end = i === routesMeta.length - 1; + let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/"; + let match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end + }, remainingPathname); + let route = meta.route; + if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) { + match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end: false + }, remainingPathname); + } + if (!match) { + return null; + } + Object.assign(matchedParams, match.params); + matches.push({ + // TODO: Can this as be avoided? + params: matchedParams, + pathname: joinPaths([matchedPathname, match.pathname]), + pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])), + route + }); + if (match.pathnameBase !== "/") { + matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); + } + } + return matches; +} + +/** + * Returns a path with params interpolated. + * + * @see https://reactrouter.com/utils/generate-path + */ +function generatePath(originalPath, params) { + if (params === void 0) { + params = {}; + } + let path = originalPath; + if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { + warning(false, "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + path = path.replace(/\*$/, "/*"); + } + + // ensure `/` is added at the beginning if the path is absolute + const prefix = path.startsWith("/") ? "/" : ""; + const stringify = p => p == null ? "" : typeof p === "string" ? p : String(p); + const segments = path.split(/\/+/).map((segment, index, array) => { + const isLastSegment = index === array.length - 1; + + // only apply the splat if it's the last segment + if (isLastSegment && segment === "*") { + const star = "*"; + // Apply the splat + return stringify(params[star]); + } + const keyMatch = segment.match(/^:([\w-]+)(\??)$/); + if (keyMatch) { + const [, key, optional] = keyMatch; + let param = params[key]; + invariant(optional === "?" || param != null, "Missing \":" + key + "\" param"); + return stringify(param); + } + + // Remove any optional markers from optional static segments + return segment.replace(/\?$/g, ""); + }) + // Remove empty segments + .filter(segment => !!segment); + return prefix + segments.join("/"); +} + +/** + * A PathPattern is used to match on some portion of a URL pathname. + */ + +/** + * A PathMatch contains info about how a PathPattern matched on a URL pathname. + */ + +/** + * Performs pattern matching on a URL pathname and returns information about + * the match. + * + * @see https://reactrouter.com/utils/match-path + */ +function matchPath(pattern, pathname) { + if (typeof pattern === "string") { + pattern = { + path: pattern, + caseSensitive: false, + end: true + }; + } + let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end); + let match = pathname.match(matcher); + if (!match) return null; + let matchedPathname = match[0]; + let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); + let captureGroups = match.slice(1); + let params = compiledParams.reduce((memo, _ref, index) => { + let { + paramName, + isOptional + } = _ref; + // We need to compute the pathnameBase here using the raw splat value + // instead of using params["*"] later because it will be decoded then + if (paramName === "*") { + let splatValue = captureGroups[index] || ""; + pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1"); + } + const value = captureGroups[index]; + if (isOptional && !value) { + memo[paramName] = undefined; + } else { + memo[paramName] = (value || "").replace(/%2F/g, "/"); + } + return memo; + }, {}); + return { + params, + pathname: matchedPathname, + pathnameBase, + pattern + }; +} +function compilePath(path, caseSensitive, end) { + if (caseSensitive === void 0) { + caseSensitive = false; + } + if (end === void 0) { + end = true; + } + warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + let params = []; + let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below + .replace(/^\/*/, "/") // Make sure it has a leading / + .replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars + .replace(/\/:([\w-]+)(\?)?/g, (_, paramName, isOptional) => { + params.push({ + paramName, + isOptional: isOptional != null + }); + return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)"; + }); + if (path.endsWith("*")) { + params.push({ + paramName: "*" + }); + regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest + : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"] + } else if (end) { + // When matching to the end, ignore trailing slashes + regexpSource += "\\/*$"; + } else if (path !== "" && path !== "/") { + // If our path is non-empty and contains anything beyond an initial slash, + // then we have _some_ form of path in our regex, so we should expect to + // match only if we find the end of this path segment. Look for an optional + // non-captured trailing slash (to match a portion of the URL) or the end + // of the path (if we've matched to the end). We used to do this with a + // word boundary but that gives false positives on routes like + // /user-preferences since `-` counts as a word boundary. + regexpSource += "(?:(?=\\/|$))"; + } else ; + let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i"); + return [matcher, params]; +} +function decodePath(value) { + try { + return value.split("/").map(v => decodeURIComponent(v).replace(/\//g, "%2F")).join("/"); + } catch (error) { + warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ").")); + return value; + } +} + +/** + * @private + */ +function stripBasename(pathname, basename) { + if (basename === "/") return pathname; + if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { + return null; + } + + // We want to leave trailing slash behavior in the user's control, so if they + // specify a basename with a trailing slash, we should support it + let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length; + let nextChar = pathname.charAt(startIndex); + if (nextChar && nextChar !== "/") { + // pathname does not start with basename/ + return null; + } + return pathname.slice(startIndex) || "/"; +} + +/** + * Returns a resolved path object relative to the given pathname. + * + * @see https://reactrouter.com/utils/resolve-path + */ +function resolvePath(to, fromPathname) { + if (fromPathname === void 0) { + fromPathname = "/"; + } + let { + pathname: toPathname, + search = "", + hash = "" + } = typeof to === "string" ? parsePath(to) : to; + let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname; + return { + pathname, + search: normalizeSearch(search), + hash: normalizeHash(hash) + }; +} +function resolvePathname(relativePath, fromPathname) { + let segments = fromPathname.replace(/\/+$/, "").split("/"); + let relativeSegments = relativePath.split("/"); + relativeSegments.forEach(segment => { + if (segment === "..") { + // Keep the root "" segment so the pathname starts at / + if (segments.length > 1) segments.pop(); + } else if (segment !== ".") { + segments.push(segment); + } + }); + return segments.length > 1 ? segments.join("/") : "/"; +} +function getInvalidPathError(char, field, dest, path) { + return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in and the router will parse it for you."; +} + +/** + * @private + * + * When processing relative navigation we want to ignore ancestor routes that + * do not contribute to the path, such that index/pathless layout routes don't + * interfere. + * + * For example, when moving a route element into an index route and/or a + * pathless layout route, relative link behavior contained within should stay + * the same. Both of the following examples should link back to the root: + * + * + * + * + * + * + * + * }> // <-- Does not contribute + * // <-- Does not contribute + * + * + */ +function getPathContributingMatches(matches) { + return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0); +} + +// Return the array of pathnames for the current route matches - used to +// generate the routePathnames input for resolveTo() +function getResolveToMatches(matches, v7_relativeSplatPath) { + let pathMatches = getPathContributingMatches(matches); + + // When v7_relativeSplatPath is enabled, use the full pathname for the leaf + // match so we include splat values for "." links. See: + // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329 + if (v7_relativeSplatPath) { + return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase); + } + return pathMatches.map(match => match.pathnameBase); +} + +/** + * @private + */ +function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) { + if (isPathRelative === void 0) { + isPathRelative = false; + } + let to; + if (typeof toArg === "string") { + to = parsePath(toArg); + } else { + to = _extends({}, toArg); + invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to)); + invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to)); + invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to)); + } + let isEmptyPath = toArg === "" || to.pathname === ""; + let toPathname = isEmptyPath ? "/" : to.pathname; + let from; + + // Routing is relative to the current pathname if explicitly requested. + // + // If a pathname is explicitly provided in `to`, it should be relative to the + // route context. This is explained in `Note on `` values` in our + // migration guide from v5 as a means of disambiguation between `to` values + // that begin with `/` and those that do not. However, this is problematic for + // `to` values that do not provide a pathname. `to` can simply be a search or + // hash string, in which case we should assume that the navigation is relative + // to the current location's pathname and *not* the route pathname. + if (toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + // With relative="route" (the default), each leading .. segment means + // "go up one route" instead of "go up one URL segment". This is a key + // difference from how works and a major reason we call this a + // "to" value instead of a "href". + if (!isPathRelative && toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + to.pathname = toSegments.join("/"); + } + from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; + } + let path = resolvePath(to, from); + + // Ensure the pathname has a trailing slash if the original "to" had one + let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/"); + // Or if this was a link to the current path which has a trailing slash + let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); + if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) { + path.pathname += "/"; + } + return path; +} + +/** + * @private + */ +function getToPathname(to) { + // Empty strings should be treated the same as / paths + return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? parsePath(to).pathname : to.pathname; +} + +/** + * @private + */ +const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/"); + +/** + * @private + */ +const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/"); + +/** + * @private + */ +const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search; + +/** + * @private + */ +const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; +/** + * This is a shortcut for creating `application/json` responses. Converts `data` + * to JSON and sets the `Content-Type` header. + */ +const json = function json(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + let headers = new Headers(responseInit.headers); + if (!headers.has("Content-Type")) { + headers.set("Content-Type", "application/json; charset=utf-8"); + } + return new Response(JSON.stringify(data), _extends({}, responseInit, { + headers + })); +}; +class AbortedDeferredError extends Error {} +class DeferredData { + constructor(data, responseInit) { + this.pendingKeysSet = new Set(); + this.subscribers = new Set(); + this.deferredKeys = []; + invariant(data && typeof data === "object" && !Array.isArray(data), "defer() only accepts plain objects"); + + // Set up an AbortController + Promise we can race against to exit early + // cancellation + let reject; + this.abortPromise = new Promise((_, r) => reject = r); + this.controller = new AbortController(); + let onAbort = () => reject(new AbortedDeferredError("Deferred data aborted")); + this.unlistenAbortSignal = () => this.controller.signal.removeEventListener("abort", onAbort); + this.controller.signal.addEventListener("abort", onAbort); + this.data = Object.entries(data).reduce((acc, _ref2) => { + let [key, value] = _ref2; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + if (this.done) { + // All incoming values were resolved + this.unlistenAbortSignal(); + } + this.init = responseInit; + } + trackPromise(key, value) { + if (!(value instanceof Promise)) { + return value; + } + this.deferredKeys.push(key); + this.pendingKeysSet.add(key); + + // We store a little wrapper promise that will be extended with + // _data/_error props upon resolve/reject + let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, undefined, data), error => this.onSettle(promise, key, error)); + + // Register rejection listeners to avoid uncaught promise rejections on + // errors or aborted deferred values + promise.catch(() => {}); + Object.defineProperty(promise, "_tracked", { + get: () => true + }); + return promise; + } + onSettle(promise, key, error, data) { + if (this.controller.signal.aborted && error instanceof AbortedDeferredError) { + this.unlistenAbortSignal(); + Object.defineProperty(promise, "_error", { + get: () => error + }); + return Promise.reject(error); + } + this.pendingKeysSet.delete(key); + if (this.done) { + // Nothing left to abort! + this.unlistenAbortSignal(); + } + + // If the promise was resolved/rejected with undefined, we'll throw an error as you + // should always resolve with a value or null + if (error === undefined && data === undefined) { + let undefinedError = new Error("Deferred data for key \"" + key + "\" resolved/rejected with `undefined`, " + "you must resolve/reject with a value or `null`."); + Object.defineProperty(promise, "_error", { + get: () => undefinedError + }); + this.emit(false, key); + return Promise.reject(undefinedError); + } + if (data === undefined) { + Object.defineProperty(promise, "_error", { + get: () => error + }); + this.emit(false, key); + return Promise.reject(error); + } + Object.defineProperty(promise, "_data", { + get: () => data + }); + this.emit(false, key); + return data; + } + emit(aborted, settledKey) { + this.subscribers.forEach(subscriber => subscriber(aborted, settledKey)); + } + subscribe(fn) { + this.subscribers.add(fn); + return () => this.subscribers.delete(fn); + } + cancel() { + this.controller.abort(); + this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k)); + this.emit(true); + } + async resolveData(signal) { + let aborted = false; + if (!this.done) { + let onAbort = () => this.cancel(); + signal.addEventListener("abort", onAbort); + aborted = await new Promise(resolve => { + this.subscribe(aborted => { + signal.removeEventListener("abort", onAbort); + if (aborted || this.done) { + resolve(aborted); + } + }); + }); + } + return aborted; + } + get done() { + return this.pendingKeysSet.size === 0; + } + get unwrappedData() { + invariant(this.data !== null && this.done, "Can only unwrap data on initialized and settled deferreds"); + return Object.entries(this.data).reduce((acc, _ref3) => { + let [key, value] = _ref3; + return Object.assign(acc, { + [key]: unwrapTrackedPromise(value) + }); + }, {}); + } + get pendingKeys() { + return Array.from(this.pendingKeysSet); + } +} +function isTrackedPromise(value) { + return value instanceof Promise && value._tracked === true; +} +function unwrapTrackedPromise(value) { + if (!isTrackedPromise(value)) { + return value; + } + if (value._error) { + throw value._error; + } + return value._data; +} +const defer = function defer(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + return new DeferredData(data, responseInit); +}; +/** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +const redirect = function redirect(url, init) { + if (init === void 0) { + init = 302; + } + let responseInit = init; + if (typeof responseInit === "number") { + responseInit = { + status: responseInit + }; + } else if (typeof responseInit.status === "undefined") { + responseInit.status = 302; + } + let headers = new Headers(responseInit.headers); + headers.set("Location", url); + return new Response(null, _extends({}, responseInit, { + headers + })); +}; + +/** + * A redirect response that will force a document reload to the new location. + * Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +const redirectDocument = (url, init) => { + let response = redirect(url, init); + response.headers.set("X-Remix-Reload-Document", "true"); + return response; +}; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + * + * We don't export the class for public use since it's an implementation + * detail, but we export the interface above so folks can build their own + * abstractions around instances via isRouteErrorResponse() + */ +class ErrorResponseImpl { + constructor(status, statusText, data, internal) { + if (internal === void 0) { + internal = false; + } + this.status = status; + this.statusText = statusText || ""; + this.internal = internal; + if (data instanceof Error) { + this.data = data.toString(); + this.error = data; + } else { + this.data = data; + } + } +} + +/** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response thrown from an action/loader + */ +function isRouteErrorResponse(error) { + return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error; +} + +//////////////////////////////////////////////////////////////////////////////// +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// + +/** + * A Router instance manages all navigation and data loading/mutations + */ +/** + * State maintained internally by the router. During a navigation, all states + * reflect the the "old" location unless otherwise noted. + */ +/** + * Data that can be passed into hydrate a Router from SSR + */ +/** + * Future flags to toggle new feature behavior + */ +/** + * Initialization options for createRouter + */ +/** + * State returned from a server-side query() call + */ +/** + * A StaticHandler instance manages a singular SSR navigation/fetch event + */ +/** + * Subscriber function signature for changes to router state + */ +/** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ +/** + * Function signature for determining the current scroll position + */ +// Allowed for any navigation or fetch +// Only allowed for navigations +// Only allowed for submission navigations +/** + * Options for a navigate() call for a normal (non-submission) navigation + */ +/** + * Options for a navigate() call for a submission navigation + */ +/** + * Options to pass to navigate() for a navigation + */ +/** + * Options for a fetch() load + */ +/** + * Options for a fetch() submission + */ +/** + * Options to pass to fetch() + */ +/** + * Potential states for state.navigation + */ +/** + * Potential states for fetchers + */ +/** + * Cached info for active fetcher.load() instances so they can participate + * in revalidation + */ +/** + * Identified fetcher.load() calls that need to be revalidated + */ +const validMutationMethodsArr = ["post", "put", "patch", "delete"]; +const validMutationMethods = new Set(validMutationMethodsArr); +const validRequestMethodsArr = ["get", ...validMutationMethodsArr]; +const validRequestMethods = new Set(validRequestMethodsArr); +const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); +const redirectPreserveMethodStatusCodes = new Set([307, 308]); +const IDLE_NAVIGATION = { + state: "idle", + location: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined +}; +const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined +}; +const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined +}; +const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; +const defaultMapRouteProperties = route => ({ + hasErrorBoundary: Boolean(route.hasErrorBoundary) +}); +const TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; + +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a router and listen to history POP navigations + */ +function createRouter(init) { + const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : undefined; + const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined"; + const isServer = !isBrowser; + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let mapRouteProperties; + if (init.mapRouteProperties) { + mapRouteProperties = init.mapRouteProperties; + } else if (init.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = init.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + + // Routes keyed by ID + let manifest = {}; + // Routes in tree format for matching + let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest); + let inFlightDataRoutes; + let basename = init.basename || "/"; + let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy; + let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss; + + // Config driven behavior flags + let future = _extends({ + v7_fetcherPersist: false, + v7_normalizeFormMethod: false, + v7_partialHydration: false, + v7_prependBasename: false, + v7_relativeSplatPath: false, + v7_skipActionErrorRevalidation: false + }, init.future); + // Cleanup function for history + let unlistenHistory = null; + // Externally-provided functions to call on all state changes + let subscribers = new Set(); + // Externally-provided object to hold scroll restoration locations during routing + let savedScrollPositions = null; + // Externally-provided function to get scroll restoration keys + let getScrollRestorationKey = null; + // Externally-provided function to get current scroll position + let getScrollPosition = null; + // One-time flag to control the initial hydration scroll restoration. Because + // we don't get the saved positions from until _after_ + // the initial render, we need to manually trigger a separate updateState to + // send along the restoreScrollPosition + // Set to true if we have `hydrationData` since we assume we were SSR'd and that + // SSR did the initial scroll restoration. + let initialScrollRestored = init.hydrationData != null; + let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); + let initialErrors = null; + if (initialMatches == null && !patchRoutesOnMissImpl) { + // If we do not match a user-provided-route, fall back to the root + // to allow the error boundary to take over + let error = getInternalRouterError(404, { + pathname: init.history.location.pathname + }); + let { + matches, + route + } = getShortCircuitMatches(dataRoutes); + initialMatches = matches; + initialErrors = { + [route.id]: error + }; + } + + // In SPA apps, if the user provided a patchRoutesOnMiss implementation and + // our initial match is a splat route, clear them out so we run through lazy + // discovery on hydration in case there's a more accurate lazy route match. + // In SSR apps (with `hydrationData`), we expect that the server will send + // up the proper matched routes so we don't want to run lazy discovery on + // initial hydration and want to hydrate into the splat route. + if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) { + let fogOfWar = checkFogOfWar(initialMatches, dataRoutes, init.history.location.pathname); + if (fogOfWar.active) { + initialMatches = null; + } + } + let initialized; + if (!initialMatches) { + // We need to run patchRoutesOnMiss in initialize() + initialized = false; + initialMatches = []; + } else if (initialMatches.some(m => m.route.lazy)) { + // All initialMatches need to be loaded before we're ready. If we have lazy + // functions around still then we'll need to run them in initialize() + initialized = false; + } else if (!initialMatches.some(m => m.route.loader)) { + // If we've got no loaders to run, then we're good to go + initialized = true; + } else if (future.v7_partialHydration) { + // If partial hydration is enabled, we're initialized so long as we were + // provided with hydrationData for every route with a loader, and no loaders + // were marked for explicit hydration + let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; + let errors = init.hydrationData ? init.hydrationData.errors : null; + let isRouteInitialized = m => { + // No loader, nothing to initialize + if (!m.route.loader) { + return true; + } + // Explicitly opting-in to running on hydration + if (typeof m.route.loader === "function" && m.route.loader.hydrate === true) { + return false; + } + // Otherwise, initialized if hydrated with data or an error + return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined; + }; + + // If errors exist, don't consider routes below the boundary + if (errors) { + let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined); + initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized); + } else { + initialized = initialMatches.every(isRouteInitialized); + } + } else { + // Without partial hydration - we're initialized if we were provided any + // hydrationData - which is expected to be complete + initialized = init.hydrationData != null; + } + let router; + let state = { + historyAction: init.history.action, + location: init.history.location, + matches: initialMatches, + initialized, + navigation: IDLE_NAVIGATION, + // Don't restore on initial updateState() if we were SSR'd + restoreScrollPosition: init.hydrationData != null ? false : null, + preventScrollReset: false, + revalidation: "idle", + loaderData: init.hydrationData && init.hydrationData.loaderData || {}, + actionData: init.hydrationData && init.hydrationData.actionData || null, + errors: init.hydrationData && init.hydrationData.errors || initialErrors, + fetchers: new Map(), + blockers: new Map() + }; + + // -- Stateful internal variables to manage navigations -- + // Current navigation in progress (to be committed in completeNavigation) + let pendingAction = Action.Pop; + + // Should the current navigation prevent the scroll reset if scroll cannot + // be restored? + let pendingPreventScrollReset = false; + + // AbortController for the active navigation + let pendingNavigationController; + + // Should the current navigation enable document.startViewTransition? + let pendingViewTransitionEnabled = false; + + // Store applied view transitions so we can apply them on POP + let appliedViewTransitions = new Map(); + + // Cleanup function for persisting applied transitions to sessionStorage + let removePageHideEventListener = null; + + // We use this to avoid touching history in completeNavigation if a + // revalidation is entirely uninterrupted + let isUninterruptedRevalidation = false; + + // Use this internal flag to force revalidation of all loaders: + // - submissions (completed or interrupted) + // - useRevalidator() + // - X-Remix-Revalidate (from redirect) + let isRevalidationRequired = false; + + // Use this internal array to capture routes that require revalidation due + // to a cancelled deferred on action submission + let cancelledDeferredRoutes = []; + + // Use this internal array to capture fetcher loads that were cancelled by an + // action navigation and require revalidation + let cancelledFetcherLoads = []; + + // AbortControllers for any in-flight fetchers + let fetchControllers = new Map(); + + // Track loads based on the order in which they started + let incrementingLoadId = 0; + + // Track the outstanding pending navigation data load to be compared against + // the globally incrementing load when a fetcher load lands after a completed + // navigation + let pendingNavigationLoadId = -1; + + // Fetchers that triggered data reloads as a result of their actions + let fetchReloadIds = new Map(); + + // Fetchers that triggered redirect navigations + let fetchRedirectIds = new Set(); + + // Most recent href/match for fetcher.load calls for fetchers + let fetchLoadMatches = new Map(); + + // Ref-count mounted fetchers so we know when it's ok to clean them up + let activeFetchers = new Map(); + + // Fetchers that have requested a delete when using v7_fetcherPersist, + // they'll be officially removed after they return to idle + let deletedFetchers = new Set(); + + // Store DeferredData instances for active route matches. When a + // route loader returns defer() we stick one in here. Then, when a nested + // promise resolves we update loaderData. If a new navigation starts we + // cancel active deferreds for eliminated routes. + let activeDeferreds = new Map(); + + // Store blocker functions in a separate Map outside of router state since + // we don't need to update UI state if they change + let blockerFunctions = new Map(); + + // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so + // that we only kick them off once for a given combo + let pendingPatchRoutes = new Map(); + + // Flag to ignore the next history update, so we can revert the URL change on + // a POP navigation that was blocked by the user without touching router state + let ignoreNextHistoryUpdate = false; + + // Initialize the router, all side effects should be kicked off from here. + // Implemented as a Fluent API for ease of: + // let router = createRouter(init).initialize(); + function initialize() { + // If history informs us of a POP navigation, start the navigation but do not update + // state. We'll update our own state once the navigation completes + unlistenHistory = init.history.listen(_ref => { + let { + action: historyAction, + location, + delta + } = _ref; + // Ignore this event if it was just us resetting the URL from a + // blocked POP navigation + if (ignoreNextHistoryUpdate) { + ignoreNextHistoryUpdate = false; + return; + } + warning(blockerFunctions.size === 0 || delta != null, "You are trying to use a blocker on a POP navigation to a location " + "that was not created by @remix-run/router. This will fail silently in " + "production. This can happen if you are navigating outside the router " + "via `window.history.pushState`/`window.location.hash` instead of using " + "router navigation APIs. This can also happen if you are using " + "createHashRouter and the user manually changes the URL."); + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + if (blockerKey && delta != null) { + // Restore the URL to match the current UI, but don't update router state + ignoreNextHistoryUpdate = true; + init.history.go(delta * -1); + + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location + }); + // Re-do the same POP navigation we just blocked + init.history.go(delta); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return startNavigation(historyAction, location); + }); + if (isBrowser) { + // FIXME: This feels gross. How can we cleanup the lines between + // scrollRestoration/appliedTransitions persistance? + restoreAppliedTransitions(routerWindow, appliedViewTransitions); + let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions); + routerWindow.addEventListener("pagehide", _saveAppliedTransitions); + removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); + } + + // Kick off initial data load if needed. Use Pop to avoid modifying history + // Note we don't do any handling of lazy here. For SPA's it'll get handled + // in the normal navigation flow. For SSR it's expected that lazy modules are + // resolved prior to router creation since we can't go into a fallbackElement + // UI for SSR'd apps + if (!state.initialized) { + startNavigation(Action.Pop, state.location, { + initialHydration: true + }); + } + return router; + } + + // Clean up a router and it's side effects + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + if (removePageHideEventListener) { + removePageHideEventListener(); + } + subscribers.clear(); + pendingNavigationController && pendingNavigationController.abort(); + state.fetchers.forEach((_, key) => deleteFetcher(key)); + state.blockers.forEach((_, key) => deleteBlocker(key)); + } + + // Subscribe to state updates for the router + function subscribe(fn) { + subscribers.add(fn); + return () => subscribers.delete(fn); + } + + // Update our state and notify the calling context of the change + function updateState(newState, opts) { + if (opts === void 0) { + opts = {}; + } + state = _extends({}, state, newState); + + // Prep fetcher cleanup so we can tell the UI which fetcher data entries + // can be removed + let completedFetchers = []; + let deletedFetchersKeys = []; + if (future.v7_fetcherPersist) { + state.fetchers.forEach((fetcher, key) => { + if (fetcher.state === "idle") { + if (deletedFetchers.has(key)) { + // Unmounted from the UI and can be totally removed + deletedFetchersKeys.push(key); + } else { + // Returned to idle but still mounted in the UI, so semi-remains for + // revalidations and such + completedFetchers.push(key); + } + } + }); + } + + // Iterate over a local copy so that if flushSync is used and we end up + // removing and adding a new subscriber due to the useCallback dependencies, + // we don't get ourselves into a loop calling the new subscriber immediately + [...subscribers].forEach(subscriber => subscriber(state, { + deletedFetchers: deletedFetchersKeys, + unstable_viewTransitionOpts: opts.viewTransitionOpts, + unstable_flushSync: opts.flushSync === true + })); + + // Remove idle fetchers from state since we only care about in-flight fetchers. + if (future.v7_fetcherPersist) { + completedFetchers.forEach(key => state.fetchers.delete(key)); + deletedFetchersKeys.forEach(key => deleteFetcher(key)); + } + } + + // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION + // and setting state.[historyAction/location/matches] to the new route. + // - Location is a required param + // - Navigation will always be set to IDLE_NAVIGATION + // - Can pass any other state in newState + function completeNavigation(location, newState, _temp) { + var _location$state, _location$state2; + let { + flushSync + } = _temp === void 0 ? {} : _temp; + // Deduce if we're in a loading/actionReload state: + // - We have committed actionData in the store + // - The current navigation was a mutation submission + // - We're past the submitting state and into the loading state + // - The location being loaded is not the result of a redirect + let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && ((_location$state = location.state) == null ? void 0 : _location$state._isRedirect) !== true; + let actionData; + if (newState.actionData) { + if (Object.keys(newState.actionData).length > 0) { + actionData = newState.actionData; + } else { + // Empty actionData -> clear prior actionData due to an action error + actionData = null; + } + } else if (isActionReload) { + // Keep the current data if we're wrapping up the action reload + actionData = state.actionData; + } else { + // Clear actionData on any other completed navigations + actionData = null; + } + + // Always preserve any existing loaderData from re-used routes + let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; + + // On a successful navigation we can assume we got through all blockers + // so we can start fresh + let blockers = state.blockers; + if (blockers.size > 0) { + blockers = new Map(blockers); + blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); + } + + // Always respect the user flag. Otherwise don't reset on mutation + // submission navigations unless they redirect + let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true; + + // Commit any in-flight routes at the end of the HMR revalidation "navigation" + if (inFlightDataRoutes) { + dataRoutes = inFlightDataRoutes; + inFlightDataRoutes = undefined; + } + if (isUninterruptedRevalidation) ; else if (pendingAction === Action.Pop) ; else if (pendingAction === Action.Push) { + init.history.push(location, location.state); + } else if (pendingAction === Action.Replace) { + init.history.replace(location, location.state); + } + let viewTransitionOpts; + + // On POP, enable transitions if they were enabled on the original navigation + if (pendingAction === Action.Pop) { + // Forward takes precedence so they behave like the original navigation + let priorPaths = appliedViewTransitions.get(state.location.pathname); + if (priorPaths && priorPaths.has(location.pathname)) { + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } else if (appliedViewTransitions.has(location.pathname)) { + // If we don't have a previous forward nav, assume we're popping back to + // the new location and enable if that location previously enabled + viewTransitionOpts = { + currentLocation: location, + nextLocation: state.location + }; + } + } else if (pendingViewTransitionEnabled) { + // Store the applied transition on PUSH/REPLACE + let toPaths = appliedViewTransitions.get(state.location.pathname); + if (toPaths) { + toPaths.add(location.pathname); + } else { + toPaths = new Set([location.pathname]); + appliedViewTransitions.set(state.location.pathname, toPaths); + } + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } + updateState(_extends({}, newState, { + // matches, errors, fetchers go through as-is + actionData, + loaderData, + historyAction: pendingAction, + location, + initialized: true, + navigation: IDLE_NAVIGATION, + revalidation: "idle", + restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches), + preventScrollReset, + blockers + }), { + viewTransitionOpts, + flushSync: flushSync === true + }); + + // Reset stateful navigation vars + pendingAction = Action.Pop; + pendingPreventScrollReset = false; + pendingViewTransitionEnabled = false; + isUninterruptedRevalidation = false; + isRevalidationRequired = false; + cancelledDeferredRoutes = []; + cancelledFetcherLoads = []; + } + + // Trigger a navigation event, which can either be a numerical POP or a PUSH + // replace with an optional submission + async function navigate(to, opts) { + if (typeof to === "number") { + init.history.go(to); + return; + } + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, to, future.v7_relativeSplatPath, opts == null ? void 0 : opts.fromRouteId, opts == null ? void 0 : opts.relative); + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, false, normalizedPath, opts); + let currentLocation = state.location; + let nextLocation = createLocation(state.location, path, opts && opts.state); + + // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded + // URL from window.location, so we need to encode it here so the behavior + // remains the same as POP and non-data-router usages. new URL() does all + // the same encoding we'd get from a history.pushState/window.location read + // without having to touch history + nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation)); + let userReplace = opts && opts.replace != null ? opts.replace : undefined; + let historyAction = Action.Push; + if (userReplace === true) { + historyAction = Action.Replace; + } else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) { + // By default on submissions to the current location we REPLACE so that + // users don't have to double-click the back button to get to the prior + // location. If the user redirects to a different location from the + // action/loader this will be ignored and the redirect will be a PUSH + historyAction = Action.Replace; + } + let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined; + let flushSync = (opts && opts.unstable_flushSync) === true; + let blockerKey = shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction + }); + if (blockerKey) { + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location: nextLocation, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location: nextLocation + }); + // Send the same navigation through + navigate(to, opts); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return await startNavigation(historyAction, nextLocation, { + submission, + // Send through the formData serialization error if we have one so we can + // render at the right error boundary after we match routes + pendingError: error, + preventScrollReset, + replace: opts && opts.replace, + enableViewTransition: opts && opts.unstable_viewTransition, + flushSync + }); + } + + // Revalidate all current loaders. If a navigation is in progress or if this + // is interrupted by a navigation, allow this to "succeed" by calling all + // loaders during the next loader round + function revalidate() { + interruptActiveLoads(); + updateState({ + revalidation: "loading" + }); + + // If we're currently submitting an action, we don't need to start a new + // navigation, we'll just let the follow up loader execution call all loaders + if (state.navigation.state === "submitting") { + return; + } + + // If we're currently in an idle state, start a new navigation for the current + // action/location and mark it as uninterrupted, which will skip the history + // update in completeNavigation + if (state.navigation.state === "idle") { + startNavigation(state.historyAction, state.location, { + startUninterruptedRevalidation: true + }); + return; + } + + // Otherwise, if we're currently in a loading state, just start a new + // navigation to the navigation.location but do not trigger an uninterrupted + // revalidation so that history correctly updates once the navigation completes + startNavigation(pendingAction || state.historyAction, state.navigation.location, { + overrideNavigation: state.navigation + }); + } + + // Start a navigation to the given action/location. Can optionally provide a + // overrideNavigation which will override the normalLoad in the case of a redirect + // navigation + async function startNavigation(historyAction, location, opts) { + // Abort any in-progress navigations and start a new one. Unset any ongoing + // uninterrupted revalidations unless told otherwise, since we want this + // new navigation to update history normally + pendingNavigationController && pendingNavigationController.abort(); + pendingNavigationController = null; + pendingAction = historyAction; + isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true; + + // Save the current scroll position every time we start a new navigation, + // and track whether we should reset scroll on completion + saveScrollPosition(state.location, state.matches); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(routesToUse, location, basename); + let flushSync = (opts && opts.flushSync) === true; + let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + + // Short circuit with a 404 on the root error boundary if we match nothing + if (!matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }, { + flushSync + }); + return; + } + + // Short circuit if it's only a hash change and not a revalidation or + // mutation submission. + // + // Ignore on initial page loads because since the initial load will always + // be "same hash". For example, on /page#hash and submit a + // which will default to a navigation to /page + if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) { + completeNavigation(location, { + matches + }, { + flushSync + }); + return; + } + + // Create a controller/Request for this navigation + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionResult; + if (opts && opts.pendingError) { + // If we have a pendingError, it means the user attempted a GET submission + // with binary FormData so assign here and skip to handleLoaders. That + // way we handle calling loaders above the boundary etc. It's not really + // different from an actionError in that sense. + pendingActionResult = [findNearestBoundary(matches).route.id, { + type: ResultType.error, + error: opts.pendingError + }]; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionResult = await handleAction(request, location, opts.submission, matches, fogOfWar.active, { + replace: opts.replace, + flushSync + }); + if (actionResult.shortCircuited) { + return; + } + + // If we received a 404 from handleAction, it's because we couldn't lazily + // discover the destination route so we don't want to call loaders + if (actionResult.pendingActionResult) { + let [routeId, result] = actionResult.pendingActionResult; + if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) { + pendingNavigationController = null; + completeNavigation(location, { + matches: actionResult.matches, + loaderData: {}, + errors: { + [routeId]: result.error + } + }); + return; + } + } + matches = actionResult.matches || matches; + pendingActionResult = actionResult.pendingActionResult; + loadingNavigation = getLoadingNavigation(location, opts.submission); + flushSync = false; + // No need to do fog of war matching again on loader execution + fogOfWar.active = false; + + // Create a GET request for the loaders + request = createClientSideRequest(init.history, request.url, request.signal); + } + + // Call loaders + let { + shortCircuited, + matches: updatedMatches, + loaderData, + errors + } = await handleLoaders(request, location, matches, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult); + if (shortCircuited) { + return; + } + + // Clean up now that the action/loaders have completed. Don't clean up if + // we short circuited because pendingNavigationController will have already + // been assigned to a new controller for the next navigation + pendingNavigationController = null; + completeNavigation(location, _extends({ + matches: updatedMatches || matches + }, getActionDataForCommit(pendingActionResult), { + loaderData, + errors + })); + } + + // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + async function handleAction(request, location, submission, matches, isFogOfWar, opts) { + if (opts === void 0) { + opts = {}; + } + interruptActiveLoads(); + + // Put us in a submitting state + let navigation = getSubmittingNavigation(location, submission); + updateState({ + navigation + }, { + flushSync: opts.flushSync === true + }); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + pendingActionResult: [boundaryId, { + type: ResultType.error, + error + }] + }; + } else if (!discoverResult.matches) { + let { + notFoundMatches, + error, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + pendingActionResult: [route.id, { + type: ResultType.error, + error + }] + }; + } else { + matches = discoverResult.matches; + } + } + + // Call our action and get the result + let result; + let actionMatch = getTargetMatch(matches, location); + if (!actionMatch.route.action && !actionMatch.route.lazy) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches); + result = results[0]; + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + } + if (isRedirectResult(result)) { + let replace; + if (opts && opts.replace != null) { + replace = opts.replace; + } else { + // If the user didn't explicity indicate replace behavior, replace if + // we redirected to the exact same location we're currently at to avoid + // double back-buttons + let location = normalizeRedirectLocation(result.response.headers.get("Location"), new URL(request.url), basename); + replace = location === state.location.pathname + state.location.search; + } + await startRedirectNavigation(request, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); + + // By default, all submissions to the current location are REPLACE + // navigations, but if the action threw an error that'll be rendered in + // an errorElement, we fall back to PUSH so that the user can use the + // back button to get back to the pre-submission form location to try + // again + if ((opts && opts.replace) !== true) { + pendingAction = Action.Push; + } + return { + matches, + pendingActionResult: [boundaryMatch.route.id, result] + }; + } + return { + matches, + pendingActionResult: [actionMatch.route.id, result] + }; + } + + // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission); + + // If this was a redirect from an action we don't have a "submission" but + // we have it on the loading navigation so use that if available + let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation); + + // If this is an uninterrupted revalidation, we remain in our current idle + // state. If not, we need to switch to our loading state and load data, + // preserving any new action data or existing action data (in the case of + // a revalidation interrupting an actionReload) + // If we have partialHydration enabled, then don't update the state for the + // initial data load since it's not a "navigation" + let shouldUpdateNavigationState = !isUninterruptedRevalidation && (!future.v7_partialHydration || !initialHydration); + + // When fog of war is enabled, we enter our `loading` state earlier so we + // can discover new routes during the `loading` state. We skip this if + // we've already run actions since we would have done our matching already. + // If the children() function threw then, we want to proceed with the + // partial matches it discovered. + if (isFogOfWar) { + if (shouldUpdateNavigationState) { + let actionData = getUpdatedActionData(pendingActionResult); + updateState(_extends({ + navigation: loadingNavigation + }, actionData !== undefined ? { + actionData + } : {}), { + flushSync + }); + } + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + loaderData: {}, + errors: { + [boundaryId]: error + } + }; + } else if (!discoverResult.matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }; + } else { + matches = discoverResult.matches; + } + } + let routesToUse = inFlightDataRoutes || dataRoutes; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, future.v7_partialHydration && initialHydration === true, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult); + + // Cancel pending deferreds for no-longer-matched routes or routes we're + // about to reload. Note that if this is an action reload we would have + // already cancelled all pending deferreds so this would be a no-op + cancelActiveDeferreds(routeId => !(matches && matches.some(m => m.route.id === routeId)) || matchesToLoad && matchesToLoad.some(m => m.route.id === routeId)); + pendingNavigationLoadId = ++incrementingLoadId; + + // Short circuit if we have no loaders to run + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + let updatedFetchers = markFetchRedirectsDone(); + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null + }, getActionDataForCommit(pendingActionResult), updatedFetchers ? { + fetchers: new Map(state.fetchers) + } : {}), { + flushSync + }); + return { + shortCircuited: true + }; + } + if (shouldUpdateNavigationState) { + let updates = {}; + if (!isFogOfWar) { + // Only update navigation/actionNData if we didn't already do it above + updates.navigation = loadingNavigation; + let actionData = getUpdatedActionData(pendingActionResult); + if (actionData !== undefined) { + updates.actionData = actionData; + } + } + if (revalidatingFetchers.length > 0) { + updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); + } + updateState(updates, { + flushSync + }); + } + revalidatingFetchers.forEach(rf => { + if (fetchControllers.has(rf.key)) { + abortFetcher(rf.key); + } + if (rf.controller) { + // Fetchers use an independent AbortController so that aborting a fetcher + // (via deleteFetcher) does not abort the triggering navigation that + // triggered the revalidation + fetchControllers.set(rf.key, rf.controller); + } + }); + + // Proxy navigation abort through to revalidation fetchers + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(f => abortFetcher(f.key)); + if (pendingNavigationController) { + pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations); + } + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request); + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + + // Clean up _after_ loaders have completed. Don't clean up if we short + // circuited because fetchControllers would have been aborted and + // reassigned to new controllers for the next navigation + if (pendingNavigationController) { + pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + } + revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key)); + + // If any loaders returned a redirect Response, start a new REPLACE navigation + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + await startRedirectNavigation(request, redirect.result, { + replace + }); + return { + shortCircuited: true + }; + } + + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds); + + // Wire up subscribers to update loaderData as promises settle + activeDeferreds.forEach((deferredData, routeId) => { + deferredData.subscribe(aborted => { + // Note: No need to updateState here since the TrackedPromise on + // loaderData is stable across resolve/reject + // Remove this instance if we were aborted or if promises have settled + if (aborted || deferredData.done) { + activeDeferreds.delete(routeId); + } + }); + }); + + // During partial hydration, preserve SSR errors for routes that don't re-run + if (future.v7_partialHydration && initialHydration && state.errors) { + Object.entries(state.errors).filter(_ref2 => { + let [id] = _ref2; + return !matchesToLoad.some(m => m.route.id === id); + }).forEach(_ref3 => { + let [routeId, error] = _ref3; + errors = Object.assign(errors || {}, { + [routeId]: error + }); + }); + } + let updatedFetchers = markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; + return _extends({ + matches, + loaderData, + errors + }, shouldUpdateFetchers ? { + fetchers: new Map(state.fetchers) + } : {}); + } + function getUpdatedActionData(pendingActionResult) { + if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { + // This is cast to `any` currently because `RouteData`uses any and it + // would be a breaking change to use any. + // TODO: v7 - change `RouteData` to use `unknown` instead of `any` + return { + [pendingActionResult[0]]: pendingActionResult[1].data + }; + } else if (state.actionData) { + if (Object.keys(state.actionData).length === 0) { + return null; + } else { + return state.actionData; + } + } + } + function getUpdatedRevalidatingFetchers(revalidatingFetchers) { + revalidatingFetchers.forEach(rf => { + let fetcher = state.fetchers.get(rf.key); + let revalidatingFetcher = getLoadingFetcher(undefined, fetcher ? fetcher.data : undefined); + state.fetchers.set(rf.key, revalidatingFetcher); + }); + return new Map(state.fetchers); + } + + // Trigger a fetcher load/submit for the given fetcher key + function fetch(key, routeId, href, opts) { + if (isServer) { + throw new Error("router.fetch() was called during the server render, but it shouldn't be. " + "You are likely calling a useFetcher() method in the body of your component. " + "Try moving it to a useEffect or a callback."); + } + if (fetchControllers.has(key)) abortFetcher(key); + let flushSync = (opts && opts.unstable_flushSync) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative); + let matches = matchRoutes(routesToUse, normalizedPath, basename); + let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: normalizedPath + }), { + flushSync + }); + return; + } + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, true, normalizedPath, opts); + if (error) { + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } + let match = getTargetMatch(matches, path); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + return; + } + + // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + fetchLoadMatches.set(key, { + routeId, + path + }); + handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + } + + // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + function detectAndHandle405Error(m) { + if (!m.route.action && !m.route.lazy) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error, { + flushSync + }); + return true; + } + return false; + } + if (!isFogOfWar && detectAndHandle405Error(match)) { + return; + } + + // Put this fetcher into it's submitting state + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(requestMatches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + requestMatches = discoverResult.matches; + match = getTargetMatch(requestMatches, path); + if (detectAndHandle405Error(match)) { + return; + } + } + } + + // Call the action for the fetcher + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let actionResults = await callDataStrategy("action", fetchRequest, [match], requestMatches); + let actionResult = actionResults[0]; + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + return; + } + + // When using v7_fetcherPersist, we don't want errors bubbling up to the UI + // or redirects processed for unmounted fetchers so we just revert them to + // idle + if (future.v7_fetcherPersist && deletedFetchers.has(key)) { + if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + // Let SuccessResult's fall through for revalidation + } else { + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our action started, so that + // should take precedence over this redirect navigation. We already + // set isRevalidationRequired so all loaders for the new route should + // fire unless opted out via shouldRevalidate + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + updateFetcherState(key, getLoadingFetcher(submission)); + return startRedirectNavigation(fetchRequest, actionResult, { + fetcherSubmission: submission + }); + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(actionResult)) { + setFetcherError(key, routeId, actionResult.error); + return; + } + } + if (isDeferredResult(actionResult)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + + // Start the data load for current matches, or the next location if we're + // in the middle of a navigation + let nextLocation = state.navigation.location || state.location; + let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal); + let routesToUse = inFlightDataRoutes || dataRoutes; + let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + let loadFetcher = getLoadingFetcher(submission, actionResult.data); + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, [match.route.id, actionResult]); + + // Put all revalidating fetchers into the loading state, except for the + // current fetcher which we want to keep in it's current loading state which + // contains it's action submission info + action data + revalidatingFetchers.filter(rf => rf.key !== key).forEach(rf => { + let staleKey = rf.key; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined); + state.fetchers.set(staleKey, revalidatingFetcher); + if (fetchControllers.has(staleKey)) { + abortFetcher(staleKey); + } + if (rf.controller) { + fetchControllers.set(staleKey, rf.controller); + } + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key)); + abortController.signal.addEventListener("abort", abortPendingFetchRevalidations); + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + if (abortController.signal.aborted) { + return; + } + abortController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(r => fetchControllers.delete(r.key)); + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + return startRedirectNavigation(revalidationRequest, redirect.result); + } + + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + + // Since we let revalidations complete even if the submitting fetcher was + // deleted, only put it back to idle if it hasn't been deleted + if (state.fetchers.has(key)) { + let doneFetcher = getDoneFetcher(actionResult.data); + state.fetchers.set(key, doneFetcher); + } + abortStaleFetchLoads(loadId); + + // If we are currently in a navigation loading state and this fetcher is + // more recent than the navigation, we want the newer data so abort the + // navigation and complete it with the fetcher data + if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) { + invariant(pendingAction, "Expected pending action"); + pendingNavigationController && pendingNavigationController.abort(); + completeNavigation(state.navigation.location, { + matches, + loaderData, + errors, + fetchers: new Map(state.fetchers) + }); + } else { + // otherwise just update with the fetcher data, preserving any existing + // loaderData for loaders that did not need to reload. We have to + // manually merge here since we aren't going through completeNavigation + updateState({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors), + fetchers: new Map(state.fetchers) + }); + isRevalidationRequired = false; + } + } + + // Call the matched loader for fetcher.load(), handling redirects, errors, etc. + async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, submission) { + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + matches = discoverResult.matches; + match = getTargetMatch(matches, path); + } + } + + // Call the loader for this fetcher route match + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let results = await callDataStrategy("loader", fetchRequest, [match], matches); + let result = results[0]; + + // Deferred isn't supported for fetcher loads, await everything and treat it + // as a normal load. resolveDeferredData will return undefined if this + // fetcher gets aborted, so we just leave result untouched and short circuit + // below if that happens + if (isDeferredResult(result)) { + result = (await resolveDeferredData(result, fetchRequest.signal, true)) || result; + } + + // We can delete this so long as we weren't aborted by our our own fetcher + // re-load which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + if (fetchRequest.signal.aborted) { + return; + } + + // We don't want errors bubbling up or redirects followed for unmounted + // fetchers, so short circuit here if it was removed from the UI + if (deletedFetchers.has(key)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + + // If the loader threw a redirect Response, start a new REPLACE navigation + if (isRedirectResult(result)) { + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our loader started, so that + // should take precedence over this redirect navigation + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + await startRedirectNavigation(fetchRequest, result); + return; + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(result)) { + setFetcherError(key, routeId, result.error); + return; + } + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); + + // Put the fetcher back into an idle state + updateFetcherState(key, getDoneFetcher(result.data)); + } + + /** + * Utility function to handle redirects returned from an action or loader. + * Normally, a redirect "replaces" the navigation that triggered it. So, for + * example: + * + * - user is on /a + * - user clicks a link to /b + * - loader for /b redirects to /c + * + * In a non-JS app the browser would track the in-flight navigation to /b and + * then replace it with /c when it encountered the redirect response. In + * the end it would only ever update the URL bar with /c. + * + * In client-side routing using pushState/replaceState, we aim to emulate + * this behavior and we also do not update history until the end of the + * navigation (including processed redirects). This means that we never + * actually touch history until we've processed redirects, so we just use + * the history action from the original navigation (PUSH or REPLACE). + */ + async function startRedirectNavigation(request, redirect, _temp2) { + let { + submission, + fetcherSubmission, + replace + } = _temp2 === void 0 ? {} : _temp2; + if (redirect.response.headers.has("X-Remix-Revalidate")) { + isRevalidationRequired = true; + } + let location = redirect.response.headers.get("Location"); + invariant(location, "Expected a Location header on the redirect Response"); + location = normalizeRedirectLocation(location, new URL(request.url), basename); + let redirectLocation = createLocation(state.location, location, { + _isRedirect: true + }); + if (isBrowser) { + let isDocumentReload = false; + if (redirect.response.headers.has("X-Remix-Reload-Document")) { + // Hard reload if the response contained X-Remix-Reload-Document + isDocumentReload = true; + } else if (ABSOLUTE_URL_REGEX.test(location)) { + const url = init.history.createURL(location); + isDocumentReload = + // Hard reload if it's an absolute URL to a new origin + url.origin !== routerWindow.location.origin || + // Hard reload if it's an absolute URL that does not match our basename + stripBasename(url.pathname, basename) == null; + } + if (isDocumentReload) { + if (replace) { + routerWindow.location.replace(location); + } else { + routerWindow.location.assign(location); + } + return; + } + } + + // There's no need to abort on redirects, since we don't detect the + // redirect until the action/loaders have settled + pendingNavigationController = null; + let redirectHistoryAction = replace === true ? Action.Replace : Action.Push; + + // Use the incoming submission if provided, fallback on the active one in + // state.navigation + let { + formMethod, + formAction, + formEncType + } = state.navigation; + if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) { + submission = getSubmissionFromNavigation(state.navigation); + } + + // If this was a 307/308 submission we want to preserve the HTTP method and + // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the + // redirected location + let activeSubmission = submission || fetcherSubmission; + if (redirectPreserveMethodStatusCodes.has(redirect.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, activeSubmission, { + formAction: location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // If we have a navigation submission, we will preserve it through the + // redirect navigation + let overrideNavigation = getLoadingNavigation(redirectLocation, submission); + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation, + // Send fetcher submissions through for shouldRevalidate + fetcherSubmission, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + + // Utility wrapper for calling dataStrategy client-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches) { + try { + let results = await callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + return { + type: ResultType.redirect, + response: normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath) + }; + } + return convertHandlerResultToDataResult(result); + })); + } catch (e) { + // If the outer dataStrategy method throws, just return the error for all + // matches - and it'll naturally bubble to the root + return matchesToLoad.map(() => ({ + type: ResultType.error, + error: e + })); + } + } + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + let [loaderResults, ...fetcherResults] = await Promise.all([matchesToLoad.length ? callDataStrategy("loader", request, matchesToLoad, matches) : [], ...fetchersToLoad.map(f => { + if (f.matches && f.match && f.controller) { + let fetcherRequest = createClientSideRequest(init.history, f.path, f.controller.signal); + return callDataStrategy("loader", fetcherRequest, [f.match], f.matches).then(r => r[0]); + } else { + return Promise.resolve({ + type: ResultType.error, + error: getInternalRouterError(404, { + pathname: f.path + }) + }); + } + })]); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(() => request.signal), false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, fetchersToLoad.map(f => f.controller ? f.controller.signal : null), true)]); + return { + loaderResults, + fetcherResults + }; + } + function interruptActiveLoads() { + // Every interruption triggers a revalidation + isRevalidationRequired = true; + + // Cancel pending route-level deferreds and mark cancelled routes for + // revalidation + cancelledDeferredRoutes.push(...cancelActiveDeferreds()); + + // Abort in-flight fetcher loads + fetchLoadMatches.forEach((_, key) => { + if (fetchControllers.has(key)) { + cancelledFetcherLoads.push(key); + abortFetcher(key); + } + }); + } + function updateFetcherState(key, fetcher, opts) { + if (opts === void 0) { + opts = {}; + } + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function setFetcherError(key, routeId, error, opts) { + if (opts === void 0) { + opts = {}; + } + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function getFetcher(key) { + if (future.v7_fetcherPersist) { + activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); + // If this fetcher was previously marked for deletion, unmark it since we + // have a new instance + if (deletedFetchers.has(key)) { + deletedFetchers.delete(key); + } + } + return state.fetchers.get(key) || IDLE_FETCHER; + } + function deleteFetcher(key) { + let fetcher = state.fetchers.get(key); + // Don't abort the controller if this is a deletion of a fetcher.submit() + // in it's loading phase since - we don't want to abort the corresponding + // revalidation and want them to complete and land + if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) { + abortFetcher(key); + } + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + deletedFetchers.delete(key); + state.fetchers.delete(key); + } + function deleteFetcherAndUpdateState(key) { + if (future.v7_fetcherPersist) { + let count = (activeFetchers.get(key) || 0) - 1; + if (count <= 0) { + activeFetchers.delete(key); + deletedFetchers.add(key); + } else { + activeFetchers.set(key, count); + } + } else { + deleteFetcher(key); + } + updateState({ + fetchers: new Map(state.fetchers) + }); + } + function abortFetcher(key) { + let controller = fetchControllers.get(key); + invariant(controller, "Expected fetch controller: " + key); + controller.abort(); + fetchControllers.delete(key); + } + function markFetchersDone(keys) { + for (let key of keys) { + let fetcher = getFetcher(key); + let doneFetcher = getDoneFetcher(fetcher.data); + state.fetchers.set(key, doneFetcher); + } + } + function markFetchRedirectsDone() { + let doneKeys = []; + let updatedFetchers = false; + for (let key of fetchRedirectIds) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + fetchRedirectIds.delete(key); + doneKeys.push(key); + updatedFetchers = true; + } + } + markFetchersDone(doneKeys); + return updatedFetchers; + } + function abortStaleFetchLoads(landedId) { + let yeetedKeys = []; + for (let [key, id] of fetchReloadIds) { + if (id < landedId) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + abortFetcher(key); + fetchReloadIds.delete(key); + yeetedKeys.push(key); + } + } + } + markFetchersDone(yeetedKeys); + return yeetedKeys.length > 0; + } + function getBlocker(key, fn) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + if (blockerFunctions.get(key) !== fn) { + blockerFunctions.set(key, fn); + } + return blocker; + } + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + } + + // Utility function to update blockers, ensuring valid state transitions + function updateBlocker(key, newBlocker) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + + // Poor mans state machine :) + // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM + invariant(blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state); + let blockers = new Map(state.blockers); + blockers.set(key, newBlocker); + updateState({ + blockers + }); + } + function shouldBlockNavigation(_ref4) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref4; + if (blockerFunctions.size === 0) { + return; + } + + // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + if (blockerFunctions.size > 1) { + warning(false, "A router only supports one blocker at a time"); + } + let entries = Array.from(blockerFunctions.entries()); + let [blockerKey, blockerFunction] = entries[entries.length - 1]; + let blocker = state.blockers.get(blockerKey); + if (blocker && blocker.state === "proceeding") { + // If the blocker is currently proceeding, we don't need to re-check + // it and can let this navigation continue + return; + } + + // At this point, we know we're unblocked/blocked so we need to check the + // user-provided blocker function + if (blockerFunction({ + currentLocation, + nextLocation, + historyAction + })) { + return blockerKey; + } + } + function handleNavigational404(pathname) { + let error = getInternalRouterError(404, { + pathname + }); + let routesToUse = inFlightDataRoutes || dataRoutes; + let { + matches, + route + } = getShortCircuitMatches(routesToUse); + + // Cancel all pending deferred on 404s since we don't keep any routes + cancelActiveDeferreds(); + return { + notFoundMatches: matches, + route, + error + }; + } + function handleDiscoverRouteError(pathname, discoverResult) { + return { + boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id, + error: getInternalRouterError(400, { + type: "route-discovery", + pathname, + message: discoverResult.error != null && "message" in discoverResult.error ? discoverResult.error : String(discoverResult.error) + }) + }; + } + function cancelActiveDeferreds(predicate) { + let cancelledRouteIds = []; + activeDeferreds.forEach((dfd, routeId) => { + if (!predicate || predicate(routeId)) { + // Cancel the deferred - but do not remove from activeDeferreds here - + // we rely on the subscribers to do that so our tests can assert proper + // cleanup via _internalActiveDeferreds + dfd.cancel(); + cancelledRouteIds.push(routeId); + activeDeferreds.delete(routeId); + } + }); + return cancelledRouteIds; + } + + // Opt in to capturing and reporting scroll positions during navigations, + // used by the component + function enableScrollRestoration(positions, getPosition, getKey) { + savedScrollPositions = positions; + getScrollPosition = getPosition; + getScrollRestorationKey = getKey || null; + + // Perform initial hydration scroll restoration, since we miss the boat on + // the initial updateState() because we've not yet rendered + // and therefore have no savedScrollPositions available + if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { + initialScrollRestored = true; + let y = getSavedScrollPosition(state.location, state.matches); + if (y != null) { + updateState({ + restoreScrollPosition: y + }); + } + } + return () => { + savedScrollPositions = null; + getScrollPosition = null; + getScrollRestorationKey = null; + }; + } + function getScrollKey(location, matches) { + if (getScrollRestorationKey) { + let key = getScrollRestorationKey(location, matches.map(m => convertRouteMatchToUiMatch(m, state.loaderData))); + return key || location.key; + } + return location.key; + } + function saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollPosition) { + let key = getScrollKey(location, matches); + savedScrollPositions[key] = getScrollPosition(); + } + } + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions) { + let key = getScrollKey(location, matches); + let y = savedScrollPositions[key]; + if (typeof y === "number") { + return y; + } + } + return null; + } + function checkFogOfWar(matches, routesToUse, pathname) { + if (patchRoutesOnMissImpl) { + if (!matches) { + let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: fogMatches || [] + }; + } else { + let leafRoute = matches[matches.length - 1].route; + if (leafRoute.path && (leafRoute.path === "*" || leafRoute.path.endsWith("/*"))) { + // If we matched a splat, it might only be because we haven't yet fetched + // the children that would match with a higher score, so let's fetch + // around and find out + let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: partialMatches + }; + } + } + } + return { + active: false, + matches: null + }; + } + async function discoverRoutes(matches, pathname, signal) { + let partialMatches = matches; + let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null; + while (true) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + try { + await loadLazyRouteChildren(patchRoutesOnMissImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal); + } catch (e) { + return { + type: "error", + error: e, + partialMatches + }; + } finally { + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity so when we `updateState` at the end of + // this navigation/fetch `router.routes` will be a new identity and + // trigger a re-run of memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + } + } + if (signal.aborted) { + return { + type: "aborted" + }; + } + let newMatches = matchRoutes(routesToUse, pathname, basename); + let matchedSplat = false; + if (newMatches) { + let leafRoute = newMatches[newMatches.length - 1].route; + if (leafRoute.index) { + // If we found an index route, we can stop + return { + type: "success", + matches: newMatches + }; + } + if (leafRoute.path && leafRoute.path.length > 0) { + if (leafRoute.path === "*") { + // If we found a splat route, we can't be sure there's not a + // higher-scoring route down some partial matches trail so we need + // to check that out + matchedSplat = true; + } else { + // If we found a non-splat route, we can stop + return { + type: "success", + matches: newMatches + }; + } + } + } + let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + + // If we are no longer partially matching anything, this was either a + // legit splat match above, or it's a 404. Also avoid loops if the + // second pass results in the same partial matches + if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) { + return { + type: "success", + matches: matchedSplat ? newMatches : null + }; + } + partialMatches = newPartialMatches; + route = partialMatches[partialMatches.length - 1].route; + if (route.path === "*") { + // The splat is still our most accurate partial, so run with it + return { + type: "success", + matches: partialMatches + }; + } + } + } + function _internalSetRoutes(newRoutes) { + manifest = {}; + inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest); + } + function patchRoutes(routeId, children) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties); + + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity and trigger a reflow via `updateState` + // to re-run memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + updateState({}); + } + } + router = { + get basename() { + return basename; + }, + get future() { + return future; + }, + get state() { + return state; + }, + get routes() { + return dataRoutes; + }, + get window() { + return routerWindow; + }, + initialize, + subscribe, + enableScrollRestoration, + navigate, + fetch, + revalidate, + // Passthrough to history-aware createHref used by useHref so we get proper + // hash-aware URLs in DOM paths + createHref: to => init.history.createHref(to), + encodeLocation: to => init.history.encodeLocation(to), + getFetcher, + deleteFetcher: deleteFetcherAndUpdateState, + dispose, + getBlocker, + deleteBlocker, + patchRoutes, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds, + // TODO: Remove setRoutes, it's temporary to avoid dealing with + // updating the tree while validating the update algorithm. + _internalSetRoutes + }; + return router; +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createStaticHandler +//////////////////////////////////////////////////////////////////////////////// + +const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred"); + +/** + * Future flags to toggle new feature behavior + */ + +function createStaticHandler(routes, opts) { + invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler"); + let manifest = {}; + let basename = (opts ? opts.basename : null) || "/"; + let mapRouteProperties; + if (opts != null && opts.mapRouteProperties) { + mapRouteProperties = opts.mapRouteProperties; + } else if (opts != null && opts.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = opts.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + // Config driven behavior flags + let future = _extends({ + v7_relativeSplatPath: false, + v7_throwAbortReason: false + }, opts ? opts.future : null); + let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest); + + /** + * The query() method is intended for document requests, in which we want to + * call an optional action and potentially multiple loaders for all nested + * routes. It returns a StaticHandlerContext object, which is very similar + * to the router state (location, loaderData, actionData, errors, etc.) and + * also adds SSR-specific information such as the statusCode and headers + * from action/loaders Responses. + * + * It _should_ never throw and should report all errors through the + * returned context.errors object, properly associating errors to their error + * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be + * used to emulate React error boundaries during SSr by performing a second + * pass only down to the boundaryId. + * + * The one exception where we do not return a StaticHandlerContext is when a + * redirect response is returned or thrown from any action/loader. We + * propagate that out and return the raw Response so the HTTP server can + * return it directly. + * + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent + * the bubbling of errors which allows single-fetch-type implementations + * where the client will handle the bubbling and we may need to return data + * for the handling route + */ + async function query(request, _temp3) { + let { + requestContext, + skipLoaderErrorBubbling, + unstable_dataStrategy + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD") { + let error = getInternalRouterError(405, { + method + }); + let { + matches: methodNotAllowedMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: methodNotAllowedMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } else if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: notFoundMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, skipLoaderErrorBubbling === true, null); + if (isResponse(result)) { + return result; + } + + // When returning StaticHandlerContext, we patch back in the location here + // since we need it for React Context. But this helps keep our submit and + // loadRouteData operating on a Request instead of a Location + return _extends({ + location, + basename + }, result); + } + + /** + * The queryRoute() method is intended for targeted route requests, either + * for fetch ?_data requests or resource route requests. In this case, we + * are only ever calling a single action or loader, and we are returning the + * returned value directly. In most cases, this will be a Response returned + * from the action/loader, but it may be a primitive or other value as well - + * and in such cases the calling context should handle that accordingly. + * + * We do respect the throw/return differentiation, so if an action/loader + * throws, then this method will throw the value. This is important so we + * can do proper boundary identification in Remix where a thrown Response + * must go to the Catch Boundary but a returned Response is happy-path. + * + * One thing to note is that any Router-initiated Errors that make sense + * to associate with a status code will be thrown as an ErrorResponse + * instance which include the raw Error, such that the calling context can + * serialize the error as they see fit while including the proper response + * code. Examples here are 404 and 405 errors that occur prior to reaching + * any user-defined loaders. + * + * - `opts.routeId` allows you to specify the specific route handler to call. + * If not provided the handler will determine the proper route by matching + * against `request.url` + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + */ + async function queryRoute(request, _temp4) { + let { + routeId, + requestContext, + unstable_dataStrategy + } = _temp4 === void 0 ? {} : _temp4; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { + throw getInternalRouterError(405, { + method + }); + } else if (!matches) { + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let match = routeId ? matches.find(m => m.route.id === routeId) : getTargetMatch(matches, location); + if (routeId && !match) { + throw getInternalRouterError(403, { + pathname: location.pathname, + routeId + }); + } else if (!match) { + // This should never hit I don't think? + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, false, match); + if (isResponse(result)) { + return result; + } + let error = result.errors ? Object.values(result.errors)[0] : undefined; + if (error !== undefined) { + // If we got back result.errors, that means the loader/action threw + // _something_ that wasn't a Response, but it's not guaranteed/required + // to be an `instanceof Error` either, so we have to use throw here to + // preserve the "error" state outside of queryImpl. + throw error; + } + + // Pick off the right state value to return + if (result.actionData) { + return Object.values(result.actionData)[0]; + } + if (result.loaderData) { + var _result$activeDeferre; + let data = Object.values(result.loaderData)[0]; + if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) { + data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id]; + } + return data; + } + return undefined; + } + async function queryImpl(request, location, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch) { + invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal"); + try { + if (isMutationMethod(request.method.toLowerCase())) { + let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch != null); + return result; + } + let result = await loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction for a + // `queryRoute` call, we throw the `HandlerResult` to bail out early + // and then return or throw the raw Response here accordingly + if (isHandlerResult(e) && isResponse(e.result)) { + if (e.type === ResultType.error) { + throw e.result; + } + return e.result; + } + // Redirects are always returned since they don't propagate to catch + // boundaries + if (isRedirectResponse(e)) { + return e; + } + throw e; + } + } + async function submit(request, matches, actionMatch, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, isRouteRequest) { + let result; + if (!actionMatch.route.action && !actionMatch.route.lazy) { + let error = getInternalRouterError(405, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: actionMatch.route.id + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, unstable_dataStrategy); + result = results[0]; + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + } + if (isRedirectResult(result)) { + // Uhhhh - this should never happen, we should always throw these from + // callLoaderOrAction, but the type narrowing here keeps TS happy and we + // can get back on the "throw all redirect responses" train here should + // this ever happen :/ + throw new Response(null, { + status: result.response.status, + headers: { + Location: result.response.headers.get("Location") + } + }); + } + if (isDeferredResult(result)) { + let error = getInternalRouterError(400, { + type: "defer-action" + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } + if (isRouteRequest) { + // Note: This should only be non-Response values if we get here, since + // isRouteRequest should throw any Response received in callLoaderOrAction + if (isErrorResult(result)) { + throw result.error; + } + return { + matches: [actionMatch], + loaderData: {}, + actionData: { + [actionMatch.route.id]: result.data + }, + errors: null, + // Note: statusCode + headers are unused here since queryRoute will + // return the raw Response or value + statusCode: 200, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + + // Create a GET request for the loaders + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]); + + // action status codes take precedence over loader status codes + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null); + return _extends({}, context, { + actionData: { + [actionMatch.route.id]: result.data + } + }, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionHeaders: result.headers ? { + [actionMatch.route.id]: result.headers + } : {} + }); + } + async function loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) { + let isRouteRequest = routeMatch != null; + + // Short circuit if we have no loaders to run (queryRoute()) + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches; + let matchesToLoad = requestMatches.filter(m => m.route.loader || m.route.lazy); + + // Short circuit if we have no loaders to run (query()) + if (matchesToLoad.length === 0) { + return { + matches, + // Add a null for all matched routes for proper revalidation on the client + loaderData: matches.reduce((acc, m) => Object.assign(acc, { + [m.route.id]: null + }), {}), + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy); + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + + // Process and commit output from loaders + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling); + + // Add a null for any non-loader matches for proper revalidation on the client + let executedLoaders = new Set(matchesToLoad.map(match => match.route.id)); + matches.forEach(match => { + if (!executedLoaders.has(match.route.id)) { + context.loaderData[match.route.id] = null; + } + }); + return _extends({}, context, { + matches, + activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null + }); + } + + // Utility wrapper for calling dataStrategy server-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy) { + let results = await callDataStrategyImpl(unstable_dataStrategy || defaultDataStrategy, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + // Throw redirects and let the server handle them with an HTTP redirect + throw normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath); + } + if (isResponse(result.result) && isRouteRequest) { + // For SSR single-route requests, we want to hand Responses back + // directly without unwrapping + throw result; + } + return convertHandlerResultToDataResult(result); + })); + } + return { + dataRoutes, + query, + queryRoute + }; +} + +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Helpers +//////////////////////////////////////////////////////////////////////////////// + +/** + * Given an existing StaticHandlerContext and an error thrown at render time, + * provide an updated StaticHandlerContext suitable for a second SSR render + */ +function getStaticContextFromError(routes, context, error) { + let newContext = _extends({}, context, { + statusCode: isRouteErrorResponse(error) ? error.status : 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + return newContext; +} +function throwStaticHandlerAbortedError(request, isRouteRequest, future) { + if (future.v7_throwAbortReason && request.signal.reason !== undefined) { + throw request.signal.reason; + } + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted: " + request.method + " " + request.url); +} +function isSubmissionNavigation(opts) { + return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== undefined); +} +function normalizeTo(location, matches, basename, prependBasename, to, v7_relativeSplatPath, fromRouteId, relative) { + let contextualMatches; + let activeRouteMatch; + if (fromRouteId) { + // Grab matches up to the calling route so our route-relative logic is + // relative to the correct source route + contextualMatches = []; + for (let match of matches) { + contextualMatches.push(match); + if (match.route.id === fromRouteId) { + activeRouteMatch = match; + break; + } + } + } else { + contextualMatches = matches; + activeRouteMatch = matches[matches.length - 1]; + } + + // Resolve the relative path + let path = resolveTo(to ? to : ".", getResolveToMatches(contextualMatches, v7_relativeSplatPath), stripBasename(location.pathname, basename) || location.pathname, relative === "path"); + + // When `to` is not specified we inherit search/hash from the current + // location, unlike when to="." and we just inherit the path. + // See https://github.com/remix-run/remix/issues/927 + if (to == null) { + path.search = location.search; + path.hash = location.hash; + } + + // Add an ?index param for matched index routes if we don't already have one + if ((to == null || to === "" || to === ".") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) { + path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; + } + + // If we're operating within a basename, prepend it to the pathname. If + // this is a root navigation, then just use the raw basename which allows + // the basename to have full control over the presence of a trailing slash + // on root actions + if (prependBasename && basename !== "/") { + path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); + } + return createPath(path); +} + +// Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params +function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) { + // Return location verbatim on non-submission navigations + if (!opts || !isSubmissionNavigation(opts)) { + return { + path + }; + } + if (opts.formMethod && !isValidMethod(opts.formMethod)) { + return { + path, + error: getInternalRouterError(405, { + method: opts.formMethod + }) + }; + } + let getInvalidBodyError = () => ({ + path, + error: getInternalRouterError(400, { + type: "invalid-body" + }) + }); + + // Create a Submission on non-GET navigations + let rawFormMethod = opts.formMethod || "get"; + let formMethod = normalizeFormMethod ? rawFormMethod.toUpperCase() : rawFormMethod.toLowerCase(); + let formAction = stripHashFromPath(path); + if (opts.body !== undefined) { + if (opts.formEncType === "text/plain") { + // text only support POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data + Array.from(opts.body.entries()).reduce((acc, _ref5) => { + let [name, value] = _ref5; + return "" + acc + name + "=" + value + "\n"; + }, "") : String(opts.body); + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json: undefined, + text + } + }; + } else if (opts.formEncType === "application/json") { + // json only supports POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + try { + let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json, + text: undefined + } + }; + } catch (e) { + return getInvalidBodyError(); + } + } + } + invariant(typeof FormData === "function", "FormData is not available in this environment"); + let searchParams; + let formData; + if (opts.formData) { + searchParams = convertFormDataToSearchParams(opts.formData); + formData = opts.formData; + } else if (opts.body instanceof FormData) { + searchParams = convertFormDataToSearchParams(opts.body); + formData = opts.body; + } else if (opts.body instanceof URLSearchParams) { + searchParams = opts.body; + formData = convertSearchParamsToFormData(searchParams); + } else if (opts.body == null) { + searchParams = new URLSearchParams(); + formData = new FormData(); + } else { + try { + searchParams = new URLSearchParams(opts.body); + formData = convertSearchParamsToFormData(searchParams); + } catch (e) { + return getInvalidBodyError(); + } + } + let submission = { + formMethod, + formAction, + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData, + json: undefined, + text: undefined + }; + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + + // Flatten submission onto URLSearchParams for GET submissions + let parsedPath = parsePath(path); + // On GET navigation submissions we can drop the ?index param from the + // resulting location since all loaders will run. But fetcher GET submissions + // only run a single loader so we need to preserve any incoming ?index params + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + parsedPath.search = "?" + searchParams; + return { + path: createPath(parsedPath), + submission + }; +} + +// Filter out all routes below any caught error as they aren't going to +// render so we don't need to load them +function getLoaderMatchesUntilBoundary(matches, boundaryId) { + let boundaryMatches = matches; + if (boundaryId) { + let index = matches.findIndex(m => m.route.id === boundaryId); + if (index >= 0) { + boundaryMatches = matches.slice(0, index); + } + } + return boundaryMatches; +} +function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) { + let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined; + let currentUrl = history.createURL(state.location); + let nextUrl = history.createURL(location); + + // Pick navigation matches that are net-new or qualify for revalidation + let boundaryId = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[0] : undefined; + let boundaryMatches = boundaryId ? getLoaderMatchesUntilBoundary(matches, boundaryId) : matches; + + // Don't revalidate loaders by default after action 4xx/5xx responses + // when the flag is enabled. They can still opt-into revalidation via + // `shouldRevalidate` via `actionResult` + let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : undefined; + let shouldSkipRevalidation = skipActionErrorRevalidation && actionStatus && actionStatus >= 400; + let navigationMatches = boundaryMatches.filter((match, index) => { + let { + route + } = match; + if (route.lazy) { + // We haven't loaded this route yet so we don't know if it's got a loader! + return true; + } + if (route.loader == null) { + return false; + } + if (isInitialLoad) { + if (typeof route.loader !== "function" || route.loader.hydrate) { + return true; + } + return state.loaderData[route.id] === undefined && ( + // Don't re-run if the loader ran and threw an error + !state.errors || state.errors[route.id] === undefined); + } + + // Always call the loader on new route instances and pending defer cancellations + if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) { + return true; + } + + // This is the default implementation for when we revalidate. If the route + // provides it's own implementation, then we give them full control but + // provide this value so they can leverage it if needed after they check + // their own specific use cases + let currentRouteMatch = state.matches[index]; + let nextRouteMatch = match; + return shouldRevalidateLoader(match, _extends({ + currentUrl, + currentParams: currentRouteMatch.params, + nextUrl, + nextParams: nextRouteMatch.params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : + // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate + isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || + // Search params affect all loaders + currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch) + })); + }); + + // Pick fetcher.loads that need to be revalidated + let revalidatingFetchers = []; + fetchLoadMatches.forEach((f, key) => { + // Don't revalidate: + // - on initial load (shouldn't be any fetchers then anyway) + // - if fetcher won't be present in the subsequent render + // - no longer matches the URL (v7_fetcherPersist=false) + // - was unmounted but persisted due to v7_fetcherPersist=true + if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) { + return; + } + let fetcherMatches = matchRoutes(routesToUse, f.path, basename); + + // If the fetcher path no longer matches, push it in with null matches so + // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is + // currently only a use-case for Remix HMR where the route tree can change + // at runtime and remove a route previously loaded via a fetcher + if (!fetcherMatches) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: null, + match: null, + controller: null + }); + return; + } + + // Revalidating fetchers are decoupled from the route matches since they + // load from a static href. They revalidate based on explicit revalidation + // (submission, useRevalidator, or X-Remix-Revalidate) + let fetcher = state.fetchers.get(key); + let fetcherMatch = getTargetMatch(fetcherMatches, f.path); + let shouldRevalidate = false; + if (fetchRedirectIds.has(key)) { + // Never trigger a revalidation of an actively redirecting fetcher + shouldRevalidate = false; + } else if (cancelledFetcherLoads.includes(key)) { + // Always revalidate if the fetcher was cancelled + shouldRevalidate = true; + } else if (fetcher && fetcher.state !== "idle" && fetcher.data === undefined) { + // If the fetcher hasn't ever completed loading yet, then this isn't a + // revalidation, it would just be a brand new load if an explicit + // revalidation is required + shouldRevalidate = isRevalidationRequired; + } else { + // Otherwise fall back on any user-defined shouldRevalidate, defaulting + // to explicit revalidations only + shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({ + currentUrl, + currentParams: state.matches[state.matches.length - 1].params, + nextUrl, + nextParams: matches[matches.length - 1].params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired + })); + } + if (shouldRevalidate) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: fetcherMatches, + match: fetcherMatch, + controller: new AbortController() + }); + } + }); + return [navigationMatches, revalidatingFetchers]; +} +function isNewLoader(currentLoaderData, currentMatch, match) { + let isNew = + // [a] -> [a, b] + !currentMatch || + // [a, b] -> [a, c] + match.route.id !== currentMatch.route.id; + + // Handle the case that we don't have data for a re-used route, potentially + // from a prior error or from a cancelled pending deferred + let isMissingData = currentLoaderData[match.route.id] === undefined; + + // Always load if this is a net-new route or we don't yet have data + return isNew || isMissingData; +} +function isNewRouteInstance(currentMatch, match) { + let currentPath = currentMatch.route.path; + return ( + // param change for this match, /users/123 -> /users/456 + currentMatch.pathname !== match.pathname || + // splat param changed, which is not present in match.path + // e.g. /files/images/avatar.jpg -> files/finances.xls + currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); +} +function shouldRevalidateLoader(loaderMatch, arg) { + if (loaderMatch.route.shouldRevalidate) { + let routeChoice = loaderMatch.route.shouldRevalidate(arg); + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + return arg.defaultShouldRevalidate; +} + +/** + * Idempotent utility to execute patchRoutesOnMiss() to lazily load route + * definitions and update the routes/routeManifest + */ +async function loadLazyRouteChildren(patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) { + let key = [path, ...matches.map(m => m.route.id)].join("-"); + try { + let pending = pendingRouteChildren.get(key); + if (!pending) { + pending = patchRoutesOnMissImpl({ + path, + matches, + patch: (routeId, children) => { + if (!signal.aborted) { + patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties); + } + } + }); + pendingRouteChildren.set(key, pending); + } + if (pending && isPromise(pending)) { + await pending; + } + } finally { + pendingRouteChildren.delete(key); + } +} +function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) { + if (routeId) { + var _route$children; + let route = manifest[routeId]; + invariant(route, "No route found to patch children into: routeId = " + routeId); + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, [routeId, "patch", String(((_route$children = route.children) == null ? void 0 : _route$children.length) || "0")], manifest); + if (route.children) { + route.children.push(...dataChildren); + } else { + route.children = dataChildren; + } + } else { + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest); + routesToUse.push(...dataChildren); + } +} + +/** + * Execute route.lazy() methods to lazily load route modules (loader, action, + * shouldRevalidate) and update the routeManifest in place which shares objects + * with dataRoutes so those get updated as well. + */ +async function loadLazyRouteModule(route, mapRouteProperties, manifest) { + if (!route.lazy) { + return; + } + let lazyRoute = await route.lazy(); + + // If the lazy route function was executed and removed by another parallel + // call then we can return - first lazy() to finish wins because the return + // value of lazy is expected to be static + if (!route.lazy) { + return; + } + let routeToUpdate = manifest[route.id]; + invariant(routeToUpdate, "No route found in manifest"); + + // Update the route in place. This should be safe because there's no way + // we could yet be sitting on this route as we can't get there without + // resolving lazy() first. + // + // This is different than the HMR "update" use-case where we may actively be + // on the route being updated. The main concern boils down to "does this + // mutation affect any ongoing navigations or any current state.matches + // values?". If not, it should be safe to update in place. + let routeUpdates = {}; + for (let lazyRouteProperty in lazyRoute) { + let staticRouteValue = routeToUpdate[lazyRouteProperty]; + let isPropertyStaticallyDefined = staticRouteValue !== undefined && + // This property isn't static since it should always be updated based + // on the route updates + lazyRouteProperty !== "hasErrorBoundary"; + warning(!isPropertyStaticallyDefined, "Route \"" + routeToUpdate.id + "\" has a static property \"" + lazyRouteProperty + "\" " + "defined but its lazy function is also returning a value for this property. " + ("The lazy route property \"" + lazyRouteProperty + "\" will be ignored.")); + if (!isPropertyStaticallyDefined && !immutableRouteKeys.has(lazyRouteProperty)) { + routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty]; + } + } + + // Mutate the route with the provided updates. Do this first so we pass + // the updated version to mapRouteProperties + Object.assign(routeToUpdate, routeUpdates); + + // Mutate the `hasErrorBoundary` property on the route based on the route + // updates and remove the `lazy` function so we don't resolve the lazy + // route again. + Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), { + lazy: undefined + })); +} + +// Default implementation of `dataStrategy` which fetches all loaders in parallel +function defaultDataStrategy(opts) { + return Promise.all(opts.matches.map(m => m.resolve())); +} +async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext) { + let routeIdsToLoad = matchesToLoad.reduce((acc, m) => acc.add(m.route.id), new Set()); + let loadedMatches = new Set(); + + // Send all matches here to allow for a middleware-type implementation. + // handler will be a no-op for unneeded routes and we filter those results + // back out below. + let results = await dataStrategyImpl({ + matches: matches.map(match => { + let shouldLoad = routeIdsToLoad.has(match.route.id); + // `resolve` encapsulates the route.lazy, executing the + // loader/action, and mapping return values/thrown errors to a + // HandlerResult. Users can pass a callback to take fine-grained control + // over the execution of the loader/action + let resolve = handlerOverride => { + loadedMatches.add(match.route.id); + return shouldLoad ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, requestContext) : Promise.resolve({ + type: ResultType.data, + result: undefined + }); + }; + return _extends({}, match, { + shouldLoad, + resolve + }); + }), + request, + params: matches[0].params, + context: requestContext + }); + + // Throw if any loadRoute implementations not called since they are what + // ensures a route is fully loaded + matches.forEach(m => invariant(loadedMatches.has(m.route.id), "`match.resolve()` was not called for route id \"" + m.route.id + "\". " + "You must call `match.resolve()` on every match passed to " + "`dataStrategy` to ensure all routes are properly loaded.")); + + // Filter out any middleware-only matches for which we didn't need to run handlers + return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id)); +} + +// Default logic for calling a loader/action is the user has no specified a dataStrategy +async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, staticContext) { + let result; + let onReject; + let runHandler = handler => { + // Setup a promise we can race against so that abort signals short circuit + let reject; + // This will never resolve so safe to type it as Promise to + // satisfy the function return value + let abortPromise = new Promise((_, r) => reject = r); + onReject = () => reject(); + request.signal.addEventListener("abort", onReject); + let actualHandler = ctx => { + if (typeof handler !== "function") { + return Promise.reject(new Error("You cannot call the handler for a route which defines a boolean " + ("\"" + type + "\" [routeId: " + match.route.id + "]"))); + } + return handler({ + request, + params: match.params, + context: staticContext + }, ...(ctx !== undefined ? [ctx] : [])); + }; + let handlerPromise; + if (handlerOverride) { + handlerPromise = handlerOverride(ctx => actualHandler(ctx)); + } else { + handlerPromise = (async () => { + try { + let val = await actualHandler(); + return { + type: "data", + result: val + }; + } catch (e) { + return { + type: "error", + result: e + }; + } + })(); + } + return Promise.race([handlerPromise, abortPromise]); + }; + try { + let handler = match.route[type]; + if (match.route.lazy) { + if (handler) { + // Run statically defined handler in parallel with lazy() + let handlerError; + let [value] = await Promise.all([ + // If the handler throws, don't let it immediately bubble out, + // since we need to let the lazy() execution finish so we know if this + // route has a boundary that can handle the error + runHandler(handler).catch(e => { + handlerError = e; + }), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]); + if (handlerError !== undefined) { + throw handlerError; + } + result = value; + } else { + // Load lazy route module, then run any returned handler + await loadLazyRouteModule(match.route, mapRouteProperties, manifest); + handler = match.route[type]; + if (handler) { + // Handler still runs even if we got interrupted to maintain consistency + // with un-abortable behavior of handler execution on non-lazy or + // previously-lazy-loaded routes + result = await runHandler(handler); + } else if (type === "action") { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(405, { + method: request.method, + pathname, + routeId: match.route.id + }); + } else { + // lazy() route has no loader to run. Short circuit here so we don't + // hit the invariant below that errors on returning undefined. + return { + type: ResultType.data, + result: undefined + }; + } + } + } else if (!handler) { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(404, { + pathname + }); + } else { + result = await runHandler(handler); + } + invariant(result.result !== undefined, "You defined " + (type === "action" ? "an action" : "a loader") + " for route " + ("\"" + match.route.id + "\" but didn't return anything from your `" + type + "` ") + "function. Please return a value or `null`."); + } catch (e) { + // We should already be catching and converting normal handler executions to + // HandlerResults and returning them, so anything that throws here is an + // unexpected error we still need to wrap + return { + type: ResultType.error, + result: e + }; + } finally { + if (onReject) { + request.signal.removeEventListener("abort", onReject); + } + } + return result; +} +async function convertHandlerResultToDataResult(handlerResult) { + let { + result, + type, + status + } = handlerResult; + if (isResponse(result)) { + let data; + try { + let contentType = result.headers.get("Content-Type"); + // Check between word boundaries instead of startsWith() due to the last + // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type + if (contentType && /\bapplication\/json\b/.test(contentType)) { + if (result.body == null) { + data = null; + } else { + data = await result.json(); + } + } else { + data = await result.text(); + } + } catch (e) { + return { + type: ResultType.error, + error: e + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: new ErrorResponseImpl(result.status, result.statusText, data), + statusCode: result.status, + headers: result.headers + }; + } + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: result, + statusCode: isRouteErrorResponse(result) ? result.status : status + }; + } + if (isDeferredData(result)) { + var _result$init, _result$init2; + return { + type: ResultType.deferred, + deferredData: result, + statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status, + headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers) + }; + } + return { + type: ResultType.data, + data: result, + statusCode: status + }; +} + +// Support relative routing in internal redirects +function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, v7_relativeSplatPath) { + let location = response.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + if (!ABSOLUTE_URL_REGEX.test(location)) { + let trimmedMatches = matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1); + location = normalizeTo(new URL(request.url), trimmedMatches, basename, true, location, v7_relativeSplatPath); + response.headers.set("Location", location); + } + return response; +} +function normalizeRedirectLocation(location, currentUrl, basename) { + if (ABSOLUTE_URL_REGEX.test(location)) { + // Strip off the protocol+origin for same-origin + same-basename absolute redirects + let normalizedLocation = location; + let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation); + let isSameBasename = stripBasename(url.pathname, basename) != null; + if (url.origin === currentUrl.origin && isSameBasename) { + return url.pathname + url.search + url.hash; + } + } + return location; +} + +// Utility method for creating the Request instances for loaders/actions during +// client-side navigations and fetches. During SSR we will always have a +// Request instance from the static handler (query/queryRoute) +function createClientSideRequest(history, location, signal, submission) { + let url = history.createURL(stripHashFromPath(location)).toString(); + let init = { + signal + }; + if (submission && isMutationMethod(submission.formMethod)) { + let { + formMethod, + formEncType + } = submission; + // Didn't think we needed this but it turns out unlike other methods, patch + // won't be properly normalized to uppercase and results in a 405 error. + // See: https://fetch.spec.whatwg.org/#concept-method + init.method = formMethod.toUpperCase(); + if (formEncType === "application/json") { + init.headers = new Headers({ + "Content-Type": formEncType + }); + init.body = JSON.stringify(submission.json); + } else if (formEncType === "text/plain") { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.text; + } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = convertFormDataToSearchParams(submission.formData); + } else { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.formData; + } + } + return new Request(url, init); +} +function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + for (let [key, value] of formData.entries()) { + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs + searchParams.append(key, typeof value === "string" ? value : value.name); + } + return searchParams; +} +function convertSearchParamsToFormData(searchParams) { + let formData = new FormData(); + for (let [key, value] of searchParams.entries()) { + formData.append(key, value); + } + return formData; +} +function processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; + let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined; + + // Process loader results into state.loaderData/state.errors + results.forEach((result, index) => { + let id = matchesToLoad[index].route.id; + invariant(!isRedirectResult(result), "Cannot handle redirect results in processLoaderData"); + if (isErrorResult(result)) { + let error = result.error; + // If we have a pending action error, we report it at the highest-route + // that throws a loader error, and then clear it out to indicate that + // it was consumed + if (pendingError !== undefined) { + error = pendingError; + pendingError = undefined; + } + errors = errors || {}; + if (skipLoaderErrorBubbling) { + errors[id] = error; + } else { + // Look upwards from the matched route for the closest ancestor error + // boundary, defaulting to the root match. Prefer higher error values + // if lower errors bubble to the same boundary + let boundaryMatch = findNearestBoundary(matches, id); + if (errors[boundaryMatch.route.id] == null) { + errors[boundaryMatch.route.id] = error; + } + } + + // Clear our any prior loaderData for the throwing route + loaderData[id] = undefined; + + // Once we find our first (highest) error, we set the status code and + // prevent deeper status codes from overriding + if (!foundError) { + foundError = true; + statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + if (isDeferredResult(result)) { + activeDeferreds.set(id, result.deferredData); + loaderData[id] = result.deferredData.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode != null && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + loaderData[id] = result.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } + } + }); + + // If we didn't consume the pending action error (i.e., all loaders + // resolved), then consume it here. Also clear out any loaderData for the + // throwing route + if (pendingError !== undefined && pendingActionResult) { + errors = { + [pendingActionResult[0]]: pendingError + }; + loaderData[pendingActionResult[0]] = undefined; + } + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; +} +function processLoaderData(state, matches, matchesToLoad, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble + ); + + // Process results from our revalidating fetchers + for (let index = 0; index < revalidatingFetchers.length; index++) { + let { + key, + match, + controller + } = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; + + // Process fetcher non-redirect errors + if (controller && controller.signal.aborted) { + // Nothing to do for aborted fetchers + continue; + } else if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id); + if (!(errors && errors[boundaryMatch.route.id])) { + errors = _extends({}, errors, { + [boundaryMatch.route.id]: result.error + }); + } + state.fetchers.delete(key); + } else if (isRedirectResult(result)) { + // Should never get here, redirects should get processed above, but we + // keep this to type narrow to a success result in the else + invariant(false, "Unhandled fetcher revalidation redirect"); + } else if (isDeferredResult(result)) { + // Should never get here, deferred data should be awaited for fetchers + // in resolveDeferredResults + invariant(false, "Unhandled fetcher deferred data"); + } else { + let doneFetcher = getDoneFetcher(result.data); + state.fetchers.set(key, doneFetcher); + } + } + return { + loaderData, + errors + }; +} +function mergeLoaderData(loaderData, newLoaderData, matches, errors) { + let mergedLoaderData = _extends({}, newLoaderData); + for (let match of matches) { + let id = match.route.id; + if (newLoaderData.hasOwnProperty(id)) { + if (newLoaderData[id] !== undefined) { + mergedLoaderData[id] = newLoaderData[id]; + } + } else if (loaderData[id] !== undefined && match.route.loader) { + // Preserve existing keys not included in newLoaderData and where a loader + // wasn't removed by HMR + mergedLoaderData[id] = loaderData[id]; + } + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + return mergedLoaderData; +} +function getActionDataForCommit(pendingActionResult) { + if (!pendingActionResult) { + return {}; + } + return isErrorResult(pendingActionResult[1]) ? { + // Clear out prior actionData on errors + actionData: {} + } : { + actionData: { + [pendingActionResult[0]]: pendingActionResult[1].data + } + }; +} + +// Find the nearest error boundary, looking upwards from the leaf route (or the +// route specified by routeId) for the closest ancestor error boundary, +// defaulting to the root match +function findNearestBoundary(matches, routeId) { + let eligibleMatches = routeId ? matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1) : [...matches]; + return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0]; +} +function getShortCircuitMatches(routes) { + // Prefer a root layout route if present, otherwise shim in a route object + let route = routes.length === 1 ? routes[0] : routes.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; +} +function getInternalRouterError(status, _temp5) { + let { + pathname, + routeId, + method, + type, + message + } = _temp5 === void 0 ? {} : _temp5; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + if (status === 400) { + statusText = "Bad Request"; + if (type === "route-discovery") { + errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnMiss()` " + ("function threw the following error:\n" + message); + } else if (method && pathname && routeId) { + errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (type === "defer-action") { + errorMessage = "defer() is not supported in actions"; + } else if (type === "invalid-body") { + errorMessage = "Unable to encode submission body"; + } + } else if (status === 403) { + statusText = "Forbidden"; + errorMessage = "Route \"" + routeId + "\" does not match URL \"" + pathname + "\""; + } else if (status === 404) { + statusText = "Not Found"; + errorMessage = "No route matches URL \"" + pathname + "\""; + } else if (status === 405) { + statusText = "Method Not Allowed"; + if (method && pathname && routeId) { + errorMessage = "You made a " + method.toUpperCase() + " request to \"" + pathname + "\" but " + ("did not provide an `action` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (method) { + errorMessage = "Invalid request method \"" + method.toUpperCase() + "\""; + } + } + return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true); +} + +// Find any returned redirect errors, starting from the lowest match +function findRedirect(results) { + for (let i = results.length - 1; i >= 0; i--) { + let result = results[i]; + if (isRedirectResult(result)) { + return { + result, + idx: i + }; + } + } +} +function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); +} +function isHashChangeOnly(a, b) { + if (a.pathname !== b.pathname || a.search !== b.search) { + return false; + } + if (a.hash === "") { + // /page -> /page#hash + return b.hash !== ""; + } else if (a.hash === b.hash) { + // /page#hash -> /page#hash + return true; + } else if (b.hash !== "") { + // /page#hash -> /page#other + return true; + } + + // If the hash is removed the browser will re-perform a request to the server + // /page#hash -> /page + return false; +} +function isPromise(val) { + return typeof val === "object" && val != null && "then" in val; +} +function isHandlerResult(result) { + return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error); +} +function isRedirectHandlerResult(result) { + return isResponse(result.result) && redirectStatusCodes.has(result.result.status); +} +function isDeferredResult(result) { + return result.type === ResultType.deferred; +} +function isErrorResult(result) { + return result.type === ResultType.error; +} +function isRedirectResult(result) { + return (result && result.type) === ResultType.redirect; +} +function isDeferredData(value) { + let deferred = value; + return deferred && typeof deferred === "object" && typeof deferred.data === "object" && typeof deferred.subscribe === "function" && typeof deferred.cancel === "function" && typeof deferred.resolveData === "function"; +} +function isResponse(value) { + return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined"; +} +function isRedirectResponse(result) { + if (!isResponse(result)) { + return false; + } + let status = result.status; + let location = result.headers.get("Location"); + return status >= 300 && status <= 399 && location != null; +} +function isValidMethod(method) { + return validRequestMethods.has(method.toLowerCase()); +} +function isMutationMethod(method) { + return validMutationMethods.has(method.toLowerCase()); +} +async function resolveDeferredResults(currentMatches, matchesToLoad, results, signals, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + // If we don't have a match, then we can have a deferred result to do + // anything with. This is for revalidating fetchers where the route was + // removed during HMR + if (!match) { + continue; + } + let currentMatch = currentMatches.find(m => m.route.id === match.route.id); + let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined; + if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) { + // Note: we do not have to touch activeDeferreds here since we race them + // against the signal in resolveDeferredData and they'll get aborted + // there if needed + let signal = signals[index]; + invariant(signal, "Expected an AbortSignal for revalidating fetcher deferred result"); + await resolveDeferredData(result, signal, isFetcher).then(result => { + if (result) { + results[index] = result || results[index]; + } + }); + } + } +} +async function resolveDeferredData(result, signal, unwrap) { + if (unwrap === void 0) { + unwrap = false; + } + let aborted = await result.deferredData.resolveData(signal); + if (aborted) { + return; + } + if (unwrap) { + try { + return { + type: ResultType.data, + data: result.deferredData.unwrappedData + }; + } catch (e) { + // Handle any TrackedPromise._error values encountered while unwrapping + return { + type: ResultType.error, + error: e + }; + } + } + return { + type: ResultType.data, + data: result.deferredData.data + }; +} +function hasNakedIndexQuery(search) { + return new URLSearchParams(search).getAll("index").some(v => v === ""); +} +function getTargetMatch(matches, location) { + let search = typeof location === "string" ? parsePath(location).search : location.search; + if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) { + // Return the leaf index route when index is present + return matches[matches.length - 1]; + } + // Otherwise grab the deepest "path contributing" match (ignoring index and + // pathless layout routes) + let pathMatches = getPathContributingMatches(matches); + return pathMatches[pathMatches.length - 1]; +} +function getSubmissionFromNavigation(navigation) { + let { + formMethod, + formAction, + formEncType, + text, + formData, + json + } = navigation; + if (!formMethod || !formAction || !formEncType) { + return; + } + if (text != null) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json: undefined, + text + }; + } else if (formData != null) { + return { + formMethod, + formAction, + formEncType, + formData, + json: undefined, + text: undefined + }; + } else if (json !== undefined) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json, + text: undefined + }; + } +} +function getLoadingNavigation(location, submission) { + if (submission) { + let navigation = { + state: "loading", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; + } else { + let navigation = { + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined + }; + return navigation; + } +} +function getSubmittingNavigation(location, submission) { + let navigation = { + state: "submitting", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; +} +function getLoadingFetcher(submission, data) { + if (submission) { + let fetcher = { + state: "loading", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data + }; + return fetcher; + } else { + let fetcher = { + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; + } +} +function getSubmittingFetcher(submission, existingFetcher) { + let fetcher = { + state: "submitting", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data: existingFetcher ? existingFetcher.data : undefined + }; + return fetcher; +} +function getDoneFetcher(data) { + let fetcher = { + state: "idle", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; +} +function restoreAppliedTransitions(_window, transitions) { + try { + let sessionPositions = _window.sessionStorage.getItem(TRANSITIONS_STORAGE_KEY); + if (sessionPositions) { + let json = JSON.parse(sessionPositions); + for (let [k, v] of Object.entries(json || {})) { + if (v && Array.isArray(v)) { + transitions.set(k, new Set(v || [])); + } + } + } + } catch (e) { + // no-op, use default empty object + } +} +function persistAppliedTransitions(_window, transitions) { + if (transitions.size > 0) { + let json = {}; + for (let [k, v] of transitions) { + json[k] = [...v]; + } + try { + _window.sessionStorage.setItem(TRANSITIONS_STORAGE_KEY, JSON.stringify(json)); + } catch (error) { + warning(false, "Failed to save applied view transitions in sessionStorage (" + error + ")."); + } + } +} +//#endregion + +exports.AbortedDeferredError = AbortedDeferredError; +exports.Action = Action; +exports.IDLE_BLOCKER = IDLE_BLOCKER; +exports.IDLE_FETCHER = IDLE_FETCHER; +exports.IDLE_NAVIGATION = IDLE_NAVIGATION; +exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL; +exports.UNSAFE_DeferredData = DeferredData; +exports.UNSAFE_ErrorResponseImpl = ErrorResponseImpl; +exports.UNSAFE_convertRouteMatchToUiMatch = convertRouteMatchToUiMatch; +exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes; +exports.UNSAFE_decodePath = decodePath; +exports.UNSAFE_getResolveToMatches = getResolveToMatches; +exports.UNSAFE_invariant = invariant; +exports.UNSAFE_warning = warning; +exports.createBrowserHistory = createBrowserHistory; +exports.createHashHistory = createHashHistory; +exports.createMemoryHistory = createMemoryHistory; +exports.createPath = createPath; +exports.createRouter = createRouter; +exports.createStaticHandler = createStaticHandler; +exports.defer = defer; +exports.generatePath = generatePath; +exports.getStaticContextFromError = getStaticContextFromError; +exports.getToPathname = getToPathname; +exports.isDeferredData = isDeferredData; +exports.isRouteErrorResponse = isRouteErrorResponse; +exports.joinPaths = joinPaths; +exports.json = json; +exports.matchPath = matchPath; +exports.matchRoutes = matchRoutes; +exports.normalizePathname = normalizePathname; +exports.parsePath = parsePath; +exports.redirect = redirect; +exports.redirectDocument = redirectDocument; +exports.resolvePath = resolvePath; +exports.resolveTo = resolveTo; +exports.stripBasename = stripBasename; +//# sourceMappingURL=router.cjs.js.map diff --git a/node_modules/@remix-run/router/dist/router.cjs.js.map b/node_modules/@remix-run/router/dist/router.cjs.js.map new file mode 100644 index 0000000000..5dec707d3a --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.cjs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"router.cjs.js","sources":["../history.ts","../utils.ts","../router.ts"],"sourcesContent":["////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Actions represent the type of change to a location value.\n */\nexport enum Action {\n /**\n * A POP indicates a change to an arbitrary index in the history stack, such\n * as a back or forward navigation. It does not describe the direction of the\n * navigation, only that the current index changed.\n *\n * Note: This is the default action for newly created history objects.\n */\n Pop = \"POP\",\n\n /**\n * A PUSH indicates a new entry being added to the history stack, such as when\n * a link is clicked and a new page loads. When this happens, all subsequent\n * entries in the stack are lost.\n */\n Push = \"PUSH\",\n\n /**\n * A REPLACE indicates the entry at the current index in the history stack\n * being replaced by a new one.\n */\n Replace = \"REPLACE\",\n}\n\n/**\n * The pathname, search, and hash values of a URL.\n */\nexport interface Path {\n /**\n * A URL pathname, beginning with a /.\n */\n pathname: string;\n\n /**\n * A URL search string, beginning with a ?.\n */\n search: string;\n\n /**\n * A URL fragment identifier, beginning with a #.\n */\n hash: string;\n}\n\n// TODO: (v7) Change the Location generic default from `any` to `unknown` and\n// remove Remix `useLocation` wrapper.\n\n/**\n * An entry in a history stack. A location contains information about the\n * URL path, as well as possibly some arbitrary state and a key.\n */\nexport interface Location extends Path {\n /**\n * A value of arbitrary data associated with this location.\n */\n state: State;\n\n /**\n * A unique string associated with this location. May be used to safely store\n * and retrieve data in some other storage API, like `localStorage`.\n *\n * Note: This value is always \"default\" on the initial location.\n */\n key: string;\n}\n\n/**\n * A change to the current location.\n */\nexport interface Update {\n /**\n * The action that triggered the change.\n */\n action: Action;\n\n /**\n * The new location.\n */\n location: Location;\n\n /**\n * The delta between this location and the former location in the history stack\n */\n delta: number | null;\n}\n\n/**\n * A function that receives notifications about location changes.\n */\nexport interface Listener {\n (update: Update): void;\n}\n\n/**\n * Describes a location that is the destination of some navigation, either via\n * `history.push` or `history.replace`. This may be either a URL or the pieces\n * of a URL path.\n */\nexport type To = string | Partial;\n\n/**\n * A history is an interface to the navigation stack. The history serves as the\n * source of truth for the current location, as well as provides a set of\n * methods that may be used to change it.\n *\n * It is similar to the DOM's `window.history` object, but with a smaller, more\n * focused API.\n */\nexport interface History {\n /**\n * The last action that modified the current location. This will always be\n * Action.Pop when a history instance is first created. This value is mutable.\n */\n readonly action: Action;\n\n /**\n * The current location. This value is mutable.\n */\n readonly location: Location;\n\n /**\n * Returns a valid href for the given `to` value that may be used as\n * the value of an attribute.\n *\n * @param to - The destination URL\n */\n createHref(to: To): string;\n\n /**\n * Returns a URL for the given `to` value\n *\n * @param to - The destination URL\n */\n createURL(to: To): URL;\n\n /**\n * Encode a location the same way window.history would do (no-op for memory\n * history) so we ensure our PUSH/REPLACE navigations for data routers\n * behave the same as POP\n *\n * @param to Unencoded path\n */\n encodeLocation(to: To): Path;\n\n /**\n * Pushes a new location onto the history stack, increasing its length by one.\n * If there were any entries in the stack after the current one, they are\n * lost.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n push(to: To, state?: any): void;\n\n /**\n * Replaces the current location in the history stack with a new one. The\n * location that was replaced will no longer be available.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n replace(to: To, state?: any): void;\n\n /**\n * Navigates `n` entries backward/forward in the history stack relative to the\n * current index. For example, a \"back\" navigation would use go(-1).\n *\n * @param delta - The delta in the stack index\n */\n go(delta: number): void;\n\n /**\n * Sets up a listener that will be called whenever the current location\n * changes.\n *\n * @param listener - A function that will be called when the location changes\n * @returns unlisten - A function that may be used to stop listening\n */\n listen(listener: Listener): () => void;\n}\n\ntype HistoryState = {\n usr: any;\n key?: string;\n idx: number;\n};\n\nconst PopStateEventType = \"popstate\";\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Memory History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A user-supplied object that describes a location. Used when providing\n * entries to `createMemoryHistory` via its `initialEntries` option.\n */\nexport type InitialEntry = string | Partial;\n\nexport type MemoryHistoryOptions = {\n initialEntries?: InitialEntry[];\n initialIndex?: number;\n v5Compat?: boolean;\n};\n\n/**\n * A memory history stores locations in memory. This is useful in stateful\n * environments where there is no web browser, such as node tests or React\n * Native.\n */\nexport interface MemoryHistory extends History {\n /**\n * The current index in the history stack.\n */\n readonly index: number;\n}\n\n/**\n * Memory history stores the current location in memory. It is designed for use\n * in stateful non-browser environments like tests and React Native.\n */\nexport function createMemoryHistory(\n options: MemoryHistoryOptions = {}\n): MemoryHistory {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries: Location[]; // Declare so we can access from createMemoryLocation\n entries = initialEntries.map((entry, index) =>\n createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index === 0 ? \"default\" : undefined\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n function clampIndex(n: number): number {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation(): Location {\n return entries[index];\n }\n function createMemoryLocation(\n to: To,\n state: any = null,\n key?: string\n ): Location {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n\n function createHref(to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n let history: MemoryHistory = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref,\n createURL(to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation(to: To) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\",\n };\n },\n push(to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn: Listener) {\n listener = fn;\n return () => {\n listener = null;\n };\n },\n };\n\n return history;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Browser History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A browser history stores the current location in regular URLs in a web\n * browser environment. This is the standard for most web apps and provides the\n * cleanest URLs the browser's address bar.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory\n */\nexport interface BrowserHistory extends UrlHistory {}\n\nexport type BrowserHistoryOptions = UrlHistoryOptions;\n\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */\nexport function createBrowserHistory(\n options: BrowserHistoryOptions = {}\n): BrowserHistory {\n function createBrowserLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let { pathname, search, hash } = window.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createBrowserHref(window: Window, to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Hash History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A hash history stores the current location in the fragment identifier portion\n * of the URL in a web browser environment.\n *\n * This is ideal for apps that do not control the server for some reason\n * (because the fragment identifier is never sent to the server), including some\n * shared hosting environments that do not provide fine-grained controls over\n * which pages are served at which URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory\n */\nexport interface HashHistory extends UrlHistory {}\n\nexport type HashHistoryOptions = UrlHistoryOptions;\n\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */\nexport function createHashHistory(\n options: HashHistoryOptions = {}\n): HashHistory {\n function createHashLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n } = parsePath(window.location.hash.substr(1));\n\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route () since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createHashHref(window: Window, to: To) {\n let base = window.document.querySelector(\"base\");\n let href = \"\";\n\n if (base && base.getAttribute(\"href\")) {\n let url = window.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n\n function validateHashLocation(location: Location, to: To) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region UTILS\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @private\n */\nexport function invariant(value: boolean, message?: string): asserts value;\nexport function invariant(\n value: T | null | undefined,\n message?: string\n): asserts value is T;\nexport function invariant(value: any, message?: string) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\n\nexport function warning(cond: any, message: string) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience, so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\n\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n\n/**\n * For browser-based histories, we combine the state and key into an object\n */\nfunction getHistoryState(location: Location, index: number): HistoryState {\n return {\n usr: location.state,\n key: location.key,\n idx: index,\n };\n}\n\n/**\n * Creates a Location object with a unique key from the given Path\n */\nexport function createLocation(\n current: string | Location,\n to: To,\n state: any = null,\n key?: string\n): Readonly {\n let location: Readonly = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...(typeof to === \"string\" ? parsePath(to) : to),\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: (to && (to as Location).key) || key || createKey(),\n };\n return location;\n}\n\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */\nexport function createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n}: Partial) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */\nexport function parsePath(path: string): Partial {\n let parsedPath: Partial = {};\n\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n\n if (path) {\n parsedPath.pathname = path;\n }\n }\n\n return parsedPath;\n}\n\nexport interface UrlHistory extends History {}\n\nexport type UrlHistoryOptions = {\n window?: Window;\n v5Compat?: boolean;\n};\n\nfunction getUrlBasedHistory(\n getLocation: (window: Window, globalHistory: Window[\"history\"]) => Location,\n createHref: (window: Window, to: To) => string,\n validateLocation: ((location: Location, to: To) => void) | null,\n options: UrlHistoryOptions = {}\n): UrlHistory {\n let { window = document.defaultView!, v5Compat = false } = options;\n let globalHistory = window.history;\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n let index = getIndex()!;\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n\n function getIndex(): number {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n\n function push(to: To, state?: any) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window.location.assign(url);\n }\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n\n function replace(to: To, state?: any) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n\n function createURL(to: To): URL {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base =\n window.location.origin !== \"null\"\n ? window.location.origin\n : window.location.href;\n\n let href = typeof to === \"string\" ? to : createPath(to);\n // Treating this as a full URL will strip any trailing spaces so we need to\n // pre-encode them since they might be part of a matching splat param from\n // an ancestor route\n href = href.replace(/ $/, \"%20\");\n invariant(\n base,\n `No window.location.(origin|href) available to create URL for href: ${href}`\n );\n return new URL(href, base);\n }\n\n let history: History = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window, globalHistory);\n },\n listen(fn: Listener) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n\n return () => {\n window.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref(window, to);\n },\n createURL,\n encodeLocation(to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n },\n push,\n replace,\n go(n) {\n return globalHistory.go(n);\n },\n };\n\n return history;\n}\n\n//#endregion\n","import type { Location, Path, To } from \"./history\";\nimport { invariant, parsePath, warning } from \"./history\";\n\n/**\n * Map of routeId -> data returned from a loader/action/error\n */\nexport interface RouteData {\n [routeId: string]: any;\n}\n\nexport enum ResultType {\n data = \"data\",\n deferred = \"deferred\",\n redirect = \"redirect\",\n error = \"error\",\n}\n\n/**\n * Successful result from a loader or action\n */\nexport interface SuccessResult {\n type: ResultType.data;\n data: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Successful defer() result from a loader or action\n */\nexport interface DeferredResult {\n type: ResultType.deferred;\n deferredData: DeferredData;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Redirect result from a loader or action\n */\nexport interface RedirectResult {\n type: ResultType.redirect;\n // We keep the raw Response for redirects so we can return it verbatim\n response: Response;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Result from a loader or action - potentially successful or unsuccessful\n */\nexport type DataResult =\n | SuccessResult\n | DeferredResult\n | RedirectResult\n | ErrorResult;\n\n/**\n * Result from a loader or action called via dataStrategy\n */\nexport interface HandlerResult {\n type: \"data\" | \"error\";\n result: unknown; // data, Error, Response, DeferredData\n status?: number;\n}\n\ntype LowerCaseFormMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\ntype UpperCaseFormMethod = Uppercase;\n\n/**\n * Users can specify either lowercase or uppercase form methods on ``,\n * useSubmit(), ``, etc.\n */\nexport type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;\n\n/**\n * Active navigation/fetcher form methods are exposed in lowercase on the\n * RouterState\n */\nexport type FormMethod = LowerCaseFormMethod;\nexport type MutationFormMethod = Exclude;\n\n/**\n * In v7, active navigation/fetcher form methods are exposed in uppercase on the\n * RouterState. This is to align with the normalization done via fetch().\n */\nexport type V7_FormMethod = UpperCaseFormMethod;\nexport type V7_MutationFormMethod = Exclude;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\"\n | \"application/json\"\n | \"text/plain\";\n\n// Thanks https://github.com/sindresorhus/type-fest!\ntype JsonObject = { [Key in string]: JsonValue } & {\n [Key in string]?: JsonValue | undefined;\n};\ntype JsonArray = JsonValue[] | readonly JsonValue[];\ntype JsonPrimitive = string | number | boolean | null;\ntype JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport type Submission =\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n json: undefined;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: JsonValue;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: undefined;\n text: string;\n };\n\n/**\n * @private\n * Arguments passed to route loader/action functions. Same for now but we keep\n * this as a private implementation detail in case they diverge in the future.\n */\ninterface DataFunctionArgs {\n request: Request;\n params: Params;\n context?: Context;\n}\n\n// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:\n// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs\n// Also, make them a type alias instead of an interface\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Loaders and actions can return anything except `undefined` (`null` is a\n * valid return value if there is no data to return). Responses are preferred\n * and will ease any future migration to Remix\n */\ntype DataFunctionValue = Response | NonNullable | null;\n\ntype DataFunctionReturnValue = Promise | DataFunctionValue;\n\n/**\n * Route loader function signature\n */\nexport type LoaderFunction = {\n (\n args: LoaderFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n} & { hydrate?: boolean };\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (\n args: ActionFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n}\n\n/**\n * Arguments passed to shouldRevalidate function\n */\nexport interface ShouldRevalidateFunctionArgs {\n currentUrl: URL;\n currentParams: AgnosticDataRouteMatch[\"params\"];\n nextUrl: URL;\n nextParams: AgnosticDataRouteMatch[\"params\"];\n formMethod?: Submission[\"formMethod\"];\n formAction?: Submission[\"formAction\"];\n formEncType?: Submission[\"formEncType\"];\n text?: Submission[\"text\"];\n formData?: Submission[\"formData\"];\n json?: Submission[\"json\"];\n actionStatus?: number;\n actionResult?: any;\n defaultShouldRevalidate: boolean;\n}\n\n/**\n * Route shouldRevalidate function signature. This runs after any submission\n * (navigation or fetcher), so we flatten the navigation/fetcher submission\n * onto the arguments. It shouldn't matter whether it came from a navigation\n * or a fetcher, what really matters is the URLs and the formData since loaders\n * have to re-run based on the data models that were potentially mutated.\n */\nexport interface ShouldRevalidateFunction {\n (args: ShouldRevalidateFunctionArgs): boolean;\n}\n\n/**\n * Function provided by the framework-aware layers to set `hasErrorBoundary`\n * from the framework-aware `errorElement` prop\n *\n * @deprecated Use `mapRouteProperties` instead\n */\nexport interface DetectErrorBoundaryFunction {\n (route: AgnosticRouteObject): boolean;\n}\n\nexport interface DataStrategyMatch\n extends AgnosticRouteMatch {\n shouldLoad: boolean;\n resolve: (\n handlerOverride?: (\n handler: (ctx?: unknown) => DataFunctionReturnValue\n ) => Promise\n ) => Promise;\n}\n\nexport interface DataStrategyFunctionArgs\n extends DataFunctionArgs {\n matches: DataStrategyMatch[];\n}\n\nexport interface DataStrategyFunction {\n (args: DataStrategyFunctionArgs): Promise;\n}\n\nexport interface AgnosticPatchRoutesOnMissFunction<\n M extends AgnosticRouteMatch = AgnosticRouteMatch\n> {\n (opts: {\n path: string;\n matches: M[];\n patch: (routeId: string | null, children: AgnosticRouteObject[]) => void;\n }): void | Promise;\n}\n\n/**\n * Function provided by the framework-aware layers to set any framework-specific\n * properties from framework-agnostic properties\n */\nexport interface MapRoutePropertiesFunction {\n (route: AgnosticRouteObject): {\n hasErrorBoundary: boolean;\n } & Record;\n}\n\n/**\n * Keys we cannot change from within a lazy() function. We spread all other keys\n * onto the route. Either they're meaningful to the router, or they'll get\n * ignored.\n */\nexport type ImmutableRouteKey =\n | \"lazy\"\n | \"caseSensitive\"\n | \"path\"\n | \"id\"\n | \"index\"\n | \"children\";\n\nexport const immutableRouteKeys = new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\",\n]);\n\ntype RequireOne = Exclude<\n {\n [K in keyof T]: K extends Key ? Omit & Required> : never;\n }[keyof T],\n undefined\n>;\n\n/**\n * lazy() function to load a route definition, which can add non-matching\n * related properties to a route\n */\nexport interface LazyRouteFunction {\n (): Promise>>;\n}\n\n/**\n * Base RouteObject with common props shared by all types of routes\n */\ntype AgnosticBaseRouteObject = {\n caseSensitive?: boolean;\n path?: string;\n id?: string;\n loader?: LoaderFunction | boolean;\n action?: ActionFunction | boolean;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\n lazy?: LazyRouteFunction;\n};\n\n/**\n * Index routes must not have children\n */\nexport type AgnosticIndexRouteObject = AgnosticBaseRouteObject & {\n children?: undefined;\n index: true;\n};\n\n/**\n * Non-index routes may have children, but cannot have index\n */\nexport type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & {\n children?: AgnosticRouteObject[];\n index?: false;\n};\n\n/**\n * A route object represents a logical route, with (optionally) its child\n * routes organized in a tree-like structure.\n */\nexport type AgnosticRouteObject =\n | AgnosticIndexRouteObject\n | AgnosticNonIndexRouteObject;\n\nexport type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & {\n id: string;\n};\n\nexport type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & {\n children?: AgnosticDataRouteObject[];\n id: string;\n};\n\n/**\n * A data route object, which is just a RouteObject with a required unique ID\n */\nexport type AgnosticDataRouteObject =\n | AgnosticDataIndexRouteObject\n | AgnosticDataNonIndexRouteObject;\n\nexport type RouteManifest = Record;\n\n// Recursive helper for finding path parameters in the absence of wildcards\ntype _PathParam =\n // split path into individual path segments\n Path extends `${infer L}/${infer R}`\n ? _PathParam | _PathParam\n : // find params after `:`\n Path extends `:${infer Param}`\n ? Param extends `${infer Optional}?`\n ? Optional\n : Param\n : // otherwise, there aren't any params present\n never;\n\n/**\n * Examples:\n * \"/a/b/*\" -> \"*\"\n * \":a\" -> \"a\"\n * \"/a/:b\" -> \"b\"\n * \"/a/blahblahblah:b\" -> \"b\"\n * \"/:a/:b\" -> \"a\" | \"b\"\n * \"/:a/b/:c/*\" -> \"a\" | \"c\" | \"*\"\n */\nexport type PathParam =\n // check if path is just a wildcard\n Path extends \"*\" | \"/*\"\n ? \"*\"\n : // look for wildcard at the end of the path\n Path extends `${infer Rest}/*`\n ? \"*\" | _PathParam\n : // look for params in the absence of wildcards\n _PathParam;\n\n// Attempt to parse the given string segment. If it fails, then just return the\n// plain string type as a default fallback. Otherwise, return the union of the\n// parsed string literals that were referenced as dynamic segments in the route.\nexport type ParamParseKey =\n // if you could not find path params, fallback to `string`\n [PathParam] extends [never] ? string : PathParam;\n\n/**\n * The parameters that were parsed from the URL path.\n */\nexport type Params = {\n readonly [key in Key]: string | undefined;\n};\n\n/**\n * A RouteMatch contains info about how a route matched a URL.\n */\nexport interface AgnosticRouteMatch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObjectType;\n}\n\nexport interface AgnosticDataRouteMatch\n extends AgnosticRouteMatch {}\n\nfunction isIndexRoute(\n route: AgnosticRouteObject\n): route is AgnosticIndexRouteObject {\n return route.index === true;\n}\n\n// Walk the route tree generating unique IDs where necessary, so we are working\n// solely with AgnosticDataRouteObject's within the Router\nexport function convertRoutesToDataRoutes(\n routes: AgnosticRouteObject[],\n mapRouteProperties: MapRoutePropertiesFunction,\n parentPath: string[] = [],\n manifest: RouteManifest = {}\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n !manifest[id],\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n };\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n children: undefined,\n };\n manifest[id] = pathOrLayoutRoute;\n\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties,\n treePath,\n manifest\n );\n }\n\n return pathOrLayoutRoute;\n }\n });\n}\n\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/utils/match-routes\n */\nexport function matchRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename = \"/\"\n): AgnosticRouteMatch[] | null {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\n\nexport function matchRoutesImpl<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename: string,\n allowPartial: boolean\n): AgnosticRouteMatch[] | null {\n let location =\n typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n\n let pathname = stripBasename(location.pathname || \"/\", basename);\n\n if (pathname == null) {\n return null;\n }\n\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n\n return matches;\n}\n\nexport interface UIMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: Data;\n handle: Handle;\n}\n\nexport function convertRouteMatchToUiMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UIMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle,\n };\n}\n\ninterface RouteMeta<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n relativePath: string;\n caseSensitive: boolean;\n childrenIndex: number;\n route: RouteObjectType;\n}\n\ninterface RouteBranch<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n path: string;\n score: number;\n routesMeta: RouteMeta[];\n}\n\nfunction flattenRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n branches: RouteBranch[] = [],\n parentsMeta: RouteMeta[] = [],\n parentPath = \"\"\n): RouteBranch[] {\n let flattenRoute = (\n route: RouteObjectType,\n index: number,\n relativePath?: string\n ) => {\n let meta: RouteMeta = {\n relativePath:\n relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route,\n };\n\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path ` +\n `\"${parentPath}\" is not valid. An absolute child route path ` +\n `must start with the combined path of all its parent routes.`\n );\n\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n\n // Add the children before adding this route to the array, so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove ` +\n `all child routes from route path \"${path}\".`\n );\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta,\n });\n };\n routes.forEach((route, index) => {\n // coarse-grain check for optional params\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, exploded);\n }\n }\n });\n\n return branches;\n}\n\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */\nfunction explodeOptionalSegments(path: string): string[] {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n\n let [first, ...rest] = segments;\n\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [required, \"\"] : [required];\n }\n\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n\n let result: string[] = [];\n\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children, so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explode _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(\n ...restExploded.map((subpath) =>\n subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n\n // Then, if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n\n // for absolute paths, ensure `/` instead of empty segment\n return result.map((exploded) =>\n path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\n\nfunction rankRouteBranches(branches: RouteBranch[]): void {\n branches.sort((a, b) =>\n a.score !== b.score\n ? b.score - a.score // Higher score first\n : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\n\nconst paramRe = /^:[\\w-]+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s: string) => s === \"*\";\n\nfunction computeScore(path: string, index: boolean | undefined): number {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n\n if (index) {\n initialScore += indexRouteValue;\n }\n\n return segments\n .filter((s) => !isSplat(s))\n .reduce(\n (score, segment) =>\n score +\n (paramRe.test(segment)\n ? dynamicSegmentValue\n : segment === \"\"\n ? emptySegmentValue\n : staticSegmentValue),\n initialScore\n );\n}\n\nfunction compareIndexes(a: number[], b: number[]): number {\n let siblings =\n a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n\n return siblings\n ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\n\nfunction matchRouteBranch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n branch: RouteBranch,\n pathname: string,\n allowPartial = false\n): AgnosticRouteMatch[] | null {\n let { routesMeta } = branch;\n\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches: AgnosticRouteMatch[] = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname =\n matchedPathname === \"/\"\n ? pathname\n : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n\n let route = meta.route;\n\n if (\n !match &&\n end &&\n allowPartial &&\n !routesMeta[routesMeta.length - 1].route.index\n ) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false,\n },\n remainingPathname\n );\n }\n\n if (!match) {\n return null;\n }\n\n Object.assign(matchedParams, match.params);\n\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams as Params,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route,\n });\n\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n\n return matches;\n}\n\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/utils/generate-path\n */\nexport function generatePath(\n originalPath: Path,\n params: {\n [key in PathParam]: string | null;\n } = {} as any\n): string {\n let path: string = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\") as Path;\n }\n\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n\n const stringify = (p: any) =>\n p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n\n const segments = path\n .split(/\\/+/)\n .map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\" as PathParam;\n // Apply the splat\n return stringify(params[star]);\n }\n\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key as PathParam];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return stringify(param);\n }\n\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })\n // Remove empty segments\n .filter((segment) => !!segment);\n\n return prefix + segments.join(\"/\");\n}\n\n/**\n * A PathPattern is used to match on some portion of a URL pathname.\n */\nexport interface PathPattern {\n /**\n * A string to match against a URL pathname. May contain `:id`-style segments\n * to indicate placeholders for dynamic parameters. May also end with `/*` to\n * indicate matching the rest of the URL pathname.\n */\n path: Path;\n /**\n * Should be `true` if the static portions of the `path` should be matched in\n * the same case.\n */\n caseSensitive?: boolean;\n /**\n * Should be `true` if this pattern should match the entire URL pathname.\n */\n end?: boolean;\n}\n\n/**\n * A PathMatch contains info about how a PathPattern matched on a URL pathname.\n */\nexport interface PathMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The pattern that was used to match.\n */\n pattern: PathPattern;\n}\n\ntype Mutable = {\n -readonly [P in keyof T]: T[P];\n};\n\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/utils/match-path\n */\nexport function matchPath<\n ParamKey extends ParamParseKey,\n Path extends string\n>(\n pattern: PathPattern | Path,\n pathname: string\n): PathMatch | null {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n\n let match = pathname.match(matcher);\n if (!match) return null;\n\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params: Params = compiledParams.reduce>(\n (memo, { paramName, isOptional }, index) => {\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname\n .slice(0, matchedPathname.length - splatValue.length)\n .replace(/(.)\\/+$/, \"$1\");\n }\n\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo[paramName] = undefined;\n } else {\n memo[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\ntype CompiledPathParam = { paramName: string; isOptional?: boolean };\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, CompiledPathParam[]] {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n\n let params: CompiledPathParam[] = [];\n let regexpSource =\n \"^\" +\n path\n .replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (_: string, paramName: string, isOptional) => {\n params.push({ paramName, isOptional: isOptional != null });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n }\n );\n\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource +=\n path === \"*\" || path === \"/*\"\n ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex, so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n // Nothing to match for \"\" or \"/\"\n }\n\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n\n return [matcher, params];\n}\n\nexport function decodePath(value: string) {\n try {\n return value\n .split(\"/\")\n .map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\"))\n .join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is is a ` +\n `malformed URL segment. This is probably due to a bad percent ` +\n `encoding (${error}).`\n );\n\n return value;\n }\n}\n\n/**\n * @private\n */\nexport function stripBasename(\n pathname: string,\n basename: string\n): string | null {\n if (basename === \"/\") return pathname;\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\")\n ? basename.length - 1\n : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n\n return pathname.slice(startIndex) || \"/\";\n}\n\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/utils/resolve-path\n */\nexport function resolvePath(to: To, fromPathname = \"/\"): Path {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\",\n } = typeof to === \"string\" ? parsePath(to) : to;\n\n let pathname = toPathname\n ? toPathname.startsWith(\"/\")\n ? toPathname\n : resolvePathname(toPathname, fromPathname)\n : fromPathname;\n\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash),\n };\n}\n\nfunction resolvePathname(relativePath: string, fromPathname: string): string {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\n\nfunction getInvalidPathError(\n char: string,\n field: string,\n dest: string,\n path: Partial\n) {\n return (\n `Cannot include a '${char}' character in a manually specified ` +\n `\\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the ` +\n `\\`to.${dest}\\` field. Alternatively you may provide the full path as ` +\n `a string in and the router will parse it for you.`\n );\n}\n\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * \n * \n * \n *\n * \n * \n * }> // <-- Does not contribute\n * // <-- Does not contribute\n * \n * \n */\nexport function getPathContributingMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[]) {\n return matches.filter(\n (match, index) =>\n index === 0 || (match.route.path && match.route.path.length > 0)\n );\n}\n\n// Return the array of pathnames for the current route matches - used to\n// generate the routePathnames input for resolveTo()\nexport function getResolveToMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[], v7_relativeSplatPath: boolean) {\n let pathMatches = getPathContributingMatches(matches);\n\n // When v7_relativeSplatPath is enabled, use the full pathname for the leaf\n // match so we include splat values for \".\" links. See:\n // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329\n if (v7_relativeSplatPath) {\n return pathMatches.map((match, idx) =>\n idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n }\n\n return pathMatches.map((match) => match.pathnameBase);\n}\n\n/**\n * @private\n */\nexport function resolveTo(\n toArg: To,\n routePathnames: string[],\n locationPathname: string,\n isPathRelative = false\n): Path {\n let to: Partial;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n\n let from: string;\n\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n // With relative=\"route\" (the default), each leading .. segment means\n // \"go up one route\" instead of \"go up one URL segment\". This is a key\n // difference from how works and a major reason we call this a\n // \"to\" value instead of a \"href\".\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n\n let path = resolvePath(to, from);\n\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash =\n toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash =\n (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (\n !path.pathname.endsWith(\"/\") &&\n (hasExplicitTrailingSlash || hasCurrentTrailingSlash)\n ) {\n path.pathname += \"/\";\n }\n\n return path;\n}\n\n/**\n * @private\n */\nexport function getToPathname(to: To): string | undefined {\n // Empty strings should be treated the same as / paths\n return to === \"\" || (to as Path).pathname === \"\"\n ? \"/\"\n : typeof to === \"string\"\n ? parsePath(to).pathname\n : to.pathname;\n}\n\n/**\n * @private\n */\nexport const joinPaths = (paths: string[]): string =>\n paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n\n/**\n * @private\n */\nexport const normalizePathname = (pathname: string): string =>\n pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n\n/**\n * @private\n */\nexport const normalizeSearch = (search: string): string =>\n !search || search === \"?\"\n ? \"\"\n : search.startsWith(\"?\")\n ? search\n : \"?\" + search;\n\n/**\n * @private\n */\nexport const normalizeHash = (hash: string): string =>\n !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n\nexport type JsonFunction = (\n data: Data,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n */\nexport const json: JsonFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n\n return new Response(JSON.stringify(data), {\n ...responseInit,\n headers,\n });\n};\n\nexport interface TrackedPromise extends Promise {\n _tracked?: boolean;\n _data?: any;\n _error?: any;\n}\n\nexport class AbortedDeferredError extends Error {}\n\nexport class DeferredData {\n private pendingKeysSet: Set = new Set();\n private controller: AbortController;\n private abortPromise: Promise;\n private unlistenAbortSignal: () => void;\n private subscribers: Set<(aborted: boolean, settledKey?: string) => void> =\n new Set();\n data: Record;\n init?: ResponseInit;\n deferredKeys: string[] = [];\n\n constructor(data: Record, responseInit?: ResponseInit) {\n invariant(\n data && typeof data === \"object\" && !Array.isArray(data),\n \"defer() only accepts plain objects\"\n );\n\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject: (e: AbortedDeferredError) => void;\n this.abortPromise = new Promise((_, r) => (reject = r));\n this.controller = new AbortController();\n let onAbort = () =>\n reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = () =>\n this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n\n this.data = Object.entries(data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: this.trackPromise(key, value),\n }),\n {}\n );\n\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n\n this.init = responseInit;\n }\n\n private trackPromise(\n key: string,\n value: Promise | unknown\n ): TrackedPromise | unknown {\n if (!(value instanceof Promise)) {\n return value;\n }\n\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise: TrackedPromise = Promise.race([value, this.abortPromise]).then(\n (data) => this.onSettle(promise, key, undefined, data as unknown),\n (error) => this.onSettle(promise, key, error as unknown)\n );\n\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(() => {});\n\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n return promise;\n }\n\n private onSettle(\n promise: TrackedPromise,\n key: string,\n error: unknown,\n data?: unknown\n ): unknown {\n if (\n this.controller.signal.aborted &&\n error instanceof AbortedDeferredError\n ) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", { get: () => error });\n return Promise.reject(error);\n }\n\n this.pendingKeysSet.delete(key);\n\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error(\n `Deferred data for key \"${key}\" resolved/rejected with \\`undefined\\`, ` +\n `you must resolve/reject with a value or \\`null\\`.`\n );\n Object.defineProperty(promise, \"_error\", { get: () => undefinedError });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", { get: () => error });\n this.emit(false, key);\n return Promise.reject(error);\n }\n\n Object.defineProperty(promise, \"_data\", { get: () => data });\n this.emit(false, key);\n return data;\n }\n\n private emit(aborted: boolean, settledKey?: string) {\n this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));\n }\n\n subscribe(fn: (aborted: boolean, settledKey?: string) => void) {\n this.subscribers.add(fn);\n return () => this.subscribers.delete(fn);\n }\n\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n\n async resolveData(signal: AbortSignal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = () => this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise((resolve) => {\n this.subscribe((aborted) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n\n get unwrappedData() {\n invariant(\n this.data !== null && this.done,\n \"Can only unwrap data on initialized and settled deferreds\"\n );\n\n return Object.entries(this.data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: unwrapTrackedPromise(value),\n }),\n {}\n );\n }\n\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\n\nfunction isTrackedPromise(value: any): value is TrackedPromise {\n return (\n value instanceof Promise && (value as TrackedPromise)._tracked === true\n );\n}\n\nfunction unwrapTrackedPromise(value: any) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\n\nexport type DeferFunction = (\n data: Record,\n init?: number | ResponseInit\n) => DeferredData;\n\nexport const defer: DeferFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n return new DeferredData(data, responseInit);\n};\n\nexport type RedirectFunction = (\n url: string,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirect: RedirectFunction = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...responseInit,\n headers,\n });\n};\n\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirectDocument: RedirectFunction = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n\nexport type ErrorResponse = {\n status: number;\n statusText: string;\n data: any;\n};\n\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n *\n * We don't export the class for public use since it's an implementation\n * detail, but we export the interface above so folks can build their own\n * abstractions around instances via isRouteErrorResponse()\n */\nexport class ErrorResponseImpl implements ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n private error?: Error;\n private internal: boolean;\n\n constructor(\n status: number,\n statusText: string | undefined,\n data: any,\n internal = false\n ) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */\nexport function isRouteErrorResponse(error: any): error is ErrorResponse {\n return (\n error != null &&\n typeof error.status === \"number\" &&\n typeof error.statusText === \"string\" &&\n typeof error.internal === \"boolean\" &&\n \"data\" in error\n );\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n warning,\n} from \"./history\";\nimport type {\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DataStrategyMatch,\n AgnosticRouteObject,\n DataResult,\n DataStrategyFunction,\n DataStrategyFunctionArgs,\n DeferredData,\n DeferredResult,\n DetectErrorBoundaryFunction,\n ErrorResult,\n FormEncType,\n FormMethod,\n HTMLFormMethod,\n HandlerResult,\n ImmutableRouteKey,\n MapRoutePropertiesFunction,\n MutationFormMethod,\n RedirectResult,\n RouteData,\n RouteManifest,\n ShouldRevalidateFunctionArgs,\n Submission,\n SuccessResult,\n UIMatch,\n V7_FormMethod,\n V7_MutationFormMethod,\n AgnosticPatchRoutesOnMissFunction,\n} from \"./utils\";\nimport {\n ErrorResponseImpl,\n ResultType,\n convertRouteMatchToUiMatch,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n getResolveToMatches,\n immutableRouteKeys,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n matchRoutesImpl,\n resolveTo,\n stripBasename,\n} from \"./utils\";\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A Router instance manages all navigation and data loading/mutations\n */\nexport interface Router {\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the basename for the router\n */\n get basename(): RouterInit[\"basename\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the future config for the router\n */\n get future(): FutureConfig;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the current state of the router\n */\n get state(): RouterState;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the routes for this router instance\n */\n get routes(): AgnosticDataRouteObject[];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the window associated with the router\n */\n get window(): RouterInit[\"window\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Initialize the router, including adding history listeners and kicking off\n * initial data fetches. Returns a function to cleanup listeners and abort\n * any in-progress loads\n */\n initialize(): Router;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Subscribe to router.state updates\n *\n * @param fn function to call with the new state\n */\n subscribe(fn: RouterSubscriber): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Enable scroll restoration behavior in the router\n *\n * @param savedScrollPositions Object that will manage positions, in case\n * it's being restored from sessionStorage\n * @param getScrollPosition Function to get the active Y scroll position\n * @param getKey Function to get the key to use for restoration\n */\n enableScrollRestoration(\n savedScrollPositions: Record,\n getScrollPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Navigate forward/backward in the history stack\n * @param to Delta to move in the history stack\n */\n navigate(to: number): Promise;\n\n /**\n * Navigate to the given path\n * @param to Path to navigate to\n * @param opts Navigation options (method, submission, etc.)\n */\n navigate(to: To | null, opts?: RouterNavigateOptions): Promise;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a fetcher load/submission\n *\n * @param key Fetcher key\n * @param routeId Route that owns the fetcher\n * @param href href to fetch\n * @param opts Fetcher options, (method, submission, etc.)\n */\n fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a revalidation of all current route loaders and fetcher loads\n */\n revalidate(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to create an href for the given location\n * @param location\n */\n createHref(location: Location | URL): string;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to URL encode a destination path according to the internal\n * history implementation\n * @param to\n */\n encodeLocation(to: To): Path;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get/create a fetcher for the given key\n * @param key\n */\n getFetcher(key: string): Fetcher;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete the fetcher for a given key\n * @param key\n */\n deleteFetcher(key: string): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Cleanup listeners and abort any in-progress loads\n */\n dispose(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get a navigation blocker\n * @param key The identifier for the blocker\n * @param fn The blocker function implementation\n */\n getBlocker(key: string, fn: BlockerFunction): Blocker;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete a navigation blocker\n * @param key The identifier for the blocker\n */\n deleteBlocker(key: string): void;\n\n /**\n * @internal\n * PRIVATE DO NOT USE\n *\n * Patch additional children routes into an existing parent route\n * @param routeId The parent route id or a callback function accepting `patch`\n * to perform batch patching\n * @param children The additional children routes\n */\n patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * HMR needs to pass in-flight route updates to React Router\n * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute)\n */\n _internalSetRoutes(routes: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal fetch AbortControllers accessed by unit tests\n */\n _internalFetchControllers: Map;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal pending DeferredData instances accessed by unit tests\n */\n _internalActiveDeferreds: Map;\n}\n\n/**\n * State maintained internally by the router. During a navigation, all states\n * reflect the the \"old\" location unless otherwise noted.\n */\nexport interface RouterState {\n /**\n * The action of the most recent navigation\n */\n historyAction: HistoryAction;\n\n /**\n * The current location reflected by the router\n */\n location: Location;\n\n /**\n * The current set of route matches\n */\n matches: AgnosticDataRouteMatch[];\n\n /**\n * Tracks whether we've completed our initial data load\n */\n initialized: boolean;\n\n /**\n * Current scroll position we should start at for a new view\n * - number -> scroll position to restore to\n * - false -> do not restore scroll at all (used during submissions)\n * - null -> don't have a saved position, scroll to hash or top of page\n */\n restoreScrollPosition: number | false | null;\n\n /**\n * Indicate whether this navigation should skip resetting the scroll position\n * if we are unable to restore the scroll position\n */\n preventScrollReset: boolean;\n\n /**\n * Tracks the state of the current navigation\n */\n navigation: Navigation;\n\n /**\n * Tracks any in-progress revalidations\n */\n revalidation: RevalidationState;\n\n /**\n * Data from the loaders for the current matches\n */\n loaderData: RouteData;\n\n /**\n * Data from the action for the current matches\n */\n actionData: RouteData | null;\n\n /**\n * Errors caught from loaders for the current matches\n */\n errors: RouteData | null;\n\n /**\n * Map of current fetchers\n */\n fetchers: Map;\n\n /**\n * Map of current blockers\n */\n blockers: Map;\n}\n\n/**\n * Data that can be passed into hydrate a Router from SSR\n */\nexport type HydrationState = Partial<\n Pick\n>;\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface FutureConfig {\n v7_fetcherPersist: boolean;\n v7_normalizeFormMethod: boolean;\n v7_partialHydration: boolean;\n v7_prependBasename: boolean;\n v7_relativeSplatPath: boolean;\n v7_skipActionErrorRevalidation: boolean;\n}\n\n/**\n * Initialization options for createRouter\n */\nexport interface RouterInit {\n routes: AgnosticRouteObject[];\n history: History;\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n hydrationData?: HydrationState;\n window?: Window;\n unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction;\n unstable_dataStrategy?: DataStrategyFunction;\n}\n\n/**\n * State returned from a server-side query() call\n */\nexport interface StaticHandlerContext {\n basename: Router[\"basename\"];\n location: RouterState[\"location\"];\n matches: RouterState[\"matches\"];\n loaderData: RouterState[\"loaderData\"];\n actionData: RouterState[\"actionData\"];\n errors: RouterState[\"errors\"];\n statusCode: number;\n loaderHeaders: Record;\n actionHeaders: Record;\n activeDeferreds: Record | null;\n _deepestRenderedBoundaryId?: string | null;\n}\n\n/**\n * A StaticHandler instance manages a singular SSR navigation/fetch event\n */\nexport interface StaticHandler {\n dataRoutes: AgnosticDataRouteObject[];\n query(\n request: Request,\n opts?: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: {\n routeId?: string;\n requestContext?: unknown;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n}\n\ntype ViewTransitionOpts = {\n currentLocation: Location;\n nextLocation: Location;\n};\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (\n state: RouterState,\n opts: {\n deletedFetchers: string[];\n unstable_viewTransitionOpts?: ViewTransitionOpts;\n unstable_flushSync: boolean;\n }\n ): void;\n}\n\n/**\n * Function signature for determining the key to be used in scroll restoration\n * for a given location\n */\nexport interface GetScrollRestorationKeyFunction {\n (location: Location, matches: UIMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\nexport type RelativeRoutingType = \"route\" | \"path\";\n\n// Allowed for any navigation or fetch\ntype BaseNavigateOrFetchOptions = {\n preventScrollReset?: boolean;\n relative?: RelativeRoutingType;\n unstable_flushSync?: boolean;\n};\n\n// Only allowed for navigations\ntype BaseNavigateOptions = BaseNavigateOrFetchOptions & {\n replace?: boolean;\n state?: any;\n fromRouteId?: string;\n unstable_viewTransition?: boolean;\n};\n\n// Only allowed for submission navigations\ntype BaseSubmissionOptions = {\n formMethod?: HTMLFormMethod;\n formEncType?: FormEncType;\n} & (\n | { formData: FormData; body?: undefined }\n | { formData?: undefined; body: any }\n);\n\n/**\n * Options for a navigate() call for a normal (non-submission) navigation\n */\ntype LinkNavigateOptions = BaseNavigateOptions;\n\n/**\n * Options for a navigate() call for a submission navigation\n */\ntype SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to navigate() for a navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options for a fetch() load\n */\ntype LoadFetchOptions = BaseNavigateOrFetchOptions;\n\n/**\n * Options for a fetch() submission\n */\ntype SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions;\n\n/**\n * Potential states for state.navigation\n */\nexport type NavigationStates = {\n Idle: {\n state: \"idle\";\n location: undefined;\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n formData: undefined;\n json: undefined;\n text: undefined;\n };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n text: Submission[\"text\"] | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n text: Submission[\"text\"];\n };\n};\n\nexport type Navigation = NavigationStates[keyof NavigationStates];\n\nexport type RevalidationState = \"idle\" | \"loading\";\n\n/**\n * Potential states for fetchers\n */\ntype FetcherStates = {\n Idle: {\n state: \"idle\";\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n text: undefined;\n formData: undefined;\n json: undefined;\n data: TData | undefined;\n };\n Loading: {\n state: \"loading\";\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n text: Submission[\"text\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n data: TData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n text: Submission[\"text\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n data: TData | undefined;\n };\n};\n\nexport type Fetcher =\n FetcherStates[keyof FetcherStates];\n\ninterface BlockerBlocked {\n state: \"blocked\";\n reset(): void;\n proceed(): void;\n location: Location;\n}\n\ninterface BlockerUnblocked {\n state: \"unblocked\";\n reset: undefined;\n proceed: undefined;\n location: undefined;\n}\n\ninterface BlockerProceeding {\n state: \"proceeding\";\n reset: undefined;\n proceed: undefined;\n location: Location;\n}\n\nexport type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;\n\nexport type BlockerFunction = (args: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n}) => boolean;\n\ninterface ShortCircuitable {\n /**\n * startNavigation does not need to complete the navigation because we\n * redirected or got interrupted\n */\n shortCircuited?: boolean;\n}\n\ntype PendingActionResult = [string, SuccessResult | ErrorResult];\n\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * Tuple for the returned or thrown value from the current action. The routeId\n * is the action route for success and the bubbled boundary route for errors.\n */\n pendingActionResult?: PendingActionResult;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * loaderData returned from the current set of loaders\n */\n loaderData?: RouterState[\"loaderData\"];\n /**\n * errors thrown from the current set of loaders\n */\n errors?: RouterState[\"errors\"];\n}\n\n/**\n * Cached info for active fetcher.load() instances so they can participate\n * in revalidation\n */\ninterface FetchLoadMatch {\n routeId: string;\n path: string;\n}\n\n/**\n * Identified fetcher.load() calls that need to be revalidated\n */\ninterface RevalidatingFetcher extends FetchLoadMatch {\n key: string;\n match: AgnosticDataRouteMatch | null;\n matches: AgnosticDataRouteMatch[] | null;\n controller: AbortController | null;\n}\n\nconst validMutationMethodsArr: MutationFormMethod[] = [\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n];\nconst validMutationMethods = new Set(\n validMutationMethodsArr\n);\n\nconst validRequestMethodsArr: FormMethod[] = [\n \"get\",\n ...validMutationMethodsArr,\n];\nconst validRequestMethods = new Set(validRequestMethodsArr);\n\nconst redirectStatusCodes = new Set([301, 302, 303, 307, 308]);\nconst redirectPreserveMethodStatusCodes = new Set([307, 308]);\n\nexport const IDLE_NAVIGATION: NavigationStates[\"Idle\"] = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_FETCHER: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\nconst defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary),\n});\n\nconst TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Create a router and listen to history POP navigations\n */\nexport function createRouter(init: RouterInit): Router {\n const routerWindow = init.window\n ? init.window\n : typeof window !== \"undefined\"\n ? window\n : undefined;\n const isBrowser =\n typeof routerWindow !== \"undefined\" &&\n typeof routerWindow.document !== \"undefined\" &&\n typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n\n // Routes keyed by ID\n let manifest: RouteManifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined;\n let basename = init.basename || \"/\";\n let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;\n let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss;\n\n // Config driven behavior flags\n let future: FutureConfig = {\n v7_fetcherPersist: false,\n v7_normalizeFormMethod: false,\n v7_partialHydration: false,\n v7_prependBasename: false,\n v7_relativeSplatPath: false,\n v7_skipActionErrorRevalidation: false,\n ...init.future,\n };\n // Cleanup function for history\n let unlistenHistory: (() => void) | null = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions: Record | null = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey: GetScrollRestorationKeyFunction | null = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition: GetScrollPositionFunction | null = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null && !patchRoutesOnMissImpl) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname,\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n }\n\n // In SPA apps, if the user provided a patchRoutesOnMiss implementation and\n // our initial match is a splat route, clear them out so we run through lazy\n // discovery on hydration in case there's a more accurate lazy route match.\n // In SSR apps (with `hydrationData`), we expect that the server will send\n // up the proper matched routes so we don't want to run lazy discovery on\n // initial hydration and want to hydrate into the splat route.\n if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n\n let initialized: boolean;\n if (!initialMatches) {\n // We need to run patchRoutesOnMiss in initialize()\n initialized = false;\n initialMatches = [];\n } else if (initialMatches.some((m) => m.route.lazy)) {\n // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n initialized = false;\n } else if (!initialMatches.some((m) => m.route.loader)) {\n // If we've got no loaders to run, then we're good to go\n initialized = true;\n } else if (future.v7_partialHydration) {\n // If partial hydration is enabled, we're initialized so long as we were\n // provided with hydrationData for every route with a loader, and no loaders\n // were marked for explicit hydration\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n let isRouteInitialized = (m: AgnosticDataRouteMatch) => {\n // No loader, nothing to initialize\n if (!m.route.loader) {\n return true;\n }\n // Explicitly opting-in to running on hydration\n if (\n typeof m.route.loader === \"function\" &&\n m.route.loader.hydrate === true\n ) {\n return false;\n }\n // Otherwise, initialized if hydrated with data or an error\n return (\n (loaderData && loaderData[m.route.id] !== undefined) ||\n (errors && errors[m.route.id] !== undefined)\n );\n };\n\n // If errors exist, don't consider routes below the boundary\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors![m.route.id] !== undefined\n );\n initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);\n } else {\n initialized = initialMatches.every(isRouteInitialized);\n }\n } else {\n // Without partial hydration - we're initialized if we were provided any\n // hydrationData - which is expected to be complete\n initialized = init.hydrationData != null;\n }\n\n let router: Router;\n let state: RouterState = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: (init.hydrationData && init.hydrationData.loaderData) || {},\n actionData: (init.hydrationData && init.hydrationData.actionData) || null,\n errors: (init.hydrationData && init.hydrationData.errors) || initialErrors,\n fetchers: new Map(),\n blockers: new Map(),\n };\n\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction: HistoryAction = HistoryAction.Pop;\n\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n\n // AbortController for the active navigation\n let pendingNavigationController: AbortController | null;\n\n // Should the current navigation enable document.startViewTransition?\n let pendingViewTransitionEnabled = false;\n\n // Store applied view transitions so we can apply them on POP\n let appliedViewTransitions: Map> = new Map<\n string,\n Set\n >();\n\n // Cleanup function for persisting applied transitions to sessionStorage\n let removePageHideEventListener: (() => void) | null = null;\n\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes: string[] = [];\n\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads: string[] = [];\n\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n\n // Ref-count mounted fetchers so we know when it's ok to clean them up\n let activeFetchers = new Map();\n\n // Fetchers that have requested a delete when using v7_fetcherPersist,\n // they'll be officially removed after they return to idle\n let deletedFetchers = new Set();\n\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n\n // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so\n // that we only kick them off once for a given combo\n let pendingPatchRoutes = new Map<\n string,\n ReturnType\n >();\n\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let ignoreNextHistoryUpdate = false;\n\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (ignoreNextHistoryUpdate) {\n ignoreNextHistoryUpdate = false;\n return;\n }\n\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location \" +\n \"that was not created by @remix-run/router. This will fail silently in \" +\n \"production. This can happen if you are navigating outside the router \" +\n \"via `window.history.pushState`/`window.location.hash` instead of using \" +\n \"router navigation APIs. This can also happen if you are using \" +\n \"createHashRouter and the user manually changes the URL.\"\n );\n\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n ignoreNextHistoryUpdate = true;\n init.history.go(delta * -1);\n\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location,\n });\n // Re-do the same POP navigation we just blocked\n init.history.go(delta);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n if (isBrowser) {\n // FIXME: This feels gross. How can we cleanup the lines between\n // scrollRestoration/appliedTransitions persistance?\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () =>\n persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () =>\n routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location, {\n initialHydration: true,\n });\n }\n\n return router;\n }\n\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n\n // Subscribe to state updates for the router\n function subscribe(fn: RouterSubscriber) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n\n // Update our state and notify the calling context of the change\n function updateState(\n newState: Partial,\n opts: {\n flushSync?: boolean;\n viewTransitionOpts?: ViewTransitionOpts;\n } = {}\n ): void {\n state = {\n ...state,\n ...newState,\n };\n\n // Prep fetcher cleanup so we can tell the UI which fetcher data entries\n // can be removed\n let completedFetchers: string[] = [];\n let deletedFetchersKeys: string[] = [];\n\n if (future.v7_fetcherPersist) {\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (deletedFetchers.has(key)) {\n // Unmounted from the UI and can be totally removed\n deletedFetchersKeys.push(key);\n } else {\n // Returned to idle but still mounted in the UI, so semi-remains for\n // revalidations and such\n completedFetchers.push(key);\n }\n }\n });\n }\n\n // Iterate over a local copy so that if flushSync is used and we end up\n // removing and adding a new subscriber due to the useCallback dependencies,\n // we don't get ourselves into a loop calling the new subscriber immediately\n [...subscribers].forEach((subscriber) =>\n subscriber(state, {\n deletedFetchers: deletedFetchersKeys,\n unstable_viewTransitionOpts: opts.viewTransitionOpts,\n unstable_flushSync: opts.flushSync === true,\n })\n );\n\n // Remove idle fetchers from state since we only care about in-flight fetchers.\n if (future.v7_fetcherPersist) {\n completedFetchers.forEach((key) => state.fetchers.delete(key));\n deletedFetchersKeys.forEach((key) => deleteFetcher(key));\n }\n }\n\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(\n location: Location,\n newState: Partial>,\n { flushSync }: { flushSync?: boolean } = {}\n ): void {\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload =\n state.actionData != null &&\n state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n state.navigation.state === \"loading\" &&\n location.state?._isRedirect !== true;\n\n let actionData: RouteData | null;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData\n ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n )\n : state.loaderData;\n\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset =\n pendingPreventScrollReset === true ||\n (state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n location.state?._isRedirect !== true);\n\n // Commit any in-flight routes at the end of the HMR revalidation \"navigation\"\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n\n if (isUninterruptedRevalidation) {\n // If this was an uninterrupted revalidation then do not touch history\n } else if (pendingAction === HistoryAction.Pop) {\n // Do nothing for POP - URL has already been updated\n } else if (pendingAction === HistoryAction.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === HistoryAction.Replace) {\n init.history.replace(location, location.state);\n }\n\n let viewTransitionOpts: ViewTransitionOpts | undefined;\n\n // On POP, enable transitions if they were enabled on the original navigation\n if (pendingAction === HistoryAction.Pop) {\n // Forward takes precedence so they behave like the original navigation\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n // If we don't have a previous forward nav, assume we're popping back to\n // the new location and enable if that location previously enabled\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location,\n };\n }\n } else if (pendingViewTransitionEnabled) {\n // Store the applied transition on PUSH/REPLACE\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n }\n\n updateState(\n {\n ...newState, // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(\n location,\n newState.matches || state.matches\n ),\n preventScrollReset,\n blockers,\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true,\n }\n );\n\n // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n cancelledFetcherLoads = [];\n }\n\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(\n to: number | To | null,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n to,\n future.v7_relativeSplatPath,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n false,\n normalizedPath,\n opts\n );\n\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation),\n };\n\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n\n let historyAction = HistoryAction.Push;\n\n if (userReplace === true) {\n historyAction = HistoryAction.Replace;\n } else if (userReplace === false) {\n // no-op\n } else if (\n submission != null &&\n isMutationMethod(submission.formMethod) &&\n submission.formAction === state.location.pathname + state.location.search\n ) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = HistoryAction.Replace;\n }\n\n let preventScrollReset =\n opts && \"preventScrollReset\" in opts\n ? opts.preventScrollReset === true\n : undefined;\n\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n });\n\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation,\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.unstable_viewTransition,\n flushSync,\n });\n }\n\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true,\n });\n return;\n }\n\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n { overrideNavigation: state.navigation }\n );\n }\n\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(\n historyAction: HistoryAction,\n location: Location,\n opts?: {\n initialHydration?: boolean;\n submission?: Submission;\n fetcherSubmission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponseImpl;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: boolean;\n enableViewTransition?: boolean;\n flushSync?: boolean;\n }\n ): Promise {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation =\n (opts && opts.startUninterruptedRevalidation) === true;\n\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n },\n { flushSync }\n );\n return;\n }\n\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial load will always\n // be \"same hash\". For example, on /page#hash and submit a \n // which will default to a navigation to /page\n if (\n state.initialized &&\n !isRevalidationRequired &&\n isHashChangeOnly(state.location, location) &&\n !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))\n ) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let pendingActionResult: PendingActionResult | undefined;\n\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: ResultType.error, error: opts.pendingError },\n ];\n } else if (\n opts &&\n opts.submission &&\n isMutationMethod(opts.submission.formMethod)\n ) {\n // Call action if we received an action submission\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n fogOfWar.active,\n { replace: opts.replace, flushSync }\n );\n\n if (actionResult.shortCircuited) {\n return;\n }\n\n // If we received a 404 from handleAction, it's because we couldn't lazily\n // discover the destination route so we don't want to call loaders\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (\n isErrorResult(result) &&\n isRouteErrorResponse(result.error) &&\n result.error.status === 404\n ) {\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error,\n },\n });\n return;\n }\n }\n\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n // No need to do fog of war matching again on loader execution\n fogOfWar.active = false;\n\n // Create a GET request for the loaders\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n\n // Call loaders\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors,\n } = await handleLoaders(\n request,\n location,\n matches,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult\n );\n\n if (shortCircuited) {\n return;\n }\n\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors,\n });\n }\n\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(\n request: Request,\n location: Location,\n submission: Submission,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n opts: { replace?: boolean; flushSync?: boolean } = {}\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n // Call our action and get the result\n let result: DataResult;\n let actionMatch = getTargetMatch(matches, location);\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id,\n }),\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches\n );\n result = results[0];\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n\n if (isRedirectResult(result)) {\n let replace: boolean;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n let location = normalizeRedirectLocation(\n result.response.headers.get(\"Location\")!,\n new URL(request.url),\n basename\n );\n replace = location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, {\n submission,\n replace,\n });\n return { shortCircuited: true };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n\n // By default, all submissions to the current location are REPLACE\n // navigations, but if the action threw an error that'll be rendered in\n // an errorElement, we fall back to PUSH so that the user can use the\n // back button to get back to the pre-submission form location to try\n // again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n matches,\n pendingActionResult: [boundaryMatch.route.id, result],\n };\n }\n\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result],\n };\n }\n\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n overrideNavigation?: Navigation,\n submission?: Submission,\n fetcherSubmission?: Submission,\n replace?: boolean,\n initialHydration?: boolean,\n flushSync?: boolean,\n pendingActionResult?: PendingActionResult\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation =\n overrideNavigation || getLoadingNavigation(location, submission);\n\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission =\n submission ||\n fetcherSubmission ||\n getSubmissionFromNavigation(loadingNavigation);\n\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n // If we have partialHydration enabled, then don't update the state for the\n // initial data load since it's not a \"navigation\"\n let shouldUpdateNavigationState =\n !isUninterruptedRevalidation &&\n (!future.v7_partialHydration || !initialHydration);\n\n // When fog of war is enabled, we enter our `loading` state earlier so we\n // can discover new routes during the `loading` state. We skip this if\n // we've already run actions since we would have done our matching already.\n // If the children() function threw then, we want to proceed with the\n // partial matches it discovered.\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...(actionData !== undefined ? { actionData } : {}),\n },\n {\n flushSync,\n }\n );\n }\n\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: error,\n },\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n future.v7_partialHydration && initialHydration === true,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n pendingActionResult\n );\n\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds(\n (routeId) =>\n !(matches && matches.some((m) => m.route.id === routeId)) ||\n (matchesToLoad && matchesToLoad.some((m) => m.route.id === routeId))\n );\n\n pendingNavigationLoadId = ++incrementingLoadId;\n\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? { [pendingActionResult[0]]: pendingActionResult[1].error }\n : null,\n ...getActionDataForCommit(pendingActionResult),\n ...(updatedFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n\n if (shouldUpdateNavigationState) {\n let updates: Partial = {};\n if (!isFogOfWar) {\n // Only update navigation/actionNData if we didn't already do it above\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== undefined) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n\n revalidatingFetchers.forEach((rf) => {\n if (fetchControllers.has(rf.key)) {\n abortFetcher(rf.key);\n }\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n request\n );\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n await startRedirectNavigation(request, redirect.result, {\n replace,\n });\n return { shortCircuited: true };\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n matchesToLoad,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId) => {\n deferredData.subscribe((aborted) => {\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n\n // During partial hydration, preserve SSR errors for routes that don't re-run\n if (future.v7_partialHydration && initialHydration && state.errors) {\n Object.entries(state.errors)\n .filter(([id]) => !matchesToLoad.some((m) => m.route.id === id))\n .forEach(([routeId, error]) => {\n errors = Object.assign(errors || {}, { [routeId]: error });\n });\n }\n\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers =\n updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n\n return {\n matches,\n loaderData,\n errors,\n ...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n };\n }\n\n function getUpdatedActionData(\n pendingActionResult: PendingActionResult | undefined\n ): Record | null | undefined {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n // This is cast to `any` currently because `RouteData`uses any and it\n // would be a breaking change to use any.\n // TODO: v7 - change `RouteData` to use `unknown` instead of `any`\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data as any,\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n\n function getUpdatedRevalidatingFetchers(\n revalidatingFetchers: RevalidatingFetcher[]\n ) {\n revalidatingFetchers.forEach((rf) => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n fetcher ? fetcher.data : undefined\n );\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ) {\n if (isServer) {\n throw new Error(\n \"router.fetch() was called during the server render, but it shouldn't be. \" +\n \"You are likely calling a useFetcher() method in the body of your component. \" +\n \"Try moving it to a useEffect or a callback.\"\n );\n }\n\n if (fetchControllers.has(key)) abortFetcher(key);\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n href,\n future.v7_relativeSplatPath,\n routeId,\n opts?.relative\n );\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n true,\n normalizedPath,\n opts\n );\n\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n\n let match = getTargetMatch(matches, path);\n\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, { routeId, path });\n handleFetcherLoader(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n }\n\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n requestMatches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n function detectAndHandle405Error(m: AgnosticDataRouteMatch) {\n if (!m.route.action && !m.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error, { flushSync });\n return true;\n }\n return false;\n }\n\n if (!isFogOfWar && detectAndHandle405Error(match)) {\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync,\n });\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n match = getTargetMatch(requestMatches, path);\n\n if (detectAndHandle405Error(match)) {\n return;\n }\n }\n }\n\n // Call the action for the fetcher\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let actionResults = await callDataStrategy(\n \"action\",\n fetchRequest,\n [match],\n requestMatches\n );\n let actionResult = actionResults[0];\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n\n // When using v7_fetcherPersist, we don't want errors bubbling up to the UI\n // or redirects processed for unmounted fetchers so we just revert them to\n // idle\n if (future.v7_fetcherPersist && deletedFetchers.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // Let SuccessResult's fall through for revalidation\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, {\n fetcherSubmission: submission,\n });\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(routesToUse, state.navigation.location, basename)\n : state.matches;\n\n invariant(matches, \"Didn't find any matches after fetcher action\");\n\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n false,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n [match.route.id, actionResult]\n );\n\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers\n .filter((rf) => rf.key !== key)\n .forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n existingFetcher ? existingFetcher.data : undefined\n );\n state.fetchers.set(staleKey, revalidatingFetcher);\n if (fetchControllers.has(staleKey)) {\n abortFetcher(staleKey);\n }\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n revalidationRequest\n );\n\n if (abortController.signal.aborted) {\n return;\n }\n\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n return startRedirectNavigation(revalidationRequest, redirect.result);\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n state.matches,\n matchesToLoad,\n loaderResults,\n undefined,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n\n abortStaleFetchLoads(loadId);\n\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (\n state.navigation.state === \"loading\" &&\n loadId > pendingNavigationLoadId\n ) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers),\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: new Map(state.fetchers),\n });\n isRevalidationRequired = false;\n }\n }\n\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : undefined\n ),\n { flushSync }\n );\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n match = getTargetMatch(matches, path);\n }\n }\n\n // Call the loader for this fetcher route match\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let results = await callDataStrategy(\n \"loader\",\n fetchRequest,\n [match],\n matches\n );\n let result = results[0];\n\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result =\n (await resolveDeferredData(result, fetchRequest.signal, true)) ||\n result;\n }\n\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n\n if (fetchRequest.signal.aborted) {\n return;\n }\n\n // We don't want errors bubbling up or redirects followed for unmounted\n // fetchers, so short circuit here if it was removed from the UI\n if (deletedFetchers.has(key)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result);\n return;\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */\n async function startRedirectNavigation(\n request: Request,\n redirect: RedirectResult,\n {\n submission,\n fetcherSubmission,\n replace,\n }: {\n submission?: Submission;\n fetcherSubmission?: Submission;\n replace?: boolean;\n } = {}\n ) {\n if (redirect.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n\n let location = redirect.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true,\n });\n\n if (isBrowser) {\n let isDocumentReload = false;\n\n if (redirect.response.headers.has(\"X-Remix-Reload-Document\")) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(location)) {\n const url = init.history.createURL(location);\n isDocumentReload =\n // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin ||\n // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n\n let redirectHistoryAction =\n replace === true ? HistoryAction.Replace : HistoryAction.Push;\n\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let { formMethod, formAction, formEncType } = state.navigation;\n if (\n !submission &&\n !fetcherSubmission &&\n formMethod &&\n formAction &&\n formEncType\n ) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n let activeSubmission = submission || fetcherSubmission;\n if (\n redirectPreserveMethodStatusCodes.has(redirect.response.status) &&\n activeSubmission &&\n isMutationMethod(activeSubmission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // If we have a navigation submission, we will preserve it through the\n // redirect navigation\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n submission\n );\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n }\n }\n\n // Utility wrapper for calling dataStrategy client-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[]\n ): Promise {\n try {\n let results = await callDataStrategyImpl(\n dataStrategyImpl,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n return {\n type: ResultType.redirect,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n ),\n };\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n } catch (e) {\n // If the outer dataStrategy method throws, just return the error for all\n // matches - and it'll naturally bubble to the root\n return matchesToLoad.map(() => ({\n type: ResultType.error,\n error: e,\n }));\n }\n }\n\n async function callLoadersAndMaybeResolveData(\n currentMatches: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n fetchersToLoad: RevalidatingFetcher[],\n request: Request\n ) {\n let [loaderResults, ...fetcherResults] = await Promise.all([\n matchesToLoad.length\n ? callDataStrategy(\"loader\", request, matchesToLoad, matches)\n : [],\n ...fetchersToLoad.map((f) => {\n if (f.matches && f.match && f.controller) {\n let fetcherRequest = createClientSideRequest(\n init.history,\n f.path,\n f.controller.signal\n );\n return callDataStrategy(\n \"loader\",\n fetcherRequest,\n [f.match],\n f.matches\n ).then((r) => r[0]);\n } else {\n return Promise.resolve({\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path,\n }),\n });\n }\n }),\n ]);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n loaderResults.map(() => request.signal),\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map((f) => f.match),\n fetcherResults,\n fetchersToLoad.map((f) => (f.controller ? f.controller.signal : null)),\n true\n ),\n ]);\n\n return {\n loaderResults,\n fetcherResults,\n };\n }\n\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.push(key);\n abortFetcher(key);\n }\n });\n }\n\n function updateFetcherState(\n key: string,\n fetcher: Fetcher,\n opts: { flushSync?: boolean } = {}\n ) {\n state.fetchers.set(key, fetcher);\n updateState(\n { fetchers: new Map(state.fetchers) },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function setFetcherError(\n key: string,\n routeId: string,\n error: any,\n opts: { flushSync?: boolean } = {}\n ) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function getFetcher(key: string): Fetcher {\n if (future.v7_fetcherPersist) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n // If this fetcher was previously marked for deletion, unmark it since we\n // have a new instance\n if (deletedFetchers.has(key)) {\n deletedFetchers.delete(key);\n }\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n\n function deleteFetcher(key: string): void {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (\n fetchControllers.has(key) &&\n !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))\n ) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n deletedFetchers.delete(key);\n state.fetchers.delete(key);\n }\n\n function deleteFetcherAndUpdateState(key: string): void {\n if (future.v7_fetcherPersist) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n deletedFetchers.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n } else {\n deleteFetcher(key);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n\n function abortFetcher(key: string) {\n let controller = fetchControllers.get(key);\n invariant(controller, `Expected fetch controller: ${key}`);\n controller.abort();\n fetchControllers.delete(key);\n }\n\n function markFetchersDone(keys: string[]) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): boolean {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n\n function abortStaleFetchLoads(landedId: number): boolean {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n\n function getBlocker(key: string, fn: BlockerFunction) {\n let blocker: Blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key: string, newBlocker: Blocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(\n (blocker.state === \"unblocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"proceeding\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"unblocked\") ||\n (blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\"),\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n }: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n }): string | undefined {\n if (blockerFunctions.size === 0) {\n return;\n }\n\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n\n function handleNavigational404(pathname: string) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n\n return { notFoundMatches: matches, route, error };\n }\n\n function handleDiscoverRouteError(\n pathname: string,\n discoverResult: DiscoverRoutesErrorResult\n ) {\n return {\n boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,\n error: getInternalRouterError(400, {\n type: \"route-discovery\",\n pathname,\n message:\n discoverResult.error != null && \"message\" in discoverResult.error\n ? discoverResult.error\n : String(discoverResult.error),\n }),\n };\n }\n\n function cancelActiveDeferreds(\n predicate?: (routeId: string) => boolean\n ): string[] {\n let cancelledRouteIds: string[] = [];\n activeDeferreds.forEach((dfd, routeId) => {\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the component\n function enableScrollRestoration(\n positions: Record,\n getPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered \n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n\n return () => {\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n\n function getScrollKey(location: Location, matches: AgnosticDataRouteMatch[]) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n\n function saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n function checkFogOfWar(\n matches: AgnosticDataRouteMatch[] | null,\n routesToUse: AgnosticDataRouteObject[],\n pathname: string\n ): { active: boolean; matches: AgnosticDataRouteMatch[] | null } {\n if (patchRoutesOnMissImpl) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n return { active: true, matches: fogMatches || [] };\n } else {\n let leafRoute = matches[matches.length - 1].route;\n if (\n leafRoute.path &&\n (leafRoute.path === \"*\" || leafRoute.path.endsWith(\"/*\"))\n ) {\n // If we matched a splat, it might only be because we haven't yet fetched\n // the children that would match with a higher score, so let's fetch\n // around and find out\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n\n return { active: false, matches: null };\n }\n\n type DiscoverRoutesSuccessResult = {\n type: \"success\";\n matches: AgnosticDataRouteMatch[] | null;\n };\n type DiscoverRoutesErrorResult = {\n type: \"error\";\n error: any;\n partialMatches: AgnosticDataRouteMatch[];\n };\n type DiscoverRoutesAbortedResult = { type: \"aborted\" };\n type DiscoverRoutesResult =\n | DiscoverRoutesSuccessResult\n | DiscoverRoutesErrorResult\n | DiscoverRoutesAbortedResult;\n\n async function discoverRoutes(\n matches: AgnosticDataRouteMatch[],\n pathname: string,\n signal: AbortSignal\n ): Promise {\n let partialMatches: AgnosticDataRouteMatch[] | null = matches;\n let route =\n partialMatches.length > 0\n ? partialMatches[partialMatches.length - 1].route\n : null;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n try {\n await loadLazyRouteChildren(\n patchRoutesOnMissImpl!,\n pathname,\n partialMatches,\n routesToUse,\n manifest,\n mapRouteProperties,\n pendingPatchRoutes,\n signal\n );\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n } finally {\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity so when we `updateState` at the end of\n // this navigation/fetch `router.routes` will be a new identity and\n // trigger a re-run of memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n }\n }\n\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n let matchedSplat = false;\n if (newMatches) {\n let leafRoute = newMatches[newMatches.length - 1].route;\n\n if (leafRoute.index) {\n // If we found an index route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n\n if (leafRoute.path && leafRoute.path.length > 0) {\n if (leafRoute.path === \"*\") {\n // If we found a splat route, we can't be sure there's not a\n // higher-scoring route down some partial matches trail so we need\n // to check that out\n matchedSplat = true;\n } else {\n // If we found a non-splat route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n\n let newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n // If we are no longer partially matching anything, this was either a\n // legit splat match above, or it's a 404. Also avoid loops if the\n // second pass results in the same partial matches\n if (\n !newPartialMatches ||\n partialMatches.map((m) => m.route.id).join(\"-\") ===\n newPartialMatches.map((m) => m.route.id).join(\"-\")\n ) {\n return { type: \"success\", matches: matchedSplat ? newMatches : null };\n }\n\n partialMatches = newPartialMatches;\n route = partialMatches[partialMatches.length - 1].route;\n if (route.path === \"*\") {\n // The splat is still our most accurate partial, so run with it\n return { type: \"success\", matches: partialMatches };\n }\n }\n }\n\n function _internalSetRoutes(newRoutes: AgnosticDataRouteObject[]) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties,\n undefined,\n manifest\n );\n }\n\n function patchRoutes(\n routeId: string | null,\n children: AgnosticRouteObject[]\n ): void {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n manifest,\n mapRouteProperties\n );\n\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity and trigger a reflow via `updateState`\n // to re-run memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to: To) => init.history.createHref(to),\n encodeLocation: (to: To) => init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher: deleteFetcherAndUpdateState,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface StaticHandlerFutureConfig {\n v7_relativeSplatPath: boolean;\n v7_throwAbortReason: boolean;\n}\n\nexport interface CreateStaticHandlerOptions {\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n}\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: CreateStaticHandlerOptions\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let manifest: RouteManifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (opts?.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts?.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Config driven behavior flags\n let future: StaticHandlerFutureConfig = {\n v7_relativeSplatPath: false,\n v7_throwAbortReason: false,\n ...(opts ? opts.future : null),\n };\n\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n *\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent\n * the bubbling of errors which allows single-fetch-type implementations\n * where the client will handle the bubbling and we may need to return data\n * for the handling route\n */\n async function query(\n request: Request,\n {\n requestContext,\n skipLoaderErrorBubbling,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null\n );\n if (isResponse(result)) {\n return result;\n }\n\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return { location, basename, ...result };\n }\n\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n *\n * - `opts.routeId` allows you to specify the specific route handler to call.\n * If not provided the handler will determine the proper route by matching\n * against `request.url`\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n */\n async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n routeId?: string;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let match = routeId\n ? matches.find((m) => m.route.id === routeId)\n : getTargetMatch(matches, location);\n\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId,\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n false,\n match\n );\n\n if (isResponse(result)) {\n return result;\n }\n\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n\n if (result.loaderData) {\n let data = Object.values(result.loaderData)[0];\n if (result.activeDeferreds?.[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n\n return undefined;\n }\n\n async function queryImpl(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null\n ): Promise | Response> {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(\n request,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch\n );\n return isResponse(result)\n ? result\n : {\n ...result,\n actionData: null,\n actionHeaders: {},\n };\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction for a\n // `queryRoute` call, we throw the `HandlerResult` to bail out early\n // and then return or throw the raw Response here accordingly\n if (isHandlerResult(e) && isResponse(e.result)) {\n if (e.type === ResultType.error) {\n throw e.result;\n }\n return e.result;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n\n async function submit(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n actionMatch: AgnosticDataRouteMatch,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id,\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n result = results[0];\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n }\n\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")!,\n },\n });\n }\n\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, { type: \"defer-action\" });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n }\n\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal,\n });\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = skipLoaderErrorBubbling\n ? actionMatch\n : findNearestBoundary(matches, actionMatch.route.id);\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null,\n [boundaryMatch.route.id, result]\n );\n\n // action status codes take precedence over loader status codes\n return {\n ...context,\n statusCode: isRouteErrorResponse(result.error)\n ? result.error.status\n : result.statusCode != null\n ? result.statusCode\n : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null\n );\n\n return {\n ...context,\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionHeaders: result.headers\n ? { [actionMatch.route.id]: result.headers }\n : {},\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null,\n pendingActionResult?: PendingActionResult\n ): Promise<\n | Omit<\n StaticHandlerContext,\n \"location\" | \"basename\" | \"actionData\" | \"actionHeaders\"\n >\n | Response\n > {\n let isRouteRequest = routeMatch != null;\n\n // Short circuit if we have no loaders to run (queryRoute())\n if (\n isRouteRequest &&\n !routeMatch?.route.loader &&\n !routeMatch?.route.lazy\n ) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id,\n });\n }\n\n let requestMatches = routeMatch\n ? [routeMatch]\n : pendingActionResult && isErrorResult(pendingActionResult[1])\n ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0])\n : matches;\n let matchesToLoad = requestMatches.filter(\n (m) => m.route.loader || m.route.lazy\n );\n\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce(\n (acc, m) => Object.assign(acc, { [m.route.id]: null }),\n {}\n ),\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? {\n [pendingActionResult[0]]: pendingActionResult[1].error,\n }\n : null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await callDataStrategy(\n \"loader\",\n request,\n matchesToLoad,\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n skipLoaderErrorBubbling\n );\n\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(\n matchesToLoad.map((match) => match.route.id)\n );\n matches.forEach((match) => {\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n\n return {\n ...context,\n matches,\n activeDeferreds:\n activeDeferreds.size > 0\n ? Object.fromEntries(activeDeferreds.entries())\n : null,\n };\n }\n\n // Utility wrapper for calling dataStrategy server-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n isRouteRequest: boolean,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null\n ): Promise {\n let results = await callDataStrategyImpl(\n unstable_dataStrategy || defaultDataStrategy,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties,\n requestContext\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n // Throw redirects and let the server handle them with an HTTP redirect\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n );\n }\n if (isResponse(result.result) && isRouteRequest) {\n // For SSR single-route requests, we want to hand Responses back\n // directly without unwrapping\n throw result;\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n }\n\n return {\n dataRoutes,\n query,\n queryRoute,\n };\n}\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */\nexport function getStaticContextFromError(\n routes: AgnosticDataRouteObject[],\n context: StaticHandlerContext,\n error: any\n) {\n let newContext: StaticHandlerContext = {\n ...context,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction throwStaticHandlerAbortedError(\n request: Request,\n isRouteRequest: boolean,\n future: StaticHandlerFutureConfig\n) {\n if (future.v7_throwAbortReason && request.signal.reason !== undefined) {\n throw request.signal.reason;\n }\n\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted: ${request.method} ${request.url}`);\n}\n\nfunction isSubmissionNavigation(\n opts: BaseNavigateOrFetchOptions\n): opts is SubmissionNavigateOptions {\n return (\n opts != null &&\n ((\"formData\" in opts && opts.formData != null) ||\n (\"body\" in opts && opts.body !== undefined))\n );\n}\n\nfunction normalizeTo(\n location: Path,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n prependBasename: boolean,\n to: To | null,\n v7_relativeSplatPath: boolean,\n fromRouteId?: string,\n relative?: RelativeRoutingType\n) {\n let contextualMatches: AgnosticDataRouteMatch[];\n let activeRouteMatch: AgnosticDataRouteMatch | undefined;\n if (fromRouteId) {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n\n // Resolve the relative path\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches, v7_relativeSplatPath),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n\n // Add an ?index param for matched index routes if we don't already have one\n if (\n (to == null || to === \"\" || to === \".\") &&\n activeRouteMatch &&\n activeRouteMatch.route.index &&\n !hasNakedIndexQuery(path.search)\n ) {\n path.search = path.search\n ? path.search.replace(/^\\?/, \"?index&\")\n : \"?index\";\n }\n\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname =\n path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n\n return createPath(path);\n}\n\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(\n normalizeFormMethod: boolean,\n isFetcher: boolean,\n path: string,\n opts?: BaseNavigateOrFetchOptions\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponseImpl;\n} {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod }),\n };\n }\n\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" }),\n });\n\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod\n ? (rawFormMethod.toUpperCase() as V7_FormMethod)\n : (rawFormMethod.toLowerCase() as FormMethod);\n let formAction = stripHashFromPath(path);\n\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n let text =\n typeof opts.body === \"string\"\n ? opts.body\n : opts.body instanceof FormData ||\n opts.body instanceof URLSearchParams\n ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\\n`,\n \"\"\n )\n : String(opts.body);\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text,\n },\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n try {\n let json =\n typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined,\n },\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n\n let searchParams: URLSearchParams;\n let formData: FormData;\n\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n\n let submission: Submission = {\n formMethod,\n formAction,\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n\n return { path: createPath(parsedPath), submission };\n}\n\n// Filter out all routes below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(\n matches: AgnosticDataRouteMatch[],\n boundaryId: string\n) {\n let boundaryMatches = matches;\n if (boundaryId) {\n let index = matches.findIndex((m) => m.route.id === boundaryId);\n if (index >= 0) {\n boundaryMatches = matches.slice(0, index);\n }\n }\n return boundaryMatches;\n}\n\nfunction getMatchesToLoad(\n history: History,\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n submission: Submission | undefined,\n location: Location,\n isInitialLoad: boolean,\n skipActionErrorRevalidation: boolean,\n isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n deletedFetchers: Set,\n fetchLoadMatches: Map,\n fetchRedirectIds: Set,\n routesToUse: AgnosticDataRouteObject[],\n basename: string | undefined,\n pendingActionResult?: PendingActionResult\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingActionResult\n ? isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : pendingActionResult[1].data\n : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[0]\n : undefined;\n let boundaryMatches = boundaryId\n ? getLoaderMatchesUntilBoundary(matches, boundaryId)\n : matches;\n\n // Don't revalidate loaders by default after action 4xx/5xx responses\n // when the flag is enabled. They can still opt-into revalidation via\n // `shouldRevalidate` via `actionResult`\n let actionStatus = pendingActionResult\n ? pendingActionResult[1].statusCode\n : undefined;\n let shouldSkipRevalidation =\n skipActionErrorRevalidation && actionStatus && actionStatus >= 400;\n\n let navigationMatches = boundaryMatches.filter((match, index) => {\n let { route } = match;\n if (route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n\n if (route.loader == null) {\n return false;\n }\n\n if (isInitialLoad) {\n if (typeof route.loader !== \"function\" || route.loader.hydrate) {\n return true;\n }\n return (\n state.loaderData[route.id] === undefined &&\n // Don't re-run if the loader ran and threw an error\n (!state.errors || state.errors[route.id] === undefined)\n );\n }\n\n // Always call the loader on new route instances and pending defer cancellations\n if (\n isNewLoader(state.loaderData, state.matches[index], match) ||\n cancelledDeferredRoutes.some((id) => id === match.route.id)\n ) {\n return true;\n }\n\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n\n return shouldRevalidateLoader(match, {\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired ||\n currentUrl.pathname + currentUrl.search ===\n nextUrl.pathname + nextUrl.search ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n isNewRouteInstance(currentRouteMatch, nextRouteMatch),\n });\n });\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches.forEach((f, key) => {\n // Don't revalidate:\n // - on initial load (shouldn't be any fetchers then anyway)\n // - if fetcher won't be present in the subsequent render\n // - no longer matches the URL (v7_fetcherPersist=false)\n // - was unmounted but persisted due to v7_fetcherPersist=true\n if (\n isInitialLoad ||\n !matches.some((m) => m.route.id === f.routeId) ||\n deletedFetchers.has(key)\n ) {\n return;\n }\n\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null,\n });\n return;\n }\n\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.includes(key)) {\n // Always revalidate if the fetcher was cancelled\n shouldRevalidate = true;\n } else if (\n fetcher &&\n fetcher.state !== \"idle\" &&\n fetcher.data === undefined\n ) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, {\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : isRevalidationRequired,\n });\n }\n\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController(),\n });\n }\n });\n\n return [navigationMatches, revalidatingFetchers];\n}\n\nfunction isNewLoader(\n currentLoaderData: RouteData,\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let isNew =\n // [a] -> [a, b]\n !currentMatch ||\n // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\n\nfunction isNewRouteInstance(\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname ||\n // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n (currentPath != null &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n loaderMatch: AgnosticDataRouteMatch,\n arg: ShouldRevalidateFunctionArgs\n) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return arg.defaultShouldRevalidate;\n}\n\n/**\n * Idempotent utility to execute patchRoutesOnMiss() to lazily load route\n * definitions and update the routes/routeManifest\n */\nasync function loadLazyRouteChildren(\n patchRoutesOnMissImpl: AgnosticPatchRoutesOnMissFunction,\n path: string,\n matches: AgnosticDataRouteMatch[],\n routes: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n pendingRouteChildren: Map>,\n signal: AbortSignal\n) {\n let key = [path, ...matches.map((m) => m.route.id)].join(\"-\");\n try {\n let pending = pendingRouteChildren.get(key);\n if (!pending) {\n pending = patchRoutesOnMissImpl({\n path,\n matches,\n patch: (routeId, children) => {\n if (!signal.aborted) {\n patchRoutesImpl(\n routeId,\n children,\n routes,\n manifest,\n mapRouteProperties\n );\n }\n },\n });\n pendingRouteChildren.set(key, pending);\n }\n\n if (pending && isPromise(pending)) {\n await pending;\n }\n } finally {\n pendingRouteChildren.delete(key);\n }\n}\n\nfunction patchRoutesImpl(\n routeId: string | null,\n children: AgnosticRouteObject[],\n routesToUse: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction\n) {\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [routeId, \"patch\", String(route.children?.length || \"0\")],\n manifest\n );\n if (route.children) {\n route.children.push(...dataChildren);\n } else {\n route.children = dataChildren;\n }\n } else {\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [\"patch\", String(routesToUse.length || \"0\")],\n manifest\n );\n routesToUse.push(...dataChildren);\n }\n}\n\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */\nasync function loadLazyRouteModule(\n route: AgnosticDataRouteObject,\n mapRouteProperties: MapRoutePropertiesFunction,\n manifest: RouteManifest\n) {\n if (!route.lazy) {\n return;\n }\n\n let lazyRoute = await route.lazy();\n\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates: Record = {};\n for (let lazyRouteProperty in lazyRoute) {\n let staticRouteValue =\n routeToUpdate[lazyRouteProperty as keyof typeof routeToUpdate];\n\n let isPropertyStaticallyDefined =\n staticRouteValue !== undefined &&\n // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n\n warning(\n !isPropertyStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" ` +\n `defined but its lazy function is also returning a value for this property. ` +\n `The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n\n if (\n !isPropertyStaticallyDefined &&\n !immutableRouteKeys.has(lazyRouteProperty as ImmutableRouteKey)\n ) {\n routeUpdates[lazyRouteProperty] =\n lazyRoute[lazyRouteProperty as keyof typeof lazyRoute];\n }\n }\n\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided\n // `mapRouteProperties` (or wrapped `detectErrorBoundary`) function to\n // set the framework-aware properties (`element`/`hasErrorBoundary`) since\n // the logic will differ between frameworks.\n ...mapRouteProperties(routeToUpdate),\n lazy: undefined,\n });\n}\n\n// Default implementation of `dataStrategy` which fetches all loaders in parallel\nfunction defaultDataStrategy(\n opts: DataStrategyFunctionArgs\n): ReturnType {\n return Promise.all(opts.matches.map((m) => m.resolve()));\n}\n\nasync function callDataStrategyImpl(\n dataStrategyImpl: DataStrategyFunction,\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n requestContext?: unknown\n): Promise {\n let routeIdsToLoad = matchesToLoad.reduce(\n (acc, m) => acc.add(m.route.id),\n new Set()\n );\n let loadedMatches = new Set();\n\n // Send all matches here to allow for a middleware-type implementation.\n // handler will be a no-op for unneeded routes and we filter those results\n // back out below.\n let results = await dataStrategyImpl({\n matches: matches.map((match) => {\n let shouldLoad = routeIdsToLoad.has(match.route.id);\n // `resolve` encapsulates the route.lazy, executing the\n // loader/action, and mapping return values/thrown errors to a\n // HandlerResult. Users can pass a callback to take fine-grained control\n // over the execution of the loader/action\n let resolve: DataStrategyMatch[\"resolve\"] = (handlerOverride) => {\n loadedMatches.add(match.route.id);\n return shouldLoad\n ? callLoaderOrAction(\n type,\n request,\n match,\n manifest,\n mapRouteProperties,\n handlerOverride,\n requestContext\n )\n : Promise.resolve({ type: ResultType.data, result: undefined });\n };\n\n return {\n ...match,\n shouldLoad,\n resolve,\n };\n }),\n request,\n params: matches[0].params,\n context: requestContext,\n });\n\n // Throw if any loadRoute implementations not called since they are what\n // ensures a route is fully loaded\n matches.forEach((m) =>\n invariant(\n loadedMatches.has(m.route.id),\n `\\`match.resolve()\\` was not called for route id \"${m.route.id}\". ` +\n \"You must call `match.resolve()` on every match passed to \" +\n \"`dataStrategy` to ensure all routes are properly loaded.\"\n )\n );\n\n // Filter out any middleware-only matches for which we didn't need to run handlers\n return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id));\n}\n\n// Default logic for calling a loader/action is the user has no specified a dataStrategy\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n handlerOverride: Parameters[0],\n staticContext?: unknown\n): Promise {\n let result: HandlerResult;\n let onReject: (() => void) | undefined;\n\n let runHandler = (\n handler: AgnosticRouteObject[\"loader\"] | AgnosticRouteObject[\"action\"]\n ): Promise => {\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n // This will never resolve so safe to type it as Promise to\n // satisfy the function return value\n let abortPromise = new Promise((_, r) => (reject = r));\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n let actualHandler = (ctx?: unknown) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean ` +\n `\"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n params: match.params,\n context: staticContext,\n },\n ...(ctx !== undefined ? [ctx] : [])\n );\n };\n\n let handlerPromise: Promise;\n if (handlerOverride) {\n handlerPromise = handlerOverride((ctx: unknown) => actualHandler(ctx));\n } else {\n handlerPromise = (async () => {\n try {\n let val = await actualHandler();\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n }\n\n return Promise.race([handlerPromise, abortPromise]);\n };\n\n try {\n let handler = match.route[type];\n\n if (match.route.lazy) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n loadLazyRouteModule(match.route, mapRouteProperties, manifest),\n ]);\n if (handlerError !== undefined) {\n throw handlerError;\n }\n result = value!;\n } else {\n // Load lazy route module, then run any returned handler\n await loadLazyRouteModule(match.route, mapRouteProperties, manifest);\n\n handler = match.route[type];\n if (handler) {\n // Handler still runs even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id,\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return { type: ResultType.data, result: undefined };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname,\n });\n } else {\n result = await runHandler(handler);\n }\n\n invariant(\n result.result !== undefined,\n `You defined ${type === \"action\" ? \"an action\" : \"a loader\"} for route ` +\n `\"${match.route.id}\" but didn't return anything from your \\`${type}\\` ` +\n `function. Please return a value or \\`null\\`.`\n );\n } catch (e) {\n // We should already be catching and converting normal handler executions to\n // HandlerResults and returning them, so anything that throws here is an\n // unexpected error we still need to wrap\n return { type: ResultType.error, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n\n return result;\n}\n\nasync function convertHandlerResultToDataResult(\n handlerResult: HandlerResult\n): Promise {\n let { result, type, status } = handlerResult;\n\n if (isResponse(result)) {\n let data: any;\n\n try {\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n if (result.body == null) {\n data = null;\n } else {\n data = await result.json();\n }\n } else {\n data = await result.text();\n }\n } catch (e) {\n return { type: ResultType.error, error: e };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(result.status, result.statusText, data),\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : status,\n };\n }\n\n if (isDeferredData(result)) {\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: result.init?.status,\n headers: result.init?.headers && new Headers(result.init.headers),\n };\n }\n\n return { type: ResultType.data, data: result, statusCode: status };\n}\n\n// Support relative routing in internal redirects\nfunction normalizeRelativeRoutingRedirectResponse(\n response: Response,\n request: Request,\n routeId: string,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n v7_relativeSplatPath: boolean\n) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n true,\n location,\n v7_relativeSplatPath\n );\n response.headers.set(\"Location\", location);\n }\n\n return response;\n}\n\nfunction normalizeRedirectLocation(\n location: string,\n currentUrl: URL,\n basename: string\n): string {\n if (ABSOLUTE_URL_REGEX.test(location)) {\n // Strip off the protocol+origin for same-origin + same-basename absolute redirects\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\")\n ? new URL(currentUrl.protocol + normalizedLocation)\n : new URL(normalizedLocation);\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n return location;\n}\n\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(\n history: History,\n location: string | Location,\n signal: AbortSignal,\n submission?: Submission\n): Request {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init: RequestInit = { signal };\n\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (\n formEncType === \"application/x-www-form-urlencoded\" &&\n submission.formData\n ) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n\n return new Request(url, init);\n}\n\nfunction convertFormDataToSearchParams(formData: FormData): URLSearchParams {\n let searchParams = new URLSearchParams();\n\n for (let [key, value] of formData.entries()) {\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n\n return searchParams;\n}\n\nfunction convertSearchParamsToFormData(\n searchParams: URLSearchParams\n): FormData {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n activeDeferreds: Map,\n skipLoaderErrorBubbling: boolean\n): {\n loaderData: RouterState[\"loaderData\"];\n errors: RouterState[\"errors\"] | null;\n statusCode: number;\n loaderHeaders: Record;\n} {\n // Fill in loaderData/errors from our loaders\n let loaderData: RouterState[\"loaderData\"] = {};\n let errors: RouterState[\"errors\"] | null = null;\n let statusCode: number | undefined;\n let foundError = false;\n let loaderHeaders: Record = {};\n let pendingError =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : undefined;\n\n // Process loader results into state.loaderData/state.errors\n results.forEach((result, index) => {\n let id = matchesToLoad[index].route.id;\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError !== undefined) {\n error = pendingError;\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n // Look upwards from the matched route for the closest ancestor error\n // boundary, defaulting to the root match. Prefer higher error values\n // if lower errors bubble to the same boundary\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error)\n ? result.error.status\n : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (\n result.statusCode != null &&\n result.statusCode !== 200 &&\n !foundError\n ) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n }\n });\n\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError !== undefined && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n loaderData[pendingActionResult[0]] = undefined;\n }\n\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders,\n };\n}\n\nfunction processLoaderData(\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n revalidatingFetchers: RevalidatingFetcher[],\n fetcherResults: DataResult[],\n activeDeferreds: Map\n): {\n loaderData: RouterState[\"loaderData\"];\n errors?: RouterState[\"errors\"];\n} {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n false // This method is only called client side so we always want to bubble\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let { key, match, controller } = revalidatingFetchers[index];\n invariant(\n fetcherResults !== undefined && fetcherResults[index] !== undefined,\n \"Did not find corresponding fetcher result\"\n );\n let result = fetcherResults[index];\n\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n // Nothing to do for aborted fetchers\n continue;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error,\n };\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n return { loaderData, errors };\n}\n\nfunction mergeLoaderData(\n loaderData: RouteData,\n newLoaderData: RouteData,\n matches: AgnosticDataRouteMatch[],\n errors: RouteData | null | undefined\n): RouteData {\n let mergedLoaderData = { ...newLoaderData };\n for (let match of matches) {\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n } else {\n // No-op - this is so we ignore existing data if we have a key in the\n // incoming object with an undefined value, which is how we unset a prior\n // loaderData if we encounter a loader error\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n\n if (errors && errors.hasOwnProperty(id)) {\n // Don't keep any loader data below the boundary\n break;\n }\n }\n return mergedLoaderData;\n}\n\nfunction getActionDataForCommit(\n pendingActionResult: PendingActionResult | undefined\n) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1])\n ? {\n // Clear out prior actionData on errors\n actionData: {},\n }\n : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data,\n },\n };\n}\n\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(\n matches: AgnosticDataRouteMatch[],\n routeId?: string\n): AgnosticDataRouteMatch {\n let eligibleMatches = routeId\n ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1)\n : [...matches];\n return (\n eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) ||\n matches[0]\n );\n}\n\nfunction getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {\n matches: AgnosticDataRouteMatch[];\n route: AgnosticDataRouteObject;\n} {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route =\n routes.length === 1\n ? routes[0]\n : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`,\n };\n\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route,\n },\n ],\n route,\n };\n}\n\nfunction getInternalRouterError(\n status: number,\n {\n pathname,\n routeId,\n method,\n type,\n message,\n }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\" | \"invalid-body\" | \"route-discovery\";\n message?: string;\n } = {}\n) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n\n if (status === 400) {\n statusText = \"Bad Request\";\n if (type === \"route-discovery\") {\n errorMessage =\n `Unable to match URL \"${pathname}\" - the \\`unstable_patchRoutesOnMiss()\\` ` +\n `function threw the following error:\\n${message}`;\n } else if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method} request to \"${pathname}\" but ` +\n `did not provide a \\`loader\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method.toUpperCase()} request to \"${pathname}\" but ` +\n `did not provide an \\`action\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\n\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(\n results: DataResult[]\n): { result: RedirectResult; idx: number } | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return { result, idx: i };\n }\n }\n}\n\nfunction stripHashFromPath(path: To) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\n\nfunction isHashChangeOnly(a: Location, b: Location): boolean {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\n\nfunction isPromise(val: unknown): val is Promise {\n return typeof val === \"object\" && val != null && \"then\" in val;\n}\n\nfunction isHandlerResult(result: unknown): result is HandlerResult {\n return (\n result != null &&\n typeof result === \"object\" &&\n \"type\" in result &&\n \"result\" in result &&\n (result.type === ResultType.data || result.type === ResultType.error)\n );\n}\n\nfunction isRedirectHandlerResult(result: HandlerResult) {\n return (\n isResponse(result.result) && redirectStatusCodes.has(result.result.status)\n );\n}\n\nfunction isDeferredResult(result: DataResult): result is DeferredResult {\n return result.type === ResultType.deferred;\n}\n\nfunction isErrorResult(result: DataResult): result is ErrorResult {\n return result.type === ResultType.error;\n}\n\nfunction isRedirectResult(result?: DataResult): result is RedirectResult {\n return (result && result.type) === ResultType.redirect;\n}\n\nexport function isDeferredData(value: any): value is DeferredData {\n let deferred: DeferredData = value;\n return (\n deferred &&\n typeof deferred === \"object\" &&\n typeof deferred.data === \"object\" &&\n typeof deferred.subscribe === \"function\" &&\n typeof deferred.cancel === \"function\" &&\n typeof deferred.resolveData === \"function\"\n );\n}\n\nfunction isResponse(value: any): value is Response {\n return (\n value != null &&\n typeof value.status === \"number\" &&\n typeof value.statusText === \"string\" &&\n typeof value.headers === \"object\" &&\n typeof value.body !== \"undefined\"\n );\n}\n\nfunction isRedirectResponse(result: any): result is Response {\n if (!isResponse(result)) {\n return false;\n }\n\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\n\nfunction isValidMethod(method: string): method is FormMethod | V7_FormMethod {\n return validRequestMethods.has(method.toLowerCase() as FormMethod);\n}\n\nfunction isMutationMethod(\n method: string\n): method is MutationFormMethod | V7_MutationFormMethod {\n return validMutationMethods.has(method.toLowerCase() as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: (AgnosticDataRouteMatch | null)[],\n results: DataResult[],\n signals: (AbortSignal | null)[],\n isFetcher: boolean,\n currentLoaderData?: RouteData\n) {\n for (let index = 0; index < results.length; index++) {\n let result = results[index];\n let match = matchesToLoad[index];\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n\n let currentMatch = currentMatches.find(\n (m) => m.route.id === match!.route.id\n );\n let isRevalidatingLoader =\n currentMatch != null &&\n !isNewRouteInstance(currentMatch, match) &&\n (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n\n if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n let signal = signals[index];\n invariant(\n signal,\n \"Expected an AbortSignal for revalidating fetcher deferred result\"\n );\n await resolveDeferredData(result, signal, isFetcher).then((result) => {\n if (result) {\n results[index] = result || results[index];\n }\n });\n }\n }\n}\n\nasync function resolveDeferredData(\n result: DeferredResult,\n signal: AbortSignal,\n unwrap = false\n): Promise {\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData,\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e,\n };\n }\n }\n\n return {\n type: ResultType.data,\n data: result.deferredData.data,\n };\n}\n\nfunction hasNakedIndexQuery(search: string): boolean {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\n\nfunction getTargetMatch(\n matches: AgnosticDataRouteMatch[],\n location: Location | string\n) {\n let search =\n typeof location === \"string\" ? parsePath(location).search : location.search;\n if (\n matches[matches.length - 1].route.index &&\n hasNakedIndexQuery(search || \"\")\n ) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\n\nfunction getSubmissionFromNavigation(\n navigation: Navigation\n): Submission | undefined {\n let { formMethod, formAction, formEncType, text, formData, json } =\n navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text,\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined,\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined,\n };\n }\n}\n\nfunction getLoadingNavigation(\n location: Location,\n submission?: Submission\n): NavigationStates[\"Loading\"] {\n if (submission) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n } else {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n };\n return navigation;\n }\n}\n\nfunction getSubmittingNavigation(\n location: Location,\n submission: Submission\n): NavigationStates[\"Submitting\"] {\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n}\n\nfunction getLoadingFetcher(\n submission?: Submission,\n data?: Fetcher[\"data\"]\n): FetcherStates[\"Loading\"] {\n if (submission) {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data,\n };\n return fetcher;\n } else {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n }\n}\n\nfunction getSubmittingFetcher(\n submission: Submission,\n existingFetcher?: Fetcher\n): FetcherStates[\"Submitting\"] {\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined,\n };\n return fetcher;\n}\n\nfunction getDoneFetcher(data: Fetcher[\"data\"]): FetcherStates[\"Idle\"] {\n let fetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n}\n\nfunction restoreAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n // no-op, use default empty object\n }\n}\n\nfunction persistAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n if (transitions.size > 0) {\n let json: Record = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\n//#endregion\n"],"names":["Action","PopStateEventType","createMemoryHistory","options","initialEntries","initialIndex","v5Compat","entries","map","entry","index","createMemoryLocation","state","undefined","clampIndex","length","action","Pop","listener","n","Math","min","max","getCurrentLocation","to","key","location","createLocation","pathname","warning","charAt","JSON","stringify","createHref","createPath","history","createURL","URL","encodeLocation","path","parsePath","search","hash","push","Push","nextLocation","splice","delta","replace","Replace","go","nextIndex","listen","fn","createBrowserHistory","createBrowserLocation","window","globalHistory","usr","createBrowserHref","getUrlBasedHistory","createHashHistory","createHashLocation","substr","startsWith","createHashHref","base","document","querySelector","href","getAttribute","url","hashIndex","indexOf","slice","validateHashLocation","invariant","value","message","Error","cond","console","warn","e","createKey","random","toString","getHistoryState","idx","current","_extends","_ref","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","historyState","pushState","error","DOMException","name","assign","origin","addEventListener","removeEventListener","ResultType","immutableRouteKeys","Set","isIndexRoute","route","convertRoutesToDataRoutes","routes","mapRouteProperties","parentPath","manifest","treePath","String","id","join","children","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","matchRoutesImpl","allowPartial","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","decoded","decodePath","matchRouteBranch","convertRouteMatchToUiMatch","match","loaderData","params","data","handle","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","joinPaths","routesMeta","concat","score","computeScore","forEach","_route$path","includes","exploded","explodeOptionalSegments","segments","split","first","rest","isOptional","endsWith","required","restExploded","result","subpath","sort","a","b","compareIndexes","paramRe","dynamicSegmentValue","indexRouteValue","emptySegmentValue","staticSegmentValue","splatPenalty","isSplat","s","initialScore","some","filter","reduce","segment","test","siblings","every","branch","matchedParams","matchedPathname","end","remainingPathname","matchPath","Object","pathnameBase","normalizePathname","generatePath","originalPath","prefix","p","array","isLastSegment","star","keyMatch","optional","param","pattern","matcher","compiledParams","compilePath","captureGroups","memo","paramName","splatValue","regexpSource","_","RegExp","v","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","getResolveToMatches","v7_relativeSplatPath","pathMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","init","responseInit","status","headers","Headers","has","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","_ref2","trackPromise","done","add","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","undefinedError","emit","settledKey","subscriber","subscribe","cancel","abort","k","resolveData","resolve","size","unwrappedData","_ref3","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","redirectDocument","response","ErrorResponseImpl","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","text","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","ABSOLUTE_URL_REGEX","defaultMapRouteProperties","hasErrorBoundary","Boolean","TRANSITIONS_STORAGE_KEY","createRouter","routerWindow","isBrowser","createElement","isServer","detectErrorBoundary","dataRoutes","inFlightDataRoutes","dataStrategyImpl","unstable_dataStrategy","defaultDataStrategy","patchRoutesOnMissImpl","unstable_patchRoutesOnMiss","future","v7_fetcherPersist","v7_normalizeFormMethod","v7_partialHydration","v7_prependBasename","v7_skipActionErrorRevalidation","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","fogOfWar","checkFogOfWar","active","initialized","m","lazy","loader","errors","isRouteInitialized","hydrate","findIndex","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","actionData","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","pendingViewTransitionEnabled","appliedViewTransitions","removePageHideEventListener","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeFetchers","deletedFetchers","activeDeferreds","blockerFunctions","pendingPatchRoutes","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","updateState","startNavigation","restoreAppliedTransitions","_saveAppliedTransitions","persistAppliedTransitions","initialHydration","dispose","clear","deleteFetcher","deleteBlocker","newState","opts","completedFetchers","deletedFetchersKeys","fetcher","unstable_viewTransitionOpts","viewTransitionOpts","unstable_flushSync","flushSync","completeNavigation","_temp","_location$state","_location$state2","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","priorPaths","toPaths","getSavedScrollPosition","navigate","normalizedPath","normalizeTo","fromRouteId","relative","submission","normalizeNavigateOptions","userReplace","pendingError","enableViewTransition","unstable_viewTransition","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","routesToUse","loadingNavigation","notFoundMatches","handleNavigational404","isHashChangeOnly","request","createClientSideRequest","pendingActionResult","findNearestBoundary","type","actionResult","handleAction","shortCircuited","routeId","isErrorResult","getLoadingNavigation","updatedMatches","handleLoaders","fetcherSubmission","getActionDataForCommit","isFogOfWar","getSubmittingNavigation","discoverResult","discoverRoutes","boundaryId","handleDiscoverRouteError","partialMatches","actionMatch","getTargetMatch","method","results","callDataStrategy","isRedirectResult","normalizeRedirectLocation","startRedirectNavigation","isDeferredResult","boundaryMatch","activeSubmission","getSubmissionFromNavigation","shouldUpdateNavigationState","getUpdatedActionData","matchesToLoad","revalidatingFetchers","getMatchesToLoad","cancelActiveDeferreds","updatedFetchers","markFetchRedirectsDone","updates","getUpdatedRevalidatingFetchers","rf","abortFetcher","abortPendingFetchRevalidations","f","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","fetcherKey","processLoaderData","deferredData","didAbortFetchLoads","abortStaleFetchLoads","shouldUpdateFetchers","revalidatingFetcher","getLoadingFetcher","fetch","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","detectAndHandle405Error","existingFetcher","updateFetcherState","getSubmittingFetcher","abortController","fetchRequest","originatingLoadId","actionResults","getDoneFetcher","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","_temp2","redirectLocation","isDocumentReload","redirectHistoryAction","callDataStrategyImpl","all","isRedirectHandlerResult","normalizeRelativeRoutingRedirectResponse","convertHandlerResultToDataResult","currentMatches","fetchersToLoad","fetcherRequest","resolveDeferredResults","getFetcher","deleteFetcherAndUpdateState","count","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","_ref4","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","getScrollKey","fogMatches","leafRoute","isNonHMR","loadLazyRouteChildren","newMatches","matchedSplat","newPartialMatches","_internalSetRoutes","newRoutes","patchRoutes","patchRoutesImpl","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","v7_throwAbortReason","query","_temp3","requestContext","skipLoaderErrorBubbling","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","_temp4","find","values","_result$activeDeferre","routeMatch","submit","loadRouteData","isHandlerResult","isRedirectResponse","isRouteRequest","throwStaticHandlerAbortedError","Location","loaderRequest","Request","context","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","reason","isSubmissionNavigation","body","prependBasename","contextualMatches","activeRouteMatch","hasNakedIndexQuery","normalizeFormMethod","isFetcher","getInvalidBodyError","rawFormMethod","toUpperCase","stripHashFromPath","FormData","URLSearchParams","_ref5","parse","searchParams","convertFormDataToSearchParams","convertSearchParamsToFormData","append","boundaryMatches","isInitialLoad","skipActionErrorRevalidation","currentUrl","nextUrl","actionStatus","shouldSkipRevalidation","navigationMatches","isNewLoader","currentRouteMatch","nextRouteMatch","shouldRevalidateLoader","currentParams","nextParams","defaultShouldRevalidate","isNewRouteInstance","fetcherMatches","fetcherMatch","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","currentPath","loaderMatch","arg","routeChoice","pendingRouteChildren","pending","patch","isPromise","_route$children","dataChildren","loadLazyRouteModule","lazyRoute","routeToUpdate","routeUpdates","lazyRouteProperty","staticRouteValue","isPropertyStaticallyDefined","routeIdsToLoad","loadedMatches","shouldLoad","handlerOverride","callLoaderOrAction","staticContext","onReject","runHandler","handler","actualHandler","ctx","handlerPromise","val","handlerError","handlerResult","contentType","isDeferredData","_result$init","_result$init2","deferred","trimmedMatches","normalizedLocation","protocol","isSameBasename","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","_temp5","errorMessage","signals","isRevalidatingLoader","unwrap","getAll","_window","transitions","sessionPositions","sessionStorage","getItem","setItem"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@remix-run/router/dist/router.d.ts b/node_modules/@remix-run/router/dist/router.d.ts new file mode 100644 index 0000000000..48c47492e0 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.d.ts @@ -0,0 +1,524 @@ +import type { History, Location, Path, To } from "./history"; +import { Action as HistoryAction } from "./history"; +import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteObject, DataStrategyFunction, DeferredData, DetectErrorBoundaryFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, RouteData, Submission, UIMatch, AgnosticPatchRoutesOnMissFunction } from "./utils"; +/** + * A Router instance manages all navigation and data loading/mutations + */ +export interface Router { + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the basename for the router + */ + get basename(): RouterInit["basename"]; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the future config for the router + */ + get future(): FutureConfig; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the current state of the router + */ + get state(): RouterState; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the routes for this router instance + */ + get routes(): AgnosticDataRouteObject[]; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the window associated with the router + */ + get window(): RouterInit["window"]; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Initialize the router, including adding history listeners and kicking off + * initial data fetches. Returns a function to cleanup listeners and abort + * any in-progress loads + */ + initialize(): Router; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Subscribe to router.state updates + * + * @param fn function to call with the new state + */ + subscribe(fn: RouterSubscriber): () => void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Enable scroll restoration behavior in the router + * + * @param savedScrollPositions Object that will manage positions, in case + * it's being restored from sessionStorage + * @param getScrollPosition Function to get the active Y scroll position + * @param getKey Function to get the key to use for restoration + */ + enableScrollRestoration(savedScrollPositions: Record, getScrollPosition: GetScrollPositionFunction, getKey?: GetScrollRestorationKeyFunction): () => void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Navigate forward/backward in the history stack + * @param to Delta to move in the history stack + */ + navigate(to: number): Promise; + /** + * Navigate to the given path + * @param to Path to navigate to + * @param opts Navigation options (method, submission, etc.) + */ + navigate(to: To | null, opts?: RouterNavigateOptions): Promise; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Trigger a fetcher load/submission + * + * @param key Fetcher key + * @param routeId Route that owns the fetcher + * @param href href to fetch + * @param opts Fetcher options, (method, submission, etc.) + */ + fetch(key: string, routeId: string, href: string | null, opts?: RouterFetchOptions): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Trigger a revalidation of all current route loaders and fetcher loads + */ + revalidate(): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Utility function to create an href for the given location + * @param location + */ + createHref(location: Location | URL): string; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Utility function to URL encode a destination path according to the internal + * history implementation + * @param to + */ + encodeLocation(to: To): Path; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Get/create a fetcher for the given key + * @param key + */ + getFetcher(key: string): Fetcher; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Delete the fetcher for a given key + * @param key + */ + deleteFetcher(key: string): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Cleanup listeners and abort any in-progress loads + */ + dispose(): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Get a navigation blocker + * @param key The identifier for the blocker + * @param fn The blocker function implementation + */ + getBlocker(key: string, fn: BlockerFunction): Blocker; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Delete a navigation blocker + * @param key The identifier for the blocker + */ + deleteBlocker(key: string): void; + /** + * @internal + * PRIVATE DO NOT USE + * + * Patch additional children routes into an existing parent route + * @param routeId The parent route id or a callback function accepting `patch` + * to perform batch patching + * @param children The additional children routes + */ + patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * HMR needs to pass in-flight route updates to React Router + * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute) + */ + _internalSetRoutes(routes: AgnosticRouteObject[]): void; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Internal fetch AbortControllers accessed by unit tests + */ + _internalFetchControllers: Map; + /** + * @internal + * PRIVATE - DO NOT USE + * + * Internal pending DeferredData instances accessed by unit tests + */ + _internalActiveDeferreds: Map; +} +/** + * State maintained internally by the router. During a navigation, all states + * reflect the the "old" location unless otherwise noted. + */ +export interface RouterState { + /** + * The action of the most recent navigation + */ + historyAction: HistoryAction; + /** + * The current location reflected by the router + */ + location: Location; + /** + * The current set of route matches + */ + matches: AgnosticDataRouteMatch[]; + /** + * Tracks whether we've completed our initial data load + */ + initialized: boolean; + /** + * Current scroll position we should start at for a new view + * - number -> scroll position to restore to + * - false -> do not restore scroll at all (used during submissions) + * - null -> don't have a saved position, scroll to hash or top of page + */ + restoreScrollPosition: number | false | null; + /** + * Indicate whether this navigation should skip resetting the scroll position + * if we are unable to restore the scroll position + */ + preventScrollReset: boolean; + /** + * Tracks the state of the current navigation + */ + navigation: Navigation; + /** + * Tracks any in-progress revalidations + */ + revalidation: RevalidationState; + /** + * Data from the loaders for the current matches + */ + loaderData: RouteData; + /** + * Data from the action for the current matches + */ + actionData: RouteData | null; + /** + * Errors caught from loaders for the current matches + */ + errors: RouteData | null; + /** + * Map of current fetchers + */ + fetchers: Map; + /** + * Map of current blockers + */ + blockers: Map; +} +/** + * Data that can be passed into hydrate a Router from SSR + */ +export type HydrationState = Partial>; +/** + * Future flags to toggle new feature behavior + */ +export interface FutureConfig { + v7_fetcherPersist: boolean; + v7_normalizeFormMethod: boolean; + v7_partialHydration: boolean; + v7_prependBasename: boolean; + v7_relativeSplatPath: boolean; + v7_skipActionErrorRevalidation: boolean; +} +/** + * Initialization options for createRouter + */ +export interface RouterInit { + routes: AgnosticRouteObject[]; + history: History; + basename?: string; + /** + * @deprecated Use `mapRouteProperties` instead + */ + detectErrorBoundary?: DetectErrorBoundaryFunction; + mapRouteProperties?: MapRoutePropertiesFunction; + future?: Partial; + hydrationData?: HydrationState; + window?: Window; + unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction; + unstable_dataStrategy?: DataStrategyFunction; +} +/** + * State returned from a server-side query() call + */ +export interface StaticHandlerContext { + basename: Router["basename"]; + location: RouterState["location"]; + matches: RouterState["matches"]; + loaderData: RouterState["loaderData"]; + actionData: RouterState["actionData"]; + errors: RouterState["errors"]; + statusCode: number; + loaderHeaders: Record; + actionHeaders: Record; + activeDeferreds: Record | null; + _deepestRenderedBoundaryId?: string | null; +} +/** + * A StaticHandler instance manages a singular SSR navigation/fetch event + */ +export interface StaticHandler { + dataRoutes: AgnosticDataRouteObject[]; + query(request: Request, opts?: { + requestContext?: unknown; + skipLoaderErrorBubbling?: boolean; + unstable_dataStrategy?: DataStrategyFunction; + }): Promise; + queryRoute(request: Request, opts?: { + routeId?: string; + requestContext?: unknown; + unstable_dataStrategy?: DataStrategyFunction; + }): Promise; +} +type ViewTransitionOpts = { + currentLocation: Location; + nextLocation: Location; +}; +/** + * Subscriber function signature for changes to router state + */ +export interface RouterSubscriber { + (state: RouterState, opts: { + deletedFetchers: string[]; + unstable_viewTransitionOpts?: ViewTransitionOpts; + unstable_flushSync: boolean; + }): void; +} +/** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ +export interface GetScrollRestorationKeyFunction { + (location: Location, matches: UIMatch[]): string | null; +} +/** + * Function signature for determining the current scroll position + */ +export interface GetScrollPositionFunction { + (): number; +} +export type RelativeRoutingType = "route" | "path"; +type BaseNavigateOrFetchOptions = { + preventScrollReset?: boolean; + relative?: RelativeRoutingType; + unstable_flushSync?: boolean; +}; +type BaseNavigateOptions = BaseNavigateOrFetchOptions & { + replace?: boolean; + state?: any; + fromRouteId?: string; + unstable_viewTransition?: boolean; +}; +type BaseSubmissionOptions = { + formMethod?: HTMLFormMethod; + formEncType?: FormEncType; +} & ({ + formData: FormData; + body?: undefined; +} | { + formData?: undefined; + body: any; +}); +/** + * Options for a navigate() call for a normal (non-submission) navigation + */ +type LinkNavigateOptions = BaseNavigateOptions; +/** + * Options for a navigate() call for a submission navigation + */ +type SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions; +/** + * Options to pass to navigate() for a navigation + */ +export type RouterNavigateOptions = LinkNavigateOptions | SubmissionNavigateOptions; +/** + * Options for a fetch() load + */ +type LoadFetchOptions = BaseNavigateOrFetchOptions; +/** + * Options for a fetch() submission + */ +type SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions; +/** + * Options to pass to fetch() + */ +export type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions; +/** + * Potential states for state.navigation + */ +export type NavigationStates = { + Idle: { + state: "idle"; + location: undefined; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + formData: undefined; + json: undefined; + text: undefined; + }; + Loading: { + state: "loading"; + location: Location; + formMethod: Submission["formMethod"] | undefined; + formAction: Submission["formAction"] | undefined; + formEncType: Submission["formEncType"] | undefined; + formData: Submission["formData"] | undefined; + json: Submission["json"] | undefined; + text: Submission["text"] | undefined; + }; + Submitting: { + state: "submitting"; + location: Location; + formMethod: Submission["formMethod"]; + formAction: Submission["formAction"]; + formEncType: Submission["formEncType"]; + formData: Submission["formData"]; + json: Submission["json"]; + text: Submission["text"]; + }; +}; +export type Navigation = NavigationStates[keyof NavigationStates]; +export type RevalidationState = "idle" | "loading"; +/** + * Potential states for fetchers + */ +type FetcherStates = { + Idle: { + state: "idle"; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + text: undefined; + formData: undefined; + json: undefined; + data: TData | undefined; + }; + Loading: { + state: "loading"; + formMethod: Submission["formMethod"] | undefined; + formAction: Submission["formAction"] | undefined; + formEncType: Submission["formEncType"] | undefined; + text: Submission["text"] | undefined; + formData: Submission["formData"] | undefined; + json: Submission["json"] | undefined; + data: TData | undefined; + }; + Submitting: { + state: "submitting"; + formMethod: Submission["formMethod"]; + formAction: Submission["formAction"]; + formEncType: Submission["formEncType"]; + text: Submission["text"]; + formData: Submission["formData"]; + json: Submission["json"]; + data: TData | undefined; + }; +}; +export type Fetcher = FetcherStates[keyof FetcherStates]; +interface BlockerBlocked { + state: "blocked"; + reset(): void; + proceed(): void; + location: Location; +} +interface BlockerUnblocked { + state: "unblocked"; + reset: undefined; + proceed: undefined; + location: undefined; +} +interface BlockerProceeding { + state: "proceeding"; + reset: undefined; + proceed: undefined; + location: Location; +} +export type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding; +export type BlockerFunction = (args: { + currentLocation: Location; + nextLocation: Location; + historyAction: HistoryAction; +}) => boolean; +export declare const IDLE_NAVIGATION: NavigationStates["Idle"]; +export declare const IDLE_FETCHER: FetcherStates["Idle"]; +export declare const IDLE_BLOCKER: BlockerUnblocked; +/** + * Create a router and listen to history POP navigations + */ +export declare function createRouter(init: RouterInit): Router; +export declare const UNSAFE_DEFERRED_SYMBOL: unique symbol; +/** + * Future flags to toggle new feature behavior + */ +export interface StaticHandlerFutureConfig { + v7_relativeSplatPath: boolean; + v7_throwAbortReason: boolean; +} +export interface CreateStaticHandlerOptions { + basename?: string; + /** + * @deprecated Use `mapRouteProperties` instead + */ + detectErrorBoundary?: DetectErrorBoundaryFunction; + mapRouteProperties?: MapRoutePropertiesFunction; + future?: Partial; +} +export declare function createStaticHandler(routes: AgnosticRouteObject[], opts?: CreateStaticHandlerOptions): StaticHandler; +/** + * Given an existing StaticHandlerContext and an error thrown at render time, + * provide an updated StaticHandlerContext suitable for a second SSR render + */ +export declare function getStaticContextFromError(routes: AgnosticDataRouteObject[], context: StaticHandlerContext, error: any): StaticHandlerContext; +export declare function isDeferredData(value: any): value is DeferredData; +export {}; diff --git a/node_modules/@remix-run/router/dist/router.js b/node_modules/@remix-run/router/dist/router.js new file mode 100644 index 0000000000..d29bee5f6b --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.js @@ -0,0 +1,4885 @@ +/** + * @remix-run/router v1.18.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */ +function _extends() { + _extends = Object.assign ? Object.assign.bind() : function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); +} + +//////////////////////////////////////////////////////////////////////////////// +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// +/** + * Actions represent the type of change to a location value. + */ +var Action; +(function (Action) { + /** + * A POP indicates a change to an arbitrary index in the history stack, such + * as a back or forward navigation. It does not describe the direction of the + * navigation, only that the current index changed. + * + * Note: This is the default action for newly created history objects. + */ + Action["Pop"] = "POP"; + /** + * A PUSH indicates a new entry being added to the history stack, such as when + * a link is clicked and a new page loads. When this happens, all subsequent + * entries in the stack are lost. + */ + Action["Push"] = "PUSH"; + /** + * A REPLACE indicates the entry at the current index in the history stack + * being replaced by a new one. + */ + Action["Replace"] = "REPLACE"; +})(Action || (Action = {})); +const PopStateEventType = "popstate"; +/** + * Memory history stores the current location in memory. It is designed for use + * in stateful non-browser environments like tests and React Native. + */ +function createMemoryHistory(options) { + if (options === void 0) { + options = {}; + } + let { + initialEntries = ["/"], + initialIndex, + v5Compat = false + } = options; + let entries; // Declare so we can access from createMemoryLocation + entries = initialEntries.map((entry, index) => createMemoryLocation(entry, typeof entry === "string" ? null : entry.state, index === 0 ? "default" : undefined)); + let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex); + let action = Action.Pop; + let listener = null; + function clampIndex(n) { + return Math.min(Math.max(n, 0), entries.length - 1); + } + function getCurrentLocation() { + return entries[index]; + } + function createMemoryLocation(to, state, key) { + if (state === void 0) { + state = null; + } + let location = createLocation(entries ? getCurrentLocation().pathname : "/", to, state, key); + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in memory history: " + JSON.stringify(to)); + return location; + } + function createHref(to) { + return typeof to === "string" ? to : createPath(to); + } + let history = { + get index() { + return index; + }, + get action() { + return action; + }, + get location() { + return getCurrentLocation(); + }, + createHref, + createURL(to) { + return new URL(createHref(to), "http://localhost"); + }, + encodeLocation(to) { + let path = typeof to === "string" ? parsePath(to) : to; + return { + pathname: path.pathname || "", + search: path.search || "", + hash: path.hash || "" + }; + }, + push(to, state) { + action = Action.Push; + let nextLocation = createMemoryLocation(to, state); + index += 1; + entries.splice(index, entries.length, nextLocation); + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 1 + }); + } + }, + replace(to, state) { + action = Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 0 + }); + } + }, + go(delta) { + action = Action.Pop; + let nextIndex = clampIndex(index + delta); + let nextLocation = entries[nextIndex]; + index = nextIndex; + if (listener) { + listener({ + action, + location: nextLocation, + delta + }); + } + }, + listen(fn) { + listener = fn; + return () => { + listener = null; + }; + } + }; + return history; +} +/** + * Browser history stores the location in regular URLs. This is the standard for + * most web apps, but it requires some configuration on the server to ensure you + * serve the same app at multiple URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory + */ +function createBrowserHistory(options) { + if (options === void 0) { + options = {}; + } + function createBrowserLocation(window, globalHistory) { + let { + pathname, + search, + hash + } = window.location; + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createBrowserHref(window, to) { + return typeof to === "string" ? to : createPath(to); + } + return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options); +} +/** + * Hash history stores the location in window.location.hash. This makes it ideal + * for situations where you don't want to send the location to the server for + * some reason, either because you do cannot configure it or the URL space is + * reserved for something else. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory + */ +function createHashHistory(options) { + if (options === void 0) { + options = {}; + } + function createHashLocation(window, globalHistory) { + let { + pathname = "/", + search = "", + hash = "" + } = parsePath(window.location.hash.substr(1)); + // Hash URL should always have a leading / just like window.location.pathname + // does, so if an app ends up at a route like /#something then we add a + // leading slash so all of our path-matching behaves the same as if it would + // in a browser router. This is particularly important when there exists a + // root splat route () since that matches internally against + // "/*" and we'd expect /#something to 404 in a hash router app. + if (!pathname.startsWith("/") && !pathname.startsWith(".")) { + pathname = "/" + pathname; + } + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createHashHref(window, to) { + let base = window.document.querySelector("base"); + let href = ""; + if (base && base.getAttribute("href")) { + let url = window.location.href; + let hashIndex = url.indexOf("#"); + href = hashIndex === -1 ? url : url.slice(0, hashIndex); + } + return href + "#" + (typeof to === "string" ? to : createPath(to)); + } + function validateHashLocation(location, to) { + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")"); + } + return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options); +} +function invariant(value, message) { + if (value === false || value === null || typeof value === "undefined") { + throw new Error(message); + } +} +function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + try { + // Welcome to debugging history! + // + // This error is thrown as a convenience, so you can more easily + // find the source for a warning that appears in the console by + // enabling "pause on exceptions" in your JavaScript debugger. + throw new Error(message); + // eslint-disable-next-line no-empty + } catch (e) {} + } +} +function createKey() { + return Math.random().toString(36).substr(2, 8); +} +/** + * For browser-based histories, we combine the state and key into an object + */ +function getHistoryState(location, index) { + return { + usr: location.state, + key: location.key, + idx: index + }; +} +/** + * Creates a Location object with a unique key from the given Path + */ +function createLocation(current, to, state, key) { + if (state === void 0) { + state = null; + } + let location = _extends({ + pathname: typeof current === "string" ? current : current.pathname, + search: "", + hash: "" + }, typeof to === "string" ? parsePath(to) : to, { + state, + // TODO: This could be cleaned up. push/replace should probably just take + // full Locations now and avoid the need to run through this flow at all + // But that's a pretty big refactor to the current test suite so going to + // keep as is for the time being and just let any incoming keys take precedence + key: to && to.key || key || createKey() + }); + return location; +} +/** + * Creates a string URL path from the given pathname, search, and hash components. + */ +function createPath(_ref) { + let { + pathname = "/", + search = "", + hash = "" + } = _ref; + if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search; + if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash; + return pathname; +} +/** + * Parses a string URL path into its separate pathname, search, and hash components. + */ +function parsePath(path) { + let parsedPath = {}; + if (path) { + let hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + parsedPath.hash = path.substr(hashIndex); + path = path.substr(0, hashIndex); + } + let searchIndex = path.indexOf("?"); + if (searchIndex >= 0) { + parsedPath.search = path.substr(searchIndex); + path = path.substr(0, searchIndex); + } + if (path) { + parsedPath.pathname = path; + } + } + return parsedPath; +} +function getUrlBasedHistory(getLocation, createHref, validateLocation, options) { + if (options === void 0) { + options = {}; + } + let { + window = document.defaultView, + v5Compat = false + } = options; + let globalHistory = window.history; + let action = Action.Pop; + let listener = null; + let index = getIndex(); + // Index should only be null when we initialize. If not, it's because the + // user called history.pushState or history.replaceState directly, in which + // case we should log a warning as it will result in bugs. + if (index == null) { + index = 0; + globalHistory.replaceState(_extends({}, globalHistory.state, { + idx: index + }), ""); + } + function getIndex() { + let state = globalHistory.state || { + idx: null + }; + return state.idx; + } + function handlePop() { + action = Action.Pop; + let nextIndex = getIndex(); + let delta = nextIndex == null ? null : nextIndex - index; + index = nextIndex; + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } + function push(to, state) { + action = Action.Push; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex() + 1; + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + // try...catch because iOS limits us to 100 pushState calls :/ + try { + globalHistory.pushState(historyState, "", url); + } catch (error) { + // If the exception is because `state` can't be serialized, let that throw + // outwards just like a replace call would so the dev knows the cause + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + if (error instanceof DOMException && error.name === "DataCloneError") { + throw error; + } + // They are going to lose state here, but there is no real + // way to warn them about it since the page will refresh... + window.location.assign(url); + } + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 1 + }); + } + } + function replace(to, state) { + action = Action.Replace; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex(); + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + globalHistory.replaceState(historyState, "", url); + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 0 + }); + } + } + function createURL(to) { + // window.location.origin is "null" (the literal string value) in Firefox + // under certain conditions, notably when serving from a local HTML file + // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297 + let base = window.location.origin !== "null" ? window.location.origin : window.location.href; + let href = typeof to === "string" ? to : createPath(to); + // Treating this as a full URL will strip any trailing spaces so we need to + // pre-encode them since they might be part of a matching splat param from + // an ancestor route + href = href.replace(/ $/, "%20"); + invariant(base, "No window.location.(origin|href) available to create URL for href: " + href); + return new URL(href, base); + } + let history = { + get action() { + return action; + }, + get location() { + return getLocation(window, globalHistory); + }, + listen(fn) { + if (listener) { + throw new Error("A history only accepts one active listener"); + } + window.addEventListener(PopStateEventType, handlePop); + listener = fn; + return () => { + window.removeEventListener(PopStateEventType, handlePop); + listener = null; + }; + }, + createHref(to) { + return createHref(window, to); + }, + createURL, + encodeLocation(to) { + // Encode a Location the same way window.location would + let url = createURL(to); + return { + pathname: url.pathname, + search: url.search, + hash: url.hash + }; + }, + push, + replace, + go(n) { + return globalHistory.go(n); + } + }; + return history; +} +//#endregion + +var ResultType; +(function (ResultType) { + ResultType["data"] = "data"; + ResultType["deferred"] = "deferred"; + ResultType["redirect"] = "redirect"; + ResultType["error"] = "error"; +})(ResultType || (ResultType = {})); +const immutableRouteKeys = new Set(["lazy", "caseSensitive", "path", "id", "index", "children"]); +function isIndexRoute(route) { + return route.index === true; +} +// Walk the route tree generating unique IDs where necessary, so we are working +// solely with AgnosticDataRouteObject's within the Router +function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) { + if (parentPath === void 0) { + parentPath = []; + } + if (manifest === void 0) { + manifest = {}; + } + return routes.map((route, index) => { + let treePath = [...parentPath, String(index)]; + let id = typeof route.id === "string" ? route.id : treePath.join("-"); + invariant(route.index !== true || !route.children, "Cannot specify children on an index route"); + invariant(!manifest[id], "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, mapRouteProperties(route), { + id + }); + manifest[id] = indexRoute; + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, mapRouteProperties(route), { + id, + children: undefined + }); + manifest[id] = pathOrLayoutRoute; + if (route.children) { + pathOrLayoutRoute.children = convertRoutesToDataRoutes(route.children, mapRouteProperties, treePath, manifest); + } + return pathOrLayoutRoute; + } + }); +} +/** + * Matches the given routes to a location and returns the match data. + * + * @see https://reactrouter.com/utils/match-routes + */ +function matchRoutes(routes, locationArg, basename) { + if (basename === void 0) { + basename = "/"; + } + return matchRoutesImpl(routes, locationArg, basename, false); +} +function matchRoutesImpl(routes, locationArg, basename, allowPartial) { + let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; + let pathname = stripBasename(location.pathname || "/", basename); + if (pathname == null) { + return null; + } + let branches = flattenRoutes(routes); + rankRouteBranches(branches); + let matches = null; + for (let i = 0; matches == null && i < branches.length; ++i) { + // Incoming pathnames are generally encoded from either window.location + // or from router.navigate, but we want to match against the unencoded + // paths in the route definitions. Memory router locations won't be + // encoded here but there also shouldn't be anything to decode so this + // should be a safe operation. This avoids needing matchRoutes to be + // history-aware. + let decoded = decodePath(pathname); + matches = matchRouteBranch(branches[i], decoded, allowPartial); + } + return matches; +} +function convertRouteMatchToUiMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; +} +function flattenRoutes(routes, branches, parentsMeta, parentPath) { + if (branches === void 0) { + branches = []; + } + if (parentsMeta === void 0) { + parentsMeta = []; + } + if (parentPath === void 0) { + parentPath = ""; + } + let flattenRoute = (route, index, relativePath) => { + let meta = { + relativePath: relativePath === undefined ? route.path || "" : relativePath, + caseSensitive: route.caseSensitive === true, + childrenIndex: index, + route + }; + if (meta.relativePath.startsWith("/")) { + invariant(meta.relativePath.startsWith(parentPath), "Absolute route path \"" + meta.relativePath + "\" nested under path " + ("\"" + parentPath + "\" is not valid. An absolute child route path ") + "must start with the combined path of all its parent routes."); + meta.relativePath = meta.relativePath.slice(parentPath.length); + } + let path = joinPaths([parentPath, meta.relativePath]); + let routesMeta = parentsMeta.concat(meta); + // Add the children before adding this route to the array, so we traverse the + // route tree depth-first and child routes appear before their parents in + // the "flattened" version. + if (route.children && route.children.length > 0) { + invariant( + // Our types know better, but runtime JS may not! + // @ts-expect-error + route.index !== true, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")); + flattenRoutes(route.children, branches, routesMeta, path); + } + // Routes without a path shouldn't ever match by themselves unless they are + // index routes, so don't add them to the list of possible branches. + if (route.path == null && !route.index) { + return; + } + branches.push({ + path, + score: computeScore(path, route.index), + routesMeta + }); + }; + routes.forEach((route, index) => { + var _route$path; + // coarse-grain check for optional params + if (route.path === "" || !((_route$path = route.path) != null && _route$path.includes("?"))) { + flattenRoute(route, index); + } else { + for (let exploded of explodeOptionalSegments(route.path)) { + flattenRoute(route, index, exploded); + } + } + }); + return branches; +} +/** + * Computes all combinations of optional path segments for a given path, + * excluding combinations that are ambiguous and of lower priority. + * + * For example, `/one/:two?/three/:four?/:five?` explodes to: + * - `/one/three` + * - `/one/:two/three` + * - `/one/three/:four` + * - `/one/three/:five` + * - `/one/:two/three/:four` + * - `/one/:two/three/:five` + * - `/one/three/:four/:five` + * - `/one/:two/three/:four/:five` + */ +function explodeOptionalSegments(path) { + let segments = path.split("/"); + if (segments.length === 0) return []; + let [first, ...rest] = segments; + // Optional path segments are denoted by a trailing `?` + let isOptional = first.endsWith("?"); + // Compute the corresponding required segment: `foo?` -> `foo` + let required = first.replace(/\?$/, ""); + if (rest.length === 0) { + // Intepret empty string as omitting an optional segment + // `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three` + return isOptional ? [required, ""] : [required]; + } + let restExploded = explodeOptionalSegments(rest.join("/")); + let result = []; + // All child paths with the prefix. Do this for all children before the + // optional version for all children, so we get consistent ordering where the + // parent optional aspect is preferred as required. Otherwise, we can get + // child sections interspersed where deeper optional segments are higher than + // parent optional segments, where for example, /:two would explode _earlier_ + // then /:one. By always including the parent as required _for all children_ + // first, we avoid this issue + result.push(...restExploded.map(subpath => subpath === "" ? required : [required, subpath].join("/"))); + // Then, if this is an optional value, add all child versions without + if (isOptional) { + result.push(...restExploded); + } + // for absolute paths, ensure `/` instead of empty segment + return result.map(exploded => path.startsWith("/") && exploded === "" ? "/" : exploded); +} +function rankRouteBranches(branches) { + branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first + : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex))); +} +const paramRe = /^:[\w-]+$/; +const dynamicSegmentValue = 3; +const indexRouteValue = 2; +const emptySegmentValue = 1; +const staticSegmentValue = 10; +const splatPenalty = -2; +const isSplat = s => s === "*"; +function computeScore(path, index) { + let segments = path.split("/"); + let initialScore = segments.length; + if (segments.some(isSplat)) { + initialScore += splatPenalty; + } + if (index) { + initialScore += indexRouteValue; + } + return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore); +} +function compareIndexes(a, b) { + let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); + return siblings ? + // If two routes are siblings, we should try to match the earlier sibling + // first. This allows people to have fine-grained control over the matching + // behavior by simply putting routes with identical paths in the order they + // want them tried. + a[a.length - 1] - b[b.length - 1] : + // Otherwise, it doesn't really make sense to rank non-siblings by index, + // so they sort equally. + 0; +} +function matchRouteBranch(branch, pathname, allowPartial) { + if (allowPartial === void 0) { + allowPartial = false; + } + let { + routesMeta + } = branch; + let matchedParams = {}; + let matchedPathname = "/"; + let matches = []; + for (let i = 0; i < routesMeta.length; ++i) { + let meta = routesMeta[i]; + let end = i === routesMeta.length - 1; + let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/"; + let match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end + }, remainingPathname); + let route = meta.route; + if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) { + match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end: false + }, remainingPathname); + } + if (!match) { + return null; + } + Object.assign(matchedParams, match.params); + matches.push({ + // TODO: Can this as be avoided? + params: matchedParams, + pathname: joinPaths([matchedPathname, match.pathname]), + pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])), + route + }); + if (match.pathnameBase !== "/") { + matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); + } + } + return matches; +} +/** + * Returns a path with params interpolated. + * + * @see https://reactrouter.com/utils/generate-path + */ +function generatePath(originalPath, params) { + if (params === void 0) { + params = {}; + } + let path = originalPath; + if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { + warning(false, "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + path = path.replace(/\*$/, "/*"); + } + // ensure `/` is added at the beginning if the path is absolute + const prefix = path.startsWith("/") ? "/" : ""; + const stringify = p => p == null ? "" : typeof p === "string" ? p : String(p); + const segments = path.split(/\/+/).map((segment, index, array) => { + const isLastSegment = index === array.length - 1; + // only apply the splat if it's the last segment + if (isLastSegment && segment === "*") { + const star = "*"; + // Apply the splat + return stringify(params[star]); + } + const keyMatch = segment.match(/^:([\w-]+)(\??)$/); + if (keyMatch) { + const [, key, optional] = keyMatch; + let param = params[key]; + invariant(optional === "?" || param != null, "Missing \":" + key + "\" param"); + return stringify(param); + } + // Remove any optional markers from optional static segments + return segment.replace(/\?$/g, ""); + }) + // Remove empty segments + .filter(segment => !!segment); + return prefix + segments.join("/"); +} +/** + * Performs pattern matching on a URL pathname and returns information about + * the match. + * + * @see https://reactrouter.com/utils/match-path + */ +function matchPath(pattern, pathname) { + if (typeof pattern === "string") { + pattern = { + path: pattern, + caseSensitive: false, + end: true + }; + } + let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end); + let match = pathname.match(matcher); + if (!match) return null; + let matchedPathname = match[0]; + let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); + let captureGroups = match.slice(1); + let params = compiledParams.reduce((memo, _ref, index) => { + let { + paramName, + isOptional + } = _ref; + // We need to compute the pathnameBase here using the raw splat value + // instead of using params["*"] later because it will be decoded then + if (paramName === "*") { + let splatValue = captureGroups[index] || ""; + pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1"); + } + const value = captureGroups[index]; + if (isOptional && !value) { + memo[paramName] = undefined; + } else { + memo[paramName] = (value || "").replace(/%2F/g, "/"); + } + return memo; + }, {}); + return { + params, + pathname: matchedPathname, + pathnameBase, + pattern + }; +} +function compilePath(path, caseSensitive, end) { + if (caseSensitive === void 0) { + caseSensitive = false; + } + if (end === void 0) { + end = true; + } + warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + let params = []; + let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below + .replace(/^\/*/, "/") // Make sure it has a leading / + .replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars + .replace(/\/:([\w-]+)(\?)?/g, (_, paramName, isOptional) => { + params.push({ + paramName, + isOptional: isOptional != null + }); + return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)"; + }); + if (path.endsWith("*")) { + params.push({ + paramName: "*" + }); + regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest + : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"] + } else if (end) { + // When matching to the end, ignore trailing slashes + regexpSource += "\\/*$"; + } else if (path !== "" && path !== "/") { + // If our path is non-empty and contains anything beyond an initial slash, + // then we have _some_ form of path in our regex, so we should expect to + // match only if we find the end of this path segment. Look for an optional + // non-captured trailing slash (to match a portion of the URL) or the end + // of the path (if we've matched to the end). We used to do this with a + // word boundary but that gives false positives on routes like + // /user-preferences since `-` counts as a word boundary. + regexpSource += "(?:(?=\\/|$))"; + } else ; + let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i"); + return [matcher, params]; +} +function decodePath(value) { + try { + return value.split("/").map(v => decodeURIComponent(v).replace(/\//g, "%2F")).join("/"); + } catch (error) { + warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ").")); + return value; + } +} +/** + * @private + */ +function stripBasename(pathname, basename) { + if (basename === "/") return pathname; + if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { + return null; + } + // We want to leave trailing slash behavior in the user's control, so if they + // specify a basename with a trailing slash, we should support it + let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length; + let nextChar = pathname.charAt(startIndex); + if (nextChar && nextChar !== "/") { + // pathname does not start with basename/ + return null; + } + return pathname.slice(startIndex) || "/"; +} +/** + * Returns a resolved path object relative to the given pathname. + * + * @see https://reactrouter.com/utils/resolve-path + */ +function resolvePath(to, fromPathname) { + if (fromPathname === void 0) { + fromPathname = "/"; + } + let { + pathname: toPathname, + search = "", + hash = "" + } = typeof to === "string" ? parsePath(to) : to; + let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname; + return { + pathname, + search: normalizeSearch(search), + hash: normalizeHash(hash) + }; +} +function resolvePathname(relativePath, fromPathname) { + let segments = fromPathname.replace(/\/+$/, "").split("/"); + let relativeSegments = relativePath.split("/"); + relativeSegments.forEach(segment => { + if (segment === "..") { + // Keep the root "" segment so the pathname starts at / + if (segments.length > 1) segments.pop(); + } else if (segment !== ".") { + segments.push(segment); + } + }); + return segments.length > 1 ? segments.join("/") : "/"; +} +function getInvalidPathError(char, field, dest, path) { + return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in and the router will parse it for you."; +} +/** + * @private + * + * When processing relative navigation we want to ignore ancestor routes that + * do not contribute to the path, such that index/pathless layout routes don't + * interfere. + * + * For example, when moving a route element into an index route and/or a + * pathless layout route, relative link behavior contained within should stay + * the same. Both of the following examples should link back to the root: + * + * + * + * + * + * + * + * }> // <-- Does not contribute + * // <-- Does not contribute + * + * + */ +function getPathContributingMatches(matches) { + return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0); +} +// Return the array of pathnames for the current route matches - used to +// generate the routePathnames input for resolveTo() +function getResolveToMatches(matches, v7_relativeSplatPath) { + let pathMatches = getPathContributingMatches(matches); + // When v7_relativeSplatPath is enabled, use the full pathname for the leaf + // match so we include splat values for "." links. See: + // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329 + if (v7_relativeSplatPath) { + return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase); + } + return pathMatches.map(match => match.pathnameBase); +} +/** + * @private + */ +function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) { + if (isPathRelative === void 0) { + isPathRelative = false; + } + let to; + if (typeof toArg === "string") { + to = parsePath(toArg); + } else { + to = _extends({}, toArg); + invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to)); + invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to)); + invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to)); + } + let isEmptyPath = toArg === "" || to.pathname === ""; + let toPathname = isEmptyPath ? "/" : to.pathname; + let from; + // Routing is relative to the current pathname if explicitly requested. + // + // If a pathname is explicitly provided in `to`, it should be relative to the + // route context. This is explained in `Note on `` values` in our + // migration guide from v5 as a means of disambiguation between `to` values + // that begin with `/` and those that do not. However, this is problematic for + // `to` values that do not provide a pathname. `to` can simply be a search or + // hash string, in which case we should assume that the navigation is relative + // to the current location's pathname and *not* the route pathname. + if (toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + // With relative="route" (the default), each leading .. segment means + // "go up one route" instead of "go up one URL segment". This is a key + // difference from how works and a major reason we call this a + // "to" value instead of a "href". + if (!isPathRelative && toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + to.pathname = toSegments.join("/"); + } + from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; + } + let path = resolvePath(to, from); + // Ensure the pathname has a trailing slash if the original "to" had one + let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/"); + // Or if this was a link to the current path which has a trailing slash + let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); + if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) { + path.pathname += "/"; + } + return path; +} +/** + * @private + */ +function getToPathname(to) { + // Empty strings should be treated the same as / paths + return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? parsePath(to).pathname : to.pathname; +} +/** + * @private + */ +const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/"); +/** + * @private + */ +const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/"); +/** + * @private + */ +const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search; +/** + * @private + */ +const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; +/** + * This is a shortcut for creating `application/json` responses. Converts `data` + * to JSON and sets the `Content-Type` header. + */ +const json = function json(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + let headers = new Headers(responseInit.headers); + if (!headers.has("Content-Type")) { + headers.set("Content-Type", "application/json; charset=utf-8"); + } + return new Response(JSON.stringify(data), _extends({}, responseInit, { + headers + })); +}; +class AbortedDeferredError extends Error {} +class DeferredData { + constructor(data, responseInit) { + this.pendingKeysSet = new Set(); + this.subscribers = new Set(); + this.deferredKeys = []; + invariant(data && typeof data === "object" && !Array.isArray(data), "defer() only accepts plain objects"); + // Set up an AbortController + Promise we can race against to exit early + // cancellation + let reject; + this.abortPromise = new Promise((_, r) => reject = r); + this.controller = new AbortController(); + let onAbort = () => reject(new AbortedDeferredError("Deferred data aborted")); + this.unlistenAbortSignal = () => this.controller.signal.removeEventListener("abort", onAbort); + this.controller.signal.addEventListener("abort", onAbort); + this.data = Object.entries(data).reduce((acc, _ref2) => { + let [key, value] = _ref2; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + if (this.done) { + // All incoming values were resolved + this.unlistenAbortSignal(); + } + this.init = responseInit; + } + trackPromise(key, value) { + if (!(value instanceof Promise)) { + return value; + } + this.deferredKeys.push(key); + this.pendingKeysSet.add(key); + // We store a little wrapper promise that will be extended with + // _data/_error props upon resolve/reject + let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, undefined, data), error => this.onSettle(promise, key, error)); + // Register rejection listeners to avoid uncaught promise rejections on + // errors or aborted deferred values + promise.catch(() => {}); + Object.defineProperty(promise, "_tracked", { + get: () => true + }); + return promise; + } + onSettle(promise, key, error, data) { + if (this.controller.signal.aborted && error instanceof AbortedDeferredError) { + this.unlistenAbortSignal(); + Object.defineProperty(promise, "_error", { + get: () => error + }); + return Promise.reject(error); + } + this.pendingKeysSet.delete(key); + if (this.done) { + // Nothing left to abort! + this.unlistenAbortSignal(); + } + // If the promise was resolved/rejected with undefined, we'll throw an error as you + // should always resolve with a value or null + if (error === undefined && data === undefined) { + let undefinedError = new Error("Deferred data for key \"" + key + "\" resolved/rejected with `undefined`, " + "you must resolve/reject with a value or `null`."); + Object.defineProperty(promise, "_error", { + get: () => undefinedError + }); + this.emit(false, key); + return Promise.reject(undefinedError); + } + if (data === undefined) { + Object.defineProperty(promise, "_error", { + get: () => error + }); + this.emit(false, key); + return Promise.reject(error); + } + Object.defineProperty(promise, "_data", { + get: () => data + }); + this.emit(false, key); + return data; + } + emit(aborted, settledKey) { + this.subscribers.forEach(subscriber => subscriber(aborted, settledKey)); + } + subscribe(fn) { + this.subscribers.add(fn); + return () => this.subscribers.delete(fn); + } + cancel() { + this.controller.abort(); + this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k)); + this.emit(true); + } + async resolveData(signal) { + let aborted = false; + if (!this.done) { + let onAbort = () => this.cancel(); + signal.addEventListener("abort", onAbort); + aborted = await new Promise(resolve => { + this.subscribe(aborted => { + signal.removeEventListener("abort", onAbort); + if (aborted || this.done) { + resolve(aborted); + } + }); + }); + } + return aborted; + } + get done() { + return this.pendingKeysSet.size === 0; + } + get unwrappedData() { + invariant(this.data !== null && this.done, "Can only unwrap data on initialized and settled deferreds"); + return Object.entries(this.data).reduce((acc, _ref3) => { + let [key, value] = _ref3; + return Object.assign(acc, { + [key]: unwrapTrackedPromise(value) + }); + }, {}); + } + get pendingKeys() { + return Array.from(this.pendingKeysSet); + } +} +function isTrackedPromise(value) { + return value instanceof Promise && value._tracked === true; +} +function unwrapTrackedPromise(value) { + if (!isTrackedPromise(value)) { + return value; + } + if (value._error) { + throw value._error; + } + return value._data; +} +const defer = function defer(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + return new DeferredData(data, responseInit); +}; +/** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +const redirect = function redirect(url, init) { + if (init === void 0) { + init = 302; + } + let responseInit = init; + if (typeof responseInit === "number") { + responseInit = { + status: responseInit + }; + } else if (typeof responseInit.status === "undefined") { + responseInit.status = 302; + } + let headers = new Headers(responseInit.headers); + headers.set("Location", url); + return new Response(null, _extends({}, responseInit, { + headers + })); +}; +/** + * A redirect response that will force a document reload to the new location. + * Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +const redirectDocument = (url, init) => { + let response = redirect(url, init); + response.headers.set("X-Remix-Reload-Document", "true"); + return response; +}; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + * + * We don't export the class for public use since it's an implementation + * detail, but we export the interface above so folks can build their own + * abstractions around instances via isRouteErrorResponse() + */ +class ErrorResponseImpl { + constructor(status, statusText, data, internal) { + if (internal === void 0) { + internal = false; + } + this.status = status; + this.statusText = statusText || ""; + this.internal = internal; + if (data instanceof Error) { + this.data = data.toString(); + this.error = data; + } else { + this.data = data; + } + } +} +/** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response thrown from an action/loader + */ +function isRouteErrorResponse(error) { + return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error; +} + +const validMutationMethodsArr = ["post", "put", "patch", "delete"]; +const validMutationMethods = new Set(validMutationMethodsArr); +const validRequestMethodsArr = ["get", ...validMutationMethodsArr]; +const validRequestMethods = new Set(validRequestMethodsArr); +const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); +const redirectPreserveMethodStatusCodes = new Set([307, 308]); +const IDLE_NAVIGATION = { + state: "idle", + location: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined +}; +const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined +}; +const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined +}; +const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; +const defaultMapRouteProperties = route => ({ + hasErrorBoundary: Boolean(route.hasErrorBoundary) +}); +const TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; +//#endregion +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// +/** + * Create a router and listen to history POP navigations + */ +function createRouter(init) { + const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : undefined; + const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined"; + const isServer = !isBrowser; + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let mapRouteProperties; + if (init.mapRouteProperties) { + mapRouteProperties = init.mapRouteProperties; + } else if (init.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = init.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + // Routes keyed by ID + let manifest = {}; + // Routes in tree format for matching + let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest); + let inFlightDataRoutes; + let basename = init.basename || "/"; + let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy; + let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss; + // Config driven behavior flags + let future = _extends({ + v7_fetcherPersist: false, + v7_normalizeFormMethod: false, + v7_partialHydration: false, + v7_prependBasename: false, + v7_relativeSplatPath: false, + v7_skipActionErrorRevalidation: false + }, init.future); + // Cleanup function for history + let unlistenHistory = null; + // Externally-provided functions to call on all state changes + let subscribers = new Set(); + // Externally-provided object to hold scroll restoration locations during routing + let savedScrollPositions = null; + // Externally-provided function to get scroll restoration keys + let getScrollRestorationKey = null; + // Externally-provided function to get current scroll position + let getScrollPosition = null; + // One-time flag to control the initial hydration scroll restoration. Because + // we don't get the saved positions from until _after_ + // the initial render, we need to manually trigger a separate updateState to + // send along the restoreScrollPosition + // Set to true if we have `hydrationData` since we assume we were SSR'd and that + // SSR did the initial scroll restoration. + let initialScrollRestored = init.hydrationData != null; + let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); + let initialErrors = null; + if (initialMatches == null && !patchRoutesOnMissImpl) { + // If we do not match a user-provided-route, fall back to the root + // to allow the error boundary to take over + let error = getInternalRouterError(404, { + pathname: init.history.location.pathname + }); + let { + matches, + route + } = getShortCircuitMatches(dataRoutes); + initialMatches = matches; + initialErrors = { + [route.id]: error + }; + } + // In SPA apps, if the user provided a patchRoutesOnMiss implementation and + // our initial match is a splat route, clear them out so we run through lazy + // discovery on hydration in case there's a more accurate lazy route match. + // In SSR apps (with `hydrationData`), we expect that the server will send + // up the proper matched routes so we don't want to run lazy discovery on + // initial hydration and want to hydrate into the splat route. + if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) { + let fogOfWar = checkFogOfWar(initialMatches, dataRoutes, init.history.location.pathname); + if (fogOfWar.active) { + initialMatches = null; + } + } + let initialized; + if (!initialMatches) { + // We need to run patchRoutesOnMiss in initialize() + initialized = false; + initialMatches = []; + } else if (initialMatches.some(m => m.route.lazy)) { + // All initialMatches need to be loaded before we're ready. If we have lazy + // functions around still then we'll need to run them in initialize() + initialized = false; + } else if (!initialMatches.some(m => m.route.loader)) { + // If we've got no loaders to run, then we're good to go + initialized = true; + } else if (future.v7_partialHydration) { + // If partial hydration is enabled, we're initialized so long as we were + // provided with hydrationData for every route with a loader, and no loaders + // were marked for explicit hydration + let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; + let errors = init.hydrationData ? init.hydrationData.errors : null; + let isRouteInitialized = m => { + // No loader, nothing to initialize + if (!m.route.loader) { + return true; + } + // Explicitly opting-in to running on hydration + if (typeof m.route.loader === "function" && m.route.loader.hydrate === true) { + return false; + } + // Otherwise, initialized if hydrated with data or an error + return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined; + }; + // If errors exist, don't consider routes below the boundary + if (errors) { + let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined); + initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized); + } else { + initialized = initialMatches.every(isRouteInitialized); + } + } else { + // Without partial hydration - we're initialized if we were provided any + // hydrationData - which is expected to be complete + initialized = init.hydrationData != null; + } + let router; + let state = { + historyAction: init.history.action, + location: init.history.location, + matches: initialMatches, + initialized, + navigation: IDLE_NAVIGATION, + // Don't restore on initial updateState() if we were SSR'd + restoreScrollPosition: init.hydrationData != null ? false : null, + preventScrollReset: false, + revalidation: "idle", + loaderData: init.hydrationData && init.hydrationData.loaderData || {}, + actionData: init.hydrationData && init.hydrationData.actionData || null, + errors: init.hydrationData && init.hydrationData.errors || initialErrors, + fetchers: new Map(), + blockers: new Map() + }; + // -- Stateful internal variables to manage navigations -- + // Current navigation in progress (to be committed in completeNavigation) + let pendingAction = Action.Pop; + // Should the current navigation prevent the scroll reset if scroll cannot + // be restored? + let pendingPreventScrollReset = false; + // AbortController for the active navigation + let pendingNavigationController; + // Should the current navigation enable document.startViewTransition? + let pendingViewTransitionEnabled = false; + // Store applied view transitions so we can apply them on POP + let appliedViewTransitions = new Map(); + // Cleanup function for persisting applied transitions to sessionStorage + let removePageHideEventListener = null; + // We use this to avoid touching history in completeNavigation if a + // revalidation is entirely uninterrupted + let isUninterruptedRevalidation = false; + // Use this internal flag to force revalidation of all loaders: + // - submissions (completed or interrupted) + // - useRevalidator() + // - X-Remix-Revalidate (from redirect) + let isRevalidationRequired = false; + // Use this internal array to capture routes that require revalidation due + // to a cancelled deferred on action submission + let cancelledDeferredRoutes = []; + // Use this internal array to capture fetcher loads that were cancelled by an + // action navigation and require revalidation + let cancelledFetcherLoads = []; + // AbortControllers for any in-flight fetchers + let fetchControllers = new Map(); + // Track loads based on the order in which they started + let incrementingLoadId = 0; + // Track the outstanding pending navigation data load to be compared against + // the globally incrementing load when a fetcher load lands after a completed + // navigation + let pendingNavigationLoadId = -1; + // Fetchers that triggered data reloads as a result of their actions + let fetchReloadIds = new Map(); + // Fetchers that triggered redirect navigations + let fetchRedirectIds = new Set(); + // Most recent href/match for fetcher.load calls for fetchers + let fetchLoadMatches = new Map(); + // Ref-count mounted fetchers so we know when it's ok to clean them up + let activeFetchers = new Map(); + // Fetchers that have requested a delete when using v7_fetcherPersist, + // they'll be officially removed after they return to idle + let deletedFetchers = new Set(); + // Store DeferredData instances for active route matches. When a + // route loader returns defer() we stick one in here. Then, when a nested + // promise resolves we update loaderData. If a new navigation starts we + // cancel active deferreds for eliminated routes. + let activeDeferreds = new Map(); + // Store blocker functions in a separate Map outside of router state since + // we don't need to update UI state if they change + let blockerFunctions = new Map(); + // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so + // that we only kick them off once for a given combo + let pendingPatchRoutes = new Map(); + // Flag to ignore the next history update, so we can revert the URL change on + // a POP navigation that was blocked by the user without touching router state + let ignoreNextHistoryUpdate = false; + // Initialize the router, all side effects should be kicked off from here. + // Implemented as a Fluent API for ease of: + // let router = createRouter(init).initialize(); + function initialize() { + // If history informs us of a POP navigation, start the navigation but do not update + // state. We'll update our own state once the navigation completes + unlistenHistory = init.history.listen(_ref => { + let { + action: historyAction, + location, + delta + } = _ref; + // Ignore this event if it was just us resetting the URL from a + // blocked POP navigation + if (ignoreNextHistoryUpdate) { + ignoreNextHistoryUpdate = false; + return; + } + warning(blockerFunctions.size === 0 || delta != null, "You are trying to use a blocker on a POP navigation to a location " + "that was not created by @remix-run/router. This will fail silently in " + "production. This can happen if you are navigating outside the router " + "via `window.history.pushState`/`window.location.hash` instead of using " + "router navigation APIs. This can also happen if you are using " + "createHashRouter and the user manually changes the URL."); + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + if (blockerKey && delta != null) { + // Restore the URL to match the current UI, but don't update router state + ignoreNextHistoryUpdate = true; + init.history.go(delta * -1); + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location + }); + // Re-do the same POP navigation we just blocked + init.history.go(delta); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return startNavigation(historyAction, location); + }); + if (isBrowser) { + // FIXME: This feels gross. How can we cleanup the lines between + // scrollRestoration/appliedTransitions persistance? + restoreAppliedTransitions(routerWindow, appliedViewTransitions); + let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions); + routerWindow.addEventListener("pagehide", _saveAppliedTransitions); + removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); + } + // Kick off initial data load if needed. Use Pop to avoid modifying history + // Note we don't do any handling of lazy here. For SPA's it'll get handled + // in the normal navigation flow. For SSR it's expected that lazy modules are + // resolved prior to router creation since we can't go into a fallbackElement + // UI for SSR'd apps + if (!state.initialized) { + startNavigation(Action.Pop, state.location, { + initialHydration: true + }); + } + return router; + } + // Clean up a router and it's side effects + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + if (removePageHideEventListener) { + removePageHideEventListener(); + } + subscribers.clear(); + pendingNavigationController && pendingNavigationController.abort(); + state.fetchers.forEach((_, key) => deleteFetcher(key)); + state.blockers.forEach((_, key) => deleteBlocker(key)); + } + // Subscribe to state updates for the router + function subscribe(fn) { + subscribers.add(fn); + return () => subscribers.delete(fn); + } + // Update our state and notify the calling context of the change + function updateState(newState, opts) { + if (opts === void 0) { + opts = {}; + } + state = _extends({}, state, newState); + // Prep fetcher cleanup so we can tell the UI which fetcher data entries + // can be removed + let completedFetchers = []; + let deletedFetchersKeys = []; + if (future.v7_fetcherPersist) { + state.fetchers.forEach((fetcher, key) => { + if (fetcher.state === "idle") { + if (deletedFetchers.has(key)) { + // Unmounted from the UI and can be totally removed + deletedFetchersKeys.push(key); + } else { + // Returned to idle but still mounted in the UI, so semi-remains for + // revalidations and such + completedFetchers.push(key); + } + } + }); + } + // Iterate over a local copy so that if flushSync is used and we end up + // removing and adding a new subscriber due to the useCallback dependencies, + // we don't get ourselves into a loop calling the new subscriber immediately + [...subscribers].forEach(subscriber => subscriber(state, { + deletedFetchers: deletedFetchersKeys, + unstable_viewTransitionOpts: opts.viewTransitionOpts, + unstable_flushSync: opts.flushSync === true + })); + // Remove idle fetchers from state since we only care about in-flight fetchers. + if (future.v7_fetcherPersist) { + completedFetchers.forEach(key => state.fetchers.delete(key)); + deletedFetchersKeys.forEach(key => deleteFetcher(key)); + } + } + // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION + // and setting state.[historyAction/location/matches] to the new route. + // - Location is a required param + // - Navigation will always be set to IDLE_NAVIGATION + // - Can pass any other state in newState + function completeNavigation(location, newState, _temp) { + var _location$state, _location$state2; + let { + flushSync + } = _temp === void 0 ? {} : _temp; + // Deduce if we're in a loading/actionReload state: + // - We have committed actionData in the store + // - The current navigation was a mutation submission + // - We're past the submitting state and into the loading state + // - The location being loaded is not the result of a redirect + let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && ((_location$state = location.state) == null ? void 0 : _location$state._isRedirect) !== true; + let actionData; + if (newState.actionData) { + if (Object.keys(newState.actionData).length > 0) { + actionData = newState.actionData; + } else { + // Empty actionData -> clear prior actionData due to an action error + actionData = null; + } + } else if (isActionReload) { + // Keep the current data if we're wrapping up the action reload + actionData = state.actionData; + } else { + // Clear actionData on any other completed navigations + actionData = null; + } + // Always preserve any existing loaderData from re-used routes + let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; + // On a successful navigation we can assume we got through all blockers + // so we can start fresh + let blockers = state.blockers; + if (blockers.size > 0) { + blockers = new Map(blockers); + blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); + } + // Always respect the user flag. Otherwise don't reset on mutation + // submission navigations unless they redirect + let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true; + // Commit any in-flight routes at the end of the HMR revalidation "navigation" + if (inFlightDataRoutes) { + dataRoutes = inFlightDataRoutes; + inFlightDataRoutes = undefined; + } + if (isUninterruptedRevalidation) ; else if (pendingAction === Action.Pop) ; else if (pendingAction === Action.Push) { + init.history.push(location, location.state); + } else if (pendingAction === Action.Replace) { + init.history.replace(location, location.state); + } + let viewTransitionOpts; + // On POP, enable transitions if they were enabled on the original navigation + if (pendingAction === Action.Pop) { + // Forward takes precedence so they behave like the original navigation + let priorPaths = appliedViewTransitions.get(state.location.pathname); + if (priorPaths && priorPaths.has(location.pathname)) { + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } else if (appliedViewTransitions.has(location.pathname)) { + // If we don't have a previous forward nav, assume we're popping back to + // the new location and enable if that location previously enabled + viewTransitionOpts = { + currentLocation: location, + nextLocation: state.location + }; + } + } else if (pendingViewTransitionEnabled) { + // Store the applied transition on PUSH/REPLACE + let toPaths = appliedViewTransitions.get(state.location.pathname); + if (toPaths) { + toPaths.add(location.pathname); + } else { + toPaths = new Set([location.pathname]); + appliedViewTransitions.set(state.location.pathname, toPaths); + } + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } + updateState(_extends({}, newState, { + actionData, + loaderData, + historyAction: pendingAction, + location, + initialized: true, + navigation: IDLE_NAVIGATION, + revalidation: "idle", + restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches), + preventScrollReset, + blockers + }), { + viewTransitionOpts, + flushSync: flushSync === true + }); + // Reset stateful navigation vars + pendingAction = Action.Pop; + pendingPreventScrollReset = false; + pendingViewTransitionEnabled = false; + isUninterruptedRevalidation = false; + isRevalidationRequired = false; + cancelledDeferredRoutes = []; + cancelledFetcherLoads = []; + } + // Trigger a navigation event, which can either be a numerical POP or a PUSH + // replace with an optional submission + async function navigate(to, opts) { + if (typeof to === "number") { + init.history.go(to); + return; + } + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, to, future.v7_relativeSplatPath, opts == null ? void 0 : opts.fromRouteId, opts == null ? void 0 : opts.relative); + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, false, normalizedPath, opts); + let currentLocation = state.location; + let nextLocation = createLocation(state.location, path, opts && opts.state); + // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded + // URL from window.location, so we need to encode it here so the behavior + // remains the same as POP and non-data-router usages. new URL() does all + // the same encoding we'd get from a history.pushState/window.location read + // without having to touch history + nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation)); + let userReplace = opts && opts.replace != null ? opts.replace : undefined; + let historyAction = Action.Push; + if (userReplace === true) { + historyAction = Action.Replace; + } else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) { + // By default on submissions to the current location we REPLACE so that + // users don't have to double-click the back button to get to the prior + // location. If the user redirects to a different location from the + // action/loader this will be ignored and the redirect will be a PUSH + historyAction = Action.Replace; + } + let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined; + let flushSync = (opts && opts.unstable_flushSync) === true; + let blockerKey = shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction + }); + if (blockerKey) { + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location: nextLocation, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location: nextLocation + }); + // Send the same navigation through + navigate(to, opts); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return await startNavigation(historyAction, nextLocation, { + submission, + // Send through the formData serialization error if we have one so we can + // render at the right error boundary after we match routes + pendingError: error, + preventScrollReset, + replace: opts && opts.replace, + enableViewTransition: opts && opts.unstable_viewTransition, + flushSync + }); + } + // Revalidate all current loaders. If a navigation is in progress or if this + // is interrupted by a navigation, allow this to "succeed" by calling all + // loaders during the next loader round + function revalidate() { + interruptActiveLoads(); + updateState({ + revalidation: "loading" + }); + // If we're currently submitting an action, we don't need to start a new + // navigation, we'll just let the follow up loader execution call all loaders + if (state.navigation.state === "submitting") { + return; + } + // If we're currently in an idle state, start a new navigation for the current + // action/location and mark it as uninterrupted, which will skip the history + // update in completeNavigation + if (state.navigation.state === "idle") { + startNavigation(state.historyAction, state.location, { + startUninterruptedRevalidation: true + }); + return; + } + // Otherwise, if we're currently in a loading state, just start a new + // navigation to the navigation.location but do not trigger an uninterrupted + // revalidation so that history correctly updates once the navigation completes + startNavigation(pendingAction || state.historyAction, state.navigation.location, { + overrideNavigation: state.navigation + }); + } + // Start a navigation to the given action/location. Can optionally provide a + // overrideNavigation which will override the normalLoad in the case of a redirect + // navigation + async function startNavigation(historyAction, location, opts) { + // Abort any in-progress navigations and start a new one. Unset any ongoing + // uninterrupted revalidations unless told otherwise, since we want this + // new navigation to update history normally + pendingNavigationController && pendingNavigationController.abort(); + pendingNavigationController = null; + pendingAction = historyAction; + isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true; + // Save the current scroll position every time we start a new navigation, + // and track whether we should reset scroll on completion + saveScrollPosition(state.location, state.matches); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(routesToUse, location, basename); + let flushSync = (opts && opts.flushSync) === true; + let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + // Short circuit with a 404 on the root error boundary if we match nothing + if (!matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }, { + flushSync + }); + return; + } + // Short circuit if it's only a hash change and not a revalidation or + // mutation submission. + // + // Ignore on initial page loads because since the initial load will always + // be "same hash". For example, on /page#hash and submit a + // which will default to a navigation to /page + if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) { + completeNavigation(location, { + matches + }, { + flushSync + }); + return; + } + // Create a controller/Request for this navigation + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionResult; + if (opts && opts.pendingError) { + // If we have a pendingError, it means the user attempted a GET submission + // with binary FormData so assign here and skip to handleLoaders. That + // way we handle calling loaders above the boundary etc. It's not really + // different from an actionError in that sense. + pendingActionResult = [findNearestBoundary(matches).route.id, { + type: ResultType.error, + error: opts.pendingError + }]; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionResult = await handleAction(request, location, opts.submission, matches, fogOfWar.active, { + replace: opts.replace, + flushSync + }); + if (actionResult.shortCircuited) { + return; + } + // If we received a 404 from handleAction, it's because we couldn't lazily + // discover the destination route so we don't want to call loaders + if (actionResult.pendingActionResult) { + let [routeId, result] = actionResult.pendingActionResult; + if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) { + pendingNavigationController = null; + completeNavigation(location, { + matches: actionResult.matches, + loaderData: {}, + errors: { + [routeId]: result.error + } + }); + return; + } + } + matches = actionResult.matches || matches; + pendingActionResult = actionResult.pendingActionResult; + loadingNavigation = getLoadingNavigation(location, opts.submission); + flushSync = false; + // No need to do fog of war matching again on loader execution + fogOfWar.active = false; + // Create a GET request for the loaders + request = createClientSideRequest(init.history, request.url, request.signal); + } + // Call loaders + let { + shortCircuited, + matches: updatedMatches, + loaderData, + errors + } = await handleLoaders(request, location, matches, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult); + if (shortCircuited) { + return; + } + // Clean up now that the action/loaders have completed. Don't clean up if + // we short circuited because pendingNavigationController will have already + // been assigned to a new controller for the next navigation + pendingNavigationController = null; + completeNavigation(location, _extends({ + matches: updatedMatches || matches + }, getActionDataForCommit(pendingActionResult), { + loaderData, + errors + })); + } + // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + async function handleAction(request, location, submission, matches, isFogOfWar, opts) { + if (opts === void 0) { + opts = {}; + } + interruptActiveLoads(); + // Put us in a submitting state + let navigation = getSubmittingNavigation(location, submission); + updateState({ + navigation + }, { + flushSync: opts.flushSync === true + }); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + pendingActionResult: [boundaryId, { + type: ResultType.error, + error + }] + }; + } else if (!discoverResult.matches) { + let { + notFoundMatches, + error, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + pendingActionResult: [route.id, { + type: ResultType.error, + error + }] + }; + } else { + matches = discoverResult.matches; + } + } + // Call our action and get the result + let result; + let actionMatch = getTargetMatch(matches, location); + if (!actionMatch.route.action && !actionMatch.route.lazy) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches); + result = results[0]; + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + } + if (isRedirectResult(result)) { + let replace; + if (opts && opts.replace != null) { + replace = opts.replace; + } else { + // If the user didn't explicity indicate replace behavior, replace if + // we redirected to the exact same location we're currently at to avoid + // double back-buttons + let location = normalizeRedirectLocation(result.response.headers.get("Location"), new URL(request.url), basename); + replace = location === state.location.pathname + state.location.search; + } + await startRedirectNavigation(request, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); + // By default, all submissions to the current location are REPLACE + // navigations, but if the action threw an error that'll be rendered in + // an errorElement, we fall back to PUSH so that the user can use the + // back button to get back to the pre-submission form location to try + // again + if ((opts && opts.replace) !== true) { + pendingAction = Action.Push; + } + return { + matches, + pendingActionResult: [boundaryMatch.route.id, result] + }; + } + return { + matches, + pendingActionResult: [actionMatch.route.id, result] + }; + } + // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission); + // If this was a redirect from an action we don't have a "submission" but + // we have it on the loading navigation so use that if available + let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation); + // If this is an uninterrupted revalidation, we remain in our current idle + // state. If not, we need to switch to our loading state and load data, + // preserving any new action data or existing action data (in the case of + // a revalidation interrupting an actionReload) + // If we have partialHydration enabled, then don't update the state for the + // initial data load since it's not a "navigation" + let shouldUpdateNavigationState = !isUninterruptedRevalidation && (!future.v7_partialHydration || !initialHydration); + // When fog of war is enabled, we enter our `loading` state earlier so we + // can discover new routes during the `loading` state. We skip this if + // we've already run actions since we would have done our matching already. + // If the children() function threw then, we want to proceed with the + // partial matches it discovered. + if (isFogOfWar) { + if (shouldUpdateNavigationState) { + let actionData = getUpdatedActionData(pendingActionResult); + updateState(_extends({ + navigation: loadingNavigation + }, actionData !== undefined ? { + actionData + } : {}), { + flushSync + }); + } + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + loaderData: {}, + errors: { + [boundaryId]: error + } + }; + } else if (!discoverResult.matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }; + } else { + matches = discoverResult.matches; + } + } + let routesToUse = inFlightDataRoutes || dataRoutes; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, future.v7_partialHydration && initialHydration === true, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult); + // Cancel pending deferreds for no-longer-matched routes or routes we're + // about to reload. Note that if this is an action reload we would have + // already cancelled all pending deferreds so this would be a no-op + cancelActiveDeferreds(routeId => !(matches && matches.some(m => m.route.id === routeId)) || matchesToLoad && matchesToLoad.some(m => m.route.id === routeId)); + pendingNavigationLoadId = ++incrementingLoadId; + // Short circuit if we have no loaders to run + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + let updatedFetchers = markFetchRedirectsDone(); + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null + }, getActionDataForCommit(pendingActionResult), updatedFetchers ? { + fetchers: new Map(state.fetchers) + } : {}), { + flushSync + }); + return { + shortCircuited: true + }; + } + if (shouldUpdateNavigationState) { + let updates = {}; + if (!isFogOfWar) { + // Only update navigation/actionNData if we didn't already do it above + updates.navigation = loadingNavigation; + let actionData = getUpdatedActionData(pendingActionResult); + if (actionData !== undefined) { + updates.actionData = actionData; + } + } + if (revalidatingFetchers.length > 0) { + updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); + } + updateState(updates, { + flushSync + }); + } + revalidatingFetchers.forEach(rf => { + if (fetchControllers.has(rf.key)) { + abortFetcher(rf.key); + } + if (rf.controller) { + // Fetchers use an independent AbortController so that aborting a fetcher + // (via deleteFetcher) does not abort the triggering navigation that + // triggered the revalidation + fetchControllers.set(rf.key, rf.controller); + } + }); + // Proxy navigation abort through to revalidation fetchers + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(f => abortFetcher(f.key)); + if (pendingNavigationController) { + pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations); + } + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request); + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + // Clean up _after_ loaders have completed. Don't clean up if we short + // circuited because fetchControllers would have been aborted and + // reassigned to new controllers for the next navigation + if (pendingNavigationController) { + pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + } + revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key)); + // If any loaders returned a redirect Response, start a new REPLACE navigation + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + await startRedirectNavigation(request, redirect.result, { + replace + }); + return { + shortCircuited: true + }; + } + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds); + // Wire up subscribers to update loaderData as promises settle + activeDeferreds.forEach((deferredData, routeId) => { + deferredData.subscribe(aborted => { + // Note: No need to updateState here since the TrackedPromise on + // loaderData is stable across resolve/reject + // Remove this instance if we were aborted or if promises have settled + if (aborted || deferredData.done) { + activeDeferreds.delete(routeId); + } + }); + }); + // During partial hydration, preserve SSR errors for routes that don't re-run + if (future.v7_partialHydration && initialHydration && state.errors) { + Object.entries(state.errors).filter(_ref2 => { + let [id] = _ref2; + return !matchesToLoad.some(m => m.route.id === id); + }).forEach(_ref3 => { + let [routeId, error] = _ref3; + errors = Object.assign(errors || {}, { + [routeId]: error + }); + }); + } + let updatedFetchers = markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; + return _extends({ + matches, + loaderData, + errors + }, shouldUpdateFetchers ? { + fetchers: new Map(state.fetchers) + } : {}); + } + function getUpdatedActionData(pendingActionResult) { + if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { + // This is cast to `any` currently because `RouteData`uses any and it + // would be a breaking change to use any. + // TODO: v7 - change `RouteData` to use `unknown` instead of `any` + return { + [pendingActionResult[0]]: pendingActionResult[1].data + }; + } else if (state.actionData) { + if (Object.keys(state.actionData).length === 0) { + return null; + } else { + return state.actionData; + } + } + } + function getUpdatedRevalidatingFetchers(revalidatingFetchers) { + revalidatingFetchers.forEach(rf => { + let fetcher = state.fetchers.get(rf.key); + let revalidatingFetcher = getLoadingFetcher(undefined, fetcher ? fetcher.data : undefined); + state.fetchers.set(rf.key, revalidatingFetcher); + }); + return new Map(state.fetchers); + } + // Trigger a fetcher load/submit for the given fetcher key + function fetch(key, routeId, href, opts) { + if (isServer) { + throw new Error("router.fetch() was called during the server render, but it shouldn't be. " + "You are likely calling a useFetcher() method in the body of your component. " + "Try moving it to a useEffect or a callback."); + } + if (fetchControllers.has(key)) abortFetcher(key); + let flushSync = (opts && opts.unstable_flushSync) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative); + let matches = matchRoutes(routesToUse, normalizedPath, basename); + let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: normalizedPath + }), { + flushSync + }); + return; + } + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, true, normalizedPath, opts); + if (error) { + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } + let match = getTargetMatch(matches, path); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + return; + } + // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + fetchLoadMatches.set(key, { + routeId, + path + }); + handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + } + // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + function detectAndHandle405Error(m) { + if (!m.route.action && !m.route.lazy) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error, { + flushSync + }); + return true; + } + return false; + } + if (!isFogOfWar && detectAndHandle405Error(match)) { + return; + } + // Put this fetcher into it's submitting state + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(requestMatches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + requestMatches = discoverResult.matches; + match = getTargetMatch(requestMatches, path); + if (detectAndHandle405Error(match)) { + return; + } + } + } + // Call the action for the fetcher + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let actionResults = await callDataStrategy("action", fetchRequest, [match], requestMatches); + let actionResult = actionResults[0]; + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + return; + } + // When using v7_fetcherPersist, we don't want errors bubbling up to the UI + // or redirects processed for unmounted fetchers so we just revert them to + // idle + if (future.v7_fetcherPersist && deletedFetchers.has(key)) { + if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + // Let SuccessResult's fall through for revalidation + } else { + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our action started, so that + // should take precedence over this redirect navigation. We already + // set isRevalidationRequired so all loaders for the new route should + // fire unless opted out via shouldRevalidate + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + updateFetcherState(key, getLoadingFetcher(submission)); + return startRedirectNavigation(fetchRequest, actionResult, { + fetcherSubmission: submission + }); + } + } + // Process any non-redirect errors thrown + if (isErrorResult(actionResult)) { + setFetcherError(key, routeId, actionResult.error); + return; + } + } + if (isDeferredResult(actionResult)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + // Start the data load for current matches, or the next location if we're + // in the middle of a navigation + let nextLocation = state.navigation.location || state.location; + let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal); + let routesToUse = inFlightDataRoutes || dataRoutes; + let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + let loadFetcher = getLoadingFetcher(submission, actionResult.data); + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, [match.route.id, actionResult]); + // Put all revalidating fetchers into the loading state, except for the + // current fetcher which we want to keep in it's current loading state which + // contains it's action submission info + action data + revalidatingFetchers.filter(rf => rf.key !== key).forEach(rf => { + let staleKey = rf.key; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined); + state.fetchers.set(staleKey, revalidatingFetcher); + if (fetchControllers.has(staleKey)) { + abortFetcher(staleKey); + } + if (rf.controller) { + fetchControllers.set(staleKey, rf.controller); + } + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key)); + abortController.signal.addEventListener("abort", abortPendingFetchRevalidations); + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + if (abortController.signal.aborted) { + return; + } + abortController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(r => fetchControllers.delete(r.key)); + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + return startRedirectNavigation(revalidationRequest, redirect.result); + } + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + // Since we let revalidations complete even if the submitting fetcher was + // deleted, only put it back to idle if it hasn't been deleted + if (state.fetchers.has(key)) { + let doneFetcher = getDoneFetcher(actionResult.data); + state.fetchers.set(key, doneFetcher); + } + abortStaleFetchLoads(loadId); + // If we are currently in a navigation loading state and this fetcher is + // more recent than the navigation, we want the newer data so abort the + // navigation and complete it with the fetcher data + if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) { + invariant(pendingAction, "Expected pending action"); + pendingNavigationController && pendingNavigationController.abort(); + completeNavigation(state.navigation.location, { + matches, + loaderData, + errors, + fetchers: new Map(state.fetchers) + }); + } else { + // otherwise just update with the fetcher data, preserving any existing + // loaderData for loaders that did not need to reload. We have to + // manually merge here since we aren't going through completeNavigation + updateState({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors), + fetchers: new Map(state.fetchers) + }); + isRevalidationRequired = false; + } + } + // Call the matched loader for fetcher.load(), handling redirects, errors, etc. + async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, submission) { + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + matches = discoverResult.matches; + match = getTargetMatch(matches, path); + } + } + // Call the loader for this fetcher route match + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let results = await callDataStrategy("loader", fetchRequest, [match], matches); + let result = results[0]; + // Deferred isn't supported for fetcher loads, await everything and treat it + // as a normal load. resolveDeferredData will return undefined if this + // fetcher gets aborted, so we just leave result untouched and short circuit + // below if that happens + if (isDeferredResult(result)) { + result = (await resolveDeferredData(result, fetchRequest.signal, true)) || result; + } + // We can delete this so long as we weren't aborted by our our own fetcher + // re-load which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + if (fetchRequest.signal.aborted) { + return; + } + // We don't want errors bubbling up or redirects followed for unmounted + // fetchers, so short circuit here if it was removed from the UI + if (deletedFetchers.has(key)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + // If the loader threw a redirect Response, start a new REPLACE navigation + if (isRedirectResult(result)) { + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our loader started, so that + // should take precedence over this redirect navigation + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + await startRedirectNavigation(fetchRequest, result); + return; + } + } + // Process any non-redirect errors thrown + if (isErrorResult(result)) { + setFetcherError(key, routeId, result.error); + return; + } + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); + // Put the fetcher back into an idle state + updateFetcherState(key, getDoneFetcher(result.data)); + } + /** + * Utility function to handle redirects returned from an action or loader. + * Normally, a redirect "replaces" the navigation that triggered it. So, for + * example: + * + * - user is on /a + * - user clicks a link to /b + * - loader for /b redirects to /c + * + * In a non-JS app the browser would track the in-flight navigation to /b and + * then replace it with /c when it encountered the redirect response. In + * the end it would only ever update the URL bar with /c. + * + * In client-side routing using pushState/replaceState, we aim to emulate + * this behavior and we also do not update history until the end of the + * navigation (including processed redirects). This means that we never + * actually touch history until we've processed redirects, so we just use + * the history action from the original navigation (PUSH or REPLACE). + */ + async function startRedirectNavigation(request, redirect, _temp2) { + let { + submission, + fetcherSubmission, + replace + } = _temp2 === void 0 ? {} : _temp2; + if (redirect.response.headers.has("X-Remix-Revalidate")) { + isRevalidationRequired = true; + } + let location = redirect.response.headers.get("Location"); + invariant(location, "Expected a Location header on the redirect Response"); + location = normalizeRedirectLocation(location, new URL(request.url), basename); + let redirectLocation = createLocation(state.location, location, { + _isRedirect: true + }); + if (isBrowser) { + let isDocumentReload = false; + if (redirect.response.headers.has("X-Remix-Reload-Document")) { + // Hard reload if the response contained X-Remix-Reload-Document + isDocumentReload = true; + } else if (ABSOLUTE_URL_REGEX.test(location)) { + const url = init.history.createURL(location); + isDocumentReload = + // Hard reload if it's an absolute URL to a new origin + url.origin !== routerWindow.location.origin || + // Hard reload if it's an absolute URL that does not match our basename + stripBasename(url.pathname, basename) == null; + } + if (isDocumentReload) { + if (replace) { + routerWindow.location.replace(location); + } else { + routerWindow.location.assign(location); + } + return; + } + } + // There's no need to abort on redirects, since we don't detect the + // redirect until the action/loaders have settled + pendingNavigationController = null; + let redirectHistoryAction = replace === true ? Action.Replace : Action.Push; + // Use the incoming submission if provided, fallback on the active one in + // state.navigation + let { + formMethod, + formAction, + formEncType + } = state.navigation; + if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) { + submission = getSubmissionFromNavigation(state.navigation); + } + // If this was a 307/308 submission we want to preserve the HTTP method and + // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the + // redirected location + let activeSubmission = submission || fetcherSubmission; + if (redirectPreserveMethodStatusCodes.has(redirect.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, activeSubmission, { + formAction: location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // If we have a navigation submission, we will preserve it through the + // redirect navigation + let overrideNavigation = getLoadingNavigation(redirectLocation, submission); + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation, + // Send fetcher submissions through for shouldRevalidate + fetcherSubmission, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + // Utility wrapper for calling dataStrategy client-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches) { + try { + let results = await callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + return { + type: ResultType.redirect, + response: normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath) + }; + } + return convertHandlerResultToDataResult(result); + })); + } catch (e) { + // If the outer dataStrategy method throws, just return the error for all + // matches - and it'll naturally bubble to the root + return matchesToLoad.map(() => ({ + type: ResultType.error, + error: e + })); + } + } + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + let [loaderResults, ...fetcherResults] = await Promise.all([matchesToLoad.length ? callDataStrategy("loader", request, matchesToLoad, matches) : [], ...fetchersToLoad.map(f => { + if (f.matches && f.match && f.controller) { + let fetcherRequest = createClientSideRequest(init.history, f.path, f.controller.signal); + return callDataStrategy("loader", fetcherRequest, [f.match], f.matches).then(r => r[0]); + } else { + return Promise.resolve({ + type: ResultType.error, + error: getInternalRouterError(404, { + pathname: f.path + }) + }); + } + })]); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(() => request.signal), false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, fetchersToLoad.map(f => f.controller ? f.controller.signal : null), true)]); + return { + loaderResults, + fetcherResults + }; + } + function interruptActiveLoads() { + // Every interruption triggers a revalidation + isRevalidationRequired = true; + // Cancel pending route-level deferreds and mark cancelled routes for + // revalidation + cancelledDeferredRoutes.push(...cancelActiveDeferreds()); + // Abort in-flight fetcher loads + fetchLoadMatches.forEach((_, key) => { + if (fetchControllers.has(key)) { + cancelledFetcherLoads.push(key); + abortFetcher(key); + } + }); + } + function updateFetcherState(key, fetcher, opts) { + if (opts === void 0) { + opts = {}; + } + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function setFetcherError(key, routeId, error, opts) { + if (opts === void 0) { + opts = {}; + } + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function getFetcher(key) { + if (future.v7_fetcherPersist) { + activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); + // If this fetcher was previously marked for deletion, unmark it since we + // have a new instance + if (deletedFetchers.has(key)) { + deletedFetchers.delete(key); + } + } + return state.fetchers.get(key) || IDLE_FETCHER; + } + function deleteFetcher(key) { + let fetcher = state.fetchers.get(key); + // Don't abort the controller if this is a deletion of a fetcher.submit() + // in it's loading phase since - we don't want to abort the corresponding + // revalidation and want them to complete and land + if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) { + abortFetcher(key); + } + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + deletedFetchers.delete(key); + state.fetchers.delete(key); + } + function deleteFetcherAndUpdateState(key) { + if (future.v7_fetcherPersist) { + let count = (activeFetchers.get(key) || 0) - 1; + if (count <= 0) { + activeFetchers.delete(key); + deletedFetchers.add(key); + } else { + activeFetchers.set(key, count); + } + } else { + deleteFetcher(key); + } + updateState({ + fetchers: new Map(state.fetchers) + }); + } + function abortFetcher(key) { + let controller = fetchControllers.get(key); + invariant(controller, "Expected fetch controller: " + key); + controller.abort(); + fetchControllers.delete(key); + } + function markFetchersDone(keys) { + for (let key of keys) { + let fetcher = getFetcher(key); + let doneFetcher = getDoneFetcher(fetcher.data); + state.fetchers.set(key, doneFetcher); + } + } + function markFetchRedirectsDone() { + let doneKeys = []; + let updatedFetchers = false; + for (let key of fetchRedirectIds) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + fetchRedirectIds.delete(key); + doneKeys.push(key); + updatedFetchers = true; + } + } + markFetchersDone(doneKeys); + return updatedFetchers; + } + function abortStaleFetchLoads(landedId) { + let yeetedKeys = []; + for (let [key, id] of fetchReloadIds) { + if (id < landedId) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + abortFetcher(key); + fetchReloadIds.delete(key); + yeetedKeys.push(key); + } + } + } + markFetchersDone(yeetedKeys); + return yeetedKeys.length > 0; + } + function getBlocker(key, fn) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + if (blockerFunctions.get(key) !== fn) { + blockerFunctions.set(key, fn); + } + return blocker; + } + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + } + // Utility function to update blockers, ensuring valid state transitions + function updateBlocker(key, newBlocker) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + // Poor mans state machine :) + // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM + invariant(blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state); + let blockers = new Map(state.blockers); + blockers.set(key, newBlocker); + updateState({ + blockers + }); + } + function shouldBlockNavigation(_ref4) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref4; + if (blockerFunctions.size === 0) { + return; + } + // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + if (blockerFunctions.size > 1) { + warning(false, "A router only supports one blocker at a time"); + } + let entries = Array.from(blockerFunctions.entries()); + let [blockerKey, blockerFunction] = entries[entries.length - 1]; + let blocker = state.blockers.get(blockerKey); + if (blocker && blocker.state === "proceeding") { + // If the blocker is currently proceeding, we don't need to re-check + // it and can let this navigation continue + return; + } + // At this point, we know we're unblocked/blocked so we need to check the + // user-provided blocker function + if (blockerFunction({ + currentLocation, + nextLocation, + historyAction + })) { + return blockerKey; + } + } + function handleNavigational404(pathname) { + let error = getInternalRouterError(404, { + pathname + }); + let routesToUse = inFlightDataRoutes || dataRoutes; + let { + matches, + route + } = getShortCircuitMatches(routesToUse); + // Cancel all pending deferred on 404s since we don't keep any routes + cancelActiveDeferreds(); + return { + notFoundMatches: matches, + route, + error + }; + } + function handleDiscoverRouteError(pathname, discoverResult) { + return { + boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id, + error: getInternalRouterError(400, { + type: "route-discovery", + pathname, + message: discoverResult.error != null && "message" in discoverResult.error ? discoverResult.error : String(discoverResult.error) + }) + }; + } + function cancelActiveDeferreds(predicate) { + let cancelledRouteIds = []; + activeDeferreds.forEach((dfd, routeId) => { + if (!predicate || predicate(routeId)) { + // Cancel the deferred - but do not remove from activeDeferreds here - + // we rely on the subscribers to do that so our tests can assert proper + // cleanup via _internalActiveDeferreds + dfd.cancel(); + cancelledRouteIds.push(routeId); + activeDeferreds.delete(routeId); + } + }); + return cancelledRouteIds; + } + // Opt in to capturing and reporting scroll positions during navigations, + // used by the component + function enableScrollRestoration(positions, getPosition, getKey) { + savedScrollPositions = positions; + getScrollPosition = getPosition; + getScrollRestorationKey = getKey || null; + // Perform initial hydration scroll restoration, since we miss the boat on + // the initial updateState() because we've not yet rendered + // and therefore have no savedScrollPositions available + if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { + initialScrollRestored = true; + let y = getSavedScrollPosition(state.location, state.matches); + if (y != null) { + updateState({ + restoreScrollPosition: y + }); + } + } + return () => { + savedScrollPositions = null; + getScrollPosition = null; + getScrollRestorationKey = null; + }; + } + function getScrollKey(location, matches) { + if (getScrollRestorationKey) { + let key = getScrollRestorationKey(location, matches.map(m => convertRouteMatchToUiMatch(m, state.loaderData))); + return key || location.key; + } + return location.key; + } + function saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollPosition) { + let key = getScrollKey(location, matches); + savedScrollPositions[key] = getScrollPosition(); + } + } + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions) { + let key = getScrollKey(location, matches); + let y = savedScrollPositions[key]; + if (typeof y === "number") { + return y; + } + } + return null; + } + function checkFogOfWar(matches, routesToUse, pathname) { + if (patchRoutesOnMissImpl) { + if (!matches) { + let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: fogMatches || [] + }; + } else { + let leafRoute = matches[matches.length - 1].route; + if (leafRoute.path && (leafRoute.path === "*" || leafRoute.path.endsWith("/*"))) { + // If we matched a splat, it might only be because we haven't yet fetched + // the children that would match with a higher score, so let's fetch + // around and find out + let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: partialMatches + }; + } + } + } + return { + active: false, + matches: null + }; + } + async function discoverRoutes(matches, pathname, signal) { + let partialMatches = matches; + let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null; + while (true) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + try { + await loadLazyRouteChildren(patchRoutesOnMissImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal); + } catch (e) { + return { + type: "error", + error: e, + partialMatches + }; + } finally { + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity so when we `updateState` at the end of + // this navigation/fetch `router.routes` will be a new identity and + // trigger a re-run of memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + } + } + if (signal.aborted) { + return { + type: "aborted" + }; + } + let newMatches = matchRoutes(routesToUse, pathname, basename); + let matchedSplat = false; + if (newMatches) { + let leafRoute = newMatches[newMatches.length - 1].route; + if (leafRoute.index) { + // If we found an index route, we can stop + return { + type: "success", + matches: newMatches + }; + } + if (leafRoute.path && leafRoute.path.length > 0) { + if (leafRoute.path === "*") { + // If we found a splat route, we can't be sure there's not a + // higher-scoring route down some partial matches trail so we need + // to check that out + matchedSplat = true; + } else { + // If we found a non-splat route, we can stop + return { + type: "success", + matches: newMatches + }; + } + } + } + let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + // If we are no longer partially matching anything, this was either a + // legit splat match above, or it's a 404. Also avoid loops if the + // second pass results in the same partial matches + if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) { + return { + type: "success", + matches: matchedSplat ? newMatches : null + }; + } + partialMatches = newPartialMatches; + route = partialMatches[partialMatches.length - 1].route; + if (route.path === "*") { + // The splat is still our most accurate partial, so run with it + return { + type: "success", + matches: partialMatches + }; + } + } + } + function _internalSetRoutes(newRoutes) { + manifest = {}; + inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest); + } + function patchRoutes(routeId, children) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties); + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity and trigger a reflow via `updateState` + // to re-run memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + updateState({}); + } + } + router = { + get basename() { + return basename; + }, + get future() { + return future; + }, + get state() { + return state; + }, + get routes() { + return dataRoutes; + }, + get window() { + return routerWindow; + }, + initialize, + subscribe, + enableScrollRestoration, + navigate, + fetch, + revalidate, + // Passthrough to history-aware createHref used by useHref so we get proper + // hash-aware URLs in DOM paths + createHref: to => init.history.createHref(to), + encodeLocation: to => init.history.encodeLocation(to), + getFetcher, + deleteFetcher: deleteFetcherAndUpdateState, + dispose, + getBlocker, + deleteBlocker, + patchRoutes, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds, + // TODO: Remove setRoutes, it's temporary to avoid dealing with + // updating the tree while validating the update algorithm. + _internalSetRoutes + }; + return router; +} +//#endregion +//////////////////////////////////////////////////////////////////////////////// +//#region createStaticHandler +//////////////////////////////////////////////////////////////////////////////// +const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred"); +function createStaticHandler(routes, opts) { + invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler"); + let manifest = {}; + let basename = (opts ? opts.basename : null) || "/"; + let mapRouteProperties; + if (opts != null && opts.mapRouteProperties) { + mapRouteProperties = opts.mapRouteProperties; + } else if (opts != null && opts.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = opts.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + // Config driven behavior flags + let future = _extends({ + v7_relativeSplatPath: false, + v7_throwAbortReason: false + }, opts ? opts.future : null); + let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest); + /** + * The query() method is intended for document requests, in which we want to + * call an optional action and potentially multiple loaders for all nested + * routes. It returns a StaticHandlerContext object, which is very similar + * to the router state (location, loaderData, actionData, errors, etc.) and + * also adds SSR-specific information such as the statusCode and headers + * from action/loaders Responses. + * + * It _should_ never throw and should report all errors through the + * returned context.errors object, properly associating errors to their error + * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be + * used to emulate React error boundaries during SSr by performing a second + * pass only down to the boundaryId. + * + * The one exception where we do not return a StaticHandlerContext is when a + * redirect response is returned or thrown from any action/loader. We + * propagate that out and return the raw Response so the HTTP server can + * return it directly. + * + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent + * the bubbling of errors which allows single-fetch-type implementations + * where the client will handle the bubbling and we may need to return data + * for the handling route + */ + async function query(request, _temp3) { + let { + requestContext, + skipLoaderErrorBubbling, + unstable_dataStrategy + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD") { + let error = getInternalRouterError(405, { + method + }); + let { + matches: methodNotAllowedMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: methodNotAllowedMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } else if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: notFoundMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, skipLoaderErrorBubbling === true, null); + if (isResponse(result)) { + return result; + } + // When returning StaticHandlerContext, we patch back in the location here + // since we need it for React Context. But this helps keep our submit and + // loadRouteData operating on a Request instead of a Location + return _extends({ + location, + basename + }, result); + } + /** + * The queryRoute() method is intended for targeted route requests, either + * for fetch ?_data requests or resource route requests. In this case, we + * are only ever calling a single action or loader, and we are returning the + * returned value directly. In most cases, this will be a Response returned + * from the action/loader, but it may be a primitive or other value as well - + * and in such cases the calling context should handle that accordingly. + * + * We do respect the throw/return differentiation, so if an action/loader + * throws, then this method will throw the value. This is important so we + * can do proper boundary identification in Remix where a thrown Response + * must go to the Catch Boundary but a returned Response is happy-path. + * + * One thing to note is that any Router-initiated Errors that make sense + * to associate with a status code will be thrown as an ErrorResponse + * instance which include the raw Error, such that the calling context can + * serialize the error as they see fit while including the proper response + * code. Examples here are 404 and 405 errors that occur prior to reaching + * any user-defined loaders. + * + * - `opts.routeId` allows you to specify the specific route handler to call. + * If not provided the handler will determine the proper route by matching + * against `request.url` + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + */ + async function queryRoute(request, _temp4) { + let { + routeId, + requestContext, + unstable_dataStrategy + } = _temp4 === void 0 ? {} : _temp4; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { + throw getInternalRouterError(405, { + method + }); + } else if (!matches) { + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let match = routeId ? matches.find(m => m.route.id === routeId) : getTargetMatch(matches, location); + if (routeId && !match) { + throw getInternalRouterError(403, { + pathname: location.pathname, + routeId + }); + } else if (!match) { + // This should never hit I don't think? + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, false, match); + if (isResponse(result)) { + return result; + } + let error = result.errors ? Object.values(result.errors)[0] : undefined; + if (error !== undefined) { + // If we got back result.errors, that means the loader/action threw + // _something_ that wasn't a Response, but it's not guaranteed/required + // to be an `instanceof Error` either, so we have to use throw here to + // preserve the "error" state outside of queryImpl. + throw error; + } + // Pick off the right state value to return + if (result.actionData) { + return Object.values(result.actionData)[0]; + } + if (result.loaderData) { + var _result$activeDeferre; + let data = Object.values(result.loaderData)[0]; + if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) { + data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id]; + } + return data; + } + return undefined; + } + async function queryImpl(request, location, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch) { + invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal"); + try { + if (isMutationMethod(request.method.toLowerCase())) { + let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch != null); + return result; + } + let result = await loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction for a + // `queryRoute` call, we throw the `HandlerResult` to bail out early + // and then return or throw the raw Response here accordingly + if (isHandlerResult(e) && isResponse(e.result)) { + if (e.type === ResultType.error) { + throw e.result; + } + return e.result; + } + // Redirects are always returned since they don't propagate to catch + // boundaries + if (isRedirectResponse(e)) { + return e; + } + throw e; + } + } + async function submit(request, matches, actionMatch, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, isRouteRequest) { + let result; + if (!actionMatch.route.action && !actionMatch.route.lazy) { + let error = getInternalRouterError(405, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: actionMatch.route.id + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, unstable_dataStrategy); + result = results[0]; + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + } + if (isRedirectResult(result)) { + // Uhhhh - this should never happen, we should always throw these from + // callLoaderOrAction, but the type narrowing here keeps TS happy and we + // can get back on the "throw all redirect responses" train here should + // this ever happen :/ + throw new Response(null, { + status: result.response.status, + headers: { + Location: result.response.headers.get("Location") + } + }); + } + if (isDeferredResult(result)) { + let error = getInternalRouterError(400, { + type: "defer-action" + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } + if (isRouteRequest) { + // Note: This should only be non-Response values if we get here, since + // isRouteRequest should throw any Response received in callLoaderOrAction + if (isErrorResult(result)) { + throw result.error; + } + return { + matches: [actionMatch], + loaderData: {}, + actionData: { + [actionMatch.route.id]: result.data + }, + errors: null, + // Note: statusCode + headers are unused here since queryRoute will + // return the raw Response or value + statusCode: 200, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + // Create a GET request for the loaders + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]); + // action status codes take precedence over loader status codes + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null); + return _extends({}, context, { + actionData: { + [actionMatch.route.id]: result.data + } + }, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionHeaders: result.headers ? { + [actionMatch.route.id]: result.headers + } : {} + }); + } + async function loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) { + let isRouteRequest = routeMatch != null; + // Short circuit if we have no loaders to run (queryRoute()) + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches; + let matchesToLoad = requestMatches.filter(m => m.route.loader || m.route.lazy); + // Short circuit if we have no loaders to run (query()) + if (matchesToLoad.length === 0) { + return { + matches, + // Add a null for all matched routes for proper revalidation on the client + loaderData: matches.reduce((acc, m) => Object.assign(acc, { + [m.route.id]: null + }), {}), + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy); + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + // Process and commit output from loaders + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling); + // Add a null for any non-loader matches for proper revalidation on the client + let executedLoaders = new Set(matchesToLoad.map(match => match.route.id)); + matches.forEach(match => { + if (!executedLoaders.has(match.route.id)) { + context.loaderData[match.route.id] = null; + } + }); + return _extends({}, context, { + matches, + activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null + }); + } + // Utility wrapper for calling dataStrategy server-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy) { + let results = await callDataStrategyImpl(unstable_dataStrategy || defaultDataStrategy, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + // Throw redirects and let the server handle them with an HTTP redirect + throw normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath); + } + if (isResponse(result.result) && isRouteRequest) { + // For SSR single-route requests, we want to hand Responses back + // directly without unwrapping + throw result; + } + return convertHandlerResultToDataResult(result); + })); + } + return { + dataRoutes, + query, + queryRoute + }; +} +//#endregion +//////////////////////////////////////////////////////////////////////////////// +//#region Helpers +//////////////////////////////////////////////////////////////////////////////// +/** + * Given an existing StaticHandlerContext and an error thrown at render time, + * provide an updated StaticHandlerContext suitable for a second SSR render + */ +function getStaticContextFromError(routes, context, error) { + let newContext = _extends({}, context, { + statusCode: isRouteErrorResponse(error) ? error.status : 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + return newContext; +} +function throwStaticHandlerAbortedError(request, isRouteRequest, future) { + if (future.v7_throwAbortReason && request.signal.reason !== undefined) { + throw request.signal.reason; + } + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted: " + request.method + " " + request.url); +} +function isSubmissionNavigation(opts) { + return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== undefined); +} +function normalizeTo(location, matches, basename, prependBasename, to, v7_relativeSplatPath, fromRouteId, relative) { + let contextualMatches; + let activeRouteMatch; + if (fromRouteId) { + // Grab matches up to the calling route so our route-relative logic is + // relative to the correct source route + contextualMatches = []; + for (let match of matches) { + contextualMatches.push(match); + if (match.route.id === fromRouteId) { + activeRouteMatch = match; + break; + } + } + } else { + contextualMatches = matches; + activeRouteMatch = matches[matches.length - 1]; + } + // Resolve the relative path + let path = resolveTo(to ? to : ".", getResolveToMatches(contextualMatches, v7_relativeSplatPath), stripBasename(location.pathname, basename) || location.pathname, relative === "path"); + // When `to` is not specified we inherit search/hash from the current + // location, unlike when to="." and we just inherit the path. + // See https://github.com/remix-run/remix/issues/927 + if (to == null) { + path.search = location.search; + path.hash = location.hash; + } + // Add an ?index param for matched index routes if we don't already have one + if ((to == null || to === "" || to === ".") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) { + path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; + } + // If we're operating within a basename, prepend it to the pathname. If + // this is a root navigation, then just use the raw basename which allows + // the basename to have full control over the presence of a trailing slash + // on root actions + if (prependBasename && basename !== "/") { + path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); + } + return createPath(path); +} +// Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params +function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) { + // Return location verbatim on non-submission navigations + if (!opts || !isSubmissionNavigation(opts)) { + return { + path + }; + } + if (opts.formMethod && !isValidMethod(opts.formMethod)) { + return { + path, + error: getInternalRouterError(405, { + method: opts.formMethod + }) + }; + } + let getInvalidBodyError = () => ({ + path, + error: getInternalRouterError(400, { + type: "invalid-body" + }) + }); + // Create a Submission on non-GET navigations + let rawFormMethod = opts.formMethod || "get"; + let formMethod = normalizeFormMethod ? rawFormMethod.toUpperCase() : rawFormMethod.toLowerCase(); + let formAction = stripHashFromPath(path); + if (opts.body !== undefined) { + if (opts.formEncType === "text/plain") { + // text only support POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data + Array.from(opts.body.entries()).reduce((acc, _ref5) => { + let [name, value] = _ref5; + return "" + acc + name + "=" + value + "\n"; + }, "") : String(opts.body); + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json: undefined, + text + } + }; + } else if (opts.formEncType === "application/json") { + // json only supports POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + try { + let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json, + text: undefined + } + }; + } catch (e) { + return getInvalidBodyError(); + } + } + } + invariant(typeof FormData === "function", "FormData is not available in this environment"); + let searchParams; + let formData; + if (opts.formData) { + searchParams = convertFormDataToSearchParams(opts.formData); + formData = opts.formData; + } else if (opts.body instanceof FormData) { + searchParams = convertFormDataToSearchParams(opts.body); + formData = opts.body; + } else if (opts.body instanceof URLSearchParams) { + searchParams = opts.body; + formData = convertSearchParamsToFormData(searchParams); + } else if (opts.body == null) { + searchParams = new URLSearchParams(); + formData = new FormData(); + } else { + try { + searchParams = new URLSearchParams(opts.body); + formData = convertSearchParamsToFormData(searchParams); + } catch (e) { + return getInvalidBodyError(); + } + } + let submission = { + formMethod, + formAction, + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData, + json: undefined, + text: undefined + }; + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + // Flatten submission onto URLSearchParams for GET submissions + let parsedPath = parsePath(path); + // On GET navigation submissions we can drop the ?index param from the + // resulting location since all loaders will run. But fetcher GET submissions + // only run a single loader so we need to preserve any incoming ?index params + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + parsedPath.search = "?" + searchParams; + return { + path: createPath(parsedPath), + submission + }; +} +// Filter out all routes below any caught error as they aren't going to +// render so we don't need to load them +function getLoaderMatchesUntilBoundary(matches, boundaryId) { + let boundaryMatches = matches; + if (boundaryId) { + let index = matches.findIndex(m => m.route.id === boundaryId); + if (index >= 0) { + boundaryMatches = matches.slice(0, index); + } + } + return boundaryMatches; +} +function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) { + let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined; + let currentUrl = history.createURL(state.location); + let nextUrl = history.createURL(location); + // Pick navigation matches that are net-new or qualify for revalidation + let boundaryId = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[0] : undefined; + let boundaryMatches = boundaryId ? getLoaderMatchesUntilBoundary(matches, boundaryId) : matches; + // Don't revalidate loaders by default after action 4xx/5xx responses + // when the flag is enabled. They can still opt-into revalidation via + // `shouldRevalidate` via `actionResult` + let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : undefined; + let shouldSkipRevalidation = skipActionErrorRevalidation && actionStatus && actionStatus >= 400; + let navigationMatches = boundaryMatches.filter((match, index) => { + let { + route + } = match; + if (route.lazy) { + // We haven't loaded this route yet so we don't know if it's got a loader! + return true; + } + if (route.loader == null) { + return false; + } + if (isInitialLoad) { + if (typeof route.loader !== "function" || route.loader.hydrate) { + return true; + } + return state.loaderData[route.id] === undefined && ( + // Don't re-run if the loader ran and threw an error + !state.errors || state.errors[route.id] === undefined); + } + // Always call the loader on new route instances and pending defer cancellations + if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) { + return true; + } + // This is the default implementation for when we revalidate. If the route + // provides it's own implementation, then we give them full control but + // provide this value so they can leverage it if needed after they check + // their own specific use cases + let currentRouteMatch = state.matches[index]; + let nextRouteMatch = match; + return shouldRevalidateLoader(match, _extends({ + currentUrl, + currentParams: currentRouteMatch.params, + nextUrl, + nextParams: nextRouteMatch.params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : + // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate + isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || + // Search params affect all loaders + currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch) + })); + }); + // Pick fetcher.loads that need to be revalidated + let revalidatingFetchers = []; + fetchLoadMatches.forEach((f, key) => { + // Don't revalidate: + // - on initial load (shouldn't be any fetchers then anyway) + // - if fetcher won't be present in the subsequent render + // - no longer matches the URL (v7_fetcherPersist=false) + // - was unmounted but persisted due to v7_fetcherPersist=true + if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) { + return; + } + let fetcherMatches = matchRoutes(routesToUse, f.path, basename); + // If the fetcher path no longer matches, push it in with null matches so + // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is + // currently only a use-case for Remix HMR where the route tree can change + // at runtime and remove a route previously loaded via a fetcher + if (!fetcherMatches) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: null, + match: null, + controller: null + }); + return; + } + // Revalidating fetchers are decoupled from the route matches since they + // load from a static href. They revalidate based on explicit revalidation + // (submission, useRevalidator, or X-Remix-Revalidate) + let fetcher = state.fetchers.get(key); + let fetcherMatch = getTargetMatch(fetcherMatches, f.path); + let shouldRevalidate = false; + if (fetchRedirectIds.has(key)) { + // Never trigger a revalidation of an actively redirecting fetcher + shouldRevalidate = false; + } else if (cancelledFetcherLoads.includes(key)) { + // Always revalidate if the fetcher was cancelled + shouldRevalidate = true; + } else if (fetcher && fetcher.state !== "idle" && fetcher.data === undefined) { + // If the fetcher hasn't ever completed loading yet, then this isn't a + // revalidation, it would just be a brand new load if an explicit + // revalidation is required + shouldRevalidate = isRevalidationRequired; + } else { + // Otherwise fall back on any user-defined shouldRevalidate, defaulting + // to explicit revalidations only + shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({ + currentUrl, + currentParams: state.matches[state.matches.length - 1].params, + nextUrl, + nextParams: matches[matches.length - 1].params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired + })); + } + if (shouldRevalidate) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: fetcherMatches, + match: fetcherMatch, + controller: new AbortController() + }); + } + }); + return [navigationMatches, revalidatingFetchers]; +} +function isNewLoader(currentLoaderData, currentMatch, match) { + let isNew = + // [a] -> [a, b] + !currentMatch || + // [a, b] -> [a, c] + match.route.id !== currentMatch.route.id; + // Handle the case that we don't have data for a re-used route, potentially + // from a prior error or from a cancelled pending deferred + let isMissingData = currentLoaderData[match.route.id] === undefined; + // Always load if this is a net-new route or we don't yet have data + return isNew || isMissingData; +} +function isNewRouteInstance(currentMatch, match) { + let currentPath = currentMatch.route.path; + return ( + // param change for this match, /users/123 -> /users/456 + currentMatch.pathname !== match.pathname || + // splat param changed, which is not present in match.path + // e.g. /files/images/avatar.jpg -> files/finances.xls + currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); +} +function shouldRevalidateLoader(loaderMatch, arg) { + if (loaderMatch.route.shouldRevalidate) { + let routeChoice = loaderMatch.route.shouldRevalidate(arg); + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + return arg.defaultShouldRevalidate; +} +/** + * Idempotent utility to execute patchRoutesOnMiss() to lazily load route + * definitions and update the routes/routeManifest + */ +async function loadLazyRouteChildren(patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) { + let key = [path, ...matches.map(m => m.route.id)].join("-"); + try { + let pending = pendingRouteChildren.get(key); + if (!pending) { + pending = patchRoutesOnMissImpl({ + path, + matches, + patch: (routeId, children) => { + if (!signal.aborted) { + patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties); + } + } + }); + pendingRouteChildren.set(key, pending); + } + if (pending && isPromise(pending)) { + await pending; + } + } finally { + pendingRouteChildren.delete(key); + } +} +function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) { + if (routeId) { + var _route$children; + let route = manifest[routeId]; + invariant(route, "No route found to patch children into: routeId = " + routeId); + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, [routeId, "patch", String(((_route$children = route.children) == null ? void 0 : _route$children.length) || "0")], manifest); + if (route.children) { + route.children.push(...dataChildren); + } else { + route.children = dataChildren; + } + } else { + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest); + routesToUse.push(...dataChildren); + } +} +/** + * Execute route.lazy() methods to lazily load route modules (loader, action, + * shouldRevalidate) and update the routeManifest in place which shares objects + * with dataRoutes so those get updated as well. + */ +async function loadLazyRouteModule(route, mapRouteProperties, manifest) { + if (!route.lazy) { + return; + } + let lazyRoute = await route.lazy(); + // If the lazy route function was executed and removed by another parallel + // call then we can return - first lazy() to finish wins because the return + // value of lazy is expected to be static + if (!route.lazy) { + return; + } + let routeToUpdate = manifest[route.id]; + invariant(routeToUpdate, "No route found in manifest"); + // Update the route in place. This should be safe because there's no way + // we could yet be sitting on this route as we can't get there without + // resolving lazy() first. + // + // This is different than the HMR "update" use-case where we may actively be + // on the route being updated. The main concern boils down to "does this + // mutation affect any ongoing navigations or any current state.matches + // values?". If not, it should be safe to update in place. + let routeUpdates = {}; + for (let lazyRouteProperty in lazyRoute) { + let staticRouteValue = routeToUpdate[lazyRouteProperty]; + let isPropertyStaticallyDefined = staticRouteValue !== undefined && + // This property isn't static since it should always be updated based + // on the route updates + lazyRouteProperty !== "hasErrorBoundary"; + warning(!isPropertyStaticallyDefined, "Route \"" + routeToUpdate.id + "\" has a static property \"" + lazyRouteProperty + "\" " + "defined but its lazy function is also returning a value for this property. " + ("The lazy route property \"" + lazyRouteProperty + "\" will be ignored.")); + if (!isPropertyStaticallyDefined && !immutableRouteKeys.has(lazyRouteProperty)) { + routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty]; + } + } + // Mutate the route with the provided updates. Do this first so we pass + // the updated version to mapRouteProperties + Object.assign(routeToUpdate, routeUpdates); + // Mutate the `hasErrorBoundary` property on the route based on the route + // updates and remove the `lazy` function so we don't resolve the lazy + // route again. + Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), { + lazy: undefined + })); +} +// Default implementation of `dataStrategy` which fetches all loaders in parallel +function defaultDataStrategy(opts) { + return Promise.all(opts.matches.map(m => m.resolve())); +} +async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext) { + let routeIdsToLoad = matchesToLoad.reduce((acc, m) => acc.add(m.route.id), new Set()); + let loadedMatches = new Set(); + // Send all matches here to allow for a middleware-type implementation. + // handler will be a no-op for unneeded routes and we filter those results + // back out below. + let results = await dataStrategyImpl({ + matches: matches.map(match => { + let shouldLoad = routeIdsToLoad.has(match.route.id); + // `resolve` encapsulates the route.lazy, executing the + // loader/action, and mapping return values/thrown errors to a + // HandlerResult. Users can pass a callback to take fine-grained control + // over the execution of the loader/action + let resolve = handlerOverride => { + loadedMatches.add(match.route.id); + return shouldLoad ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, requestContext) : Promise.resolve({ + type: ResultType.data, + result: undefined + }); + }; + return _extends({}, match, { + shouldLoad, + resolve + }); + }), + request, + params: matches[0].params, + context: requestContext + }); + // Throw if any loadRoute implementations not called since they are what + // ensures a route is fully loaded + matches.forEach(m => invariant(loadedMatches.has(m.route.id), "`match.resolve()` was not called for route id \"" + m.route.id + "\". " + "You must call `match.resolve()` on every match passed to " + "`dataStrategy` to ensure all routes are properly loaded.")); + // Filter out any middleware-only matches for which we didn't need to run handlers + return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id)); +} +// Default logic for calling a loader/action is the user has no specified a dataStrategy +async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, staticContext) { + let result; + let onReject; + let runHandler = handler => { + // Setup a promise we can race against so that abort signals short circuit + let reject; + // This will never resolve so safe to type it as Promise to + // satisfy the function return value + let abortPromise = new Promise((_, r) => reject = r); + onReject = () => reject(); + request.signal.addEventListener("abort", onReject); + let actualHandler = ctx => { + if (typeof handler !== "function") { + return Promise.reject(new Error("You cannot call the handler for a route which defines a boolean " + ("\"" + type + "\" [routeId: " + match.route.id + "]"))); + } + return handler({ + request, + params: match.params, + context: staticContext + }, ...(ctx !== undefined ? [ctx] : [])); + }; + let handlerPromise; + if (handlerOverride) { + handlerPromise = handlerOverride(ctx => actualHandler(ctx)); + } else { + handlerPromise = (async () => { + try { + let val = await actualHandler(); + return { + type: "data", + result: val + }; + } catch (e) { + return { + type: "error", + result: e + }; + } + })(); + } + return Promise.race([handlerPromise, abortPromise]); + }; + try { + let handler = match.route[type]; + if (match.route.lazy) { + if (handler) { + // Run statically defined handler in parallel with lazy() + let handlerError; + let [value] = await Promise.all([ + // If the handler throws, don't let it immediately bubble out, + // since we need to let the lazy() execution finish so we know if this + // route has a boundary that can handle the error + runHandler(handler).catch(e => { + handlerError = e; + }), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]); + if (handlerError !== undefined) { + throw handlerError; + } + result = value; + } else { + // Load lazy route module, then run any returned handler + await loadLazyRouteModule(match.route, mapRouteProperties, manifest); + handler = match.route[type]; + if (handler) { + // Handler still runs even if we got interrupted to maintain consistency + // with un-abortable behavior of handler execution on non-lazy or + // previously-lazy-loaded routes + result = await runHandler(handler); + } else if (type === "action") { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(405, { + method: request.method, + pathname, + routeId: match.route.id + }); + } else { + // lazy() route has no loader to run. Short circuit here so we don't + // hit the invariant below that errors on returning undefined. + return { + type: ResultType.data, + result: undefined + }; + } + } + } else if (!handler) { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(404, { + pathname + }); + } else { + result = await runHandler(handler); + } + invariant(result.result !== undefined, "You defined " + (type === "action" ? "an action" : "a loader") + " for route " + ("\"" + match.route.id + "\" but didn't return anything from your `" + type + "` ") + "function. Please return a value or `null`."); + } catch (e) { + // We should already be catching and converting normal handler executions to + // HandlerResults and returning them, so anything that throws here is an + // unexpected error we still need to wrap + return { + type: ResultType.error, + result: e + }; + } finally { + if (onReject) { + request.signal.removeEventListener("abort", onReject); + } + } + return result; +} +async function convertHandlerResultToDataResult(handlerResult) { + let { + result, + type, + status + } = handlerResult; + if (isResponse(result)) { + let data; + try { + let contentType = result.headers.get("Content-Type"); + // Check between word boundaries instead of startsWith() due to the last + // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type + if (contentType && /\bapplication\/json\b/.test(contentType)) { + if (result.body == null) { + data = null; + } else { + data = await result.json(); + } + } else { + data = await result.text(); + } + } catch (e) { + return { + type: ResultType.error, + error: e + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: new ErrorResponseImpl(result.status, result.statusText, data), + statusCode: result.status, + headers: result.headers + }; + } + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: result, + statusCode: isRouteErrorResponse(result) ? result.status : status + }; + } + if (isDeferredData(result)) { + var _result$init, _result$init2; + return { + type: ResultType.deferred, + deferredData: result, + statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status, + headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers) + }; + } + return { + type: ResultType.data, + data: result, + statusCode: status + }; +} +// Support relative routing in internal redirects +function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, v7_relativeSplatPath) { + let location = response.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + if (!ABSOLUTE_URL_REGEX.test(location)) { + let trimmedMatches = matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1); + location = normalizeTo(new URL(request.url), trimmedMatches, basename, true, location, v7_relativeSplatPath); + response.headers.set("Location", location); + } + return response; +} +function normalizeRedirectLocation(location, currentUrl, basename) { + if (ABSOLUTE_URL_REGEX.test(location)) { + // Strip off the protocol+origin for same-origin + same-basename absolute redirects + let normalizedLocation = location; + let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation); + let isSameBasename = stripBasename(url.pathname, basename) != null; + if (url.origin === currentUrl.origin && isSameBasename) { + return url.pathname + url.search + url.hash; + } + } + return location; +} +// Utility method for creating the Request instances for loaders/actions during +// client-side navigations and fetches. During SSR we will always have a +// Request instance from the static handler (query/queryRoute) +function createClientSideRequest(history, location, signal, submission) { + let url = history.createURL(stripHashFromPath(location)).toString(); + let init = { + signal + }; + if (submission && isMutationMethod(submission.formMethod)) { + let { + formMethod, + formEncType + } = submission; + // Didn't think we needed this but it turns out unlike other methods, patch + // won't be properly normalized to uppercase and results in a 405 error. + // See: https://fetch.spec.whatwg.org/#concept-method + init.method = formMethod.toUpperCase(); + if (formEncType === "application/json") { + init.headers = new Headers({ + "Content-Type": formEncType + }); + init.body = JSON.stringify(submission.json); + } else if (formEncType === "text/plain") { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.text; + } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = convertFormDataToSearchParams(submission.formData); + } else { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.formData; + } + } + return new Request(url, init); +} +function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + for (let [key, value] of formData.entries()) { + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs + searchParams.append(key, typeof value === "string" ? value : value.name); + } + return searchParams; +} +function convertSearchParamsToFormData(searchParams) { + let formData = new FormData(); + for (let [key, value] of searchParams.entries()) { + formData.append(key, value); + } + return formData; +} +function processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; + let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined; + // Process loader results into state.loaderData/state.errors + results.forEach((result, index) => { + let id = matchesToLoad[index].route.id; + invariant(!isRedirectResult(result), "Cannot handle redirect results in processLoaderData"); + if (isErrorResult(result)) { + let error = result.error; + // If we have a pending action error, we report it at the highest-route + // that throws a loader error, and then clear it out to indicate that + // it was consumed + if (pendingError !== undefined) { + error = pendingError; + pendingError = undefined; + } + errors = errors || {}; + if (skipLoaderErrorBubbling) { + errors[id] = error; + } else { + // Look upwards from the matched route for the closest ancestor error + // boundary, defaulting to the root match. Prefer higher error values + // if lower errors bubble to the same boundary + let boundaryMatch = findNearestBoundary(matches, id); + if (errors[boundaryMatch.route.id] == null) { + errors[boundaryMatch.route.id] = error; + } + } + // Clear our any prior loaderData for the throwing route + loaderData[id] = undefined; + // Once we find our first (highest) error, we set the status code and + // prevent deeper status codes from overriding + if (!foundError) { + foundError = true; + statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + if (isDeferredResult(result)) { + activeDeferreds.set(id, result.deferredData); + loaderData[id] = result.deferredData.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode != null && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + loaderData[id] = result.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } + } + }); + // If we didn't consume the pending action error (i.e., all loaders + // resolved), then consume it here. Also clear out any loaderData for the + // throwing route + if (pendingError !== undefined && pendingActionResult) { + errors = { + [pendingActionResult[0]]: pendingError + }; + loaderData[pendingActionResult[0]] = undefined; + } + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; +} +function processLoaderData(state, matches, matchesToLoad, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble + ); + // Process results from our revalidating fetchers + for (let index = 0; index < revalidatingFetchers.length; index++) { + let { + key, + match, + controller + } = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; + // Process fetcher non-redirect errors + if (controller && controller.signal.aborted) { + // Nothing to do for aborted fetchers + continue; + } else if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id); + if (!(errors && errors[boundaryMatch.route.id])) { + errors = _extends({}, errors, { + [boundaryMatch.route.id]: result.error + }); + } + state.fetchers.delete(key); + } else if (isRedirectResult(result)) { + // Should never get here, redirects should get processed above, but we + // keep this to type narrow to a success result in the else + invariant(false, "Unhandled fetcher revalidation redirect"); + } else if (isDeferredResult(result)) { + // Should never get here, deferred data should be awaited for fetchers + // in resolveDeferredResults + invariant(false, "Unhandled fetcher deferred data"); + } else { + let doneFetcher = getDoneFetcher(result.data); + state.fetchers.set(key, doneFetcher); + } + } + return { + loaderData, + errors + }; +} +function mergeLoaderData(loaderData, newLoaderData, matches, errors) { + let mergedLoaderData = _extends({}, newLoaderData); + for (let match of matches) { + let id = match.route.id; + if (newLoaderData.hasOwnProperty(id)) { + if (newLoaderData[id] !== undefined) { + mergedLoaderData[id] = newLoaderData[id]; + } + } else if (loaderData[id] !== undefined && match.route.loader) { + // Preserve existing keys not included in newLoaderData and where a loader + // wasn't removed by HMR + mergedLoaderData[id] = loaderData[id]; + } + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + return mergedLoaderData; +} +function getActionDataForCommit(pendingActionResult) { + if (!pendingActionResult) { + return {}; + } + return isErrorResult(pendingActionResult[1]) ? { + // Clear out prior actionData on errors + actionData: {} + } : { + actionData: { + [pendingActionResult[0]]: pendingActionResult[1].data + } + }; +} +// Find the nearest error boundary, looking upwards from the leaf route (or the +// route specified by routeId) for the closest ancestor error boundary, +// defaulting to the root match +function findNearestBoundary(matches, routeId) { + let eligibleMatches = routeId ? matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1) : [...matches]; + return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0]; +} +function getShortCircuitMatches(routes) { + // Prefer a root layout route if present, otherwise shim in a route object + let route = routes.length === 1 ? routes[0] : routes.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; +} +function getInternalRouterError(status, _temp5) { + let { + pathname, + routeId, + method, + type, + message + } = _temp5 === void 0 ? {} : _temp5; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + if (status === 400) { + statusText = "Bad Request"; + if (type === "route-discovery") { + errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnMiss()` " + ("function threw the following error:\n" + message); + } else if (method && pathname && routeId) { + errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (type === "defer-action") { + errorMessage = "defer() is not supported in actions"; + } else if (type === "invalid-body") { + errorMessage = "Unable to encode submission body"; + } + } else if (status === 403) { + statusText = "Forbidden"; + errorMessage = "Route \"" + routeId + "\" does not match URL \"" + pathname + "\""; + } else if (status === 404) { + statusText = "Not Found"; + errorMessage = "No route matches URL \"" + pathname + "\""; + } else if (status === 405) { + statusText = "Method Not Allowed"; + if (method && pathname && routeId) { + errorMessage = "You made a " + method.toUpperCase() + " request to \"" + pathname + "\" but " + ("did not provide an `action` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (method) { + errorMessage = "Invalid request method \"" + method.toUpperCase() + "\""; + } + } + return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true); +} +// Find any returned redirect errors, starting from the lowest match +function findRedirect(results) { + for (let i = results.length - 1; i >= 0; i--) { + let result = results[i]; + if (isRedirectResult(result)) { + return { + result, + idx: i + }; + } + } +} +function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); +} +function isHashChangeOnly(a, b) { + if (a.pathname !== b.pathname || a.search !== b.search) { + return false; + } + if (a.hash === "") { + // /page -> /page#hash + return b.hash !== ""; + } else if (a.hash === b.hash) { + // /page#hash -> /page#hash + return true; + } else if (b.hash !== "") { + // /page#hash -> /page#other + return true; + } + // If the hash is removed the browser will re-perform a request to the server + // /page#hash -> /page + return false; +} +function isPromise(val) { + return typeof val === "object" && val != null && "then" in val; +} +function isHandlerResult(result) { + return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error); +} +function isRedirectHandlerResult(result) { + return isResponse(result.result) && redirectStatusCodes.has(result.result.status); +} +function isDeferredResult(result) { + return result.type === ResultType.deferred; +} +function isErrorResult(result) { + return result.type === ResultType.error; +} +function isRedirectResult(result) { + return (result && result.type) === ResultType.redirect; +} +function isDeferredData(value) { + let deferred = value; + return deferred && typeof deferred === "object" && typeof deferred.data === "object" && typeof deferred.subscribe === "function" && typeof deferred.cancel === "function" && typeof deferred.resolveData === "function"; +} +function isResponse(value) { + return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined"; +} +function isRedirectResponse(result) { + if (!isResponse(result)) { + return false; + } + let status = result.status; + let location = result.headers.get("Location"); + return status >= 300 && status <= 399 && location != null; +} +function isValidMethod(method) { + return validRequestMethods.has(method.toLowerCase()); +} +function isMutationMethod(method) { + return validMutationMethods.has(method.toLowerCase()); +} +async function resolveDeferredResults(currentMatches, matchesToLoad, results, signals, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + // If we don't have a match, then we can have a deferred result to do + // anything with. This is for revalidating fetchers where the route was + // removed during HMR + if (!match) { + continue; + } + let currentMatch = currentMatches.find(m => m.route.id === match.route.id); + let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined; + if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) { + // Note: we do not have to touch activeDeferreds here since we race them + // against the signal in resolveDeferredData and they'll get aborted + // there if needed + let signal = signals[index]; + invariant(signal, "Expected an AbortSignal for revalidating fetcher deferred result"); + await resolveDeferredData(result, signal, isFetcher).then(result => { + if (result) { + results[index] = result || results[index]; + } + }); + } + } +} +async function resolveDeferredData(result, signal, unwrap) { + if (unwrap === void 0) { + unwrap = false; + } + let aborted = await result.deferredData.resolveData(signal); + if (aborted) { + return; + } + if (unwrap) { + try { + return { + type: ResultType.data, + data: result.deferredData.unwrappedData + }; + } catch (e) { + // Handle any TrackedPromise._error values encountered while unwrapping + return { + type: ResultType.error, + error: e + }; + } + } + return { + type: ResultType.data, + data: result.deferredData.data + }; +} +function hasNakedIndexQuery(search) { + return new URLSearchParams(search).getAll("index").some(v => v === ""); +} +function getTargetMatch(matches, location) { + let search = typeof location === "string" ? parsePath(location).search : location.search; + if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) { + // Return the leaf index route when index is present + return matches[matches.length - 1]; + } + // Otherwise grab the deepest "path contributing" match (ignoring index and + // pathless layout routes) + let pathMatches = getPathContributingMatches(matches); + return pathMatches[pathMatches.length - 1]; +} +function getSubmissionFromNavigation(navigation) { + let { + formMethod, + formAction, + formEncType, + text, + formData, + json + } = navigation; + if (!formMethod || !formAction || !formEncType) { + return; + } + if (text != null) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json: undefined, + text + }; + } else if (formData != null) { + return { + formMethod, + formAction, + formEncType, + formData, + json: undefined, + text: undefined + }; + } else if (json !== undefined) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json, + text: undefined + }; + } +} +function getLoadingNavigation(location, submission) { + if (submission) { + let navigation = { + state: "loading", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; + } else { + let navigation = { + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined + }; + return navigation; + } +} +function getSubmittingNavigation(location, submission) { + let navigation = { + state: "submitting", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; +} +function getLoadingFetcher(submission, data) { + if (submission) { + let fetcher = { + state: "loading", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data + }; + return fetcher; + } else { + let fetcher = { + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; + } +} +function getSubmittingFetcher(submission, existingFetcher) { + let fetcher = { + state: "submitting", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data: existingFetcher ? existingFetcher.data : undefined + }; + return fetcher; +} +function getDoneFetcher(data) { + let fetcher = { + state: "idle", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; +} +function restoreAppliedTransitions(_window, transitions) { + try { + let sessionPositions = _window.sessionStorage.getItem(TRANSITIONS_STORAGE_KEY); + if (sessionPositions) { + let json = JSON.parse(sessionPositions); + for (let [k, v] of Object.entries(json || {})) { + if (v && Array.isArray(v)) { + transitions.set(k, new Set(v || [])); + } + } + } + } catch (e) { + // no-op, use default empty object + } +} +function persistAppliedTransitions(_window, transitions) { + if (transitions.size > 0) { + let json = {}; + for (let [k, v] of transitions) { + json[k] = [...v]; + } + try { + _window.sessionStorage.setItem(TRANSITIONS_STORAGE_KEY, JSON.stringify(json)); + } catch (error) { + warning(false, "Failed to save applied view transitions in sessionStorage (" + error + ")."); + } + } +} +//#endregion + +export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, decodePath as UNSAFE_decodePath, getResolveToMatches as UNSAFE_getResolveToMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, resolvePath, resolveTo, stripBasename }; +//# sourceMappingURL=router.js.map diff --git a/node_modules/@remix-run/router/dist/router.js.map b/node_modules/@remix-run/router/dist/router.js.map new file mode 100644 index 0000000000..83249d3b88 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.js.map @@ -0,0 +1 @@ +{"version":3,"file":"router.js","sources":["../history.ts","../utils.ts","../router.ts"],"sourcesContent":["////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Actions represent the type of change to a location value.\n */\nexport enum Action {\n /**\n * A POP indicates a change to an arbitrary index in the history stack, such\n * as a back or forward navigation. It does not describe the direction of the\n * navigation, only that the current index changed.\n *\n * Note: This is the default action for newly created history objects.\n */\n Pop = \"POP\",\n\n /**\n * A PUSH indicates a new entry being added to the history stack, such as when\n * a link is clicked and a new page loads. When this happens, all subsequent\n * entries in the stack are lost.\n */\n Push = \"PUSH\",\n\n /**\n * A REPLACE indicates the entry at the current index in the history stack\n * being replaced by a new one.\n */\n Replace = \"REPLACE\",\n}\n\n/**\n * The pathname, search, and hash values of a URL.\n */\nexport interface Path {\n /**\n * A URL pathname, beginning with a /.\n */\n pathname: string;\n\n /**\n * A URL search string, beginning with a ?.\n */\n search: string;\n\n /**\n * A URL fragment identifier, beginning with a #.\n */\n hash: string;\n}\n\n// TODO: (v7) Change the Location generic default from `any` to `unknown` and\n// remove Remix `useLocation` wrapper.\n\n/**\n * An entry in a history stack. A location contains information about the\n * URL path, as well as possibly some arbitrary state and a key.\n */\nexport interface Location extends Path {\n /**\n * A value of arbitrary data associated with this location.\n */\n state: State;\n\n /**\n * A unique string associated with this location. May be used to safely store\n * and retrieve data in some other storage API, like `localStorage`.\n *\n * Note: This value is always \"default\" on the initial location.\n */\n key: string;\n}\n\n/**\n * A change to the current location.\n */\nexport interface Update {\n /**\n * The action that triggered the change.\n */\n action: Action;\n\n /**\n * The new location.\n */\n location: Location;\n\n /**\n * The delta between this location and the former location in the history stack\n */\n delta: number | null;\n}\n\n/**\n * A function that receives notifications about location changes.\n */\nexport interface Listener {\n (update: Update): void;\n}\n\n/**\n * Describes a location that is the destination of some navigation, either via\n * `history.push` or `history.replace`. This may be either a URL or the pieces\n * of a URL path.\n */\nexport type To = string | Partial;\n\n/**\n * A history is an interface to the navigation stack. The history serves as the\n * source of truth for the current location, as well as provides a set of\n * methods that may be used to change it.\n *\n * It is similar to the DOM's `window.history` object, but with a smaller, more\n * focused API.\n */\nexport interface History {\n /**\n * The last action that modified the current location. This will always be\n * Action.Pop when a history instance is first created. This value is mutable.\n */\n readonly action: Action;\n\n /**\n * The current location. This value is mutable.\n */\n readonly location: Location;\n\n /**\n * Returns a valid href for the given `to` value that may be used as\n * the value of an attribute.\n *\n * @param to - The destination URL\n */\n createHref(to: To): string;\n\n /**\n * Returns a URL for the given `to` value\n *\n * @param to - The destination URL\n */\n createURL(to: To): URL;\n\n /**\n * Encode a location the same way window.history would do (no-op for memory\n * history) so we ensure our PUSH/REPLACE navigations for data routers\n * behave the same as POP\n *\n * @param to Unencoded path\n */\n encodeLocation(to: To): Path;\n\n /**\n * Pushes a new location onto the history stack, increasing its length by one.\n * If there were any entries in the stack after the current one, they are\n * lost.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n push(to: To, state?: any): void;\n\n /**\n * Replaces the current location in the history stack with a new one. The\n * location that was replaced will no longer be available.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n replace(to: To, state?: any): void;\n\n /**\n * Navigates `n` entries backward/forward in the history stack relative to the\n * current index. For example, a \"back\" navigation would use go(-1).\n *\n * @param delta - The delta in the stack index\n */\n go(delta: number): void;\n\n /**\n * Sets up a listener that will be called whenever the current location\n * changes.\n *\n * @param listener - A function that will be called when the location changes\n * @returns unlisten - A function that may be used to stop listening\n */\n listen(listener: Listener): () => void;\n}\n\ntype HistoryState = {\n usr: any;\n key?: string;\n idx: number;\n};\n\nconst PopStateEventType = \"popstate\";\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Memory History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A user-supplied object that describes a location. Used when providing\n * entries to `createMemoryHistory` via its `initialEntries` option.\n */\nexport type InitialEntry = string | Partial;\n\nexport type MemoryHistoryOptions = {\n initialEntries?: InitialEntry[];\n initialIndex?: number;\n v5Compat?: boolean;\n};\n\n/**\n * A memory history stores locations in memory. This is useful in stateful\n * environments where there is no web browser, such as node tests or React\n * Native.\n */\nexport interface MemoryHistory extends History {\n /**\n * The current index in the history stack.\n */\n readonly index: number;\n}\n\n/**\n * Memory history stores the current location in memory. It is designed for use\n * in stateful non-browser environments like tests and React Native.\n */\nexport function createMemoryHistory(\n options: MemoryHistoryOptions = {}\n): MemoryHistory {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries: Location[]; // Declare so we can access from createMemoryLocation\n entries = initialEntries.map((entry, index) =>\n createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index === 0 ? \"default\" : undefined\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n function clampIndex(n: number): number {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation(): Location {\n return entries[index];\n }\n function createMemoryLocation(\n to: To,\n state: any = null,\n key?: string\n ): Location {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n\n function createHref(to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n let history: MemoryHistory = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref,\n createURL(to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation(to: To) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\",\n };\n },\n push(to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn: Listener) {\n listener = fn;\n return () => {\n listener = null;\n };\n },\n };\n\n return history;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Browser History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A browser history stores the current location in regular URLs in a web\n * browser environment. This is the standard for most web apps and provides the\n * cleanest URLs the browser's address bar.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory\n */\nexport interface BrowserHistory extends UrlHistory {}\n\nexport type BrowserHistoryOptions = UrlHistoryOptions;\n\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */\nexport function createBrowserHistory(\n options: BrowserHistoryOptions = {}\n): BrowserHistory {\n function createBrowserLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let { pathname, search, hash } = window.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createBrowserHref(window: Window, to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Hash History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A hash history stores the current location in the fragment identifier portion\n * of the URL in a web browser environment.\n *\n * This is ideal for apps that do not control the server for some reason\n * (because the fragment identifier is never sent to the server), including some\n * shared hosting environments that do not provide fine-grained controls over\n * which pages are served at which URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory\n */\nexport interface HashHistory extends UrlHistory {}\n\nexport type HashHistoryOptions = UrlHistoryOptions;\n\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */\nexport function createHashHistory(\n options: HashHistoryOptions = {}\n): HashHistory {\n function createHashLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n } = parsePath(window.location.hash.substr(1));\n\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route () since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createHashHref(window: Window, to: To) {\n let base = window.document.querySelector(\"base\");\n let href = \"\";\n\n if (base && base.getAttribute(\"href\")) {\n let url = window.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n\n function validateHashLocation(location: Location, to: To) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region UTILS\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @private\n */\nexport function invariant(value: boolean, message?: string): asserts value;\nexport function invariant(\n value: T | null | undefined,\n message?: string\n): asserts value is T;\nexport function invariant(value: any, message?: string) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\n\nexport function warning(cond: any, message: string) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience, so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\n\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n\n/**\n * For browser-based histories, we combine the state and key into an object\n */\nfunction getHistoryState(location: Location, index: number): HistoryState {\n return {\n usr: location.state,\n key: location.key,\n idx: index,\n };\n}\n\n/**\n * Creates a Location object with a unique key from the given Path\n */\nexport function createLocation(\n current: string | Location,\n to: To,\n state: any = null,\n key?: string\n): Readonly {\n let location: Readonly = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...(typeof to === \"string\" ? parsePath(to) : to),\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: (to && (to as Location).key) || key || createKey(),\n };\n return location;\n}\n\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */\nexport function createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n}: Partial) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */\nexport function parsePath(path: string): Partial {\n let parsedPath: Partial = {};\n\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n\n if (path) {\n parsedPath.pathname = path;\n }\n }\n\n return parsedPath;\n}\n\nexport interface UrlHistory extends History {}\n\nexport type UrlHistoryOptions = {\n window?: Window;\n v5Compat?: boolean;\n};\n\nfunction getUrlBasedHistory(\n getLocation: (window: Window, globalHistory: Window[\"history\"]) => Location,\n createHref: (window: Window, to: To) => string,\n validateLocation: ((location: Location, to: To) => void) | null,\n options: UrlHistoryOptions = {}\n): UrlHistory {\n let { window = document.defaultView!, v5Compat = false } = options;\n let globalHistory = window.history;\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n let index = getIndex()!;\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n\n function getIndex(): number {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n\n function push(to: To, state?: any) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window.location.assign(url);\n }\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n\n function replace(to: To, state?: any) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n\n function createURL(to: To): URL {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base =\n window.location.origin !== \"null\"\n ? window.location.origin\n : window.location.href;\n\n let href = typeof to === \"string\" ? to : createPath(to);\n // Treating this as a full URL will strip any trailing spaces so we need to\n // pre-encode them since they might be part of a matching splat param from\n // an ancestor route\n href = href.replace(/ $/, \"%20\");\n invariant(\n base,\n `No window.location.(origin|href) available to create URL for href: ${href}`\n );\n return new URL(href, base);\n }\n\n let history: History = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window, globalHistory);\n },\n listen(fn: Listener) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n\n return () => {\n window.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref(window, to);\n },\n createURL,\n encodeLocation(to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n },\n push,\n replace,\n go(n) {\n return globalHistory.go(n);\n },\n };\n\n return history;\n}\n\n//#endregion\n","import type { Location, Path, To } from \"./history\";\nimport { invariant, parsePath, warning } from \"./history\";\n\n/**\n * Map of routeId -> data returned from a loader/action/error\n */\nexport interface RouteData {\n [routeId: string]: any;\n}\n\nexport enum ResultType {\n data = \"data\",\n deferred = \"deferred\",\n redirect = \"redirect\",\n error = \"error\",\n}\n\n/**\n * Successful result from a loader or action\n */\nexport interface SuccessResult {\n type: ResultType.data;\n data: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Successful defer() result from a loader or action\n */\nexport interface DeferredResult {\n type: ResultType.deferred;\n deferredData: DeferredData;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Redirect result from a loader or action\n */\nexport interface RedirectResult {\n type: ResultType.redirect;\n // We keep the raw Response for redirects so we can return it verbatim\n response: Response;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Result from a loader or action - potentially successful or unsuccessful\n */\nexport type DataResult =\n | SuccessResult\n | DeferredResult\n | RedirectResult\n | ErrorResult;\n\n/**\n * Result from a loader or action called via dataStrategy\n */\nexport interface HandlerResult {\n type: \"data\" | \"error\";\n result: unknown; // data, Error, Response, DeferredData\n status?: number;\n}\n\ntype LowerCaseFormMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\ntype UpperCaseFormMethod = Uppercase;\n\n/**\n * Users can specify either lowercase or uppercase form methods on ``,\n * useSubmit(), ``, etc.\n */\nexport type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;\n\n/**\n * Active navigation/fetcher form methods are exposed in lowercase on the\n * RouterState\n */\nexport type FormMethod = LowerCaseFormMethod;\nexport type MutationFormMethod = Exclude;\n\n/**\n * In v7, active navigation/fetcher form methods are exposed in uppercase on the\n * RouterState. This is to align with the normalization done via fetch().\n */\nexport type V7_FormMethod = UpperCaseFormMethod;\nexport type V7_MutationFormMethod = Exclude;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\"\n | \"application/json\"\n | \"text/plain\";\n\n// Thanks https://github.com/sindresorhus/type-fest!\ntype JsonObject = { [Key in string]: JsonValue } & {\n [Key in string]?: JsonValue | undefined;\n};\ntype JsonArray = JsonValue[] | readonly JsonValue[];\ntype JsonPrimitive = string | number | boolean | null;\ntype JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport type Submission =\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n json: undefined;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: JsonValue;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: undefined;\n text: string;\n };\n\n/**\n * @private\n * Arguments passed to route loader/action functions. Same for now but we keep\n * this as a private implementation detail in case they diverge in the future.\n */\ninterface DataFunctionArgs {\n request: Request;\n params: Params;\n context?: Context;\n}\n\n// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:\n// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs\n// Also, make them a type alias instead of an interface\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Loaders and actions can return anything except `undefined` (`null` is a\n * valid return value if there is no data to return). Responses are preferred\n * and will ease any future migration to Remix\n */\ntype DataFunctionValue = Response | NonNullable | null;\n\ntype DataFunctionReturnValue = Promise | DataFunctionValue;\n\n/**\n * Route loader function signature\n */\nexport type LoaderFunction = {\n (\n args: LoaderFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n} & { hydrate?: boolean };\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (\n args: ActionFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n}\n\n/**\n * Arguments passed to shouldRevalidate function\n */\nexport interface ShouldRevalidateFunctionArgs {\n currentUrl: URL;\n currentParams: AgnosticDataRouteMatch[\"params\"];\n nextUrl: URL;\n nextParams: AgnosticDataRouteMatch[\"params\"];\n formMethod?: Submission[\"formMethod\"];\n formAction?: Submission[\"formAction\"];\n formEncType?: Submission[\"formEncType\"];\n text?: Submission[\"text\"];\n formData?: Submission[\"formData\"];\n json?: Submission[\"json\"];\n actionStatus?: number;\n actionResult?: any;\n defaultShouldRevalidate: boolean;\n}\n\n/**\n * Route shouldRevalidate function signature. This runs after any submission\n * (navigation or fetcher), so we flatten the navigation/fetcher submission\n * onto the arguments. It shouldn't matter whether it came from a navigation\n * or a fetcher, what really matters is the URLs and the formData since loaders\n * have to re-run based on the data models that were potentially mutated.\n */\nexport interface ShouldRevalidateFunction {\n (args: ShouldRevalidateFunctionArgs): boolean;\n}\n\n/**\n * Function provided by the framework-aware layers to set `hasErrorBoundary`\n * from the framework-aware `errorElement` prop\n *\n * @deprecated Use `mapRouteProperties` instead\n */\nexport interface DetectErrorBoundaryFunction {\n (route: AgnosticRouteObject): boolean;\n}\n\nexport interface DataStrategyMatch\n extends AgnosticRouteMatch {\n shouldLoad: boolean;\n resolve: (\n handlerOverride?: (\n handler: (ctx?: unknown) => DataFunctionReturnValue\n ) => Promise\n ) => Promise;\n}\n\nexport interface DataStrategyFunctionArgs\n extends DataFunctionArgs {\n matches: DataStrategyMatch[];\n}\n\nexport interface DataStrategyFunction {\n (args: DataStrategyFunctionArgs): Promise;\n}\n\nexport interface AgnosticPatchRoutesOnMissFunction<\n M extends AgnosticRouteMatch = AgnosticRouteMatch\n> {\n (opts: {\n path: string;\n matches: M[];\n patch: (routeId: string | null, children: AgnosticRouteObject[]) => void;\n }): void | Promise;\n}\n\n/**\n * Function provided by the framework-aware layers to set any framework-specific\n * properties from framework-agnostic properties\n */\nexport interface MapRoutePropertiesFunction {\n (route: AgnosticRouteObject): {\n hasErrorBoundary: boolean;\n } & Record;\n}\n\n/**\n * Keys we cannot change from within a lazy() function. We spread all other keys\n * onto the route. Either they're meaningful to the router, or they'll get\n * ignored.\n */\nexport type ImmutableRouteKey =\n | \"lazy\"\n | \"caseSensitive\"\n | \"path\"\n | \"id\"\n | \"index\"\n | \"children\";\n\nexport const immutableRouteKeys = new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\",\n]);\n\ntype RequireOne = Exclude<\n {\n [K in keyof T]: K extends Key ? Omit & Required> : never;\n }[keyof T],\n undefined\n>;\n\n/**\n * lazy() function to load a route definition, which can add non-matching\n * related properties to a route\n */\nexport interface LazyRouteFunction {\n (): Promise>>;\n}\n\n/**\n * Base RouteObject with common props shared by all types of routes\n */\ntype AgnosticBaseRouteObject = {\n caseSensitive?: boolean;\n path?: string;\n id?: string;\n loader?: LoaderFunction | boolean;\n action?: ActionFunction | boolean;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\n lazy?: LazyRouteFunction;\n};\n\n/**\n * Index routes must not have children\n */\nexport type AgnosticIndexRouteObject = AgnosticBaseRouteObject & {\n children?: undefined;\n index: true;\n};\n\n/**\n * Non-index routes may have children, but cannot have index\n */\nexport type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & {\n children?: AgnosticRouteObject[];\n index?: false;\n};\n\n/**\n * A route object represents a logical route, with (optionally) its child\n * routes organized in a tree-like structure.\n */\nexport type AgnosticRouteObject =\n | AgnosticIndexRouteObject\n | AgnosticNonIndexRouteObject;\n\nexport type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & {\n id: string;\n};\n\nexport type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & {\n children?: AgnosticDataRouteObject[];\n id: string;\n};\n\n/**\n * A data route object, which is just a RouteObject with a required unique ID\n */\nexport type AgnosticDataRouteObject =\n | AgnosticDataIndexRouteObject\n | AgnosticDataNonIndexRouteObject;\n\nexport type RouteManifest = Record;\n\n// Recursive helper for finding path parameters in the absence of wildcards\ntype _PathParam =\n // split path into individual path segments\n Path extends `${infer L}/${infer R}`\n ? _PathParam | _PathParam\n : // find params after `:`\n Path extends `:${infer Param}`\n ? Param extends `${infer Optional}?`\n ? Optional\n : Param\n : // otherwise, there aren't any params present\n never;\n\n/**\n * Examples:\n * \"/a/b/*\" -> \"*\"\n * \":a\" -> \"a\"\n * \"/a/:b\" -> \"b\"\n * \"/a/blahblahblah:b\" -> \"b\"\n * \"/:a/:b\" -> \"a\" | \"b\"\n * \"/:a/b/:c/*\" -> \"a\" | \"c\" | \"*\"\n */\nexport type PathParam =\n // check if path is just a wildcard\n Path extends \"*\" | \"/*\"\n ? \"*\"\n : // look for wildcard at the end of the path\n Path extends `${infer Rest}/*`\n ? \"*\" | _PathParam\n : // look for params in the absence of wildcards\n _PathParam;\n\n// Attempt to parse the given string segment. If it fails, then just return the\n// plain string type as a default fallback. Otherwise, return the union of the\n// parsed string literals that were referenced as dynamic segments in the route.\nexport type ParamParseKey =\n // if you could not find path params, fallback to `string`\n [PathParam] extends [never] ? string : PathParam;\n\n/**\n * The parameters that were parsed from the URL path.\n */\nexport type Params = {\n readonly [key in Key]: string | undefined;\n};\n\n/**\n * A RouteMatch contains info about how a route matched a URL.\n */\nexport interface AgnosticRouteMatch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObjectType;\n}\n\nexport interface AgnosticDataRouteMatch\n extends AgnosticRouteMatch {}\n\nfunction isIndexRoute(\n route: AgnosticRouteObject\n): route is AgnosticIndexRouteObject {\n return route.index === true;\n}\n\n// Walk the route tree generating unique IDs where necessary, so we are working\n// solely with AgnosticDataRouteObject's within the Router\nexport function convertRoutesToDataRoutes(\n routes: AgnosticRouteObject[],\n mapRouteProperties: MapRoutePropertiesFunction,\n parentPath: string[] = [],\n manifest: RouteManifest = {}\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n !manifest[id],\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n };\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n children: undefined,\n };\n manifest[id] = pathOrLayoutRoute;\n\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties,\n treePath,\n manifest\n );\n }\n\n return pathOrLayoutRoute;\n }\n });\n}\n\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/utils/match-routes\n */\nexport function matchRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename = \"/\"\n): AgnosticRouteMatch[] | null {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\n\nexport function matchRoutesImpl<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename: string,\n allowPartial: boolean\n): AgnosticRouteMatch[] | null {\n let location =\n typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n\n let pathname = stripBasename(location.pathname || \"/\", basename);\n\n if (pathname == null) {\n return null;\n }\n\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n\n return matches;\n}\n\nexport interface UIMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: Data;\n handle: Handle;\n}\n\nexport function convertRouteMatchToUiMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UIMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle,\n };\n}\n\ninterface RouteMeta<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n relativePath: string;\n caseSensitive: boolean;\n childrenIndex: number;\n route: RouteObjectType;\n}\n\ninterface RouteBranch<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n path: string;\n score: number;\n routesMeta: RouteMeta[];\n}\n\nfunction flattenRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n branches: RouteBranch[] = [],\n parentsMeta: RouteMeta[] = [],\n parentPath = \"\"\n): RouteBranch[] {\n let flattenRoute = (\n route: RouteObjectType,\n index: number,\n relativePath?: string\n ) => {\n let meta: RouteMeta = {\n relativePath:\n relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route,\n };\n\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path ` +\n `\"${parentPath}\" is not valid. An absolute child route path ` +\n `must start with the combined path of all its parent routes.`\n );\n\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n\n // Add the children before adding this route to the array, so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove ` +\n `all child routes from route path \"${path}\".`\n );\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta,\n });\n };\n routes.forEach((route, index) => {\n // coarse-grain check for optional params\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, exploded);\n }\n }\n });\n\n return branches;\n}\n\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */\nfunction explodeOptionalSegments(path: string): string[] {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n\n let [first, ...rest] = segments;\n\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [required, \"\"] : [required];\n }\n\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n\n let result: string[] = [];\n\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children, so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explode _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(\n ...restExploded.map((subpath) =>\n subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n\n // Then, if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n\n // for absolute paths, ensure `/` instead of empty segment\n return result.map((exploded) =>\n path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\n\nfunction rankRouteBranches(branches: RouteBranch[]): void {\n branches.sort((a, b) =>\n a.score !== b.score\n ? b.score - a.score // Higher score first\n : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\n\nconst paramRe = /^:[\\w-]+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s: string) => s === \"*\";\n\nfunction computeScore(path: string, index: boolean | undefined): number {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n\n if (index) {\n initialScore += indexRouteValue;\n }\n\n return segments\n .filter((s) => !isSplat(s))\n .reduce(\n (score, segment) =>\n score +\n (paramRe.test(segment)\n ? dynamicSegmentValue\n : segment === \"\"\n ? emptySegmentValue\n : staticSegmentValue),\n initialScore\n );\n}\n\nfunction compareIndexes(a: number[], b: number[]): number {\n let siblings =\n a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n\n return siblings\n ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\n\nfunction matchRouteBranch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n branch: RouteBranch,\n pathname: string,\n allowPartial = false\n): AgnosticRouteMatch[] | null {\n let { routesMeta } = branch;\n\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches: AgnosticRouteMatch[] = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname =\n matchedPathname === \"/\"\n ? pathname\n : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n\n let route = meta.route;\n\n if (\n !match &&\n end &&\n allowPartial &&\n !routesMeta[routesMeta.length - 1].route.index\n ) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false,\n },\n remainingPathname\n );\n }\n\n if (!match) {\n return null;\n }\n\n Object.assign(matchedParams, match.params);\n\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams as Params,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route,\n });\n\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n\n return matches;\n}\n\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/utils/generate-path\n */\nexport function generatePath(\n originalPath: Path,\n params: {\n [key in PathParam]: string | null;\n } = {} as any\n): string {\n let path: string = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\") as Path;\n }\n\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n\n const stringify = (p: any) =>\n p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n\n const segments = path\n .split(/\\/+/)\n .map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\" as PathParam;\n // Apply the splat\n return stringify(params[star]);\n }\n\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key as PathParam];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return stringify(param);\n }\n\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })\n // Remove empty segments\n .filter((segment) => !!segment);\n\n return prefix + segments.join(\"/\");\n}\n\n/**\n * A PathPattern is used to match on some portion of a URL pathname.\n */\nexport interface PathPattern {\n /**\n * A string to match against a URL pathname. May contain `:id`-style segments\n * to indicate placeholders for dynamic parameters. May also end with `/*` to\n * indicate matching the rest of the URL pathname.\n */\n path: Path;\n /**\n * Should be `true` if the static portions of the `path` should be matched in\n * the same case.\n */\n caseSensitive?: boolean;\n /**\n * Should be `true` if this pattern should match the entire URL pathname.\n */\n end?: boolean;\n}\n\n/**\n * A PathMatch contains info about how a PathPattern matched on a URL pathname.\n */\nexport interface PathMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The pattern that was used to match.\n */\n pattern: PathPattern;\n}\n\ntype Mutable = {\n -readonly [P in keyof T]: T[P];\n};\n\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/utils/match-path\n */\nexport function matchPath<\n ParamKey extends ParamParseKey,\n Path extends string\n>(\n pattern: PathPattern | Path,\n pathname: string\n): PathMatch | null {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n\n let match = pathname.match(matcher);\n if (!match) return null;\n\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params: Params = compiledParams.reduce>(\n (memo, { paramName, isOptional }, index) => {\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname\n .slice(0, matchedPathname.length - splatValue.length)\n .replace(/(.)\\/+$/, \"$1\");\n }\n\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo[paramName] = undefined;\n } else {\n memo[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\ntype CompiledPathParam = { paramName: string; isOptional?: boolean };\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, CompiledPathParam[]] {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n\n let params: CompiledPathParam[] = [];\n let regexpSource =\n \"^\" +\n path\n .replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (_: string, paramName: string, isOptional) => {\n params.push({ paramName, isOptional: isOptional != null });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n }\n );\n\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource +=\n path === \"*\" || path === \"/*\"\n ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex, so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n // Nothing to match for \"\" or \"/\"\n }\n\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n\n return [matcher, params];\n}\n\nexport function decodePath(value: string) {\n try {\n return value\n .split(\"/\")\n .map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\"))\n .join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is is a ` +\n `malformed URL segment. This is probably due to a bad percent ` +\n `encoding (${error}).`\n );\n\n return value;\n }\n}\n\n/**\n * @private\n */\nexport function stripBasename(\n pathname: string,\n basename: string\n): string | null {\n if (basename === \"/\") return pathname;\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\")\n ? basename.length - 1\n : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n\n return pathname.slice(startIndex) || \"/\";\n}\n\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/utils/resolve-path\n */\nexport function resolvePath(to: To, fromPathname = \"/\"): Path {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\",\n } = typeof to === \"string\" ? parsePath(to) : to;\n\n let pathname = toPathname\n ? toPathname.startsWith(\"/\")\n ? toPathname\n : resolvePathname(toPathname, fromPathname)\n : fromPathname;\n\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash),\n };\n}\n\nfunction resolvePathname(relativePath: string, fromPathname: string): string {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\n\nfunction getInvalidPathError(\n char: string,\n field: string,\n dest: string,\n path: Partial\n) {\n return (\n `Cannot include a '${char}' character in a manually specified ` +\n `\\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the ` +\n `\\`to.${dest}\\` field. Alternatively you may provide the full path as ` +\n `a string in and the router will parse it for you.`\n );\n}\n\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * \n * \n * \n *\n * \n * \n * }> // <-- Does not contribute\n * // <-- Does not contribute\n * \n * \n */\nexport function getPathContributingMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[]) {\n return matches.filter(\n (match, index) =>\n index === 0 || (match.route.path && match.route.path.length > 0)\n );\n}\n\n// Return the array of pathnames for the current route matches - used to\n// generate the routePathnames input for resolveTo()\nexport function getResolveToMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[], v7_relativeSplatPath: boolean) {\n let pathMatches = getPathContributingMatches(matches);\n\n // When v7_relativeSplatPath is enabled, use the full pathname for the leaf\n // match so we include splat values for \".\" links. See:\n // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329\n if (v7_relativeSplatPath) {\n return pathMatches.map((match, idx) =>\n idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n }\n\n return pathMatches.map((match) => match.pathnameBase);\n}\n\n/**\n * @private\n */\nexport function resolveTo(\n toArg: To,\n routePathnames: string[],\n locationPathname: string,\n isPathRelative = false\n): Path {\n let to: Partial;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n\n let from: string;\n\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n // With relative=\"route\" (the default), each leading .. segment means\n // \"go up one route\" instead of \"go up one URL segment\". This is a key\n // difference from how works and a major reason we call this a\n // \"to\" value instead of a \"href\".\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n\n let path = resolvePath(to, from);\n\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash =\n toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash =\n (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (\n !path.pathname.endsWith(\"/\") &&\n (hasExplicitTrailingSlash || hasCurrentTrailingSlash)\n ) {\n path.pathname += \"/\";\n }\n\n return path;\n}\n\n/**\n * @private\n */\nexport function getToPathname(to: To): string | undefined {\n // Empty strings should be treated the same as / paths\n return to === \"\" || (to as Path).pathname === \"\"\n ? \"/\"\n : typeof to === \"string\"\n ? parsePath(to).pathname\n : to.pathname;\n}\n\n/**\n * @private\n */\nexport const joinPaths = (paths: string[]): string =>\n paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n\n/**\n * @private\n */\nexport const normalizePathname = (pathname: string): string =>\n pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n\n/**\n * @private\n */\nexport const normalizeSearch = (search: string): string =>\n !search || search === \"?\"\n ? \"\"\n : search.startsWith(\"?\")\n ? search\n : \"?\" + search;\n\n/**\n * @private\n */\nexport const normalizeHash = (hash: string): string =>\n !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n\nexport type JsonFunction = (\n data: Data,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n */\nexport const json: JsonFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n\n return new Response(JSON.stringify(data), {\n ...responseInit,\n headers,\n });\n};\n\nexport interface TrackedPromise extends Promise {\n _tracked?: boolean;\n _data?: any;\n _error?: any;\n}\n\nexport class AbortedDeferredError extends Error {}\n\nexport class DeferredData {\n private pendingKeysSet: Set = new Set();\n private controller: AbortController;\n private abortPromise: Promise;\n private unlistenAbortSignal: () => void;\n private subscribers: Set<(aborted: boolean, settledKey?: string) => void> =\n new Set();\n data: Record;\n init?: ResponseInit;\n deferredKeys: string[] = [];\n\n constructor(data: Record, responseInit?: ResponseInit) {\n invariant(\n data && typeof data === \"object\" && !Array.isArray(data),\n \"defer() only accepts plain objects\"\n );\n\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject: (e: AbortedDeferredError) => void;\n this.abortPromise = new Promise((_, r) => (reject = r));\n this.controller = new AbortController();\n let onAbort = () =>\n reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = () =>\n this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n\n this.data = Object.entries(data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: this.trackPromise(key, value),\n }),\n {}\n );\n\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n\n this.init = responseInit;\n }\n\n private trackPromise(\n key: string,\n value: Promise | unknown\n ): TrackedPromise | unknown {\n if (!(value instanceof Promise)) {\n return value;\n }\n\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise: TrackedPromise = Promise.race([value, this.abortPromise]).then(\n (data) => this.onSettle(promise, key, undefined, data as unknown),\n (error) => this.onSettle(promise, key, error as unknown)\n );\n\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(() => {});\n\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n return promise;\n }\n\n private onSettle(\n promise: TrackedPromise,\n key: string,\n error: unknown,\n data?: unknown\n ): unknown {\n if (\n this.controller.signal.aborted &&\n error instanceof AbortedDeferredError\n ) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", { get: () => error });\n return Promise.reject(error);\n }\n\n this.pendingKeysSet.delete(key);\n\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error(\n `Deferred data for key \"${key}\" resolved/rejected with \\`undefined\\`, ` +\n `you must resolve/reject with a value or \\`null\\`.`\n );\n Object.defineProperty(promise, \"_error\", { get: () => undefinedError });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", { get: () => error });\n this.emit(false, key);\n return Promise.reject(error);\n }\n\n Object.defineProperty(promise, \"_data\", { get: () => data });\n this.emit(false, key);\n return data;\n }\n\n private emit(aborted: boolean, settledKey?: string) {\n this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));\n }\n\n subscribe(fn: (aborted: boolean, settledKey?: string) => void) {\n this.subscribers.add(fn);\n return () => this.subscribers.delete(fn);\n }\n\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n\n async resolveData(signal: AbortSignal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = () => this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise((resolve) => {\n this.subscribe((aborted) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n\n get unwrappedData() {\n invariant(\n this.data !== null && this.done,\n \"Can only unwrap data on initialized and settled deferreds\"\n );\n\n return Object.entries(this.data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: unwrapTrackedPromise(value),\n }),\n {}\n );\n }\n\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\n\nfunction isTrackedPromise(value: any): value is TrackedPromise {\n return (\n value instanceof Promise && (value as TrackedPromise)._tracked === true\n );\n}\n\nfunction unwrapTrackedPromise(value: any) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\n\nexport type DeferFunction = (\n data: Record,\n init?: number | ResponseInit\n) => DeferredData;\n\nexport const defer: DeferFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n return new DeferredData(data, responseInit);\n};\n\nexport type RedirectFunction = (\n url: string,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirect: RedirectFunction = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...responseInit,\n headers,\n });\n};\n\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirectDocument: RedirectFunction = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n\nexport type ErrorResponse = {\n status: number;\n statusText: string;\n data: any;\n};\n\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n *\n * We don't export the class for public use since it's an implementation\n * detail, but we export the interface above so folks can build their own\n * abstractions around instances via isRouteErrorResponse()\n */\nexport class ErrorResponseImpl implements ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n private error?: Error;\n private internal: boolean;\n\n constructor(\n status: number,\n statusText: string | undefined,\n data: any,\n internal = false\n ) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */\nexport function isRouteErrorResponse(error: any): error is ErrorResponse {\n return (\n error != null &&\n typeof error.status === \"number\" &&\n typeof error.statusText === \"string\" &&\n typeof error.internal === \"boolean\" &&\n \"data\" in error\n );\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n warning,\n} from \"./history\";\nimport type {\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DataStrategyMatch,\n AgnosticRouteObject,\n DataResult,\n DataStrategyFunction,\n DataStrategyFunctionArgs,\n DeferredData,\n DeferredResult,\n DetectErrorBoundaryFunction,\n ErrorResult,\n FormEncType,\n FormMethod,\n HTMLFormMethod,\n HandlerResult,\n ImmutableRouteKey,\n MapRoutePropertiesFunction,\n MutationFormMethod,\n RedirectResult,\n RouteData,\n RouteManifest,\n ShouldRevalidateFunctionArgs,\n Submission,\n SuccessResult,\n UIMatch,\n V7_FormMethod,\n V7_MutationFormMethod,\n AgnosticPatchRoutesOnMissFunction,\n} from \"./utils\";\nimport {\n ErrorResponseImpl,\n ResultType,\n convertRouteMatchToUiMatch,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n getResolveToMatches,\n immutableRouteKeys,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n matchRoutesImpl,\n resolveTo,\n stripBasename,\n} from \"./utils\";\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A Router instance manages all navigation and data loading/mutations\n */\nexport interface Router {\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the basename for the router\n */\n get basename(): RouterInit[\"basename\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the future config for the router\n */\n get future(): FutureConfig;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the current state of the router\n */\n get state(): RouterState;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the routes for this router instance\n */\n get routes(): AgnosticDataRouteObject[];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the window associated with the router\n */\n get window(): RouterInit[\"window\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Initialize the router, including adding history listeners and kicking off\n * initial data fetches. Returns a function to cleanup listeners and abort\n * any in-progress loads\n */\n initialize(): Router;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Subscribe to router.state updates\n *\n * @param fn function to call with the new state\n */\n subscribe(fn: RouterSubscriber): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Enable scroll restoration behavior in the router\n *\n * @param savedScrollPositions Object that will manage positions, in case\n * it's being restored from sessionStorage\n * @param getScrollPosition Function to get the active Y scroll position\n * @param getKey Function to get the key to use for restoration\n */\n enableScrollRestoration(\n savedScrollPositions: Record,\n getScrollPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Navigate forward/backward in the history stack\n * @param to Delta to move in the history stack\n */\n navigate(to: number): Promise;\n\n /**\n * Navigate to the given path\n * @param to Path to navigate to\n * @param opts Navigation options (method, submission, etc.)\n */\n navigate(to: To | null, opts?: RouterNavigateOptions): Promise;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a fetcher load/submission\n *\n * @param key Fetcher key\n * @param routeId Route that owns the fetcher\n * @param href href to fetch\n * @param opts Fetcher options, (method, submission, etc.)\n */\n fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a revalidation of all current route loaders and fetcher loads\n */\n revalidate(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to create an href for the given location\n * @param location\n */\n createHref(location: Location | URL): string;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to URL encode a destination path according to the internal\n * history implementation\n * @param to\n */\n encodeLocation(to: To): Path;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get/create a fetcher for the given key\n * @param key\n */\n getFetcher(key: string): Fetcher;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete the fetcher for a given key\n * @param key\n */\n deleteFetcher(key: string): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Cleanup listeners and abort any in-progress loads\n */\n dispose(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get a navigation blocker\n * @param key The identifier for the blocker\n * @param fn The blocker function implementation\n */\n getBlocker(key: string, fn: BlockerFunction): Blocker;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete a navigation blocker\n * @param key The identifier for the blocker\n */\n deleteBlocker(key: string): void;\n\n /**\n * @internal\n * PRIVATE DO NOT USE\n *\n * Patch additional children routes into an existing parent route\n * @param routeId The parent route id or a callback function accepting `patch`\n * to perform batch patching\n * @param children The additional children routes\n */\n patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * HMR needs to pass in-flight route updates to React Router\n * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute)\n */\n _internalSetRoutes(routes: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal fetch AbortControllers accessed by unit tests\n */\n _internalFetchControllers: Map;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal pending DeferredData instances accessed by unit tests\n */\n _internalActiveDeferreds: Map;\n}\n\n/**\n * State maintained internally by the router. During a navigation, all states\n * reflect the the \"old\" location unless otherwise noted.\n */\nexport interface RouterState {\n /**\n * The action of the most recent navigation\n */\n historyAction: HistoryAction;\n\n /**\n * The current location reflected by the router\n */\n location: Location;\n\n /**\n * The current set of route matches\n */\n matches: AgnosticDataRouteMatch[];\n\n /**\n * Tracks whether we've completed our initial data load\n */\n initialized: boolean;\n\n /**\n * Current scroll position we should start at for a new view\n * - number -> scroll position to restore to\n * - false -> do not restore scroll at all (used during submissions)\n * - null -> don't have a saved position, scroll to hash or top of page\n */\n restoreScrollPosition: number | false | null;\n\n /**\n * Indicate whether this navigation should skip resetting the scroll position\n * if we are unable to restore the scroll position\n */\n preventScrollReset: boolean;\n\n /**\n * Tracks the state of the current navigation\n */\n navigation: Navigation;\n\n /**\n * Tracks any in-progress revalidations\n */\n revalidation: RevalidationState;\n\n /**\n * Data from the loaders for the current matches\n */\n loaderData: RouteData;\n\n /**\n * Data from the action for the current matches\n */\n actionData: RouteData | null;\n\n /**\n * Errors caught from loaders for the current matches\n */\n errors: RouteData | null;\n\n /**\n * Map of current fetchers\n */\n fetchers: Map;\n\n /**\n * Map of current blockers\n */\n blockers: Map;\n}\n\n/**\n * Data that can be passed into hydrate a Router from SSR\n */\nexport type HydrationState = Partial<\n Pick\n>;\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface FutureConfig {\n v7_fetcherPersist: boolean;\n v7_normalizeFormMethod: boolean;\n v7_partialHydration: boolean;\n v7_prependBasename: boolean;\n v7_relativeSplatPath: boolean;\n v7_skipActionErrorRevalidation: boolean;\n}\n\n/**\n * Initialization options for createRouter\n */\nexport interface RouterInit {\n routes: AgnosticRouteObject[];\n history: History;\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n hydrationData?: HydrationState;\n window?: Window;\n unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction;\n unstable_dataStrategy?: DataStrategyFunction;\n}\n\n/**\n * State returned from a server-side query() call\n */\nexport interface StaticHandlerContext {\n basename: Router[\"basename\"];\n location: RouterState[\"location\"];\n matches: RouterState[\"matches\"];\n loaderData: RouterState[\"loaderData\"];\n actionData: RouterState[\"actionData\"];\n errors: RouterState[\"errors\"];\n statusCode: number;\n loaderHeaders: Record;\n actionHeaders: Record;\n activeDeferreds: Record | null;\n _deepestRenderedBoundaryId?: string | null;\n}\n\n/**\n * A StaticHandler instance manages a singular SSR navigation/fetch event\n */\nexport interface StaticHandler {\n dataRoutes: AgnosticDataRouteObject[];\n query(\n request: Request,\n opts?: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: {\n routeId?: string;\n requestContext?: unknown;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n}\n\ntype ViewTransitionOpts = {\n currentLocation: Location;\n nextLocation: Location;\n};\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (\n state: RouterState,\n opts: {\n deletedFetchers: string[];\n unstable_viewTransitionOpts?: ViewTransitionOpts;\n unstable_flushSync: boolean;\n }\n ): void;\n}\n\n/**\n * Function signature for determining the key to be used in scroll restoration\n * for a given location\n */\nexport interface GetScrollRestorationKeyFunction {\n (location: Location, matches: UIMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\nexport type RelativeRoutingType = \"route\" | \"path\";\n\n// Allowed for any navigation or fetch\ntype BaseNavigateOrFetchOptions = {\n preventScrollReset?: boolean;\n relative?: RelativeRoutingType;\n unstable_flushSync?: boolean;\n};\n\n// Only allowed for navigations\ntype BaseNavigateOptions = BaseNavigateOrFetchOptions & {\n replace?: boolean;\n state?: any;\n fromRouteId?: string;\n unstable_viewTransition?: boolean;\n};\n\n// Only allowed for submission navigations\ntype BaseSubmissionOptions = {\n formMethod?: HTMLFormMethod;\n formEncType?: FormEncType;\n} & (\n | { formData: FormData; body?: undefined }\n | { formData?: undefined; body: any }\n);\n\n/**\n * Options for a navigate() call for a normal (non-submission) navigation\n */\ntype LinkNavigateOptions = BaseNavigateOptions;\n\n/**\n * Options for a navigate() call for a submission navigation\n */\ntype SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to navigate() for a navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options for a fetch() load\n */\ntype LoadFetchOptions = BaseNavigateOrFetchOptions;\n\n/**\n * Options for a fetch() submission\n */\ntype SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions;\n\n/**\n * Potential states for state.navigation\n */\nexport type NavigationStates = {\n Idle: {\n state: \"idle\";\n location: undefined;\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n formData: undefined;\n json: undefined;\n text: undefined;\n };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n text: Submission[\"text\"] | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n text: Submission[\"text\"];\n };\n};\n\nexport type Navigation = NavigationStates[keyof NavigationStates];\n\nexport type RevalidationState = \"idle\" | \"loading\";\n\n/**\n * Potential states for fetchers\n */\ntype FetcherStates = {\n Idle: {\n state: \"idle\";\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n text: undefined;\n formData: undefined;\n json: undefined;\n data: TData | undefined;\n };\n Loading: {\n state: \"loading\";\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n text: Submission[\"text\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n data: TData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n text: Submission[\"text\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n data: TData | undefined;\n };\n};\n\nexport type Fetcher =\n FetcherStates[keyof FetcherStates];\n\ninterface BlockerBlocked {\n state: \"blocked\";\n reset(): void;\n proceed(): void;\n location: Location;\n}\n\ninterface BlockerUnblocked {\n state: \"unblocked\";\n reset: undefined;\n proceed: undefined;\n location: undefined;\n}\n\ninterface BlockerProceeding {\n state: \"proceeding\";\n reset: undefined;\n proceed: undefined;\n location: Location;\n}\n\nexport type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;\n\nexport type BlockerFunction = (args: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n}) => boolean;\n\ninterface ShortCircuitable {\n /**\n * startNavigation does not need to complete the navigation because we\n * redirected or got interrupted\n */\n shortCircuited?: boolean;\n}\n\ntype PendingActionResult = [string, SuccessResult | ErrorResult];\n\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * Tuple for the returned or thrown value from the current action. The routeId\n * is the action route for success and the bubbled boundary route for errors.\n */\n pendingActionResult?: PendingActionResult;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * loaderData returned from the current set of loaders\n */\n loaderData?: RouterState[\"loaderData\"];\n /**\n * errors thrown from the current set of loaders\n */\n errors?: RouterState[\"errors\"];\n}\n\n/**\n * Cached info for active fetcher.load() instances so they can participate\n * in revalidation\n */\ninterface FetchLoadMatch {\n routeId: string;\n path: string;\n}\n\n/**\n * Identified fetcher.load() calls that need to be revalidated\n */\ninterface RevalidatingFetcher extends FetchLoadMatch {\n key: string;\n match: AgnosticDataRouteMatch | null;\n matches: AgnosticDataRouteMatch[] | null;\n controller: AbortController | null;\n}\n\nconst validMutationMethodsArr: MutationFormMethod[] = [\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n];\nconst validMutationMethods = new Set(\n validMutationMethodsArr\n);\n\nconst validRequestMethodsArr: FormMethod[] = [\n \"get\",\n ...validMutationMethodsArr,\n];\nconst validRequestMethods = new Set(validRequestMethodsArr);\n\nconst redirectStatusCodes = new Set([301, 302, 303, 307, 308]);\nconst redirectPreserveMethodStatusCodes = new Set([307, 308]);\n\nexport const IDLE_NAVIGATION: NavigationStates[\"Idle\"] = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_FETCHER: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\nconst defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary),\n});\n\nconst TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Create a router and listen to history POP navigations\n */\nexport function createRouter(init: RouterInit): Router {\n const routerWindow = init.window\n ? init.window\n : typeof window !== \"undefined\"\n ? window\n : undefined;\n const isBrowser =\n typeof routerWindow !== \"undefined\" &&\n typeof routerWindow.document !== \"undefined\" &&\n typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n\n // Routes keyed by ID\n let manifest: RouteManifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined;\n let basename = init.basename || \"/\";\n let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;\n let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss;\n\n // Config driven behavior flags\n let future: FutureConfig = {\n v7_fetcherPersist: false,\n v7_normalizeFormMethod: false,\n v7_partialHydration: false,\n v7_prependBasename: false,\n v7_relativeSplatPath: false,\n v7_skipActionErrorRevalidation: false,\n ...init.future,\n };\n // Cleanup function for history\n let unlistenHistory: (() => void) | null = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions: Record | null = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey: GetScrollRestorationKeyFunction | null = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition: GetScrollPositionFunction | null = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null && !patchRoutesOnMissImpl) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname,\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n }\n\n // In SPA apps, if the user provided a patchRoutesOnMiss implementation and\n // our initial match is a splat route, clear them out so we run through lazy\n // discovery on hydration in case there's a more accurate lazy route match.\n // In SSR apps (with `hydrationData`), we expect that the server will send\n // up the proper matched routes so we don't want to run lazy discovery on\n // initial hydration and want to hydrate into the splat route.\n if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n\n let initialized: boolean;\n if (!initialMatches) {\n // We need to run patchRoutesOnMiss in initialize()\n initialized = false;\n initialMatches = [];\n } else if (initialMatches.some((m) => m.route.lazy)) {\n // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n initialized = false;\n } else if (!initialMatches.some((m) => m.route.loader)) {\n // If we've got no loaders to run, then we're good to go\n initialized = true;\n } else if (future.v7_partialHydration) {\n // If partial hydration is enabled, we're initialized so long as we were\n // provided with hydrationData for every route with a loader, and no loaders\n // were marked for explicit hydration\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n let isRouteInitialized = (m: AgnosticDataRouteMatch) => {\n // No loader, nothing to initialize\n if (!m.route.loader) {\n return true;\n }\n // Explicitly opting-in to running on hydration\n if (\n typeof m.route.loader === \"function\" &&\n m.route.loader.hydrate === true\n ) {\n return false;\n }\n // Otherwise, initialized if hydrated with data or an error\n return (\n (loaderData && loaderData[m.route.id] !== undefined) ||\n (errors && errors[m.route.id] !== undefined)\n );\n };\n\n // If errors exist, don't consider routes below the boundary\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors![m.route.id] !== undefined\n );\n initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);\n } else {\n initialized = initialMatches.every(isRouteInitialized);\n }\n } else {\n // Without partial hydration - we're initialized if we were provided any\n // hydrationData - which is expected to be complete\n initialized = init.hydrationData != null;\n }\n\n let router: Router;\n let state: RouterState = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: (init.hydrationData && init.hydrationData.loaderData) || {},\n actionData: (init.hydrationData && init.hydrationData.actionData) || null,\n errors: (init.hydrationData && init.hydrationData.errors) || initialErrors,\n fetchers: new Map(),\n blockers: new Map(),\n };\n\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction: HistoryAction = HistoryAction.Pop;\n\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n\n // AbortController for the active navigation\n let pendingNavigationController: AbortController | null;\n\n // Should the current navigation enable document.startViewTransition?\n let pendingViewTransitionEnabled = false;\n\n // Store applied view transitions so we can apply them on POP\n let appliedViewTransitions: Map> = new Map<\n string,\n Set\n >();\n\n // Cleanup function for persisting applied transitions to sessionStorage\n let removePageHideEventListener: (() => void) | null = null;\n\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes: string[] = [];\n\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads: string[] = [];\n\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n\n // Ref-count mounted fetchers so we know when it's ok to clean them up\n let activeFetchers = new Map();\n\n // Fetchers that have requested a delete when using v7_fetcherPersist,\n // they'll be officially removed after they return to idle\n let deletedFetchers = new Set();\n\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n\n // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so\n // that we only kick them off once for a given combo\n let pendingPatchRoutes = new Map<\n string,\n ReturnType\n >();\n\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let ignoreNextHistoryUpdate = false;\n\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (ignoreNextHistoryUpdate) {\n ignoreNextHistoryUpdate = false;\n return;\n }\n\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location \" +\n \"that was not created by @remix-run/router. This will fail silently in \" +\n \"production. This can happen if you are navigating outside the router \" +\n \"via `window.history.pushState`/`window.location.hash` instead of using \" +\n \"router navigation APIs. This can also happen if you are using \" +\n \"createHashRouter and the user manually changes the URL.\"\n );\n\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n ignoreNextHistoryUpdate = true;\n init.history.go(delta * -1);\n\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location,\n });\n // Re-do the same POP navigation we just blocked\n init.history.go(delta);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n if (isBrowser) {\n // FIXME: This feels gross. How can we cleanup the lines between\n // scrollRestoration/appliedTransitions persistance?\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () =>\n persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () =>\n routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location, {\n initialHydration: true,\n });\n }\n\n return router;\n }\n\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n\n // Subscribe to state updates for the router\n function subscribe(fn: RouterSubscriber) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n\n // Update our state and notify the calling context of the change\n function updateState(\n newState: Partial,\n opts: {\n flushSync?: boolean;\n viewTransitionOpts?: ViewTransitionOpts;\n } = {}\n ): void {\n state = {\n ...state,\n ...newState,\n };\n\n // Prep fetcher cleanup so we can tell the UI which fetcher data entries\n // can be removed\n let completedFetchers: string[] = [];\n let deletedFetchersKeys: string[] = [];\n\n if (future.v7_fetcherPersist) {\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (deletedFetchers.has(key)) {\n // Unmounted from the UI and can be totally removed\n deletedFetchersKeys.push(key);\n } else {\n // Returned to idle but still mounted in the UI, so semi-remains for\n // revalidations and such\n completedFetchers.push(key);\n }\n }\n });\n }\n\n // Iterate over a local copy so that if flushSync is used and we end up\n // removing and adding a new subscriber due to the useCallback dependencies,\n // we don't get ourselves into a loop calling the new subscriber immediately\n [...subscribers].forEach((subscriber) =>\n subscriber(state, {\n deletedFetchers: deletedFetchersKeys,\n unstable_viewTransitionOpts: opts.viewTransitionOpts,\n unstable_flushSync: opts.flushSync === true,\n })\n );\n\n // Remove idle fetchers from state since we only care about in-flight fetchers.\n if (future.v7_fetcherPersist) {\n completedFetchers.forEach((key) => state.fetchers.delete(key));\n deletedFetchersKeys.forEach((key) => deleteFetcher(key));\n }\n }\n\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(\n location: Location,\n newState: Partial>,\n { flushSync }: { flushSync?: boolean } = {}\n ): void {\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload =\n state.actionData != null &&\n state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n state.navigation.state === \"loading\" &&\n location.state?._isRedirect !== true;\n\n let actionData: RouteData | null;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData\n ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n )\n : state.loaderData;\n\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset =\n pendingPreventScrollReset === true ||\n (state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n location.state?._isRedirect !== true);\n\n // Commit any in-flight routes at the end of the HMR revalidation \"navigation\"\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n\n if (isUninterruptedRevalidation) {\n // If this was an uninterrupted revalidation then do not touch history\n } else if (pendingAction === HistoryAction.Pop) {\n // Do nothing for POP - URL has already been updated\n } else if (pendingAction === HistoryAction.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === HistoryAction.Replace) {\n init.history.replace(location, location.state);\n }\n\n let viewTransitionOpts: ViewTransitionOpts | undefined;\n\n // On POP, enable transitions if they were enabled on the original navigation\n if (pendingAction === HistoryAction.Pop) {\n // Forward takes precedence so they behave like the original navigation\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n // If we don't have a previous forward nav, assume we're popping back to\n // the new location and enable if that location previously enabled\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location,\n };\n }\n } else if (pendingViewTransitionEnabled) {\n // Store the applied transition on PUSH/REPLACE\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n }\n\n updateState(\n {\n ...newState, // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(\n location,\n newState.matches || state.matches\n ),\n preventScrollReset,\n blockers,\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true,\n }\n );\n\n // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n cancelledFetcherLoads = [];\n }\n\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(\n to: number | To | null,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n to,\n future.v7_relativeSplatPath,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n false,\n normalizedPath,\n opts\n );\n\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation),\n };\n\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n\n let historyAction = HistoryAction.Push;\n\n if (userReplace === true) {\n historyAction = HistoryAction.Replace;\n } else if (userReplace === false) {\n // no-op\n } else if (\n submission != null &&\n isMutationMethod(submission.formMethod) &&\n submission.formAction === state.location.pathname + state.location.search\n ) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = HistoryAction.Replace;\n }\n\n let preventScrollReset =\n opts && \"preventScrollReset\" in opts\n ? opts.preventScrollReset === true\n : undefined;\n\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n });\n\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation,\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.unstable_viewTransition,\n flushSync,\n });\n }\n\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true,\n });\n return;\n }\n\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n { overrideNavigation: state.navigation }\n );\n }\n\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(\n historyAction: HistoryAction,\n location: Location,\n opts?: {\n initialHydration?: boolean;\n submission?: Submission;\n fetcherSubmission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponseImpl;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: boolean;\n enableViewTransition?: boolean;\n flushSync?: boolean;\n }\n ): Promise {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation =\n (opts && opts.startUninterruptedRevalidation) === true;\n\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n },\n { flushSync }\n );\n return;\n }\n\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial load will always\n // be \"same hash\". For example, on /page#hash and submit a \n // which will default to a navigation to /page\n if (\n state.initialized &&\n !isRevalidationRequired &&\n isHashChangeOnly(state.location, location) &&\n !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))\n ) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let pendingActionResult: PendingActionResult | undefined;\n\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: ResultType.error, error: opts.pendingError },\n ];\n } else if (\n opts &&\n opts.submission &&\n isMutationMethod(opts.submission.formMethod)\n ) {\n // Call action if we received an action submission\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n fogOfWar.active,\n { replace: opts.replace, flushSync }\n );\n\n if (actionResult.shortCircuited) {\n return;\n }\n\n // If we received a 404 from handleAction, it's because we couldn't lazily\n // discover the destination route so we don't want to call loaders\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (\n isErrorResult(result) &&\n isRouteErrorResponse(result.error) &&\n result.error.status === 404\n ) {\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error,\n },\n });\n return;\n }\n }\n\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n // No need to do fog of war matching again on loader execution\n fogOfWar.active = false;\n\n // Create a GET request for the loaders\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n\n // Call loaders\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors,\n } = await handleLoaders(\n request,\n location,\n matches,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult\n );\n\n if (shortCircuited) {\n return;\n }\n\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors,\n });\n }\n\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(\n request: Request,\n location: Location,\n submission: Submission,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n opts: { replace?: boolean; flushSync?: boolean } = {}\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n // Call our action and get the result\n let result: DataResult;\n let actionMatch = getTargetMatch(matches, location);\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id,\n }),\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches\n );\n result = results[0];\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n\n if (isRedirectResult(result)) {\n let replace: boolean;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n let location = normalizeRedirectLocation(\n result.response.headers.get(\"Location\")!,\n new URL(request.url),\n basename\n );\n replace = location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, {\n submission,\n replace,\n });\n return { shortCircuited: true };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n\n // By default, all submissions to the current location are REPLACE\n // navigations, but if the action threw an error that'll be rendered in\n // an errorElement, we fall back to PUSH so that the user can use the\n // back button to get back to the pre-submission form location to try\n // again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n matches,\n pendingActionResult: [boundaryMatch.route.id, result],\n };\n }\n\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result],\n };\n }\n\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n overrideNavigation?: Navigation,\n submission?: Submission,\n fetcherSubmission?: Submission,\n replace?: boolean,\n initialHydration?: boolean,\n flushSync?: boolean,\n pendingActionResult?: PendingActionResult\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation =\n overrideNavigation || getLoadingNavigation(location, submission);\n\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission =\n submission ||\n fetcherSubmission ||\n getSubmissionFromNavigation(loadingNavigation);\n\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n // If we have partialHydration enabled, then don't update the state for the\n // initial data load since it's not a \"navigation\"\n let shouldUpdateNavigationState =\n !isUninterruptedRevalidation &&\n (!future.v7_partialHydration || !initialHydration);\n\n // When fog of war is enabled, we enter our `loading` state earlier so we\n // can discover new routes during the `loading` state. We skip this if\n // we've already run actions since we would have done our matching already.\n // If the children() function threw then, we want to proceed with the\n // partial matches it discovered.\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...(actionData !== undefined ? { actionData } : {}),\n },\n {\n flushSync,\n }\n );\n }\n\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: error,\n },\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n future.v7_partialHydration && initialHydration === true,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n pendingActionResult\n );\n\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds(\n (routeId) =>\n !(matches && matches.some((m) => m.route.id === routeId)) ||\n (matchesToLoad && matchesToLoad.some((m) => m.route.id === routeId))\n );\n\n pendingNavigationLoadId = ++incrementingLoadId;\n\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? { [pendingActionResult[0]]: pendingActionResult[1].error }\n : null,\n ...getActionDataForCommit(pendingActionResult),\n ...(updatedFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n\n if (shouldUpdateNavigationState) {\n let updates: Partial = {};\n if (!isFogOfWar) {\n // Only update navigation/actionNData if we didn't already do it above\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== undefined) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n\n revalidatingFetchers.forEach((rf) => {\n if (fetchControllers.has(rf.key)) {\n abortFetcher(rf.key);\n }\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n request\n );\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n await startRedirectNavigation(request, redirect.result, {\n replace,\n });\n return { shortCircuited: true };\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n matchesToLoad,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId) => {\n deferredData.subscribe((aborted) => {\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n\n // During partial hydration, preserve SSR errors for routes that don't re-run\n if (future.v7_partialHydration && initialHydration && state.errors) {\n Object.entries(state.errors)\n .filter(([id]) => !matchesToLoad.some((m) => m.route.id === id))\n .forEach(([routeId, error]) => {\n errors = Object.assign(errors || {}, { [routeId]: error });\n });\n }\n\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers =\n updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n\n return {\n matches,\n loaderData,\n errors,\n ...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n };\n }\n\n function getUpdatedActionData(\n pendingActionResult: PendingActionResult | undefined\n ): Record | null | undefined {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n // This is cast to `any` currently because `RouteData`uses any and it\n // would be a breaking change to use any.\n // TODO: v7 - change `RouteData` to use `unknown` instead of `any`\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data as any,\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n\n function getUpdatedRevalidatingFetchers(\n revalidatingFetchers: RevalidatingFetcher[]\n ) {\n revalidatingFetchers.forEach((rf) => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n fetcher ? fetcher.data : undefined\n );\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ) {\n if (isServer) {\n throw new Error(\n \"router.fetch() was called during the server render, but it shouldn't be. \" +\n \"You are likely calling a useFetcher() method in the body of your component. \" +\n \"Try moving it to a useEffect or a callback.\"\n );\n }\n\n if (fetchControllers.has(key)) abortFetcher(key);\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n href,\n future.v7_relativeSplatPath,\n routeId,\n opts?.relative\n );\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n true,\n normalizedPath,\n opts\n );\n\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n\n let match = getTargetMatch(matches, path);\n\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, { routeId, path });\n handleFetcherLoader(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n }\n\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n requestMatches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n function detectAndHandle405Error(m: AgnosticDataRouteMatch) {\n if (!m.route.action && !m.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error, { flushSync });\n return true;\n }\n return false;\n }\n\n if (!isFogOfWar && detectAndHandle405Error(match)) {\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync,\n });\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n match = getTargetMatch(requestMatches, path);\n\n if (detectAndHandle405Error(match)) {\n return;\n }\n }\n }\n\n // Call the action for the fetcher\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let actionResults = await callDataStrategy(\n \"action\",\n fetchRequest,\n [match],\n requestMatches\n );\n let actionResult = actionResults[0];\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n\n // When using v7_fetcherPersist, we don't want errors bubbling up to the UI\n // or redirects processed for unmounted fetchers so we just revert them to\n // idle\n if (future.v7_fetcherPersist && deletedFetchers.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // Let SuccessResult's fall through for revalidation\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, {\n fetcherSubmission: submission,\n });\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(routesToUse, state.navigation.location, basename)\n : state.matches;\n\n invariant(matches, \"Didn't find any matches after fetcher action\");\n\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n false,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n [match.route.id, actionResult]\n );\n\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers\n .filter((rf) => rf.key !== key)\n .forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n existingFetcher ? existingFetcher.data : undefined\n );\n state.fetchers.set(staleKey, revalidatingFetcher);\n if (fetchControllers.has(staleKey)) {\n abortFetcher(staleKey);\n }\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n revalidationRequest\n );\n\n if (abortController.signal.aborted) {\n return;\n }\n\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n return startRedirectNavigation(revalidationRequest, redirect.result);\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n state.matches,\n matchesToLoad,\n loaderResults,\n undefined,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n\n abortStaleFetchLoads(loadId);\n\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (\n state.navigation.state === \"loading\" &&\n loadId > pendingNavigationLoadId\n ) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers),\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: new Map(state.fetchers),\n });\n isRevalidationRequired = false;\n }\n }\n\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : undefined\n ),\n { flushSync }\n );\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n match = getTargetMatch(matches, path);\n }\n }\n\n // Call the loader for this fetcher route match\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let results = await callDataStrategy(\n \"loader\",\n fetchRequest,\n [match],\n matches\n );\n let result = results[0];\n\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result =\n (await resolveDeferredData(result, fetchRequest.signal, true)) ||\n result;\n }\n\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n\n if (fetchRequest.signal.aborted) {\n return;\n }\n\n // We don't want errors bubbling up or redirects followed for unmounted\n // fetchers, so short circuit here if it was removed from the UI\n if (deletedFetchers.has(key)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result);\n return;\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */\n async function startRedirectNavigation(\n request: Request,\n redirect: RedirectResult,\n {\n submission,\n fetcherSubmission,\n replace,\n }: {\n submission?: Submission;\n fetcherSubmission?: Submission;\n replace?: boolean;\n } = {}\n ) {\n if (redirect.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n\n let location = redirect.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true,\n });\n\n if (isBrowser) {\n let isDocumentReload = false;\n\n if (redirect.response.headers.has(\"X-Remix-Reload-Document\")) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(location)) {\n const url = init.history.createURL(location);\n isDocumentReload =\n // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin ||\n // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n\n let redirectHistoryAction =\n replace === true ? HistoryAction.Replace : HistoryAction.Push;\n\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let { formMethod, formAction, formEncType } = state.navigation;\n if (\n !submission &&\n !fetcherSubmission &&\n formMethod &&\n formAction &&\n formEncType\n ) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n let activeSubmission = submission || fetcherSubmission;\n if (\n redirectPreserveMethodStatusCodes.has(redirect.response.status) &&\n activeSubmission &&\n isMutationMethod(activeSubmission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // If we have a navigation submission, we will preserve it through the\n // redirect navigation\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n submission\n );\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n }\n }\n\n // Utility wrapper for calling dataStrategy client-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[]\n ): Promise {\n try {\n let results = await callDataStrategyImpl(\n dataStrategyImpl,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n return {\n type: ResultType.redirect,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n ),\n };\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n } catch (e) {\n // If the outer dataStrategy method throws, just return the error for all\n // matches - and it'll naturally bubble to the root\n return matchesToLoad.map(() => ({\n type: ResultType.error,\n error: e,\n }));\n }\n }\n\n async function callLoadersAndMaybeResolveData(\n currentMatches: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n fetchersToLoad: RevalidatingFetcher[],\n request: Request\n ) {\n let [loaderResults, ...fetcherResults] = await Promise.all([\n matchesToLoad.length\n ? callDataStrategy(\"loader\", request, matchesToLoad, matches)\n : [],\n ...fetchersToLoad.map((f) => {\n if (f.matches && f.match && f.controller) {\n let fetcherRequest = createClientSideRequest(\n init.history,\n f.path,\n f.controller.signal\n );\n return callDataStrategy(\n \"loader\",\n fetcherRequest,\n [f.match],\n f.matches\n ).then((r) => r[0]);\n } else {\n return Promise.resolve({\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path,\n }),\n });\n }\n }),\n ]);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n loaderResults.map(() => request.signal),\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map((f) => f.match),\n fetcherResults,\n fetchersToLoad.map((f) => (f.controller ? f.controller.signal : null)),\n true\n ),\n ]);\n\n return {\n loaderResults,\n fetcherResults,\n };\n }\n\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.push(key);\n abortFetcher(key);\n }\n });\n }\n\n function updateFetcherState(\n key: string,\n fetcher: Fetcher,\n opts: { flushSync?: boolean } = {}\n ) {\n state.fetchers.set(key, fetcher);\n updateState(\n { fetchers: new Map(state.fetchers) },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function setFetcherError(\n key: string,\n routeId: string,\n error: any,\n opts: { flushSync?: boolean } = {}\n ) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function getFetcher(key: string): Fetcher {\n if (future.v7_fetcherPersist) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n // If this fetcher was previously marked for deletion, unmark it since we\n // have a new instance\n if (deletedFetchers.has(key)) {\n deletedFetchers.delete(key);\n }\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n\n function deleteFetcher(key: string): void {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (\n fetchControllers.has(key) &&\n !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))\n ) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n deletedFetchers.delete(key);\n state.fetchers.delete(key);\n }\n\n function deleteFetcherAndUpdateState(key: string): void {\n if (future.v7_fetcherPersist) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n deletedFetchers.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n } else {\n deleteFetcher(key);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n\n function abortFetcher(key: string) {\n let controller = fetchControllers.get(key);\n invariant(controller, `Expected fetch controller: ${key}`);\n controller.abort();\n fetchControllers.delete(key);\n }\n\n function markFetchersDone(keys: string[]) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): boolean {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n\n function abortStaleFetchLoads(landedId: number): boolean {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n\n function getBlocker(key: string, fn: BlockerFunction) {\n let blocker: Blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key: string, newBlocker: Blocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(\n (blocker.state === \"unblocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"proceeding\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"unblocked\") ||\n (blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\"),\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n }: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n }): string | undefined {\n if (blockerFunctions.size === 0) {\n return;\n }\n\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n\n function handleNavigational404(pathname: string) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n\n return { notFoundMatches: matches, route, error };\n }\n\n function handleDiscoverRouteError(\n pathname: string,\n discoverResult: DiscoverRoutesErrorResult\n ) {\n return {\n boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,\n error: getInternalRouterError(400, {\n type: \"route-discovery\",\n pathname,\n message:\n discoverResult.error != null && \"message\" in discoverResult.error\n ? discoverResult.error\n : String(discoverResult.error),\n }),\n };\n }\n\n function cancelActiveDeferreds(\n predicate?: (routeId: string) => boolean\n ): string[] {\n let cancelledRouteIds: string[] = [];\n activeDeferreds.forEach((dfd, routeId) => {\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the component\n function enableScrollRestoration(\n positions: Record,\n getPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered \n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n\n return () => {\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n\n function getScrollKey(location: Location, matches: AgnosticDataRouteMatch[]) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n\n function saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n function checkFogOfWar(\n matches: AgnosticDataRouteMatch[] | null,\n routesToUse: AgnosticDataRouteObject[],\n pathname: string\n ): { active: boolean; matches: AgnosticDataRouteMatch[] | null } {\n if (patchRoutesOnMissImpl) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n return { active: true, matches: fogMatches || [] };\n } else {\n let leafRoute = matches[matches.length - 1].route;\n if (\n leafRoute.path &&\n (leafRoute.path === \"*\" || leafRoute.path.endsWith(\"/*\"))\n ) {\n // If we matched a splat, it might only be because we haven't yet fetched\n // the children that would match with a higher score, so let's fetch\n // around and find out\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n\n return { active: false, matches: null };\n }\n\n type DiscoverRoutesSuccessResult = {\n type: \"success\";\n matches: AgnosticDataRouteMatch[] | null;\n };\n type DiscoverRoutesErrorResult = {\n type: \"error\";\n error: any;\n partialMatches: AgnosticDataRouteMatch[];\n };\n type DiscoverRoutesAbortedResult = { type: \"aborted\" };\n type DiscoverRoutesResult =\n | DiscoverRoutesSuccessResult\n | DiscoverRoutesErrorResult\n | DiscoverRoutesAbortedResult;\n\n async function discoverRoutes(\n matches: AgnosticDataRouteMatch[],\n pathname: string,\n signal: AbortSignal\n ): Promise {\n let partialMatches: AgnosticDataRouteMatch[] | null = matches;\n let route =\n partialMatches.length > 0\n ? partialMatches[partialMatches.length - 1].route\n : null;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n try {\n await loadLazyRouteChildren(\n patchRoutesOnMissImpl!,\n pathname,\n partialMatches,\n routesToUse,\n manifest,\n mapRouteProperties,\n pendingPatchRoutes,\n signal\n );\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n } finally {\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity so when we `updateState` at the end of\n // this navigation/fetch `router.routes` will be a new identity and\n // trigger a re-run of memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n }\n }\n\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n let matchedSplat = false;\n if (newMatches) {\n let leafRoute = newMatches[newMatches.length - 1].route;\n\n if (leafRoute.index) {\n // If we found an index route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n\n if (leafRoute.path && leafRoute.path.length > 0) {\n if (leafRoute.path === \"*\") {\n // If we found a splat route, we can't be sure there's not a\n // higher-scoring route down some partial matches trail so we need\n // to check that out\n matchedSplat = true;\n } else {\n // If we found a non-splat route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n\n let newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n // If we are no longer partially matching anything, this was either a\n // legit splat match above, or it's a 404. Also avoid loops if the\n // second pass results in the same partial matches\n if (\n !newPartialMatches ||\n partialMatches.map((m) => m.route.id).join(\"-\") ===\n newPartialMatches.map((m) => m.route.id).join(\"-\")\n ) {\n return { type: \"success\", matches: matchedSplat ? newMatches : null };\n }\n\n partialMatches = newPartialMatches;\n route = partialMatches[partialMatches.length - 1].route;\n if (route.path === \"*\") {\n // The splat is still our most accurate partial, so run with it\n return { type: \"success\", matches: partialMatches };\n }\n }\n }\n\n function _internalSetRoutes(newRoutes: AgnosticDataRouteObject[]) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties,\n undefined,\n manifest\n );\n }\n\n function patchRoutes(\n routeId: string | null,\n children: AgnosticRouteObject[]\n ): void {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n manifest,\n mapRouteProperties\n );\n\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity and trigger a reflow via `updateState`\n // to re-run memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to: To) => init.history.createHref(to),\n encodeLocation: (to: To) => init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher: deleteFetcherAndUpdateState,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface StaticHandlerFutureConfig {\n v7_relativeSplatPath: boolean;\n v7_throwAbortReason: boolean;\n}\n\nexport interface CreateStaticHandlerOptions {\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n}\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: CreateStaticHandlerOptions\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let manifest: RouteManifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (opts?.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts?.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Config driven behavior flags\n let future: StaticHandlerFutureConfig = {\n v7_relativeSplatPath: false,\n v7_throwAbortReason: false,\n ...(opts ? opts.future : null),\n };\n\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n *\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent\n * the bubbling of errors which allows single-fetch-type implementations\n * where the client will handle the bubbling and we may need to return data\n * for the handling route\n */\n async function query(\n request: Request,\n {\n requestContext,\n skipLoaderErrorBubbling,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null\n );\n if (isResponse(result)) {\n return result;\n }\n\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return { location, basename, ...result };\n }\n\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n *\n * - `opts.routeId` allows you to specify the specific route handler to call.\n * If not provided the handler will determine the proper route by matching\n * against `request.url`\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n */\n async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n routeId?: string;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let match = routeId\n ? matches.find((m) => m.route.id === routeId)\n : getTargetMatch(matches, location);\n\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId,\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n false,\n match\n );\n\n if (isResponse(result)) {\n return result;\n }\n\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n\n if (result.loaderData) {\n let data = Object.values(result.loaderData)[0];\n if (result.activeDeferreds?.[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n\n return undefined;\n }\n\n async function queryImpl(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null\n ): Promise | Response> {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(\n request,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch\n );\n return isResponse(result)\n ? result\n : {\n ...result,\n actionData: null,\n actionHeaders: {},\n };\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction for a\n // `queryRoute` call, we throw the `HandlerResult` to bail out early\n // and then return or throw the raw Response here accordingly\n if (isHandlerResult(e) && isResponse(e.result)) {\n if (e.type === ResultType.error) {\n throw e.result;\n }\n return e.result;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n\n async function submit(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n actionMatch: AgnosticDataRouteMatch,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id,\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n result = results[0];\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n }\n\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")!,\n },\n });\n }\n\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, { type: \"defer-action\" });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n }\n\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal,\n });\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = skipLoaderErrorBubbling\n ? actionMatch\n : findNearestBoundary(matches, actionMatch.route.id);\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null,\n [boundaryMatch.route.id, result]\n );\n\n // action status codes take precedence over loader status codes\n return {\n ...context,\n statusCode: isRouteErrorResponse(result.error)\n ? result.error.status\n : result.statusCode != null\n ? result.statusCode\n : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null\n );\n\n return {\n ...context,\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionHeaders: result.headers\n ? { [actionMatch.route.id]: result.headers }\n : {},\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null,\n pendingActionResult?: PendingActionResult\n ): Promise<\n | Omit<\n StaticHandlerContext,\n \"location\" | \"basename\" | \"actionData\" | \"actionHeaders\"\n >\n | Response\n > {\n let isRouteRequest = routeMatch != null;\n\n // Short circuit if we have no loaders to run (queryRoute())\n if (\n isRouteRequest &&\n !routeMatch?.route.loader &&\n !routeMatch?.route.lazy\n ) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id,\n });\n }\n\n let requestMatches = routeMatch\n ? [routeMatch]\n : pendingActionResult && isErrorResult(pendingActionResult[1])\n ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0])\n : matches;\n let matchesToLoad = requestMatches.filter(\n (m) => m.route.loader || m.route.lazy\n );\n\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce(\n (acc, m) => Object.assign(acc, { [m.route.id]: null }),\n {}\n ),\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? {\n [pendingActionResult[0]]: pendingActionResult[1].error,\n }\n : null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await callDataStrategy(\n \"loader\",\n request,\n matchesToLoad,\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n skipLoaderErrorBubbling\n );\n\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(\n matchesToLoad.map((match) => match.route.id)\n );\n matches.forEach((match) => {\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n\n return {\n ...context,\n matches,\n activeDeferreds:\n activeDeferreds.size > 0\n ? Object.fromEntries(activeDeferreds.entries())\n : null,\n };\n }\n\n // Utility wrapper for calling dataStrategy server-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n isRouteRequest: boolean,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null\n ): Promise {\n let results = await callDataStrategyImpl(\n unstable_dataStrategy || defaultDataStrategy,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties,\n requestContext\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n // Throw redirects and let the server handle them with an HTTP redirect\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n );\n }\n if (isResponse(result.result) && isRouteRequest) {\n // For SSR single-route requests, we want to hand Responses back\n // directly without unwrapping\n throw result;\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n }\n\n return {\n dataRoutes,\n query,\n queryRoute,\n };\n}\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */\nexport function getStaticContextFromError(\n routes: AgnosticDataRouteObject[],\n context: StaticHandlerContext,\n error: any\n) {\n let newContext: StaticHandlerContext = {\n ...context,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction throwStaticHandlerAbortedError(\n request: Request,\n isRouteRequest: boolean,\n future: StaticHandlerFutureConfig\n) {\n if (future.v7_throwAbortReason && request.signal.reason !== undefined) {\n throw request.signal.reason;\n }\n\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted: ${request.method} ${request.url}`);\n}\n\nfunction isSubmissionNavigation(\n opts: BaseNavigateOrFetchOptions\n): opts is SubmissionNavigateOptions {\n return (\n opts != null &&\n ((\"formData\" in opts && opts.formData != null) ||\n (\"body\" in opts && opts.body !== undefined))\n );\n}\n\nfunction normalizeTo(\n location: Path,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n prependBasename: boolean,\n to: To | null,\n v7_relativeSplatPath: boolean,\n fromRouteId?: string,\n relative?: RelativeRoutingType\n) {\n let contextualMatches: AgnosticDataRouteMatch[];\n let activeRouteMatch: AgnosticDataRouteMatch | undefined;\n if (fromRouteId) {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n\n // Resolve the relative path\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches, v7_relativeSplatPath),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n\n // Add an ?index param for matched index routes if we don't already have one\n if (\n (to == null || to === \"\" || to === \".\") &&\n activeRouteMatch &&\n activeRouteMatch.route.index &&\n !hasNakedIndexQuery(path.search)\n ) {\n path.search = path.search\n ? path.search.replace(/^\\?/, \"?index&\")\n : \"?index\";\n }\n\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname =\n path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n\n return createPath(path);\n}\n\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(\n normalizeFormMethod: boolean,\n isFetcher: boolean,\n path: string,\n opts?: BaseNavigateOrFetchOptions\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponseImpl;\n} {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod }),\n };\n }\n\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" }),\n });\n\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod\n ? (rawFormMethod.toUpperCase() as V7_FormMethod)\n : (rawFormMethod.toLowerCase() as FormMethod);\n let formAction = stripHashFromPath(path);\n\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n let text =\n typeof opts.body === \"string\"\n ? opts.body\n : opts.body instanceof FormData ||\n opts.body instanceof URLSearchParams\n ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\\n`,\n \"\"\n )\n : String(opts.body);\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text,\n },\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n try {\n let json =\n typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined,\n },\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n\n let searchParams: URLSearchParams;\n let formData: FormData;\n\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n\n let submission: Submission = {\n formMethod,\n formAction,\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n\n return { path: createPath(parsedPath), submission };\n}\n\n// Filter out all routes below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(\n matches: AgnosticDataRouteMatch[],\n boundaryId: string\n) {\n let boundaryMatches = matches;\n if (boundaryId) {\n let index = matches.findIndex((m) => m.route.id === boundaryId);\n if (index >= 0) {\n boundaryMatches = matches.slice(0, index);\n }\n }\n return boundaryMatches;\n}\n\nfunction getMatchesToLoad(\n history: History,\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n submission: Submission | undefined,\n location: Location,\n isInitialLoad: boolean,\n skipActionErrorRevalidation: boolean,\n isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n deletedFetchers: Set,\n fetchLoadMatches: Map,\n fetchRedirectIds: Set,\n routesToUse: AgnosticDataRouteObject[],\n basename: string | undefined,\n pendingActionResult?: PendingActionResult\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingActionResult\n ? isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : pendingActionResult[1].data\n : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[0]\n : undefined;\n let boundaryMatches = boundaryId\n ? getLoaderMatchesUntilBoundary(matches, boundaryId)\n : matches;\n\n // Don't revalidate loaders by default after action 4xx/5xx responses\n // when the flag is enabled. They can still opt-into revalidation via\n // `shouldRevalidate` via `actionResult`\n let actionStatus = pendingActionResult\n ? pendingActionResult[1].statusCode\n : undefined;\n let shouldSkipRevalidation =\n skipActionErrorRevalidation && actionStatus && actionStatus >= 400;\n\n let navigationMatches = boundaryMatches.filter((match, index) => {\n let { route } = match;\n if (route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n\n if (route.loader == null) {\n return false;\n }\n\n if (isInitialLoad) {\n if (typeof route.loader !== \"function\" || route.loader.hydrate) {\n return true;\n }\n return (\n state.loaderData[route.id] === undefined &&\n // Don't re-run if the loader ran and threw an error\n (!state.errors || state.errors[route.id] === undefined)\n );\n }\n\n // Always call the loader on new route instances and pending defer cancellations\n if (\n isNewLoader(state.loaderData, state.matches[index], match) ||\n cancelledDeferredRoutes.some((id) => id === match.route.id)\n ) {\n return true;\n }\n\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n\n return shouldRevalidateLoader(match, {\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired ||\n currentUrl.pathname + currentUrl.search ===\n nextUrl.pathname + nextUrl.search ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n isNewRouteInstance(currentRouteMatch, nextRouteMatch),\n });\n });\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches.forEach((f, key) => {\n // Don't revalidate:\n // - on initial load (shouldn't be any fetchers then anyway)\n // - if fetcher won't be present in the subsequent render\n // - no longer matches the URL (v7_fetcherPersist=false)\n // - was unmounted but persisted due to v7_fetcherPersist=true\n if (\n isInitialLoad ||\n !matches.some((m) => m.route.id === f.routeId) ||\n deletedFetchers.has(key)\n ) {\n return;\n }\n\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null,\n });\n return;\n }\n\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.includes(key)) {\n // Always revalidate if the fetcher was cancelled\n shouldRevalidate = true;\n } else if (\n fetcher &&\n fetcher.state !== \"idle\" &&\n fetcher.data === undefined\n ) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, {\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : isRevalidationRequired,\n });\n }\n\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController(),\n });\n }\n });\n\n return [navigationMatches, revalidatingFetchers];\n}\n\nfunction isNewLoader(\n currentLoaderData: RouteData,\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let isNew =\n // [a] -> [a, b]\n !currentMatch ||\n // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\n\nfunction isNewRouteInstance(\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname ||\n // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n (currentPath != null &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n loaderMatch: AgnosticDataRouteMatch,\n arg: ShouldRevalidateFunctionArgs\n) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return arg.defaultShouldRevalidate;\n}\n\n/**\n * Idempotent utility to execute patchRoutesOnMiss() to lazily load route\n * definitions and update the routes/routeManifest\n */\nasync function loadLazyRouteChildren(\n patchRoutesOnMissImpl: AgnosticPatchRoutesOnMissFunction,\n path: string,\n matches: AgnosticDataRouteMatch[],\n routes: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n pendingRouteChildren: Map>,\n signal: AbortSignal\n) {\n let key = [path, ...matches.map((m) => m.route.id)].join(\"-\");\n try {\n let pending = pendingRouteChildren.get(key);\n if (!pending) {\n pending = patchRoutesOnMissImpl({\n path,\n matches,\n patch: (routeId, children) => {\n if (!signal.aborted) {\n patchRoutesImpl(\n routeId,\n children,\n routes,\n manifest,\n mapRouteProperties\n );\n }\n },\n });\n pendingRouteChildren.set(key, pending);\n }\n\n if (pending && isPromise(pending)) {\n await pending;\n }\n } finally {\n pendingRouteChildren.delete(key);\n }\n}\n\nfunction patchRoutesImpl(\n routeId: string | null,\n children: AgnosticRouteObject[],\n routesToUse: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction\n) {\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [routeId, \"patch\", String(route.children?.length || \"0\")],\n manifest\n );\n if (route.children) {\n route.children.push(...dataChildren);\n } else {\n route.children = dataChildren;\n }\n } else {\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [\"patch\", String(routesToUse.length || \"0\")],\n manifest\n );\n routesToUse.push(...dataChildren);\n }\n}\n\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */\nasync function loadLazyRouteModule(\n route: AgnosticDataRouteObject,\n mapRouteProperties: MapRoutePropertiesFunction,\n manifest: RouteManifest\n) {\n if (!route.lazy) {\n return;\n }\n\n let lazyRoute = await route.lazy();\n\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates: Record = {};\n for (let lazyRouteProperty in lazyRoute) {\n let staticRouteValue =\n routeToUpdate[lazyRouteProperty as keyof typeof routeToUpdate];\n\n let isPropertyStaticallyDefined =\n staticRouteValue !== undefined &&\n // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n\n warning(\n !isPropertyStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" ` +\n `defined but its lazy function is also returning a value for this property. ` +\n `The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n\n if (\n !isPropertyStaticallyDefined &&\n !immutableRouteKeys.has(lazyRouteProperty as ImmutableRouteKey)\n ) {\n routeUpdates[lazyRouteProperty] =\n lazyRoute[lazyRouteProperty as keyof typeof lazyRoute];\n }\n }\n\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided\n // `mapRouteProperties` (or wrapped `detectErrorBoundary`) function to\n // set the framework-aware properties (`element`/`hasErrorBoundary`) since\n // the logic will differ between frameworks.\n ...mapRouteProperties(routeToUpdate),\n lazy: undefined,\n });\n}\n\n// Default implementation of `dataStrategy` which fetches all loaders in parallel\nfunction defaultDataStrategy(\n opts: DataStrategyFunctionArgs\n): ReturnType {\n return Promise.all(opts.matches.map((m) => m.resolve()));\n}\n\nasync function callDataStrategyImpl(\n dataStrategyImpl: DataStrategyFunction,\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n requestContext?: unknown\n): Promise {\n let routeIdsToLoad = matchesToLoad.reduce(\n (acc, m) => acc.add(m.route.id),\n new Set()\n );\n let loadedMatches = new Set();\n\n // Send all matches here to allow for a middleware-type implementation.\n // handler will be a no-op for unneeded routes and we filter those results\n // back out below.\n let results = await dataStrategyImpl({\n matches: matches.map((match) => {\n let shouldLoad = routeIdsToLoad.has(match.route.id);\n // `resolve` encapsulates the route.lazy, executing the\n // loader/action, and mapping return values/thrown errors to a\n // HandlerResult. Users can pass a callback to take fine-grained control\n // over the execution of the loader/action\n let resolve: DataStrategyMatch[\"resolve\"] = (handlerOverride) => {\n loadedMatches.add(match.route.id);\n return shouldLoad\n ? callLoaderOrAction(\n type,\n request,\n match,\n manifest,\n mapRouteProperties,\n handlerOverride,\n requestContext\n )\n : Promise.resolve({ type: ResultType.data, result: undefined });\n };\n\n return {\n ...match,\n shouldLoad,\n resolve,\n };\n }),\n request,\n params: matches[0].params,\n context: requestContext,\n });\n\n // Throw if any loadRoute implementations not called since they are what\n // ensures a route is fully loaded\n matches.forEach((m) =>\n invariant(\n loadedMatches.has(m.route.id),\n `\\`match.resolve()\\` was not called for route id \"${m.route.id}\". ` +\n \"You must call `match.resolve()` on every match passed to \" +\n \"`dataStrategy` to ensure all routes are properly loaded.\"\n )\n );\n\n // Filter out any middleware-only matches for which we didn't need to run handlers\n return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id));\n}\n\n// Default logic for calling a loader/action is the user has no specified a dataStrategy\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n handlerOverride: Parameters[0],\n staticContext?: unknown\n): Promise {\n let result: HandlerResult;\n let onReject: (() => void) | undefined;\n\n let runHandler = (\n handler: AgnosticRouteObject[\"loader\"] | AgnosticRouteObject[\"action\"]\n ): Promise => {\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n // This will never resolve so safe to type it as Promise to\n // satisfy the function return value\n let abortPromise = new Promise((_, r) => (reject = r));\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n let actualHandler = (ctx?: unknown) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean ` +\n `\"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n params: match.params,\n context: staticContext,\n },\n ...(ctx !== undefined ? [ctx] : [])\n );\n };\n\n let handlerPromise: Promise;\n if (handlerOverride) {\n handlerPromise = handlerOverride((ctx: unknown) => actualHandler(ctx));\n } else {\n handlerPromise = (async () => {\n try {\n let val = await actualHandler();\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n }\n\n return Promise.race([handlerPromise, abortPromise]);\n };\n\n try {\n let handler = match.route[type];\n\n if (match.route.lazy) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n loadLazyRouteModule(match.route, mapRouteProperties, manifest),\n ]);\n if (handlerError !== undefined) {\n throw handlerError;\n }\n result = value!;\n } else {\n // Load lazy route module, then run any returned handler\n await loadLazyRouteModule(match.route, mapRouteProperties, manifest);\n\n handler = match.route[type];\n if (handler) {\n // Handler still runs even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id,\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return { type: ResultType.data, result: undefined };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname,\n });\n } else {\n result = await runHandler(handler);\n }\n\n invariant(\n result.result !== undefined,\n `You defined ${type === \"action\" ? \"an action\" : \"a loader\"} for route ` +\n `\"${match.route.id}\" but didn't return anything from your \\`${type}\\` ` +\n `function. Please return a value or \\`null\\`.`\n );\n } catch (e) {\n // We should already be catching and converting normal handler executions to\n // HandlerResults and returning them, so anything that throws here is an\n // unexpected error we still need to wrap\n return { type: ResultType.error, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n\n return result;\n}\n\nasync function convertHandlerResultToDataResult(\n handlerResult: HandlerResult\n): Promise {\n let { result, type, status } = handlerResult;\n\n if (isResponse(result)) {\n let data: any;\n\n try {\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n if (result.body == null) {\n data = null;\n } else {\n data = await result.json();\n }\n } else {\n data = await result.text();\n }\n } catch (e) {\n return { type: ResultType.error, error: e };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(result.status, result.statusText, data),\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : status,\n };\n }\n\n if (isDeferredData(result)) {\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: result.init?.status,\n headers: result.init?.headers && new Headers(result.init.headers),\n };\n }\n\n return { type: ResultType.data, data: result, statusCode: status };\n}\n\n// Support relative routing in internal redirects\nfunction normalizeRelativeRoutingRedirectResponse(\n response: Response,\n request: Request,\n routeId: string,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n v7_relativeSplatPath: boolean\n) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n true,\n location,\n v7_relativeSplatPath\n );\n response.headers.set(\"Location\", location);\n }\n\n return response;\n}\n\nfunction normalizeRedirectLocation(\n location: string,\n currentUrl: URL,\n basename: string\n): string {\n if (ABSOLUTE_URL_REGEX.test(location)) {\n // Strip off the protocol+origin for same-origin + same-basename absolute redirects\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\")\n ? new URL(currentUrl.protocol + normalizedLocation)\n : new URL(normalizedLocation);\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n return location;\n}\n\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(\n history: History,\n location: string | Location,\n signal: AbortSignal,\n submission?: Submission\n): Request {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init: RequestInit = { signal };\n\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (\n formEncType === \"application/x-www-form-urlencoded\" &&\n submission.formData\n ) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n\n return new Request(url, init);\n}\n\nfunction convertFormDataToSearchParams(formData: FormData): URLSearchParams {\n let searchParams = new URLSearchParams();\n\n for (let [key, value] of formData.entries()) {\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n\n return searchParams;\n}\n\nfunction convertSearchParamsToFormData(\n searchParams: URLSearchParams\n): FormData {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n activeDeferreds: Map,\n skipLoaderErrorBubbling: boolean\n): {\n loaderData: RouterState[\"loaderData\"];\n errors: RouterState[\"errors\"] | null;\n statusCode: number;\n loaderHeaders: Record;\n} {\n // Fill in loaderData/errors from our loaders\n let loaderData: RouterState[\"loaderData\"] = {};\n let errors: RouterState[\"errors\"] | null = null;\n let statusCode: number | undefined;\n let foundError = false;\n let loaderHeaders: Record = {};\n let pendingError =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : undefined;\n\n // Process loader results into state.loaderData/state.errors\n results.forEach((result, index) => {\n let id = matchesToLoad[index].route.id;\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError !== undefined) {\n error = pendingError;\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n // Look upwards from the matched route for the closest ancestor error\n // boundary, defaulting to the root match. Prefer higher error values\n // if lower errors bubble to the same boundary\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error)\n ? result.error.status\n : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (\n result.statusCode != null &&\n result.statusCode !== 200 &&\n !foundError\n ) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n }\n });\n\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError !== undefined && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n loaderData[pendingActionResult[0]] = undefined;\n }\n\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders,\n };\n}\n\nfunction processLoaderData(\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n revalidatingFetchers: RevalidatingFetcher[],\n fetcherResults: DataResult[],\n activeDeferreds: Map\n): {\n loaderData: RouterState[\"loaderData\"];\n errors?: RouterState[\"errors\"];\n} {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n false // This method is only called client side so we always want to bubble\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let { key, match, controller } = revalidatingFetchers[index];\n invariant(\n fetcherResults !== undefined && fetcherResults[index] !== undefined,\n \"Did not find corresponding fetcher result\"\n );\n let result = fetcherResults[index];\n\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n // Nothing to do for aborted fetchers\n continue;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error,\n };\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n return { loaderData, errors };\n}\n\nfunction mergeLoaderData(\n loaderData: RouteData,\n newLoaderData: RouteData,\n matches: AgnosticDataRouteMatch[],\n errors: RouteData | null | undefined\n): RouteData {\n let mergedLoaderData = { ...newLoaderData };\n for (let match of matches) {\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n } else {\n // No-op - this is so we ignore existing data if we have a key in the\n // incoming object with an undefined value, which is how we unset a prior\n // loaderData if we encounter a loader error\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n\n if (errors && errors.hasOwnProperty(id)) {\n // Don't keep any loader data below the boundary\n break;\n }\n }\n return mergedLoaderData;\n}\n\nfunction getActionDataForCommit(\n pendingActionResult: PendingActionResult | undefined\n) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1])\n ? {\n // Clear out prior actionData on errors\n actionData: {},\n }\n : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data,\n },\n };\n}\n\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(\n matches: AgnosticDataRouteMatch[],\n routeId?: string\n): AgnosticDataRouteMatch {\n let eligibleMatches = routeId\n ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1)\n : [...matches];\n return (\n eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) ||\n matches[0]\n );\n}\n\nfunction getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {\n matches: AgnosticDataRouteMatch[];\n route: AgnosticDataRouteObject;\n} {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route =\n routes.length === 1\n ? routes[0]\n : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`,\n };\n\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route,\n },\n ],\n route,\n };\n}\n\nfunction getInternalRouterError(\n status: number,\n {\n pathname,\n routeId,\n method,\n type,\n message,\n }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\" | \"invalid-body\" | \"route-discovery\";\n message?: string;\n } = {}\n) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n\n if (status === 400) {\n statusText = \"Bad Request\";\n if (type === \"route-discovery\") {\n errorMessage =\n `Unable to match URL \"${pathname}\" - the \\`unstable_patchRoutesOnMiss()\\` ` +\n `function threw the following error:\\n${message}`;\n } else if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method} request to \"${pathname}\" but ` +\n `did not provide a \\`loader\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method.toUpperCase()} request to \"${pathname}\" but ` +\n `did not provide an \\`action\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\n\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(\n results: DataResult[]\n): { result: RedirectResult; idx: number } | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return { result, idx: i };\n }\n }\n}\n\nfunction stripHashFromPath(path: To) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\n\nfunction isHashChangeOnly(a: Location, b: Location): boolean {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\n\nfunction isPromise(val: unknown): val is Promise {\n return typeof val === \"object\" && val != null && \"then\" in val;\n}\n\nfunction isHandlerResult(result: unknown): result is HandlerResult {\n return (\n result != null &&\n typeof result === \"object\" &&\n \"type\" in result &&\n \"result\" in result &&\n (result.type === ResultType.data || result.type === ResultType.error)\n );\n}\n\nfunction isRedirectHandlerResult(result: HandlerResult) {\n return (\n isResponse(result.result) && redirectStatusCodes.has(result.result.status)\n );\n}\n\nfunction isDeferredResult(result: DataResult): result is DeferredResult {\n return result.type === ResultType.deferred;\n}\n\nfunction isErrorResult(result: DataResult): result is ErrorResult {\n return result.type === ResultType.error;\n}\n\nfunction isRedirectResult(result?: DataResult): result is RedirectResult {\n return (result && result.type) === ResultType.redirect;\n}\n\nexport function isDeferredData(value: any): value is DeferredData {\n let deferred: DeferredData = value;\n return (\n deferred &&\n typeof deferred === \"object\" &&\n typeof deferred.data === \"object\" &&\n typeof deferred.subscribe === \"function\" &&\n typeof deferred.cancel === \"function\" &&\n typeof deferred.resolveData === \"function\"\n );\n}\n\nfunction isResponse(value: any): value is Response {\n return (\n value != null &&\n typeof value.status === \"number\" &&\n typeof value.statusText === \"string\" &&\n typeof value.headers === \"object\" &&\n typeof value.body !== \"undefined\"\n );\n}\n\nfunction isRedirectResponse(result: any): result is Response {\n if (!isResponse(result)) {\n return false;\n }\n\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\n\nfunction isValidMethod(method: string): method is FormMethod | V7_FormMethod {\n return validRequestMethods.has(method.toLowerCase() as FormMethod);\n}\n\nfunction isMutationMethod(\n method: string\n): method is MutationFormMethod | V7_MutationFormMethod {\n return validMutationMethods.has(method.toLowerCase() as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: (AgnosticDataRouteMatch | null)[],\n results: DataResult[],\n signals: (AbortSignal | null)[],\n isFetcher: boolean,\n currentLoaderData?: RouteData\n) {\n for (let index = 0; index < results.length; index++) {\n let result = results[index];\n let match = matchesToLoad[index];\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n\n let currentMatch = currentMatches.find(\n (m) => m.route.id === match!.route.id\n );\n let isRevalidatingLoader =\n currentMatch != null &&\n !isNewRouteInstance(currentMatch, match) &&\n (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n\n if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n let signal = signals[index];\n invariant(\n signal,\n \"Expected an AbortSignal for revalidating fetcher deferred result\"\n );\n await resolveDeferredData(result, signal, isFetcher).then((result) => {\n if (result) {\n results[index] = result || results[index];\n }\n });\n }\n }\n}\n\nasync function resolveDeferredData(\n result: DeferredResult,\n signal: AbortSignal,\n unwrap = false\n): Promise {\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData,\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e,\n };\n }\n }\n\n return {\n type: ResultType.data,\n data: result.deferredData.data,\n };\n}\n\nfunction hasNakedIndexQuery(search: string): boolean {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\n\nfunction getTargetMatch(\n matches: AgnosticDataRouteMatch[],\n location: Location | string\n) {\n let search =\n typeof location === \"string\" ? parsePath(location).search : location.search;\n if (\n matches[matches.length - 1].route.index &&\n hasNakedIndexQuery(search || \"\")\n ) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\n\nfunction getSubmissionFromNavigation(\n navigation: Navigation\n): Submission | undefined {\n let { formMethod, formAction, formEncType, text, formData, json } =\n navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text,\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined,\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined,\n };\n }\n}\n\nfunction getLoadingNavigation(\n location: Location,\n submission?: Submission\n): NavigationStates[\"Loading\"] {\n if (submission) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n } else {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n };\n return navigation;\n }\n}\n\nfunction getSubmittingNavigation(\n location: Location,\n submission: Submission\n): NavigationStates[\"Submitting\"] {\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n}\n\nfunction getLoadingFetcher(\n submission?: Submission,\n data?: Fetcher[\"data\"]\n): FetcherStates[\"Loading\"] {\n if (submission) {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data,\n };\n return fetcher;\n } else {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n }\n}\n\nfunction getSubmittingFetcher(\n submission: Submission,\n existingFetcher?: Fetcher\n): FetcherStates[\"Submitting\"] {\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined,\n };\n return fetcher;\n}\n\nfunction getDoneFetcher(data: Fetcher[\"data\"]): FetcherStates[\"Idle\"] {\n let fetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n}\n\nfunction restoreAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n // no-op, use default empty object\n }\n}\n\nfunction persistAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n if (transitions.size > 0) {\n let json: Record = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\n//#endregion\n"],"names":["Action","PopStateEventType","createMemoryHistory","options","initialEntries","initialIndex","v5Compat","entries","map","entry","index","createMemoryLocation","state","undefined","clampIndex","length","action","Pop","listener","n","Math","min","max","getCurrentLocation","to","key","location","createLocation","pathname","warning","charAt","JSON","stringify","createHref","createPath","history","createURL","URL","encodeLocation","path","parsePath","search","hash","push","Push","nextLocation","splice","delta","replace","Replace","go","nextIndex","listen","fn","createBrowserHistory","createBrowserLocation","window","globalHistory","usr","createBrowserHref","getUrlBasedHistory","createHashHistory","createHashLocation","substr","startsWith","createHashHref","base","document","querySelector","href","getAttribute","url","hashIndex","indexOf","slice","validateHashLocation","invariant","value","message","Error","cond","console","warn","e","createKey","random","toString","getHistoryState","idx","current","_extends","_ref","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","historyState","pushState","error","DOMException","name","assign","origin","addEventListener","removeEventListener","ResultType","immutableRouteKeys","Set","isIndexRoute","route","convertRoutesToDataRoutes","routes","mapRouteProperties","parentPath","manifest","treePath","String","id","join","children","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","matchRoutesImpl","allowPartial","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","decoded","decodePath","matchRouteBranch","convertRouteMatchToUiMatch","match","loaderData","params","data","handle","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","joinPaths","routesMeta","concat","score","computeScore","forEach","_route$path","includes","exploded","explodeOptionalSegments","segments","split","first","rest","isOptional","endsWith","required","restExploded","result","subpath","sort","a","b","compareIndexes","paramRe","dynamicSegmentValue","indexRouteValue","emptySegmentValue","staticSegmentValue","splatPenalty","isSplat","s","initialScore","some","filter","reduce","segment","test","siblings","every","branch","matchedParams","matchedPathname","end","remainingPathname","matchPath","Object","pathnameBase","normalizePathname","generatePath","originalPath","prefix","p","array","isLastSegment","star","keyMatch","optional","param","pattern","matcher","compiledParams","compilePath","captureGroups","memo","paramName","splatValue","regexpSource","_","RegExp","v","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","getResolveToMatches","v7_relativeSplatPath","pathMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","init","responseInit","status","headers","Headers","has","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","_ref2","trackPromise","done","add","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","undefinedError","emit","settledKey","subscriber","subscribe","cancel","abort","k","resolveData","resolve","size","unwrappedData","_ref3","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","redirectDocument","response","ErrorResponseImpl","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","text","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","ABSOLUTE_URL_REGEX","defaultMapRouteProperties","hasErrorBoundary","Boolean","TRANSITIONS_STORAGE_KEY","createRouter","routerWindow","isBrowser","createElement","isServer","detectErrorBoundary","dataRoutes","inFlightDataRoutes","dataStrategyImpl","unstable_dataStrategy","defaultDataStrategy","patchRoutesOnMissImpl","unstable_patchRoutesOnMiss","future","v7_fetcherPersist","v7_normalizeFormMethod","v7_partialHydration","v7_prependBasename","v7_skipActionErrorRevalidation","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","fogOfWar","checkFogOfWar","active","initialized","m","lazy","loader","errors","isRouteInitialized","hydrate","findIndex","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","actionData","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","pendingViewTransitionEnabled","appliedViewTransitions","removePageHideEventListener","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeFetchers","deletedFetchers","activeDeferreds","blockerFunctions","pendingPatchRoutes","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","updateState","startNavigation","restoreAppliedTransitions","_saveAppliedTransitions","persistAppliedTransitions","initialHydration","dispose","clear","deleteFetcher","deleteBlocker","newState","opts","completedFetchers","deletedFetchersKeys","fetcher","unstable_viewTransitionOpts","viewTransitionOpts","unstable_flushSync","flushSync","completeNavigation","_temp","_location$state","_location$state2","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","priorPaths","toPaths","getSavedScrollPosition","navigate","normalizedPath","normalizeTo","fromRouteId","relative","submission","normalizeNavigateOptions","userReplace","pendingError","enableViewTransition","unstable_viewTransition","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","routesToUse","loadingNavigation","notFoundMatches","handleNavigational404","isHashChangeOnly","request","createClientSideRequest","pendingActionResult","findNearestBoundary","type","actionResult","handleAction","shortCircuited","routeId","isErrorResult","getLoadingNavigation","updatedMatches","handleLoaders","fetcherSubmission","getActionDataForCommit","isFogOfWar","getSubmittingNavigation","discoverResult","discoverRoutes","boundaryId","handleDiscoverRouteError","partialMatches","actionMatch","getTargetMatch","method","results","callDataStrategy","isRedirectResult","normalizeRedirectLocation","startRedirectNavigation","isDeferredResult","boundaryMatch","activeSubmission","getSubmissionFromNavigation","shouldUpdateNavigationState","getUpdatedActionData","matchesToLoad","revalidatingFetchers","getMatchesToLoad","cancelActiveDeferreds","updatedFetchers","markFetchRedirectsDone","updates","getUpdatedRevalidatingFetchers","rf","abortFetcher","abortPendingFetchRevalidations","f","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","fetcherKey","processLoaderData","deferredData","didAbortFetchLoads","abortStaleFetchLoads","shouldUpdateFetchers","revalidatingFetcher","getLoadingFetcher","fetch","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","detectAndHandle405Error","existingFetcher","updateFetcherState","getSubmittingFetcher","abortController","fetchRequest","originatingLoadId","actionResults","getDoneFetcher","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","_temp2","redirectLocation","isDocumentReload","redirectHistoryAction","callDataStrategyImpl","all","isRedirectHandlerResult","normalizeRelativeRoutingRedirectResponse","convertHandlerResultToDataResult","currentMatches","fetchersToLoad","fetcherRequest","resolveDeferredResults","getFetcher","deleteFetcherAndUpdateState","count","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","_ref4","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","getScrollKey","fogMatches","leafRoute","isNonHMR","loadLazyRouteChildren","newMatches","matchedSplat","newPartialMatches","_internalSetRoutes","newRoutes","patchRoutes","patchRoutesImpl","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","v7_throwAbortReason","query","_temp3","requestContext","skipLoaderErrorBubbling","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","_temp4","find","values","_result$activeDeferre","routeMatch","submit","loadRouteData","isHandlerResult","isRedirectResponse","isRouteRequest","throwStaticHandlerAbortedError","Location","loaderRequest","Request","context","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","reason","isSubmissionNavigation","body","prependBasename","contextualMatches","activeRouteMatch","hasNakedIndexQuery","normalizeFormMethod","isFetcher","getInvalidBodyError","rawFormMethod","toUpperCase","stripHashFromPath","FormData","URLSearchParams","_ref5","parse","searchParams","convertFormDataToSearchParams","convertSearchParamsToFormData","append","boundaryMatches","isInitialLoad","skipActionErrorRevalidation","currentUrl","nextUrl","actionStatus","shouldSkipRevalidation","navigationMatches","isNewLoader","currentRouteMatch","nextRouteMatch","shouldRevalidateLoader","currentParams","nextParams","defaultShouldRevalidate","isNewRouteInstance","fetcherMatches","fetcherMatch","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","currentPath","loaderMatch","arg","routeChoice","pendingRouteChildren","pending","patch","isPromise","_route$children","dataChildren","loadLazyRouteModule","lazyRoute","routeToUpdate","routeUpdates","lazyRouteProperty","staticRouteValue","isPropertyStaticallyDefined","routeIdsToLoad","loadedMatches","shouldLoad","handlerOverride","callLoaderOrAction","staticContext","onReject","runHandler","handler","actualHandler","ctx","handlerPromise","val","handlerError","handlerResult","contentType","isDeferredData","_result$init","_result$init2","deferred","trimmedMatches","normalizedLocation","protocol","isSameBasename","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","_temp5","errorMessage","signals","isRevalidatingLoader","unwrap","getAll","_window","transitions","sessionPositions","sessionStorage","getItem","setItem"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@remix-run/router/dist/router.umd.js b/node_modules/@remix-run/router/dist/router.umd.js new file mode 100644 index 0000000000..b6f62f7bc6 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.js @@ -0,0 +1,5446 @@ +/** + * @remix-run/router v1.18.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.RemixRouter = {})); +})(this, (function (exports) { 'use strict'; + + function _extends() { + _extends = Object.assign ? Object.assign.bind() : function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + return _extends.apply(this, arguments); + } + + //////////////////////////////////////////////////////////////////////////////// + //#region Types and Constants + //////////////////////////////////////////////////////////////////////////////// + + /** + * Actions represent the type of change to a location value. + */ + let Action = /*#__PURE__*/function (Action) { + Action["Pop"] = "POP"; + Action["Push"] = "PUSH"; + Action["Replace"] = "REPLACE"; + return Action; + }({}); + + /** + * The pathname, search, and hash values of a URL. + */ + + // TODO: (v7) Change the Location generic default from `any` to `unknown` and + // remove Remix `useLocation` wrapper. + /** + * An entry in a history stack. A location contains information about the + * URL path, as well as possibly some arbitrary state and a key. + */ + /** + * A change to the current location. + */ + /** + * A function that receives notifications about location changes. + */ + /** + * Describes a location that is the destination of some navigation, either via + * `history.push` or `history.replace`. This may be either a URL or the pieces + * of a URL path. + */ + /** + * A history is an interface to the navigation stack. The history serves as the + * source of truth for the current location, as well as provides a set of + * methods that may be used to change it. + * + * It is similar to the DOM's `window.history` object, but with a smaller, more + * focused API. + */ + const PopStateEventType = "popstate"; + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region Memory History + //////////////////////////////////////////////////////////////////////////////// + + /** + * A user-supplied object that describes a location. Used when providing + * entries to `createMemoryHistory` via its `initialEntries` option. + */ + /** + * A memory history stores locations in memory. This is useful in stateful + * environments where there is no web browser, such as node tests or React + * Native. + */ + /** + * Memory history stores the current location in memory. It is designed for use + * in stateful non-browser environments like tests and React Native. + */ + function createMemoryHistory(options) { + if (options === void 0) { + options = {}; + } + let { + initialEntries = ["/"], + initialIndex, + v5Compat = false + } = options; + let entries; // Declare so we can access from createMemoryLocation + entries = initialEntries.map((entry, index) => createMemoryLocation(entry, typeof entry === "string" ? null : entry.state, index === 0 ? "default" : undefined)); + let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex); + let action = Action.Pop; + let listener = null; + function clampIndex(n) { + return Math.min(Math.max(n, 0), entries.length - 1); + } + function getCurrentLocation() { + return entries[index]; + } + function createMemoryLocation(to, state, key) { + if (state === void 0) { + state = null; + } + let location = createLocation(entries ? getCurrentLocation().pathname : "/", to, state, key); + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in memory history: " + JSON.stringify(to)); + return location; + } + function createHref(to) { + return typeof to === "string" ? to : createPath(to); + } + let history = { + get index() { + return index; + }, + get action() { + return action; + }, + get location() { + return getCurrentLocation(); + }, + createHref, + createURL(to) { + return new URL(createHref(to), "http://localhost"); + }, + encodeLocation(to) { + let path = typeof to === "string" ? parsePath(to) : to; + return { + pathname: path.pathname || "", + search: path.search || "", + hash: path.hash || "" + }; + }, + push(to, state) { + action = Action.Push; + let nextLocation = createMemoryLocation(to, state); + index += 1; + entries.splice(index, entries.length, nextLocation); + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 1 + }); + } + }, + replace(to, state) { + action = Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 0 + }); + } + }, + go(delta) { + action = Action.Pop; + let nextIndex = clampIndex(index + delta); + let nextLocation = entries[nextIndex]; + index = nextIndex; + if (listener) { + listener({ + action, + location: nextLocation, + delta + }); + } + }, + listen(fn) { + listener = fn; + return () => { + listener = null; + }; + } + }; + return history; + } + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region Browser History + //////////////////////////////////////////////////////////////////////////////// + + /** + * A browser history stores the current location in regular URLs in a web + * browser environment. This is the standard for most web apps and provides the + * cleanest URLs the browser's address bar. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory + */ + /** + * Browser history stores the location in regular URLs. This is the standard for + * most web apps, but it requires some configuration on the server to ensure you + * serve the same app at multiple URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory + */ + function createBrowserHistory(options) { + if (options === void 0) { + options = {}; + } + function createBrowserLocation(window, globalHistory) { + let { + pathname, + search, + hash + } = window.location; + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createBrowserHref(window, to) { + return typeof to === "string" ? to : createPath(to); + } + return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options); + } + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region Hash History + //////////////////////////////////////////////////////////////////////////////// + + /** + * A hash history stores the current location in the fragment identifier portion + * of the URL in a web browser environment. + * + * This is ideal for apps that do not control the server for some reason + * (because the fragment identifier is never sent to the server), including some + * shared hosting environments that do not provide fine-grained controls over + * which pages are served at which URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory + */ + /** + * Hash history stores the location in window.location.hash. This makes it ideal + * for situations where you don't want to send the location to the server for + * some reason, either because you do cannot configure it or the URL space is + * reserved for something else. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory + */ + function createHashHistory(options) { + if (options === void 0) { + options = {}; + } + function createHashLocation(window, globalHistory) { + let { + pathname = "/", + search = "", + hash = "" + } = parsePath(window.location.hash.substr(1)); + + // Hash URL should always have a leading / just like window.location.pathname + // does, so if an app ends up at a route like /#something then we add a + // leading slash so all of our path-matching behaves the same as if it would + // in a browser router. This is particularly important when there exists a + // root splat route () since that matches internally against + // "/*" and we'd expect /#something to 404 in a hash router app. + if (!pathname.startsWith("/") && !pathname.startsWith(".")) { + pathname = "/" + pathname; + } + return createLocation("", { + pathname, + search, + hash + }, + // state defaults to `null` because `window.history.state` does + globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default"); + } + function createHashHref(window, to) { + let base = window.document.querySelector("base"); + let href = ""; + if (base && base.getAttribute("href")) { + let url = window.location.href; + let hashIndex = url.indexOf("#"); + href = hashIndex === -1 ? url : url.slice(0, hashIndex); + } + return href + "#" + (typeof to === "string" ? to : createPath(to)); + } + function validateHashLocation(location, to) { + warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")"); + } + return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options); + } + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region UTILS + //////////////////////////////////////////////////////////////////////////////// + + /** + * @private + */ + function invariant(value, message) { + if (value === false || value === null || typeof value === "undefined") { + throw new Error(message); + } + } + function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + try { + // Welcome to debugging history! + // + // This error is thrown as a convenience, so you can more easily + // find the source for a warning that appears in the console by + // enabling "pause on exceptions" in your JavaScript debugger. + throw new Error(message); + // eslint-disable-next-line no-empty + } catch (e) {} + } + } + function createKey() { + return Math.random().toString(36).substr(2, 8); + } + + /** + * For browser-based histories, we combine the state and key into an object + */ + function getHistoryState(location, index) { + return { + usr: location.state, + key: location.key, + idx: index + }; + } + + /** + * Creates a Location object with a unique key from the given Path + */ + function createLocation(current, to, state, key) { + if (state === void 0) { + state = null; + } + let location = _extends({ + pathname: typeof current === "string" ? current : current.pathname, + search: "", + hash: "" + }, typeof to === "string" ? parsePath(to) : to, { + state, + // TODO: This could be cleaned up. push/replace should probably just take + // full Locations now and avoid the need to run through this flow at all + // But that's a pretty big refactor to the current test suite so going to + // keep as is for the time being and just let any incoming keys take precedence + key: to && to.key || key || createKey() + }); + return location; + } + + /** + * Creates a string URL path from the given pathname, search, and hash components. + */ + function createPath(_ref) { + let { + pathname = "/", + search = "", + hash = "" + } = _ref; + if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search; + if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash; + return pathname; + } + + /** + * Parses a string URL path into its separate pathname, search, and hash components. + */ + function parsePath(path) { + let parsedPath = {}; + if (path) { + let hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + parsedPath.hash = path.substr(hashIndex); + path = path.substr(0, hashIndex); + } + let searchIndex = path.indexOf("?"); + if (searchIndex >= 0) { + parsedPath.search = path.substr(searchIndex); + path = path.substr(0, searchIndex); + } + if (path) { + parsedPath.pathname = path; + } + } + return parsedPath; + } + function getUrlBasedHistory(getLocation, createHref, validateLocation, options) { + if (options === void 0) { + options = {}; + } + let { + window = document.defaultView, + v5Compat = false + } = options; + let globalHistory = window.history; + let action = Action.Pop; + let listener = null; + let index = getIndex(); + // Index should only be null when we initialize. If not, it's because the + // user called history.pushState or history.replaceState directly, in which + // case we should log a warning as it will result in bugs. + if (index == null) { + index = 0; + globalHistory.replaceState(_extends({}, globalHistory.state, { + idx: index + }), ""); + } + function getIndex() { + let state = globalHistory.state || { + idx: null + }; + return state.idx; + } + function handlePop() { + action = Action.Pop; + let nextIndex = getIndex(); + let delta = nextIndex == null ? null : nextIndex - index; + index = nextIndex; + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } + function push(to, state) { + action = Action.Push; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex() + 1; + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + + // try...catch because iOS limits us to 100 pushState calls :/ + try { + globalHistory.pushState(historyState, "", url); + } catch (error) { + // If the exception is because `state` can't be serialized, let that throw + // outwards just like a replace call would so the dev knows the cause + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + if (error instanceof DOMException && error.name === "DataCloneError") { + throw error; + } + // They are going to lose state here, but there is no real + // way to warn them about it since the page will refresh... + window.location.assign(url); + } + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 1 + }); + } + } + function replace(to, state) { + action = Action.Replace; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + index = getIndex(); + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + globalHistory.replaceState(historyState, "", url); + if (v5Compat && listener) { + listener({ + action, + location: history.location, + delta: 0 + }); + } + } + function createURL(to) { + // window.location.origin is "null" (the literal string value) in Firefox + // under certain conditions, notably when serving from a local HTML file + // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297 + let base = window.location.origin !== "null" ? window.location.origin : window.location.href; + let href = typeof to === "string" ? to : createPath(to); + // Treating this as a full URL will strip any trailing spaces so we need to + // pre-encode them since they might be part of a matching splat param from + // an ancestor route + href = href.replace(/ $/, "%20"); + invariant(base, "No window.location.(origin|href) available to create URL for href: " + href); + return new URL(href, base); + } + let history = { + get action() { + return action; + }, + get location() { + return getLocation(window, globalHistory); + }, + listen(fn) { + if (listener) { + throw new Error("A history only accepts one active listener"); + } + window.addEventListener(PopStateEventType, handlePop); + listener = fn; + return () => { + window.removeEventListener(PopStateEventType, handlePop); + listener = null; + }; + }, + createHref(to) { + return createHref(window, to); + }, + createURL, + encodeLocation(to) { + // Encode a Location the same way window.location would + let url = createURL(to); + return { + pathname: url.pathname, + search: url.search, + hash: url.hash + }; + }, + push, + replace, + go(n) { + return globalHistory.go(n); + } + }; + return history; + } + + //#endregion + + /** + * Map of routeId -> data returned from a loader/action/error + */ + + let ResultType = /*#__PURE__*/function (ResultType) { + ResultType["data"] = "data"; + ResultType["deferred"] = "deferred"; + ResultType["redirect"] = "redirect"; + ResultType["error"] = "error"; + return ResultType; + }({}); + + /** + * Successful result from a loader or action + */ + + /** + * Successful defer() result from a loader or action + */ + + /** + * Redirect result from a loader or action + */ + + /** + * Unsuccessful result from a loader or action + */ + + /** + * Result from a loader or action - potentially successful or unsuccessful + */ + + /** + * Result from a loader or action called via dataStrategy + */ + + /** + * Users can specify either lowercase or uppercase form methods on ``, + * useSubmit(), ``, etc. + */ + + /** + * Active navigation/fetcher form methods are exposed in lowercase on the + * RouterState + */ + + /** + * In v7, active navigation/fetcher form methods are exposed in uppercase on the + * RouterState. This is to align with the normalization done via fetch(). + */ + + // Thanks https://github.com/sindresorhus/type-fest! + + /** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ + + /** + * @private + * Arguments passed to route loader/action functions. Same for now but we keep + * this as a private implementation detail in case they diverge in the future. + */ + + // TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers: + // ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs + // Also, make them a type alias instead of an interface + /** + * Arguments passed to loader functions + */ + /** + * Arguments passed to action functions + */ + /** + * Loaders and actions can return anything except `undefined` (`null` is a + * valid return value if there is no data to return). Responses are preferred + * and will ease any future migration to Remix + */ + /** + * Route loader function signature + */ + /** + * Route action function signature + */ + /** + * Arguments passed to shouldRevalidate function + */ + /** + * Route shouldRevalidate function signature. This runs after any submission + * (navigation or fetcher), so we flatten the navigation/fetcher submission + * onto the arguments. It shouldn't matter whether it came from a navigation + * or a fetcher, what really matters is the URLs and the formData since loaders + * have to re-run based on the data models that were potentially mutated. + */ + /** + * Function provided by the framework-aware layers to set `hasErrorBoundary` + * from the framework-aware `errorElement` prop + * + * @deprecated Use `mapRouteProperties` instead + */ + /** + * Function provided by the framework-aware layers to set any framework-specific + * properties from framework-agnostic properties + */ + /** + * Keys we cannot change from within a lazy() function. We spread all other keys + * onto the route. Either they're meaningful to the router, or they'll get + * ignored. + */ + const immutableRouteKeys = new Set(["lazy", "caseSensitive", "path", "id", "index", "children"]); + + /** + * lazy() function to load a route definition, which can add non-matching + * related properties to a route + */ + + /** + * Base RouteObject with common props shared by all types of routes + */ + + /** + * Index routes must not have children + */ + + /** + * Non-index routes may have children, but cannot have index + */ + + /** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ + + /** + * A data route object, which is just a RouteObject with a required unique ID + */ + + // Recursive helper for finding path parameters in the absence of wildcards + + /** + * Examples: + * "/a/b/*" -> "*" + * ":a" -> "a" + * "/a/:b" -> "b" + * "/a/blahblahblah:b" -> "b" + * "/:a/:b" -> "a" | "b" + * "/:a/b/:c/*" -> "a" | "c" | "*" + */ + + // Attempt to parse the given string segment. If it fails, then just return the + // plain string type as a default fallback. Otherwise, return the union of the + // parsed string literals that were referenced as dynamic segments in the route. + /** + * The parameters that were parsed from the URL path. + */ + /** + * A RouteMatch contains info about how a route matched a URL. + */ + function isIndexRoute(route) { + return route.index === true; + } + + // Walk the route tree generating unique IDs where necessary, so we are working + // solely with AgnosticDataRouteObject's within the Router + function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) { + if (parentPath === void 0) { + parentPath = []; + } + if (manifest === void 0) { + manifest = {}; + } + return routes.map((route, index) => { + let treePath = [...parentPath, String(index)]; + let id = typeof route.id === "string" ? route.id : treePath.join("-"); + invariant(route.index !== true || !route.children, "Cannot specify children on an index route"); + invariant(!manifest[id], "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, mapRouteProperties(route), { + id + }); + manifest[id] = indexRoute; + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, mapRouteProperties(route), { + id, + children: undefined + }); + manifest[id] = pathOrLayoutRoute; + if (route.children) { + pathOrLayoutRoute.children = convertRoutesToDataRoutes(route.children, mapRouteProperties, treePath, manifest); + } + return pathOrLayoutRoute; + } + }); + } + + /** + * Matches the given routes to a location and returns the match data. + * + * @see https://reactrouter.com/utils/match-routes + */ + function matchRoutes(routes, locationArg, basename) { + if (basename === void 0) { + basename = "/"; + } + return matchRoutesImpl(routes, locationArg, basename, false); + } + function matchRoutesImpl(routes, locationArg, basename, allowPartial) { + let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; + let pathname = stripBasename(location.pathname || "/", basename); + if (pathname == null) { + return null; + } + let branches = flattenRoutes(routes); + rankRouteBranches(branches); + let matches = null; + for (let i = 0; matches == null && i < branches.length; ++i) { + // Incoming pathnames are generally encoded from either window.location + // or from router.navigate, but we want to match against the unencoded + // paths in the route definitions. Memory router locations won't be + // encoded here but there also shouldn't be anything to decode so this + // should be a safe operation. This avoids needing matchRoutes to be + // history-aware. + let decoded = decodePath(pathname); + matches = matchRouteBranch(branches[i], decoded, allowPartial); + } + return matches; + } + function convertRouteMatchToUiMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; + } + function flattenRoutes(routes, branches, parentsMeta, parentPath) { + if (branches === void 0) { + branches = []; + } + if (parentsMeta === void 0) { + parentsMeta = []; + } + if (parentPath === void 0) { + parentPath = ""; + } + let flattenRoute = (route, index, relativePath) => { + let meta = { + relativePath: relativePath === undefined ? route.path || "" : relativePath, + caseSensitive: route.caseSensitive === true, + childrenIndex: index, + route + }; + if (meta.relativePath.startsWith("/")) { + invariant(meta.relativePath.startsWith(parentPath), "Absolute route path \"" + meta.relativePath + "\" nested under path " + ("\"" + parentPath + "\" is not valid. An absolute child route path ") + "must start with the combined path of all its parent routes."); + meta.relativePath = meta.relativePath.slice(parentPath.length); + } + let path = joinPaths([parentPath, meta.relativePath]); + let routesMeta = parentsMeta.concat(meta); + + // Add the children before adding this route to the array, so we traverse the + // route tree depth-first and child routes appear before their parents in + // the "flattened" version. + if (route.children && route.children.length > 0) { + invariant( + // Our types know better, but runtime JS may not! + // @ts-expect-error + route.index !== true, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")); + flattenRoutes(route.children, branches, routesMeta, path); + } + + // Routes without a path shouldn't ever match by themselves unless they are + // index routes, so don't add them to the list of possible branches. + if (route.path == null && !route.index) { + return; + } + branches.push({ + path, + score: computeScore(path, route.index), + routesMeta + }); + }; + routes.forEach((route, index) => { + var _route$path; + // coarse-grain check for optional params + if (route.path === "" || !((_route$path = route.path) != null && _route$path.includes("?"))) { + flattenRoute(route, index); + } else { + for (let exploded of explodeOptionalSegments(route.path)) { + flattenRoute(route, index, exploded); + } + } + }); + return branches; + } + + /** + * Computes all combinations of optional path segments for a given path, + * excluding combinations that are ambiguous and of lower priority. + * + * For example, `/one/:two?/three/:four?/:five?` explodes to: + * - `/one/three` + * - `/one/:two/three` + * - `/one/three/:four` + * - `/one/three/:five` + * - `/one/:two/three/:four` + * - `/one/:two/three/:five` + * - `/one/three/:four/:five` + * - `/one/:two/three/:four/:five` + */ + function explodeOptionalSegments(path) { + let segments = path.split("/"); + if (segments.length === 0) return []; + let [first, ...rest] = segments; + + // Optional path segments are denoted by a trailing `?` + let isOptional = first.endsWith("?"); + // Compute the corresponding required segment: `foo?` -> `foo` + let required = first.replace(/\?$/, ""); + if (rest.length === 0) { + // Intepret empty string as omitting an optional segment + // `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three` + return isOptional ? [required, ""] : [required]; + } + let restExploded = explodeOptionalSegments(rest.join("/")); + let result = []; + + // All child paths with the prefix. Do this for all children before the + // optional version for all children, so we get consistent ordering where the + // parent optional aspect is preferred as required. Otherwise, we can get + // child sections interspersed where deeper optional segments are higher than + // parent optional segments, where for example, /:two would explode _earlier_ + // then /:one. By always including the parent as required _for all children_ + // first, we avoid this issue + result.push(...restExploded.map(subpath => subpath === "" ? required : [required, subpath].join("/"))); + + // Then, if this is an optional value, add all child versions without + if (isOptional) { + result.push(...restExploded); + } + + // for absolute paths, ensure `/` instead of empty segment + return result.map(exploded => path.startsWith("/") && exploded === "" ? "/" : exploded); + } + function rankRouteBranches(branches) { + branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first + : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex))); + } + const paramRe = /^:[\w-]+$/; + const dynamicSegmentValue = 3; + const indexRouteValue = 2; + const emptySegmentValue = 1; + const staticSegmentValue = 10; + const splatPenalty = -2; + const isSplat = s => s === "*"; + function computeScore(path, index) { + let segments = path.split("/"); + let initialScore = segments.length; + if (segments.some(isSplat)) { + initialScore += splatPenalty; + } + if (index) { + initialScore += indexRouteValue; + } + return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore); + } + function compareIndexes(a, b) { + let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); + return siblings ? + // If two routes are siblings, we should try to match the earlier sibling + // first. This allows people to have fine-grained control over the matching + // behavior by simply putting routes with identical paths in the order they + // want them tried. + a[a.length - 1] - b[b.length - 1] : + // Otherwise, it doesn't really make sense to rank non-siblings by index, + // so they sort equally. + 0; + } + function matchRouteBranch(branch, pathname, allowPartial) { + if (allowPartial === void 0) { + allowPartial = false; + } + let { + routesMeta + } = branch; + let matchedParams = {}; + let matchedPathname = "/"; + let matches = []; + for (let i = 0; i < routesMeta.length; ++i) { + let meta = routesMeta[i]; + let end = i === routesMeta.length - 1; + let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/"; + let match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end + }, remainingPathname); + let route = meta.route; + if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) { + match = matchPath({ + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end: false + }, remainingPathname); + } + if (!match) { + return null; + } + Object.assign(matchedParams, match.params); + matches.push({ + // TODO: Can this as be avoided? + params: matchedParams, + pathname: joinPaths([matchedPathname, match.pathname]), + pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])), + route + }); + if (match.pathnameBase !== "/") { + matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); + } + } + return matches; + } + + /** + * Returns a path with params interpolated. + * + * @see https://reactrouter.com/utils/generate-path + */ + function generatePath(originalPath, params) { + if (params === void 0) { + params = {}; + } + let path = originalPath; + if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { + warning(false, "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + path = path.replace(/\*$/, "/*"); + } + + // ensure `/` is added at the beginning if the path is absolute + const prefix = path.startsWith("/") ? "/" : ""; + const stringify = p => p == null ? "" : typeof p === "string" ? p : String(p); + const segments = path.split(/\/+/).map((segment, index, array) => { + const isLastSegment = index === array.length - 1; + + // only apply the splat if it's the last segment + if (isLastSegment && segment === "*") { + const star = "*"; + // Apply the splat + return stringify(params[star]); + } + const keyMatch = segment.match(/^:([\w-]+)(\??)$/); + if (keyMatch) { + const [, key, optional] = keyMatch; + let param = params[key]; + invariant(optional === "?" || param != null, "Missing \":" + key + "\" param"); + return stringify(param); + } + + // Remove any optional markers from optional static segments + return segment.replace(/\?$/g, ""); + }) + // Remove empty segments + .filter(segment => !!segment); + return prefix + segments.join("/"); + } + + /** + * A PathPattern is used to match on some portion of a URL pathname. + */ + + /** + * A PathMatch contains info about how a PathPattern matched on a URL pathname. + */ + + /** + * Performs pattern matching on a URL pathname and returns information about + * the match. + * + * @see https://reactrouter.com/utils/match-path + */ + function matchPath(pattern, pathname) { + if (typeof pattern === "string") { + pattern = { + path: pattern, + caseSensitive: false, + end: true + }; + } + let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end); + let match = pathname.match(matcher); + if (!match) return null; + let matchedPathname = match[0]; + let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); + let captureGroups = match.slice(1); + let params = compiledParams.reduce((memo, _ref, index) => { + let { + paramName, + isOptional + } = _ref; + // We need to compute the pathnameBase here using the raw splat value + // instead of using params["*"] later because it will be decoded then + if (paramName === "*") { + let splatValue = captureGroups[index] || ""; + pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1"); + } + const value = captureGroups[index]; + if (isOptional && !value) { + memo[paramName] = undefined; + } else { + memo[paramName] = (value || "").replace(/%2F/g, "/"); + } + return memo; + }, {}); + return { + params, + pathname: matchedPathname, + pathnameBase, + pattern + }; + } + function compilePath(path, caseSensitive, end) { + if (caseSensitive === void 0) { + caseSensitive = false; + } + if (end === void 0) { + end = true; + } + warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")); + let params = []; + let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below + .replace(/^\/*/, "/") // Make sure it has a leading / + .replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars + .replace(/\/:([\w-]+)(\?)?/g, (_, paramName, isOptional) => { + params.push({ + paramName, + isOptional: isOptional != null + }); + return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)"; + }); + if (path.endsWith("*")) { + params.push({ + paramName: "*" + }); + regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest + : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"] + } else if (end) { + // When matching to the end, ignore trailing slashes + regexpSource += "\\/*$"; + } else if (path !== "" && path !== "/") { + // If our path is non-empty and contains anything beyond an initial slash, + // then we have _some_ form of path in our regex, so we should expect to + // match only if we find the end of this path segment. Look for an optional + // non-captured trailing slash (to match a portion of the URL) or the end + // of the path (if we've matched to the end). We used to do this with a + // word boundary but that gives false positives on routes like + // /user-preferences since `-` counts as a word boundary. + regexpSource += "(?:(?=\\/|$))"; + } else ; + let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i"); + return [matcher, params]; + } + function decodePath(value) { + try { + return value.split("/").map(v => decodeURIComponent(v).replace(/\//g, "%2F")).join("/"); + } catch (error) { + warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ").")); + return value; + } + } + + /** + * @private + */ + function stripBasename(pathname, basename) { + if (basename === "/") return pathname; + if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { + return null; + } + + // We want to leave trailing slash behavior in the user's control, so if they + // specify a basename with a trailing slash, we should support it + let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length; + let nextChar = pathname.charAt(startIndex); + if (nextChar && nextChar !== "/") { + // pathname does not start with basename/ + return null; + } + return pathname.slice(startIndex) || "/"; + } + + /** + * Returns a resolved path object relative to the given pathname. + * + * @see https://reactrouter.com/utils/resolve-path + */ + function resolvePath(to, fromPathname) { + if (fromPathname === void 0) { + fromPathname = "/"; + } + let { + pathname: toPathname, + search = "", + hash = "" + } = typeof to === "string" ? parsePath(to) : to; + let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname; + return { + pathname, + search: normalizeSearch(search), + hash: normalizeHash(hash) + }; + } + function resolvePathname(relativePath, fromPathname) { + let segments = fromPathname.replace(/\/+$/, "").split("/"); + let relativeSegments = relativePath.split("/"); + relativeSegments.forEach(segment => { + if (segment === "..") { + // Keep the root "" segment so the pathname starts at / + if (segments.length > 1) segments.pop(); + } else if (segment !== ".") { + segments.push(segment); + } + }); + return segments.length > 1 ? segments.join("/") : "/"; + } + function getInvalidPathError(char, field, dest, path) { + return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in and the router will parse it for you."; + } + + /** + * @private + * + * When processing relative navigation we want to ignore ancestor routes that + * do not contribute to the path, such that index/pathless layout routes don't + * interfere. + * + * For example, when moving a route element into an index route and/or a + * pathless layout route, relative link behavior contained within should stay + * the same. Both of the following examples should link back to the root: + * + * + * + * + * + * + * + * }> // <-- Does not contribute + * // <-- Does not contribute + * + * + */ + function getPathContributingMatches(matches) { + return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0); + } + + // Return the array of pathnames for the current route matches - used to + // generate the routePathnames input for resolveTo() + function getResolveToMatches(matches, v7_relativeSplatPath) { + let pathMatches = getPathContributingMatches(matches); + + // When v7_relativeSplatPath is enabled, use the full pathname for the leaf + // match so we include splat values for "." links. See: + // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329 + if (v7_relativeSplatPath) { + return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase); + } + return pathMatches.map(match => match.pathnameBase); + } + + /** + * @private + */ + function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) { + if (isPathRelative === void 0) { + isPathRelative = false; + } + let to; + if (typeof toArg === "string") { + to = parsePath(toArg); + } else { + to = _extends({}, toArg); + invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to)); + invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to)); + invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to)); + } + let isEmptyPath = toArg === "" || to.pathname === ""; + let toPathname = isEmptyPath ? "/" : to.pathname; + let from; + + // Routing is relative to the current pathname if explicitly requested. + // + // If a pathname is explicitly provided in `to`, it should be relative to the + // route context. This is explained in `Note on `` values` in our + // migration guide from v5 as a means of disambiguation between `to` values + // that begin with `/` and those that do not. However, this is problematic for + // `to` values that do not provide a pathname. `to` can simply be a search or + // hash string, in which case we should assume that the navigation is relative + // to the current location's pathname and *not* the route pathname. + if (toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + // With relative="route" (the default), each leading .. segment means + // "go up one route" instead of "go up one URL segment". This is a key + // difference from how works and a major reason we call this a + // "to" value instead of a "href". + if (!isPathRelative && toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + to.pathname = toSegments.join("/"); + } + from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; + } + let path = resolvePath(to, from); + + // Ensure the pathname has a trailing slash if the original "to" had one + let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/"); + // Or if this was a link to the current path which has a trailing slash + let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); + if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) { + path.pathname += "/"; + } + return path; + } + + /** + * @private + */ + function getToPathname(to) { + // Empty strings should be treated the same as / paths + return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? parsePath(to).pathname : to.pathname; + } + + /** + * @private + */ + const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/"); + + /** + * @private + */ + const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/"); + + /** + * @private + */ + const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search; + + /** + * @private + */ + const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; + /** + * This is a shortcut for creating `application/json` responses. Converts `data` + * to JSON and sets the `Content-Type` header. + */ + const json = function json(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + let headers = new Headers(responseInit.headers); + if (!headers.has("Content-Type")) { + headers.set("Content-Type", "application/json; charset=utf-8"); + } + return new Response(JSON.stringify(data), _extends({}, responseInit, { + headers + })); + }; + class AbortedDeferredError extends Error {} + class DeferredData { + constructor(data, responseInit) { + this.pendingKeysSet = new Set(); + this.subscribers = new Set(); + this.deferredKeys = []; + invariant(data && typeof data === "object" && !Array.isArray(data), "defer() only accepts plain objects"); + + // Set up an AbortController + Promise we can race against to exit early + // cancellation + let reject; + this.abortPromise = new Promise((_, r) => reject = r); + this.controller = new AbortController(); + let onAbort = () => reject(new AbortedDeferredError("Deferred data aborted")); + this.unlistenAbortSignal = () => this.controller.signal.removeEventListener("abort", onAbort); + this.controller.signal.addEventListener("abort", onAbort); + this.data = Object.entries(data).reduce((acc, _ref2) => { + let [key, value] = _ref2; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + if (this.done) { + // All incoming values were resolved + this.unlistenAbortSignal(); + } + this.init = responseInit; + } + trackPromise(key, value) { + if (!(value instanceof Promise)) { + return value; + } + this.deferredKeys.push(key); + this.pendingKeysSet.add(key); + + // We store a little wrapper promise that will be extended with + // _data/_error props upon resolve/reject + let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, undefined, data), error => this.onSettle(promise, key, error)); + + // Register rejection listeners to avoid uncaught promise rejections on + // errors or aborted deferred values + promise.catch(() => {}); + Object.defineProperty(promise, "_tracked", { + get: () => true + }); + return promise; + } + onSettle(promise, key, error, data) { + if (this.controller.signal.aborted && error instanceof AbortedDeferredError) { + this.unlistenAbortSignal(); + Object.defineProperty(promise, "_error", { + get: () => error + }); + return Promise.reject(error); + } + this.pendingKeysSet.delete(key); + if (this.done) { + // Nothing left to abort! + this.unlistenAbortSignal(); + } + + // If the promise was resolved/rejected with undefined, we'll throw an error as you + // should always resolve with a value or null + if (error === undefined && data === undefined) { + let undefinedError = new Error("Deferred data for key \"" + key + "\" resolved/rejected with `undefined`, " + "you must resolve/reject with a value or `null`."); + Object.defineProperty(promise, "_error", { + get: () => undefinedError + }); + this.emit(false, key); + return Promise.reject(undefinedError); + } + if (data === undefined) { + Object.defineProperty(promise, "_error", { + get: () => error + }); + this.emit(false, key); + return Promise.reject(error); + } + Object.defineProperty(promise, "_data", { + get: () => data + }); + this.emit(false, key); + return data; + } + emit(aborted, settledKey) { + this.subscribers.forEach(subscriber => subscriber(aborted, settledKey)); + } + subscribe(fn) { + this.subscribers.add(fn); + return () => this.subscribers.delete(fn); + } + cancel() { + this.controller.abort(); + this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k)); + this.emit(true); + } + async resolveData(signal) { + let aborted = false; + if (!this.done) { + let onAbort = () => this.cancel(); + signal.addEventListener("abort", onAbort); + aborted = await new Promise(resolve => { + this.subscribe(aborted => { + signal.removeEventListener("abort", onAbort); + if (aborted || this.done) { + resolve(aborted); + } + }); + }); + } + return aborted; + } + get done() { + return this.pendingKeysSet.size === 0; + } + get unwrappedData() { + invariant(this.data !== null && this.done, "Can only unwrap data on initialized and settled deferreds"); + return Object.entries(this.data).reduce((acc, _ref3) => { + let [key, value] = _ref3; + return Object.assign(acc, { + [key]: unwrapTrackedPromise(value) + }); + }, {}); + } + get pendingKeys() { + return Array.from(this.pendingKeysSet); + } + } + function isTrackedPromise(value) { + return value instanceof Promise && value._tracked === true; + } + function unwrapTrackedPromise(value) { + if (!isTrackedPromise(value)) { + return value; + } + if (value._error) { + throw value._error; + } + return value._data; + } + const defer = function defer(data, init) { + if (init === void 0) { + init = {}; + } + let responseInit = typeof init === "number" ? { + status: init + } : init; + return new DeferredData(data, responseInit); + }; + /** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ + const redirect = function redirect(url, init) { + if (init === void 0) { + init = 302; + } + let responseInit = init; + if (typeof responseInit === "number") { + responseInit = { + status: responseInit + }; + } else if (typeof responseInit.status === "undefined") { + responseInit.status = 302; + } + let headers = new Headers(responseInit.headers); + headers.set("Location", url); + return new Response(null, _extends({}, responseInit, { + headers + })); + }; + + /** + * A redirect response that will force a document reload to the new location. + * Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ + const redirectDocument = (url, init) => { + let response = redirect(url, init); + response.headers.set("X-Remix-Reload-Document", "true"); + return response; + }; + /** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + * + * We don't export the class for public use since it's an implementation + * detail, but we export the interface above so folks can build their own + * abstractions around instances via isRouteErrorResponse() + */ + class ErrorResponseImpl { + constructor(status, statusText, data, internal) { + if (internal === void 0) { + internal = false; + } + this.status = status; + this.statusText = statusText || ""; + this.internal = internal; + if (data instanceof Error) { + this.data = data.toString(); + this.error = data; + } else { + this.data = data; + } + } + } + + /** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response thrown from an action/loader + */ + function isRouteErrorResponse(error) { + return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error; + } + + //////////////////////////////////////////////////////////////////////////////// + //#region Types and Constants + //////////////////////////////////////////////////////////////////////////////// + + /** + * A Router instance manages all navigation and data loading/mutations + */ + /** + * State maintained internally by the router. During a navigation, all states + * reflect the the "old" location unless otherwise noted. + */ + /** + * Data that can be passed into hydrate a Router from SSR + */ + /** + * Future flags to toggle new feature behavior + */ + /** + * Initialization options for createRouter + */ + /** + * State returned from a server-side query() call + */ + /** + * A StaticHandler instance manages a singular SSR navigation/fetch event + */ + /** + * Subscriber function signature for changes to router state + */ + /** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ + /** + * Function signature for determining the current scroll position + */ + // Allowed for any navigation or fetch + // Only allowed for navigations + // Only allowed for submission navigations + /** + * Options for a navigate() call for a normal (non-submission) navigation + */ + /** + * Options for a navigate() call for a submission navigation + */ + /** + * Options to pass to navigate() for a navigation + */ + /** + * Options for a fetch() load + */ + /** + * Options for a fetch() submission + */ + /** + * Options to pass to fetch() + */ + /** + * Potential states for state.navigation + */ + /** + * Potential states for fetchers + */ + /** + * Cached info for active fetcher.load() instances so they can participate + * in revalidation + */ + /** + * Identified fetcher.load() calls that need to be revalidated + */ + const validMutationMethodsArr = ["post", "put", "patch", "delete"]; + const validMutationMethods = new Set(validMutationMethodsArr); + const validRequestMethodsArr = ["get", ...validMutationMethodsArr]; + const validRequestMethods = new Set(validRequestMethodsArr); + const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); + const redirectPreserveMethodStatusCodes = new Set([307, 308]); + const IDLE_NAVIGATION = { + state: "idle", + location: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined + }; + const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined + }; + const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined + }; + const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; + const defaultMapRouteProperties = route => ({ + hasErrorBoundary: Boolean(route.hasErrorBoundary) + }); + const TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; + + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region createRouter + //////////////////////////////////////////////////////////////////////////////// + + /** + * Create a router and listen to history POP navigations + */ + function createRouter(init) { + const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : undefined; + const isBrowser = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined"; + const isServer = !isBrowser; + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let mapRouteProperties; + if (init.mapRouteProperties) { + mapRouteProperties = init.mapRouteProperties; + } else if (init.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = init.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + + // Routes keyed by ID + let manifest = {}; + // Routes in tree format for matching + let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest); + let inFlightDataRoutes; + let basename = init.basename || "/"; + let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy; + let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss; + + // Config driven behavior flags + let future = _extends({ + v7_fetcherPersist: false, + v7_normalizeFormMethod: false, + v7_partialHydration: false, + v7_prependBasename: false, + v7_relativeSplatPath: false, + v7_skipActionErrorRevalidation: false + }, init.future); + // Cleanup function for history + let unlistenHistory = null; + // Externally-provided functions to call on all state changes + let subscribers = new Set(); + // Externally-provided object to hold scroll restoration locations during routing + let savedScrollPositions = null; + // Externally-provided function to get scroll restoration keys + let getScrollRestorationKey = null; + // Externally-provided function to get current scroll position + let getScrollPosition = null; + // One-time flag to control the initial hydration scroll restoration. Because + // we don't get the saved positions from until _after_ + // the initial render, we need to manually trigger a separate updateState to + // send along the restoreScrollPosition + // Set to true if we have `hydrationData` since we assume we were SSR'd and that + // SSR did the initial scroll restoration. + let initialScrollRestored = init.hydrationData != null; + let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); + let initialErrors = null; + if (initialMatches == null && !patchRoutesOnMissImpl) { + // If we do not match a user-provided-route, fall back to the root + // to allow the error boundary to take over + let error = getInternalRouterError(404, { + pathname: init.history.location.pathname + }); + let { + matches, + route + } = getShortCircuitMatches(dataRoutes); + initialMatches = matches; + initialErrors = { + [route.id]: error + }; + } + + // In SPA apps, if the user provided a patchRoutesOnMiss implementation and + // our initial match is a splat route, clear them out so we run through lazy + // discovery on hydration in case there's a more accurate lazy route match. + // In SSR apps (with `hydrationData`), we expect that the server will send + // up the proper matched routes so we don't want to run lazy discovery on + // initial hydration and want to hydrate into the splat route. + if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) { + let fogOfWar = checkFogOfWar(initialMatches, dataRoutes, init.history.location.pathname); + if (fogOfWar.active) { + initialMatches = null; + } + } + let initialized; + if (!initialMatches) { + // We need to run patchRoutesOnMiss in initialize() + initialized = false; + initialMatches = []; + } else if (initialMatches.some(m => m.route.lazy)) { + // All initialMatches need to be loaded before we're ready. If we have lazy + // functions around still then we'll need to run them in initialize() + initialized = false; + } else if (!initialMatches.some(m => m.route.loader)) { + // If we've got no loaders to run, then we're good to go + initialized = true; + } else if (future.v7_partialHydration) { + // If partial hydration is enabled, we're initialized so long as we were + // provided with hydrationData for every route with a loader, and no loaders + // were marked for explicit hydration + let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; + let errors = init.hydrationData ? init.hydrationData.errors : null; + let isRouteInitialized = m => { + // No loader, nothing to initialize + if (!m.route.loader) { + return true; + } + // Explicitly opting-in to running on hydration + if (typeof m.route.loader === "function" && m.route.loader.hydrate === true) { + return false; + } + // Otherwise, initialized if hydrated with data or an error + return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined; + }; + + // If errors exist, don't consider routes below the boundary + if (errors) { + let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined); + initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized); + } else { + initialized = initialMatches.every(isRouteInitialized); + } + } else { + // Without partial hydration - we're initialized if we were provided any + // hydrationData - which is expected to be complete + initialized = init.hydrationData != null; + } + let router; + let state = { + historyAction: init.history.action, + location: init.history.location, + matches: initialMatches, + initialized, + navigation: IDLE_NAVIGATION, + // Don't restore on initial updateState() if we were SSR'd + restoreScrollPosition: init.hydrationData != null ? false : null, + preventScrollReset: false, + revalidation: "idle", + loaderData: init.hydrationData && init.hydrationData.loaderData || {}, + actionData: init.hydrationData && init.hydrationData.actionData || null, + errors: init.hydrationData && init.hydrationData.errors || initialErrors, + fetchers: new Map(), + blockers: new Map() + }; + + // -- Stateful internal variables to manage navigations -- + // Current navigation in progress (to be committed in completeNavigation) + let pendingAction = Action.Pop; + + // Should the current navigation prevent the scroll reset if scroll cannot + // be restored? + let pendingPreventScrollReset = false; + + // AbortController for the active navigation + let pendingNavigationController; + + // Should the current navigation enable document.startViewTransition? + let pendingViewTransitionEnabled = false; + + // Store applied view transitions so we can apply them on POP + let appliedViewTransitions = new Map(); + + // Cleanup function for persisting applied transitions to sessionStorage + let removePageHideEventListener = null; + + // We use this to avoid touching history in completeNavigation if a + // revalidation is entirely uninterrupted + let isUninterruptedRevalidation = false; + + // Use this internal flag to force revalidation of all loaders: + // - submissions (completed or interrupted) + // - useRevalidator() + // - X-Remix-Revalidate (from redirect) + let isRevalidationRequired = false; + + // Use this internal array to capture routes that require revalidation due + // to a cancelled deferred on action submission + let cancelledDeferredRoutes = []; + + // Use this internal array to capture fetcher loads that were cancelled by an + // action navigation and require revalidation + let cancelledFetcherLoads = []; + + // AbortControllers for any in-flight fetchers + let fetchControllers = new Map(); + + // Track loads based on the order in which they started + let incrementingLoadId = 0; + + // Track the outstanding pending navigation data load to be compared against + // the globally incrementing load when a fetcher load lands after a completed + // navigation + let pendingNavigationLoadId = -1; + + // Fetchers that triggered data reloads as a result of their actions + let fetchReloadIds = new Map(); + + // Fetchers that triggered redirect navigations + let fetchRedirectIds = new Set(); + + // Most recent href/match for fetcher.load calls for fetchers + let fetchLoadMatches = new Map(); + + // Ref-count mounted fetchers so we know when it's ok to clean them up + let activeFetchers = new Map(); + + // Fetchers that have requested a delete when using v7_fetcherPersist, + // they'll be officially removed after they return to idle + let deletedFetchers = new Set(); + + // Store DeferredData instances for active route matches. When a + // route loader returns defer() we stick one in here. Then, when a nested + // promise resolves we update loaderData. If a new navigation starts we + // cancel active deferreds for eliminated routes. + let activeDeferreds = new Map(); + + // Store blocker functions in a separate Map outside of router state since + // we don't need to update UI state if they change + let blockerFunctions = new Map(); + + // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so + // that we only kick them off once for a given combo + let pendingPatchRoutes = new Map(); + + // Flag to ignore the next history update, so we can revert the URL change on + // a POP navigation that was blocked by the user without touching router state + let ignoreNextHistoryUpdate = false; + + // Initialize the router, all side effects should be kicked off from here. + // Implemented as a Fluent API for ease of: + // let router = createRouter(init).initialize(); + function initialize() { + // If history informs us of a POP navigation, start the navigation but do not update + // state. We'll update our own state once the navigation completes + unlistenHistory = init.history.listen(_ref => { + let { + action: historyAction, + location, + delta + } = _ref; + // Ignore this event if it was just us resetting the URL from a + // blocked POP navigation + if (ignoreNextHistoryUpdate) { + ignoreNextHistoryUpdate = false; + return; + } + warning(blockerFunctions.size === 0 || delta != null, "You are trying to use a blocker on a POP navigation to a location " + "that was not created by @remix-run/router. This will fail silently in " + "production. This can happen if you are navigating outside the router " + "via `window.history.pushState`/`window.location.hash` instead of using " + "router navigation APIs. This can also happen if you are using " + "createHashRouter and the user manually changes the URL."); + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + if (blockerKey && delta != null) { + // Restore the URL to match the current UI, but don't update router state + ignoreNextHistoryUpdate = true; + init.history.go(delta * -1); + + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location + }); + // Re-do the same POP navigation we just blocked + init.history.go(delta); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return startNavigation(historyAction, location); + }); + if (isBrowser) { + // FIXME: This feels gross. How can we cleanup the lines between + // scrollRestoration/appliedTransitions persistance? + restoreAppliedTransitions(routerWindow, appliedViewTransitions); + let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions); + routerWindow.addEventListener("pagehide", _saveAppliedTransitions); + removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); + } + + // Kick off initial data load if needed. Use Pop to avoid modifying history + // Note we don't do any handling of lazy here. For SPA's it'll get handled + // in the normal navigation flow. For SSR it's expected that lazy modules are + // resolved prior to router creation since we can't go into a fallbackElement + // UI for SSR'd apps + if (!state.initialized) { + startNavigation(Action.Pop, state.location, { + initialHydration: true + }); + } + return router; + } + + // Clean up a router and it's side effects + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + if (removePageHideEventListener) { + removePageHideEventListener(); + } + subscribers.clear(); + pendingNavigationController && pendingNavigationController.abort(); + state.fetchers.forEach((_, key) => deleteFetcher(key)); + state.blockers.forEach((_, key) => deleteBlocker(key)); + } + + // Subscribe to state updates for the router + function subscribe(fn) { + subscribers.add(fn); + return () => subscribers.delete(fn); + } + + // Update our state and notify the calling context of the change + function updateState(newState, opts) { + if (opts === void 0) { + opts = {}; + } + state = _extends({}, state, newState); + + // Prep fetcher cleanup so we can tell the UI which fetcher data entries + // can be removed + let completedFetchers = []; + let deletedFetchersKeys = []; + if (future.v7_fetcherPersist) { + state.fetchers.forEach((fetcher, key) => { + if (fetcher.state === "idle") { + if (deletedFetchers.has(key)) { + // Unmounted from the UI and can be totally removed + deletedFetchersKeys.push(key); + } else { + // Returned to idle but still mounted in the UI, so semi-remains for + // revalidations and such + completedFetchers.push(key); + } + } + }); + } + + // Iterate over a local copy so that if flushSync is used and we end up + // removing and adding a new subscriber due to the useCallback dependencies, + // we don't get ourselves into a loop calling the new subscriber immediately + [...subscribers].forEach(subscriber => subscriber(state, { + deletedFetchers: deletedFetchersKeys, + unstable_viewTransitionOpts: opts.viewTransitionOpts, + unstable_flushSync: opts.flushSync === true + })); + + // Remove idle fetchers from state since we only care about in-flight fetchers. + if (future.v7_fetcherPersist) { + completedFetchers.forEach(key => state.fetchers.delete(key)); + deletedFetchersKeys.forEach(key => deleteFetcher(key)); + } + } + + // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION + // and setting state.[historyAction/location/matches] to the new route. + // - Location is a required param + // - Navigation will always be set to IDLE_NAVIGATION + // - Can pass any other state in newState + function completeNavigation(location, newState, _temp) { + var _location$state, _location$state2; + let { + flushSync + } = _temp === void 0 ? {} : _temp; + // Deduce if we're in a loading/actionReload state: + // - We have committed actionData in the store + // - The current navigation was a mutation submission + // - We're past the submitting state and into the loading state + // - The location being loaded is not the result of a redirect + let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && ((_location$state = location.state) == null ? void 0 : _location$state._isRedirect) !== true; + let actionData; + if (newState.actionData) { + if (Object.keys(newState.actionData).length > 0) { + actionData = newState.actionData; + } else { + // Empty actionData -> clear prior actionData due to an action error + actionData = null; + } + } else if (isActionReload) { + // Keep the current data if we're wrapping up the action reload + actionData = state.actionData; + } else { + // Clear actionData on any other completed navigations + actionData = null; + } + + // Always preserve any existing loaderData from re-used routes + let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; + + // On a successful navigation we can assume we got through all blockers + // so we can start fresh + let blockers = state.blockers; + if (blockers.size > 0) { + blockers = new Map(blockers); + blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); + } + + // Always respect the user flag. Otherwise don't reset on mutation + // submission navigations unless they redirect + let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true; + + // Commit any in-flight routes at the end of the HMR revalidation "navigation" + if (inFlightDataRoutes) { + dataRoutes = inFlightDataRoutes; + inFlightDataRoutes = undefined; + } + if (isUninterruptedRevalidation) ; else if (pendingAction === Action.Pop) ; else if (pendingAction === Action.Push) { + init.history.push(location, location.state); + } else if (pendingAction === Action.Replace) { + init.history.replace(location, location.state); + } + let viewTransitionOpts; + + // On POP, enable transitions if they were enabled on the original navigation + if (pendingAction === Action.Pop) { + // Forward takes precedence so they behave like the original navigation + let priorPaths = appliedViewTransitions.get(state.location.pathname); + if (priorPaths && priorPaths.has(location.pathname)) { + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } else if (appliedViewTransitions.has(location.pathname)) { + // If we don't have a previous forward nav, assume we're popping back to + // the new location and enable if that location previously enabled + viewTransitionOpts = { + currentLocation: location, + nextLocation: state.location + }; + } + } else if (pendingViewTransitionEnabled) { + // Store the applied transition on PUSH/REPLACE + let toPaths = appliedViewTransitions.get(state.location.pathname); + if (toPaths) { + toPaths.add(location.pathname); + } else { + toPaths = new Set([location.pathname]); + appliedViewTransitions.set(state.location.pathname, toPaths); + } + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location + }; + } + updateState(_extends({}, newState, { + // matches, errors, fetchers go through as-is + actionData, + loaderData, + historyAction: pendingAction, + location, + initialized: true, + navigation: IDLE_NAVIGATION, + revalidation: "idle", + restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches), + preventScrollReset, + blockers + }), { + viewTransitionOpts, + flushSync: flushSync === true + }); + + // Reset stateful navigation vars + pendingAction = Action.Pop; + pendingPreventScrollReset = false; + pendingViewTransitionEnabled = false; + isUninterruptedRevalidation = false; + isRevalidationRequired = false; + cancelledDeferredRoutes = []; + cancelledFetcherLoads = []; + } + + // Trigger a navigation event, which can either be a numerical POP or a PUSH + // replace with an optional submission + async function navigate(to, opts) { + if (typeof to === "number") { + init.history.go(to); + return; + } + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, to, future.v7_relativeSplatPath, opts == null ? void 0 : opts.fromRouteId, opts == null ? void 0 : opts.relative); + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, false, normalizedPath, opts); + let currentLocation = state.location; + let nextLocation = createLocation(state.location, path, opts && opts.state); + + // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded + // URL from window.location, so we need to encode it here so the behavior + // remains the same as POP and non-data-router usages. new URL() does all + // the same encoding we'd get from a history.pushState/window.location read + // without having to touch history + nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation)); + let userReplace = opts && opts.replace != null ? opts.replace : undefined; + let historyAction = Action.Push; + if (userReplace === true) { + historyAction = Action.Replace; + } else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) { + // By default on submissions to the current location we REPLACE so that + // users don't have to double-click the back button to get to the prior + // location. If the user redirects to a different location from the + // action/loader this will be ignored and the redirect will be a PUSH + historyAction = Action.Replace; + } + let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined; + let flushSync = (opts && opts.unstable_flushSync) === true; + let blockerKey = shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction + }); + if (blockerKey) { + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location: nextLocation, + proceed() { + updateBlocker(blockerKey, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location: nextLocation + }); + // Send the same navigation through + navigate(to, opts); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey, IDLE_BLOCKER); + updateState({ + blockers + }); + } + }); + return; + } + return await startNavigation(historyAction, nextLocation, { + submission, + // Send through the formData serialization error if we have one so we can + // render at the right error boundary after we match routes + pendingError: error, + preventScrollReset, + replace: opts && opts.replace, + enableViewTransition: opts && opts.unstable_viewTransition, + flushSync + }); + } + + // Revalidate all current loaders. If a navigation is in progress or if this + // is interrupted by a navigation, allow this to "succeed" by calling all + // loaders during the next loader round + function revalidate() { + interruptActiveLoads(); + updateState({ + revalidation: "loading" + }); + + // If we're currently submitting an action, we don't need to start a new + // navigation, we'll just let the follow up loader execution call all loaders + if (state.navigation.state === "submitting") { + return; + } + + // If we're currently in an idle state, start a new navigation for the current + // action/location and mark it as uninterrupted, which will skip the history + // update in completeNavigation + if (state.navigation.state === "idle") { + startNavigation(state.historyAction, state.location, { + startUninterruptedRevalidation: true + }); + return; + } + + // Otherwise, if we're currently in a loading state, just start a new + // navigation to the navigation.location but do not trigger an uninterrupted + // revalidation so that history correctly updates once the navigation completes + startNavigation(pendingAction || state.historyAction, state.navigation.location, { + overrideNavigation: state.navigation + }); + } + + // Start a navigation to the given action/location. Can optionally provide a + // overrideNavigation which will override the normalLoad in the case of a redirect + // navigation + async function startNavigation(historyAction, location, opts) { + // Abort any in-progress navigations and start a new one. Unset any ongoing + // uninterrupted revalidations unless told otherwise, since we want this + // new navigation to update history normally + pendingNavigationController && pendingNavigationController.abort(); + pendingNavigationController = null; + pendingAction = historyAction; + isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true; + + // Save the current scroll position every time we start a new navigation, + // and track whether we should reset scroll on completion + saveScrollPosition(state.location, state.matches); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(routesToUse, location, basename); + let flushSync = (opts && opts.flushSync) === true; + let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + + // Short circuit with a 404 on the root error boundary if we match nothing + if (!matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }, { + flushSync + }); + return; + } + + // Short circuit if it's only a hash change and not a revalidation or + // mutation submission. + // + // Ignore on initial page loads because since the initial load will always + // be "same hash". For example, on /page#hash and submit a + // which will default to a navigation to /page + if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) { + completeNavigation(location, { + matches + }, { + flushSync + }); + return; + } + + // Create a controller/Request for this navigation + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionResult; + if (opts && opts.pendingError) { + // If we have a pendingError, it means the user attempted a GET submission + // with binary FormData so assign here and skip to handleLoaders. That + // way we handle calling loaders above the boundary etc. It's not really + // different from an actionError in that sense. + pendingActionResult = [findNearestBoundary(matches).route.id, { + type: ResultType.error, + error: opts.pendingError + }]; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionResult = await handleAction(request, location, opts.submission, matches, fogOfWar.active, { + replace: opts.replace, + flushSync + }); + if (actionResult.shortCircuited) { + return; + } + + // If we received a 404 from handleAction, it's because we couldn't lazily + // discover the destination route so we don't want to call loaders + if (actionResult.pendingActionResult) { + let [routeId, result] = actionResult.pendingActionResult; + if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) { + pendingNavigationController = null; + completeNavigation(location, { + matches: actionResult.matches, + loaderData: {}, + errors: { + [routeId]: result.error + } + }); + return; + } + } + matches = actionResult.matches || matches; + pendingActionResult = actionResult.pendingActionResult; + loadingNavigation = getLoadingNavigation(location, opts.submission); + flushSync = false; + // No need to do fog of war matching again on loader execution + fogOfWar.active = false; + + // Create a GET request for the loaders + request = createClientSideRequest(init.history, request.url, request.signal); + } + + // Call loaders + let { + shortCircuited, + matches: updatedMatches, + loaderData, + errors + } = await handleLoaders(request, location, matches, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult); + if (shortCircuited) { + return; + } + + // Clean up now that the action/loaders have completed. Don't clean up if + // we short circuited because pendingNavigationController will have already + // been assigned to a new controller for the next navigation + pendingNavigationController = null; + completeNavigation(location, _extends({ + matches: updatedMatches || matches + }, getActionDataForCommit(pendingActionResult), { + loaderData, + errors + })); + } + + // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + async function handleAction(request, location, submission, matches, isFogOfWar, opts) { + if (opts === void 0) { + opts = {}; + } + interruptActiveLoads(); + + // Put us in a submitting state + let navigation = getSubmittingNavigation(location, submission); + updateState({ + navigation + }, { + flushSync: opts.flushSync === true + }); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + pendingActionResult: [boundaryId, { + type: ResultType.error, + error + }] + }; + } else if (!discoverResult.matches) { + let { + notFoundMatches, + error, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + pendingActionResult: [route.id, { + type: ResultType.error, + error + }] + }; + } else { + matches = discoverResult.matches; + } + } + + // Call our action and get the result + let result; + let actionMatch = getTargetMatch(matches, location); + if (!actionMatch.route.action && !actionMatch.route.lazy) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches); + result = results[0]; + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + } + if (isRedirectResult(result)) { + let replace; + if (opts && opts.replace != null) { + replace = opts.replace; + } else { + // If the user didn't explicity indicate replace behavior, replace if + // we redirected to the exact same location we're currently at to avoid + // double back-buttons + let location = normalizeRedirectLocation(result.response.headers.get("Location"), new URL(request.url), basename); + replace = location === state.location.pathname + state.location.search; + } + await startRedirectNavigation(request, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); + + // By default, all submissions to the current location are REPLACE + // navigations, but if the action threw an error that'll be rendered in + // an errorElement, we fall back to PUSH so that the user can use the + // back button to get back to the pre-submission form location to try + // again + if ((opts && opts.replace) !== true) { + pendingAction = Action.Push; + } + return { + matches, + pendingActionResult: [boundaryMatch.route.id, result] + }; + } + return { + matches, + pendingActionResult: [actionMatch.route.id, result] + }; + } + + // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission); + + // If this was a redirect from an action we don't have a "submission" but + // we have it on the loading navigation so use that if available + let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation); + + // If this is an uninterrupted revalidation, we remain in our current idle + // state. If not, we need to switch to our loading state and load data, + // preserving any new action data or existing action data (in the case of + // a revalidation interrupting an actionReload) + // If we have partialHydration enabled, then don't update the state for the + // initial data load since it's not a "navigation" + let shouldUpdateNavigationState = !isUninterruptedRevalidation && (!future.v7_partialHydration || !initialHydration); + + // When fog of war is enabled, we enter our `loading` state earlier so we + // can discover new routes during the `loading` state. We skip this if + // we've already run actions since we would have done our matching already. + // If the children() function threw then, we want to proceed with the + // partial matches it discovered. + if (isFogOfWar) { + if (shouldUpdateNavigationState) { + let actionData = getUpdatedActionData(pendingActionResult); + updateState(_extends({ + navigation: loadingNavigation + }, actionData !== undefined ? { + actionData + } : {}), { + flushSync + }); + } + let discoverResult = await discoverRoutes(matches, location.pathname, request.signal); + if (discoverResult.type === "aborted") { + return { + shortCircuited: true + }; + } else if (discoverResult.type === "error") { + let { + boundaryId, + error + } = handleDiscoverRouteError(location.pathname, discoverResult); + return { + matches: discoverResult.partialMatches, + loaderData: {}, + errors: { + [boundaryId]: error + } + }; + } else if (!discoverResult.matches) { + let { + error, + notFoundMatches, + route + } = handleNavigational404(location.pathname); + return { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }; + } else { + matches = discoverResult.matches; + } + } + let routesToUse = inFlightDataRoutes || dataRoutes; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, future.v7_partialHydration && initialHydration === true, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult); + + // Cancel pending deferreds for no-longer-matched routes or routes we're + // about to reload. Note that if this is an action reload we would have + // already cancelled all pending deferreds so this would be a no-op + cancelActiveDeferreds(routeId => !(matches && matches.some(m => m.route.id === routeId)) || matchesToLoad && matchesToLoad.some(m => m.route.id === routeId)); + pendingNavigationLoadId = ++incrementingLoadId; + + // Short circuit if we have no loaders to run + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + let updatedFetchers = markFetchRedirectsDone(); + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null + }, getActionDataForCommit(pendingActionResult), updatedFetchers ? { + fetchers: new Map(state.fetchers) + } : {}), { + flushSync + }); + return { + shortCircuited: true + }; + } + if (shouldUpdateNavigationState) { + let updates = {}; + if (!isFogOfWar) { + // Only update navigation/actionNData if we didn't already do it above + updates.navigation = loadingNavigation; + let actionData = getUpdatedActionData(pendingActionResult); + if (actionData !== undefined) { + updates.actionData = actionData; + } + } + if (revalidatingFetchers.length > 0) { + updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); + } + updateState(updates, { + flushSync + }); + } + revalidatingFetchers.forEach(rf => { + if (fetchControllers.has(rf.key)) { + abortFetcher(rf.key); + } + if (rf.controller) { + // Fetchers use an independent AbortController so that aborting a fetcher + // (via deleteFetcher) does not abort the triggering navigation that + // triggered the revalidation + fetchControllers.set(rf.key, rf.controller); + } + }); + + // Proxy navigation abort through to revalidation fetchers + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(f => abortFetcher(f.key)); + if (pendingNavigationController) { + pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations); + } + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request); + if (request.signal.aborted) { + return { + shortCircuited: true + }; + } + + // Clean up _after_ loaders have completed. Don't clean up if we short + // circuited because fetchControllers would have been aborted and + // reassigned to new controllers for the next navigation + if (pendingNavigationController) { + pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + } + revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key)); + + // If any loaders returned a redirect Response, start a new REPLACE navigation + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + await startRedirectNavigation(request, redirect.result, { + replace + }); + return { + shortCircuited: true + }; + } + + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds); + + // Wire up subscribers to update loaderData as promises settle + activeDeferreds.forEach((deferredData, routeId) => { + deferredData.subscribe(aborted => { + // Note: No need to updateState here since the TrackedPromise on + // loaderData is stable across resolve/reject + // Remove this instance if we were aborted or if promises have settled + if (aborted || deferredData.done) { + activeDeferreds.delete(routeId); + } + }); + }); + + // During partial hydration, preserve SSR errors for routes that don't re-run + if (future.v7_partialHydration && initialHydration && state.errors) { + Object.entries(state.errors).filter(_ref2 => { + let [id] = _ref2; + return !matchesToLoad.some(m => m.route.id === id); + }).forEach(_ref3 => { + let [routeId, error] = _ref3; + errors = Object.assign(errors || {}, { + [routeId]: error + }); + }); + } + let updatedFetchers = markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; + return _extends({ + matches, + loaderData, + errors + }, shouldUpdateFetchers ? { + fetchers: new Map(state.fetchers) + } : {}); + } + function getUpdatedActionData(pendingActionResult) { + if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { + // This is cast to `any` currently because `RouteData`uses any and it + // would be a breaking change to use any. + // TODO: v7 - change `RouteData` to use `unknown` instead of `any` + return { + [pendingActionResult[0]]: pendingActionResult[1].data + }; + } else if (state.actionData) { + if (Object.keys(state.actionData).length === 0) { + return null; + } else { + return state.actionData; + } + } + } + function getUpdatedRevalidatingFetchers(revalidatingFetchers) { + revalidatingFetchers.forEach(rf => { + let fetcher = state.fetchers.get(rf.key); + let revalidatingFetcher = getLoadingFetcher(undefined, fetcher ? fetcher.data : undefined); + state.fetchers.set(rf.key, revalidatingFetcher); + }); + return new Map(state.fetchers); + } + + // Trigger a fetcher load/submit for the given fetcher key + function fetch(key, routeId, href, opts) { + if (isServer) { + throw new Error("router.fetch() was called during the server render, but it shouldn't be. " + "You are likely calling a useFetcher() method in the body of your component. " + "Try moving it to a useEffect or a callback."); + } + if (fetchControllers.has(key)) abortFetcher(key); + let flushSync = (opts && opts.unstable_flushSync) === true; + let routesToUse = inFlightDataRoutes || dataRoutes; + let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative); + let matches = matchRoutes(routesToUse, normalizedPath, basename); + let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: normalizedPath + }), { + flushSync + }); + return; + } + let { + path, + submission, + error + } = normalizeNavigateOptions(future.v7_normalizeFormMethod, true, normalizedPath, opts); + if (error) { + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } + let match = getTargetMatch(matches, path); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + return; + } + + // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + fetchLoadMatches.set(key, { + routeId, + path + }); + handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission); + } + + // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + function detectAndHandle405Error(m) { + if (!m.route.action && !m.route.lazy) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error, { + flushSync + }); + return true; + } + return false; + } + if (!isFogOfWar && detectAndHandle405Error(match)) { + return; + } + + // Put this fetcher into it's submitting state + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(requestMatches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + requestMatches = discoverResult.matches; + match = getTargetMatch(requestMatches, path); + if (detectAndHandle405Error(match)) { + return; + } + } + } + + // Call the action for the fetcher + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let actionResults = await callDataStrategy("action", fetchRequest, [match], requestMatches); + let actionResult = actionResults[0]; + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + return; + } + + // When using v7_fetcherPersist, we don't want errors bubbling up to the UI + // or redirects processed for unmounted fetchers so we just revert them to + // idle + if (future.v7_fetcherPersist && deletedFetchers.has(key)) { + if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + // Let SuccessResult's fall through for revalidation + } else { + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our action started, so that + // should take precedence over this redirect navigation. We already + // set isRevalidationRequired so all loaders for the new route should + // fire unless opted out via shouldRevalidate + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + updateFetcherState(key, getLoadingFetcher(submission)); + return startRedirectNavigation(fetchRequest, actionResult, { + fetcherSubmission: submission + }); + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(actionResult)) { + setFetcherError(key, routeId, actionResult.error); + return; + } + } + if (isDeferredResult(actionResult)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + + // Start the data load for current matches, or the next location if we're + // in the middle of a navigation + let nextLocation = state.navigation.location || state.location; + let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal); + let routesToUse = inFlightDataRoutes || dataRoutes; + let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + let loadFetcher = getLoadingFetcher(submission, actionResult.data); + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, [match.route.id, actionResult]); + + // Put all revalidating fetchers into the loading state, except for the + // current fetcher which we want to keep in it's current loading state which + // contains it's action submission info + action data + revalidatingFetchers.filter(rf => rf.key !== key).forEach(rf => { + let staleKey = rf.key; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined); + state.fetchers.set(staleKey, revalidatingFetcher); + if (fetchControllers.has(staleKey)) { + abortFetcher(staleKey); + } + if (rf.controller) { + fetchControllers.set(staleKey, rf.controller); + } + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key)); + abortController.signal.addEventListener("abort", abortPendingFetchRevalidations); + let { + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + if (abortController.signal.aborted) { + return; + } + abortController.signal.removeEventListener("abort", abortPendingFetchRevalidations); + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(r => fetchControllers.delete(r.key)); + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + return startRedirectNavigation(revalidationRequest, redirect.result); + } + + // Process and commit output from loaders + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + + // Since we let revalidations complete even if the submitting fetcher was + // deleted, only put it back to idle if it hasn't been deleted + if (state.fetchers.has(key)) { + let doneFetcher = getDoneFetcher(actionResult.data); + state.fetchers.set(key, doneFetcher); + } + abortStaleFetchLoads(loadId); + + // If we are currently in a navigation loading state and this fetcher is + // more recent than the navigation, we want the newer data so abort the + // navigation and complete it with the fetcher data + if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) { + invariant(pendingAction, "Expected pending action"); + pendingNavigationController && pendingNavigationController.abort(); + completeNavigation(state.navigation.location, { + matches, + loaderData, + errors, + fetchers: new Map(state.fetchers) + }); + } else { + // otherwise just update with the fetcher data, preserving any existing + // loaderData for loaders that did not need to reload. We have to + // manually merge here since we aren't going through completeNavigation + updateState({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors), + fetchers: new Map(state.fetchers) + }); + isRevalidationRequired = false; + } + } + + // Call the matched loader for fetcher.load(), handling redirects, errors, etc. + async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, submission) { + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), { + flushSync + }); + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + if (isFogOfWar) { + let discoverResult = await discoverRoutes(matches, path, fetchRequest.signal); + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { + error + } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { + flushSync + }); + return; + } else if (!discoverResult.matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: path + }), { + flushSync + }); + return; + } else { + matches = discoverResult.matches; + match = getTargetMatch(matches, path); + } + } + + // Call the loader for this fetcher route match + fetchControllers.set(key, abortController); + let originatingLoadId = incrementingLoadId; + let results = await callDataStrategy("loader", fetchRequest, [match], matches); + let result = results[0]; + + // Deferred isn't supported for fetcher loads, await everything and treat it + // as a normal load. resolveDeferredData will return undefined if this + // fetcher gets aborted, so we just leave result untouched and short circuit + // below if that happens + if (isDeferredResult(result)) { + result = (await resolveDeferredData(result, fetchRequest.signal, true)) || result; + } + + // We can delete this so long as we weren't aborted by our our own fetcher + // re-load which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + if (fetchRequest.signal.aborted) { + return; + } + + // We don't want errors bubbling up or redirects followed for unmounted + // fetchers, so short circuit here if it was removed from the UI + if (deletedFetchers.has(key)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + + // If the loader threw a redirect Response, start a new REPLACE navigation + if (isRedirectResult(result)) { + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our loader started, so that + // should take precedence over this redirect navigation + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + await startRedirectNavigation(fetchRequest, result); + return; + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(result)) { + setFetcherError(key, routeId, result.error); + return; + } + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); + + // Put the fetcher back into an idle state + updateFetcherState(key, getDoneFetcher(result.data)); + } + + /** + * Utility function to handle redirects returned from an action or loader. + * Normally, a redirect "replaces" the navigation that triggered it. So, for + * example: + * + * - user is on /a + * - user clicks a link to /b + * - loader for /b redirects to /c + * + * In a non-JS app the browser would track the in-flight navigation to /b and + * then replace it with /c when it encountered the redirect response. In + * the end it would only ever update the URL bar with /c. + * + * In client-side routing using pushState/replaceState, we aim to emulate + * this behavior and we also do not update history until the end of the + * navigation (including processed redirects). This means that we never + * actually touch history until we've processed redirects, so we just use + * the history action from the original navigation (PUSH or REPLACE). + */ + async function startRedirectNavigation(request, redirect, _temp2) { + let { + submission, + fetcherSubmission, + replace + } = _temp2 === void 0 ? {} : _temp2; + if (redirect.response.headers.has("X-Remix-Revalidate")) { + isRevalidationRequired = true; + } + let location = redirect.response.headers.get("Location"); + invariant(location, "Expected a Location header on the redirect Response"); + location = normalizeRedirectLocation(location, new URL(request.url), basename); + let redirectLocation = createLocation(state.location, location, { + _isRedirect: true + }); + if (isBrowser) { + let isDocumentReload = false; + if (redirect.response.headers.has("X-Remix-Reload-Document")) { + // Hard reload if the response contained X-Remix-Reload-Document + isDocumentReload = true; + } else if (ABSOLUTE_URL_REGEX.test(location)) { + const url = init.history.createURL(location); + isDocumentReload = + // Hard reload if it's an absolute URL to a new origin + url.origin !== routerWindow.location.origin || + // Hard reload if it's an absolute URL that does not match our basename + stripBasename(url.pathname, basename) == null; + } + if (isDocumentReload) { + if (replace) { + routerWindow.location.replace(location); + } else { + routerWindow.location.assign(location); + } + return; + } + } + + // There's no need to abort on redirects, since we don't detect the + // redirect until the action/loaders have settled + pendingNavigationController = null; + let redirectHistoryAction = replace === true ? Action.Replace : Action.Push; + + // Use the incoming submission if provided, fallback on the active one in + // state.navigation + let { + formMethod, + formAction, + formEncType + } = state.navigation; + if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) { + submission = getSubmissionFromNavigation(state.navigation); + } + + // If this was a 307/308 submission we want to preserve the HTTP method and + // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the + // redirected location + let activeSubmission = submission || fetcherSubmission; + if (redirectPreserveMethodStatusCodes.has(redirect.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, activeSubmission, { + formAction: location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // If we have a navigation submission, we will preserve it through the + // redirect navigation + let overrideNavigation = getLoadingNavigation(redirectLocation, submission); + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation, + // Send fetcher submissions through for shouldRevalidate + fetcherSubmission, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + + // Utility wrapper for calling dataStrategy client-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches) { + try { + let results = await callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + return { + type: ResultType.redirect, + response: normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath) + }; + } + return convertHandlerResultToDataResult(result); + })); + } catch (e) { + // If the outer dataStrategy method throws, just return the error for all + // matches - and it'll naturally bubble to the root + return matchesToLoad.map(() => ({ + type: ResultType.error, + error: e + })); + } + } + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + let [loaderResults, ...fetcherResults] = await Promise.all([matchesToLoad.length ? callDataStrategy("loader", request, matchesToLoad, matches) : [], ...fetchersToLoad.map(f => { + if (f.matches && f.match && f.controller) { + let fetcherRequest = createClientSideRequest(init.history, f.path, f.controller.signal); + return callDataStrategy("loader", fetcherRequest, [f.match], f.matches).then(r => r[0]); + } else { + return Promise.resolve({ + type: ResultType.error, + error: getInternalRouterError(404, { + pathname: f.path + }) + }); + } + })]); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(() => request.signal), false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, fetchersToLoad.map(f => f.controller ? f.controller.signal : null), true)]); + return { + loaderResults, + fetcherResults + }; + } + function interruptActiveLoads() { + // Every interruption triggers a revalidation + isRevalidationRequired = true; + + // Cancel pending route-level deferreds and mark cancelled routes for + // revalidation + cancelledDeferredRoutes.push(...cancelActiveDeferreds()); + + // Abort in-flight fetcher loads + fetchLoadMatches.forEach((_, key) => { + if (fetchControllers.has(key)) { + cancelledFetcherLoads.push(key); + abortFetcher(key); + } + }); + } + function updateFetcherState(key, fetcher, opts) { + if (opts === void 0) { + opts = {}; + } + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function setFetcherError(key, routeId, error, opts) { + if (opts === void 0) { + opts = {}; + } + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }, { + flushSync: (opts && opts.flushSync) === true + }); + } + function getFetcher(key) { + if (future.v7_fetcherPersist) { + activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); + // If this fetcher was previously marked for deletion, unmark it since we + // have a new instance + if (deletedFetchers.has(key)) { + deletedFetchers.delete(key); + } + } + return state.fetchers.get(key) || IDLE_FETCHER; + } + function deleteFetcher(key) { + let fetcher = state.fetchers.get(key); + // Don't abort the controller if this is a deletion of a fetcher.submit() + // in it's loading phase since - we don't want to abort the corresponding + // revalidation and want them to complete and land + if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) { + abortFetcher(key); + } + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + deletedFetchers.delete(key); + state.fetchers.delete(key); + } + function deleteFetcherAndUpdateState(key) { + if (future.v7_fetcherPersist) { + let count = (activeFetchers.get(key) || 0) - 1; + if (count <= 0) { + activeFetchers.delete(key); + deletedFetchers.add(key); + } else { + activeFetchers.set(key, count); + } + } else { + deleteFetcher(key); + } + updateState({ + fetchers: new Map(state.fetchers) + }); + } + function abortFetcher(key) { + let controller = fetchControllers.get(key); + invariant(controller, "Expected fetch controller: " + key); + controller.abort(); + fetchControllers.delete(key); + } + function markFetchersDone(keys) { + for (let key of keys) { + let fetcher = getFetcher(key); + let doneFetcher = getDoneFetcher(fetcher.data); + state.fetchers.set(key, doneFetcher); + } + } + function markFetchRedirectsDone() { + let doneKeys = []; + let updatedFetchers = false; + for (let key of fetchRedirectIds) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + fetchRedirectIds.delete(key); + doneKeys.push(key); + updatedFetchers = true; + } + } + markFetchersDone(doneKeys); + return updatedFetchers; + } + function abortStaleFetchLoads(landedId) { + let yeetedKeys = []; + for (let [key, id] of fetchReloadIds) { + if (id < landedId) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, "Expected fetcher: " + key); + if (fetcher.state === "loading") { + abortFetcher(key); + fetchReloadIds.delete(key); + yeetedKeys.push(key); + } + } + } + markFetchersDone(yeetedKeys); + return yeetedKeys.length > 0; + } + function getBlocker(key, fn) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + if (blockerFunctions.get(key) !== fn) { + blockerFunctions.set(key, fn); + } + return blocker; + } + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + } + + // Utility function to update blockers, ensuring valid state transitions + function updateBlocker(key, newBlocker) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + + // Poor mans state machine :) + // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM + invariant(blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state); + let blockers = new Map(state.blockers); + blockers.set(key, newBlocker); + updateState({ + blockers + }); + } + function shouldBlockNavigation(_ref4) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref4; + if (blockerFunctions.size === 0) { + return; + } + + // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + if (blockerFunctions.size > 1) { + warning(false, "A router only supports one blocker at a time"); + } + let entries = Array.from(blockerFunctions.entries()); + let [blockerKey, blockerFunction] = entries[entries.length - 1]; + let blocker = state.blockers.get(blockerKey); + if (blocker && blocker.state === "proceeding") { + // If the blocker is currently proceeding, we don't need to re-check + // it and can let this navigation continue + return; + } + + // At this point, we know we're unblocked/blocked so we need to check the + // user-provided blocker function + if (blockerFunction({ + currentLocation, + nextLocation, + historyAction + })) { + return blockerKey; + } + } + function handleNavigational404(pathname) { + let error = getInternalRouterError(404, { + pathname + }); + let routesToUse = inFlightDataRoutes || dataRoutes; + let { + matches, + route + } = getShortCircuitMatches(routesToUse); + + // Cancel all pending deferred on 404s since we don't keep any routes + cancelActiveDeferreds(); + return { + notFoundMatches: matches, + route, + error + }; + } + function handleDiscoverRouteError(pathname, discoverResult) { + return { + boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id, + error: getInternalRouterError(400, { + type: "route-discovery", + pathname, + message: discoverResult.error != null && "message" in discoverResult.error ? discoverResult.error : String(discoverResult.error) + }) + }; + } + function cancelActiveDeferreds(predicate) { + let cancelledRouteIds = []; + activeDeferreds.forEach((dfd, routeId) => { + if (!predicate || predicate(routeId)) { + // Cancel the deferred - but do not remove from activeDeferreds here - + // we rely on the subscribers to do that so our tests can assert proper + // cleanup via _internalActiveDeferreds + dfd.cancel(); + cancelledRouteIds.push(routeId); + activeDeferreds.delete(routeId); + } + }); + return cancelledRouteIds; + } + + // Opt in to capturing and reporting scroll positions during navigations, + // used by the component + function enableScrollRestoration(positions, getPosition, getKey) { + savedScrollPositions = positions; + getScrollPosition = getPosition; + getScrollRestorationKey = getKey || null; + + // Perform initial hydration scroll restoration, since we miss the boat on + // the initial updateState() because we've not yet rendered + // and therefore have no savedScrollPositions available + if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { + initialScrollRestored = true; + let y = getSavedScrollPosition(state.location, state.matches); + if (y != null) { + updateState({ + restoreScrollPosition: y + }); + } + } + return () => { + savedScrollPositions = null; + getScrollPosition = null; + getScrollRestorationKey = null; + }; + } + function getScrollKey(location, matches) { + if (getScrollRestorationKey) { + let key = getScrollRestorationKey(location, matches.map(m => convertRouteMatchToUiMatch(m, state.loaderData))); + return key || location.key; + } + return location.key; + } + function saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollPosition) { + let key = getScrollKey(location, matches); + savedScrollPositions[key] = getScrollPosition(); + } + } + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions) { + let key = getScrollKey(location, matches); + let y = savedScrollPositions[key]; + if (typeof y === "number") { + return y; + } + } + return null; + } + function checkFogOfWar(matches, routesToUse, pathname) { + if (patchRoutesOnMissImpl) { + if (!matches) { + let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: fogMatches || [] + }; + } else { + let leafRoute = matches[matches.length - 1].route; + if (leafRoute.path && (leafRoute.path === "*" || leafRoute.path.endsWith("/*"))) { + // If we matched a splat, it might only be because we haven't yet fetched + // the children that would match with a higher score, so let's fetch + // around and find out + let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + return { + active: true, + matches: partialMatches + }; + } + } + } + return { + active: false, + matches: null + }; + } + async function discoverRoutes(matches, pathname, signal) { + let partialMatches = matches; + let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null; + while (true) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + try { + await loadLazyRouteChildren(patchRoutesOnMissImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal); + } catch (e) { + return { + type: "error", + error: e, + partialMatches + }; + } finally { + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity so when we `updateState` at the end of + // this navigation/fetch `router.routes` will be a new identity and + // trigger a re-run of memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + } + } + if (signal.aborted) { + return { + type: "aborted" + }; + } + let newMatches = matchRoutes(routesToUse, pathname, basename); + let matchedSplat = false; + if (newMatches) { + let leafRoute = newMatches[newMatches.length - 1].route; + if (leafRoute.index) { + // If we found an index route, we can stop + return { + type: "success", + matches: newMatches + }; + } + if (leafRoute.path && leafRoute.path.length > 0) { + if (leafRoute.path === "*") { + // If we found a splat route, we can't be sure there's not a + // higher-scoring route down some partial matches trail so we need + // to check that out + matchedSplat = true; + } else { + // If we found a non-splat route, we can stop + return { + type: "success", + matches: newMatches + }; + } + } + } + let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true); + + // If we are no longer partially matching anything, this was either a + // legit splat match above, or it's a 404. Also avoid loops if the + // second pass results in the same partial matches + if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) { + return { + type: "success", + matches: matchedSplat ? newMatches : null + }; + } + partialMatches = newPartialMatches; + route = partialMatches[partialMatches.length - 1].route; + if (route.path === "*") { + // The splat is still our most accurate partial, so run with it + return { + type: "success", + matches: partialMatches + }; + } + } + } + function _internalSetRoutes(newRoutes) { + manifest = {}; + inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest); + } + function patchRoutes(routeId, children) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties); + + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity and trigger a reflow via `updateState` + // to re-run memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + updateState({}); + } + } + router = { + get basename() { + return basename; + }, + get future() { + return future; + }, + get state() { + return state; + }, + get routes() { + return dataRoutes; + }, + get window() { + return routerWindow; + }, + initialize, + subscribe, + enableScrollRestoration, + navigate, + fetch, + revalidate, + // Passthrough to history-aware createHref used by useHref so we get proper + // hash-aware URLs in DOM paths + createHref: to => init.history.createHref(to), + encodeLocation: to => init.history.encodeLocation(to), + getFetcher, + deleteFetcher: deleteFetcherAndUpdateState, + dispose, + getBlocker, + deleteBlocker, + patchRoutes, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds, + // TODO: Remove setRoutes, it's temporary to avoid dealing with + // updating the tree while validating the update algorithm. + _internalSetRoutes + }; + return router; + } + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region createStaticHandler + //////////////////////////////////////////////////////////////////////////////// + + const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred"); + + /** + * Future flags to toggle new feature behavior + */ + + function createStaticHandler(routes, opts) { + invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler"); + let manifest = {}; + let basename = (opts ? opts.basename : null) || "/"; + let mapRouteProperties; + if (opts != null && opts.mapRouteProperties) { + mapRouteProperties = opts.mapRouteProperties; + } else if (opts != null && opts.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = opts.detectErrorBoundary; + mapRouteProperties = route => ({ + hasErrorBoundary: detectErrorBoundary(route) + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + // Config driven behavior flags + let future = _extends({ + v7_relativeSplatPath: false, + v7_throwAbortReason: false + }, opts ? opts.future : null); + let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest); + + /** + * The query() method is intended for document requests, in which we want to + * call an optional action and potentially multiple loaders for all nested + * routes. It returns a StaticHandlerContext object, which is very similar + * to the router state (location, loaderData, actionData, errors, etc.) and + * also adds SSR-specific information such as the statusCode and headers + * from action/loaders Responses. + * + * It _should_ never throw and should report all errors through the + * returned context.errors object, properly associating errors to their error + * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be + * used to emulate React error boundaries during SSr by performing a second + * pass only down to the boundaryId. + * + * The one exception where we do not return a StaticHandlerContext is when a + * redirect response is returned or thrown from any action/loader. We + * propagate that out and return the raw Response so the HTTP server can + * return it directly. + * + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent + * the bubbling of errors which allows single-fetch-type implementations + * where the client will handle the bubbling and we may need to return data + * for the handling route + */ + async function query(request, _temp3) { + let { + requestContext, + skipLoaderErrorBubbling, + unstable_dataStrategy + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD") { + let error = getInternalRouterError(405, { + method + }); + let { + matches: methodNotAllowedMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: methodNotAllowedMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } else if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: notFoundMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, skipLoaderErrorBubbling === true, null); + if (isResponse(result)) { + return result; + } + + // When returning StaticHandlerContext, we patch back in the location here + // since we need it for React Context. But this helps keep our submit and + // loadRouteData operating on a Request instead of a Location + return _extends({ + location, + basename + }, result); + } + + /** + * The queryRoute() method is intended for targeted route requests, either + * for fetch ?_data requests or resource route requests. In this case, we + * are only ever calling a single action or loader, and we are returning the + * returned value directly. In most cases, this will be a Response returned + * from the action/loader, but it may be a primitive or other value as well - + * and in such cases the calling context should handle that accordingly. + * + * We do respect the throw/return differentiation, so if an action/loader + * throws, then this method will throw the value. This is important so we + * can do proper boundary identification in Remix where a thrown Response + * must go to the Catch Boundary but a returned Response is happy-path. + * + * One thing to note is that any Router-initiated Errors that make sense + * to associate with a status code will be thrown as an ErrorResponse + * instance which include the raw Error, such that the calling context can + * serialize the error as they see fit while including the proper response + * code. Examples here are 404 and 405 errors that occur prior to reaching + * any user-defined loaders. + * + * - `opts.routeId` allows you to specify the specific route handler to call. + * If not provided the handler will determine the proper route by matching + * against `request.url` + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + */ + async function queryRoute(request, _temp4) { + let { + routeId, + requestContext, + unstable_dataStrategy + } = _temp4 === void 0 ? {} : _temp4; + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { + throw getInternalRouterError(405, { + method + }); + } else if (!matches) { + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let match = routeId ? matches.find(m => m.route.id === routeId) : getTargetMatch(matches, location); + if (routeId && !match) { + throw getInternalRouterError(403, { + pathname: location.pathname, + routeId + }); + } else if (!match) { + // This should never hit I don't think? + throw getInternalRouterError(404, { + pathname: location.pathname + }); + } + let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, false, match); + if (isResponse(result)) { + return result; + } + let error = result.errors ? Object.values(result.errors)[0] : undefined; + if (error !== undefined) { + // If we got back result.errors, that means the loader/action threw + // _something_ that wasn't a Response, but it's not guaranteed/required + // to be an `instanceof Error` either, so we have to use throw here to + // preserve the "error" state outside of queryImpl. + throw error; + } + + // Pick off the right state value to return + if (result.actionData) { + return Object.values(result.actionData)[0]; + } + if (result.loaderData) { + var _result$activeDeferre; + let data = Object.values(result.loaderData)[0]; + if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) { + data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id]; + } + return data; + } + return undefined; + } + async function queryImpl(request, location, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch) { + invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal"); + try { + if (isMutationMethod(request.method.toLowerCase())) { + let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch != null); + return result; + } + let result = await loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction for a + // `queryRoute` call, we throw the `HandlerResult` to bail out early + // and then return or throw the raw Response here accordingly + if (isHandlerResult(e) && isResponse(e.result)) { + if (e.type === ResultType.error) { + throw e.result; + } + return e.result; + } + // Redirects are always returned since they don't propagate to catch + // boundaries + if (isRedirectResponse(e)) { + return e; + } + throw e; + } + } + async function submit(request, matches, actionMatch, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, isRouteRequest) { + let result; + if (!actionMatch.route.action && !actionMatch.route.lazy) { + let error = getInternalRouterError(405, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: actionMatch.route.id + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } else { + let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, unstable_dataStrategy); + result = results[0]; + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + } + if (isRedirectResult(result)) { + // Uhhhh - this should never happen, we should always throw these from + // callLoaderOrAction, but the type narrowing here keeps TS happy and we + // can get back on the "throw all redirect responses" train here should + // this ever happen :/ + throw new Response(null, { + status: result.response.status, + headers: { + Location: result.response.headers.get("Location") + } + }); + } + if (isDeferredResult(result)) { + let error = getInternalRouterError(400, { + type: "defer-action" + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error + }; + } + if (isRouteRequest) { + // Note: This should only be non-Response values if we get here, since + // isRouteRequest should throw any Response received in callLoaderOrAction + if (isErrorResult(result)) { + throw result.error; + } + return { + matches: [actionMatch], + loaderData: {}, + actionData: { + [actionMatch.route.id]: result.data + }, + errors: null, + // Note: statusCode + headers are unused here since queryRoute will + // return the raw Response or value + statusCode: 200, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null + }; + } + + // Create a GET request for the loaders + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]); + + // action status codes take precedence over loader status codes + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null); + return _extends({}, context, { + actionData: { + [actionMatch.route.id]: result.data + } + }, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionHeaders: result.headers ? { + [actionMatch.route.id]: result.headers + } : {} + }); + } + async function loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) { + let isRouteRequest = routeMatch != null; + + // Short circuit if we have no loaders to run (queryRoute()) + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches; + let matchesToLoad = requestMatches.filter(m => m.route.loader || m.route.lazy); + + // Short circuit if we have no loaders to run (query()) + if (matchesToLoad.length === 0) { + return { + matches, + // Add a null for all matched routes for proper revalidation on the client + loaderData: matches.reduce((acc, m) => Object.assign(acc, { + [m.route.id]: null + }), {}), + errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { + [pendingActionResult[0]]: pendingActionResult[1].error + } : null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy); + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + + // Process and commit output from loaders + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling); + + // Add a null for any non-loader matches for proper revalidation on the client + let executedLoaders = new Set(matchesToLoad.map(match => match.route.id)); + matches.forEach(match => { + if (!executedLoaders.has(match.route.id)) { + context.loaderData[match.route.id] = null; + } + }); + return _extends({}, context, { + matches, + activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null + }); + } + + // Utility wrapper for calling dataStrategy server-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy) { + let results = await callDataStrategyImpl(unstable_dataStrategy || defaultDataStrategy, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext); + return await Promise.all(results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result; + // Throw redirects and let the server handle them with an HTTP redirect + throw normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath); + } + if (isResponse(result.result) && isRouteRequest) { + // For SSR single-route requests, we want to hand Responses back + // directly without unwrapping + throw result; + } + return convertHandlerResultToDataResult(result); + })); + } + return { + dataRoutes, + query, + queryRoute + }; + } + + //#endregion + + //////////////////////////////////////////////////////////////////////////////// + //#region Helpers + //////////////////////////////////////////////////////////////////////////////// + + /** + * Given an existing StaticHandlerContext and an error thrown at render time, + * provide an updated StaticHandlerContext suitable for a second SSR render + */ + function getStaticContextFromError(routes, context, error) { + let newContext = _extends({}, context, { + statusCode: isRouteErrorResponse(error) ? error.status : 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + return newContext; + } + function throwStaticHandlerAbortedError(request, isRouteRequest, future) { + if (future.v7_throwAbortReason && request.signal.reason !== undefined) { + throw request.signal.reason; + } + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted: " + request.method + " " + request.url); + } + function isSubmissionNavigation(opts) { + return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== undefined); + } + function normalizeTo(location, matches, basename, prependBasename, to, v7_relativeSplatPath, fromRouteId, relative) { + let contextualMatches; + let activeRouteMatch; + if (fromRouteId) { + // Grab matches up to the calling route so our route-relative logic is + // relative to the correct source route + contextualMatches = []; + for (let match of matches) { + contextualMatches.push(match); + if (match.route.id === fromRouteId) { + activeRouteMatch = match; + break; + } + } + } else { + contextualMatches = matches; + activeRouteMatch = matches[matches.length - 1]; + } + + // Resolve the relative path + let path = resolveTo(to ? to : ".", getResolveToMatches(contextualMatches, v7_relativeSplatPath), stripBasename(location.pathname, basename) || location.pathname, relative === "path"); + + // When `to` is not specified we inherit search/hash from the current + // location, unlike when to="." and we just inherit the path. + // See https://github.com/remix-run/remix/issues/927 + if (to == null) { + path.search = location.search; + path.hash = location.hash; + } + + // Add an ?index param for matched index routes if we don't already have one + if ((to == null || to === "" || to === ".") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) { + path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; + } + + // If we're operating within a basename, prepend it to the pathname. If + // this is a root navigation, then just use the raw basename which allows + // the basename to have full control over the presence of a trailing slash + // on root actions + if (prependBasename && basename !== "/") { + path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); + } + return createPath(path); + } + + // Normalize navigation options by converting formMethod=GET formData objects to + // URLSearchParams so they behave identically to links with query params + function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) { + // Return location verbatim on non-submission navigations + if (!opts || !isSubmissionNavigation(opts)) { + return { + path + }; + } + if (opts.formMethod && !isValidMethod(opts.formMethod)) { + return { + path, + error: getInternalRouterError(405, { + method: opts.formMethod + }) + }; + } + let getInvalidBodyError = () => ({ + path, + error: getInternalRouterError(400, { + type: "invalid-body" + }) + }); + + // Create a Submission on non-GET navigations + let rawFormMethod = opts.formMethod || "get"; + let formMethod = normalizeFormMethod ? rawFormMethod.toUpperCase() : rawFormMethod.toLowerCase(); + let formAction = stripHashFromPath(path); + if (opts.body !== undefined) { + if (opts.formEncType === "text/plain") { + // text only support POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data + Array.from(opts.body.entries()).reduce((acc, _ref5) => { + let [name, value] = _ref5; + return "" + acc + name + "=" + value + "\n"; + }, "") : String(opts.body); + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json: undefined, + text + } + }; + } else if (opts.formEncType === "application/json") { + // json only supports POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + try { + let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json, + text: undefined + } + }; + } catch (e) { + return getInvalidBodyError(); + } + } + } + invariant(typeof FormData === "function", "FormData is not available in this environment"); + let searchParams; + let formData; + if (opts.formData) { + searchParams = convertFormDataToSearchParams(opts.formData); + formData = opts.formData; + } else if (opts.body instanceof FormData) { + searchParams = convertFormDataToSearchParams(opts.body); + formData = opts.body; + } else if (opts.body instanceof URLSearchParams) { + searchParams = opts.body; + formData = convertSearchParamsToFormData(searchParams); + } else if (opts.body == null) { + searchParams = new URLSearchParams(); + formData = new FormData(); + } else { + try { + searchParams = new URLSearchParams(opts.body); + formData = convertSearchParamsToFormData(searchParams); + } catch (e) { + return getInvalidBodyError(); + } + } + let submission = { + formMethod, + formAction, + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData, + json: undefined, + text: undefined + }; + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + + // Flatten submission onto URLSearchParams for GET submissions + let parsedPath = parsePath(path); + // On GET navigation submissions we can drop the ?index param from the + // resulting location since all loaders will run. But fetcher GET submissions + // only run a single loader so we need to preserve any incoming ?index params + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + parsedPath.search = "?" + searchParams; + return { + path: createPath(parsedPath), + submission + }; + } + + // Filter out all routes below any caught error as they aren't going to + // render so we don't need to load them + function getLoaderMatchesUntilBoundary(matches, boundaryId) { + let boundaryMatches = matches; + if (boundaryId) { + let index = matches.findIndex(m => m.route.id === boundaryId); + if (index >= 0) { + boundaryMatches = matches.slice(0, index); + } + } + return boundaryMatches; + } + function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) { + let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined; + let currentUrl = history.createURL(state.location); + let nextUrl = history.createURL(location); + + // Pick navigation matches that are net-new or qualify for revalidation + let boundaryId = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[0] : undefined; + let boundaryMatches = boundaryId ? getLoaderMatchesUntilBoundary(matches, boundaryId) : matches; + + // Don't revalidate loaders by default after action 4xx/5xx responses + // when the flag is enabled. They can still opt-into revalidation via + // `shouldRevalidate` via `actionResult` + let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : undefined; + let shouldSkipRevalidation = skipActionErrorRevalidation && actionStatus && actionStatus >= 400; + let navigationMatches = boundaryMatches.filter((match, index) => { + let { + route + } = match; + if (route.lazy) { + // We haven't loaded this route yet so we don't know if it's got a loader! + return true; + } + if (route.loader == null) { + return false; + } + if (isInitialLoad) { + if (typeof route.loader !== "function" || route.loader.hydrate) { + return true; + } + return state.loaderData[route.id] === undefined && ( + // Don't re-run if the loader ran and threw an error + !state.errors || state.errors[route.id] === undefined); + } + + // Always call the loader on new route instances and pending defer cancellations + if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) { + return true; + } + + // This is the default implementation for when we revalidate. If the route + // provides it's own implementation, then we give them full control but + // provide this value so they can leverage it if needed after they check + // their own specific use cases + let currentRouteMatch = state.matches[index]; + let nextRouteMatch = match; + return shouldRevalidateLoader(match, _extends({ + currentUrl, + currentParams: currentRouteMatch.params, + nextUrl, + nextParams: nextRouteMatch.params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : + // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate + isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || + // Search params affect all loaders + currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch) + })); + }); + + // Pick fetcher.loads that need to be revalidated + let revalidatingFetchers = []; + fetchLoadMatches.forEach((f, key) => { + // Don't revalidate: + // - on initial load (shouldn't be any fetchers then anyway) + // - if fetcher won't be present in the subsequent render + // - no longer matches the URL (v7_fetcherPersist=false) + // - was unmounted but persisted due to v7_fetcherPersist=true + if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) { + return; + } + let fetcherMatches = matchRoutes(routesToUse, f.path, basename); + + // If the fetcher path no longer matches, push it in with null matches so + // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is + // currently only a use-case for Remix HMR where the route tree can change + // at runtime and remove a route previously loaded via a fetcher + if (!fetcherMatches) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: null, + match: null, + controller: null + }); + return; + } + + // Revalidating fetchers are decoupled from the route matches since they + // load from a static href. They revalidate based on explicit revalidation + // (submission, useRevalidator, or X-Remix-Revalidate) + let fetcher = state.fetchers.get(key); + let fetcherMatch = getTargetMatch(fetcherMatches, f.path); + let shouldRevalidate = false; + if (fetchRedirectIds.has(key)) { + // Never trigger a revalidation of an actively redirecting fetcher + shouldRevalidate = false; + } else if (cancelledFetcherLoads.includes(key)) { + // Always revalidate if the fetcher was cancelled + shouldRevalidate = true; + } else if (fetcher && fetcher.state !== "idle" && fetcher.data === undefined) { + // If the fetcher hasn't ever completed loading yet, then this isn't a + // revalidation, it would just be a brand new load if an explicit + // revalidation is required + shouldRevalidate = isRevalidationRequired; + } else { + // Otherwise fall back on any user-defined shouldRevalidate, defaulting + // to explicit revalidations only + shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({ + currentUrl, + currentParams: state.matches[state.matches.length - 1].params, + nextUrl, + nextParams: matches[matches.length - 1].params + }, submission, { + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired + })); + } + if (shouldRevalidate) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: fetcherMatches, + match: fetcherMatch, + controller: new AbortController() + }); + } + }); + return [navigationMatches, revalidatingFetchers]; + } + function isNewLoader(currentLoaderData, currentMatch, match) { + let isNew = + // [a] -> [a, b] + !currentMatch || + // [a, b] -> [a, c] + match.route.id !== currentMatch.route.id; + + // Handle the case that we don't have data for a re-used route, potentially + // from a prior error or from a cancelled pending deferred + let isMissingData = currentLoaderData[match.route.id] === undefined; + + // Always load if this is a net-new route or we don't yet have data + return isNew || isMissingData; + } + function isNewRouteInstance(currentMatch, match) { + let currentPath = currentMatch.route.path; + return ( + // param change for this match, /users/123 -> /users/456 + currentMatch.pathname !== match.pathname || + // splat param changed, which is not present in match.path + // e.g. /files/images/avatar.jpg -> files/finances.xls + currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); + } + function shouldRevalidateLoader(loaderMatch, arg) { + if (loaderMatch.route.shouldRevalidate) { + let routeChoice = loaderMatch.route.shouldRevalidate(arg); + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + return arg.defaultShouldRevalidate; + } + + /** + * Idempotent utility to execute patchRoutesOnMiss() to lazily load route + * definitions and update the routes/routeManifest + */ + async function loadLazyRouteChildren(patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) { + let key = [path, ...matches.map(m => m.route.id)].join("-"); + try { + let pending = pendingRouteChildren.get(key); + if (!pending) { + pending = patchRoutesOnMissImpl({ + path, + matches, + patch: (routeId, children) => { + if (!signal.aborted) { + patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties); + } + } + }); + pendingRouteChildren.set(key, pending); + } + if (pending && isPromise(pending)) { + await pending; + } + } finally { + pendingRouteChildren.delete(key); + } + } + function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) { + if (routeId) { + var _route$children; + let route = manifest[routeId]; + invariant(route, "No route found to patch children into: routeId = " + routeId); + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, [routeId, "patch", String(((_route$children = route.children) == null ? void 0 : _route$children.length) || "0")], manifest); + if (route.children) { + route.children.push(...dataChildren); + } else { + route.children = dataChildren; + } + } else { + let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest); + routesToUse.push(...dataChildren); + } + } + + /** + * Execute route.lazy() methods to lazily load route modules (loader, action, + * shouldRevalidate) and update the routeManifest in place which shares objects + * with dataRoutes so those get updated as well. + */ + async function loadLazyRouteModule(route, mapRouteProperties, manifest) { + if (!route.lazy) { + return; + } + let lazyRoute = await route.lazy(); + + // If the lazy route function was executed and removed by another parallel + // call then we can return - first lazy() to finish wins because the return + // value of lazy is expected to be static + if (!route.lazy) { + return; + } + let routeToUpdate = manifest[route.id]; + invariant(routeToUpdate, "No route found in manifest"); + + // Update the route in place. This should be safe because there's no way + // we could yet be sitting on this route as we can't get there without + // resolving lazy() first. + // + // This is different than the HMR "update" use-case where we may actively be + // on the route being updated. The main concern boils down to "does this + // mutation affect any ongoing navigations or any current state.matches + // values?". If not, it should be safe to update in place. + let routeUpdates = {}; + for (let lazyRouteProperty in lazyRoute) { + let staticRouteValue = routeToUpdate[lazyRouteProperty]; + let isPropertyStaticallyDefined = staticRouteValue !== undefined && + // This property isn't static since it should always be updated based + // on the route updates + lazyRouteProperty !== "hasErrorBoundary"; + warning(!isPropertyStaticallyDefined, "Route \"" + routeToUpdate.id + "\" has a static property \"" + lazyRouteProperty + "\" " + "defined but its lazy function is also returning a value for this property. " + ("The lazy route property \"" + lazyRouteProperty + "\" will be ignored.")); + if (!isPropertyStaticallyDefined && !immutableRouteKeys.has(lazyRouteProperty)) { + routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty]; + } + } + + // Mutate the route with the provided updates. Do this first so we pass + // the updated version to mapRouteProperties + Object.assign(routeToUpdate, routeUpdates); + + // Mutate the `hasErrorBoundary` property on the route based on the route + // updates and remove the `lazy` function so we don't resolve the lazy + // route again. + Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), { + lazy: undefined + })); + } + + // Default implementation of `dataStrategy` which fetches all loaders in parallel + function defaultDataStrategy(opts) { + return Promise.all(opts.matches.map(m => m.resolve())); + } + async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext) { + let routeIdsToLoad = matchesToLoad.reduce((acc, m) => acc.add(m.route.id), new Set()); + let loadedMatches = new Set(); + + // Send all matches here to allow for a middleware-type implementation. + // handler will be a no-op for unneeded routes and we filter those results + // back out below. + let results = await dataStrategyImpl({ + matches: matches.map(match => { + let shouldLoad = routeIdsToLoad.has(match.route.id); + // `resolve` encapsulates the route.lazy, executing the + // loader/action, and mapping return values/thrown errors to a + // HandlerResult. Users can pass a callback to take fine-grained control + // over the execution of the loader/action + let resolve = handlerOverride => { + loadedMatches.add(match.route.id); + return shouldLoad ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, requestContext) : Promise.resolve({ + type: ResultType.data, + result: undefined + }); + }; + return _extends({}, match, { + shouldLoad, + resolve + }); + }), + request, + params: matches[0].params, + context: requestContext + }); + + // Throw if any loadRoute implementations not called since they are what + // ensures a route is fully loaded + matches.forEach(m => invariant(loadedMatches.has(m.route.id), "`match.resolve()` was not called for route id \"" + m.route.id + "\". " + "You must call `match.resolve()` on every match passed to " + "`dataStrategy` to ensure all routes are properly loaded.")); + + // Filter out any middleware-only matches for which we didn't need to run handlers + return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id)); + } + + // Default logic for calling a loader/action is the user has no specified a dataStrategy + async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, staticContext) { + let result; + let onReject; + let runHandler = handler => { + // Setup a promise we can race against so that abort signals short circuit + let reject; + // This will never resolve so safe to type it as Promise to + // satisfy the function return value + let abortPromise = new Promise((_, r) => reject = r); + onReject = () => reject(); + request.signal.addEventListener("abort", onReject); + let actualHandler = ctx => { + if (typeof handler !== "function") { + return Promise.reject(new Error("You cannot call the handler for a route which defines a boolean " + ("\"" + type + "\" [routeId: " + match.route.id + "]"))); + } + return handler({ + request, + params: match.params, + context: staticContext + }, ...(ctx !== undefined ? [ctx] : [])); + }; + let handlerPromise; + if (handlerOverride) { + handlerPromise = handlerOverride(ctx => actualHandler(ctx)); + } else { + handlerPromise = (async () => { + try { + let val = await actualHandler(); + return { + type: "data", + result: val + }; + } catch (e) { + return { + type: "error", + result: e + }; + } + })(); + } + return Promise.race([handlerPromise, abortPromise]); + }; + try { + let handler = match.route[type]; + if (match.route.lazy) { + if (handler) { + // Run statically defined handler in parallel with lazy() + let handlerError; + let [value] = await Promise.all([ + // If the handler throws, don't let it immediately bubble out, + // since we need to let the lazy() execution finish so we know if this + // route has a boundary that can handle the error + runHandler(handler).catch(e => { + handlerError = e; + }), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]); + if (handlerError !== undefined) { + throw handlerError; + } + result = value; + } else { + // Load lazy route module, then run any returned handler + await loadLazyRouteModule(match.route, mapRouteProperties, manifest); + handler = match.route[type]; + if (handler) { + // Handler still runs even if we got interrupted to maintain consistency + // with un-abortable behavior of handler execution on non-lazy or + // previously-lazy-loaded routes + result = await runHandler(handler); + } else if (type === "action") { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(405, { + method: request.method, + pathname, + routeId: match.route.id + }); + } else { + // lazy() route has no loader to run. Short circuit here so we don't + // hit the invariant below that errors on returning undefined. + return { + type: ResultType.data, + result: undefined + }; + } + } + } else if (!handler) { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(404, { + pathname + }); + } else { + result = await runHandler(handler); + } + invariant(result.result !== undefined, "You defined " + (type === "action" ? "an action" : "a loader") + " for route " + ("\"" + match.route.id + "\" but didn't return anything from your `" + type + "` ") + "function. Please return a value or `null`."); + } catch (e) { + // We should already be catching and converting normal handler executions to + // HandlerResults and returning them, so anything that throws here is an + // unexpected error we still need to wrap + return { + type: ResultType.error, + result: e + }; + } finally { + if (onReject) { + request.signal.removeEventListener("abort", onReject); + } + } + return result; + } + async function convertHandlerResultToDataResult(handlerResult) { + let { + result, + type, + status + } = handlerResult; + if (isResponse(result)) { + let data; + try { + let contentType = result.headers.get("Content-Type"); + // Check between word boundaries instead of startsWith() due to the last + // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type + if (contentType && /\bapplication\/json\b/.test(contentType)) { + if (result.body == null) { + data = null; + } else { + data = await result.json(); + } + } else { + data = await result.text(); + } + } catch (e) { + return { + type: ResultType.error, + error: e + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: new ErrorResponseImpl(result.status, result.statusText, data), + statusCode: result.status, + headers: result.headers + }; + } + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + if (type === ResultType.error) { + return { + type: ResultType.error, + error: result, + statusCode: isRouteErrorResponse(result) ? result.status : status + }; + } + if (isDeferredData(result)) { + var _result$init, _result$init2; + return { + type: ResultType.deferred, + deferredData: result, + statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status, + headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers) + }; + } + return { + type: ResultType.data, + data: result, + statusCode: status + }; + } + + // Support relative routing in internal redirects + function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, v7_relativeSplatPath) { + let location = response.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + if (!ABSOLUTE_URL_REGEX.test(location)) { + let trimmedMatches = matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1); + location = normalizeTo(new URL(request.url), trimmedMatches, basename, true, location, v7_relativeSplatPath); + response.headers.set("Location", location); + } + return response; + } + function normalizeRedirectLocation(location, currentUrl, basename) { + if (ABSOLUTE_URL_REGEX.test(location)) { + // Strip off the protocol+origin for same-origin + same-basename absolute redirects + let normalizedLocation = location; + let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation); + let isSameBasename = stripBasename(url.pathname, basename) != null; + if (url.origin === currentUrl.origin && isSameBasename) { + return url.pathname + url.search + url.hash; + } + } + return location; + } + + // Utility method for creating the Request instances for loaders/actions during + // client-side navigations and fetches. During SSR we will always have a + // Request instance from the static handler (query/queryRoute) + function createClientSideRequest(history, location, signal, submission) { + let url = history.createURL(stripHashFromPath(location)).toString(); + let init = { + signal + }; + if (submission && isMutationMethod(submission.formMethod)) { + let { + formMethod, + formEncType + } = submission; + // Didn't think we needed this but it turns out unlike other methods, patch + // won't be properly normalized to uppercase and results in a 405 error. + // See: https://fetch.spec.whatwg.org/#concept-method + init.method = formMethod.toUpperCase(); + if (formEncType === "application/json") { + init.headers = new Headers({ + "Content-Type": formEncType + }); + init.body = JSON.stringify(submission.json); + } else if (formEncType === "text/plain") { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.text; + } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = convertFormDataToSearchParams(submission.formData); + } else { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.formData; + } + } + return new Request(url, init); + } + function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + for (let [key, value] of formData.entries()) { + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs + searchParams.append(key, typeof value === "string" ? value : value.name); + } + return searchParams; + } + function convertSearchParamsToFormData(searchParams) { + let formData = new FormData(); + for (let [key, value] of searchParams.entries()) { + formData.append(key, value); + } + return formData; + } + function processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; + let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined; + + // Process loader results into state.loaderData/state.errors + results.forEach((result, index) => { + let id = matchesToLoad[index].route.id; + invariant(!isRedirectResult(result), "Cannot handle redirect results in processLoaderData"); + if (isErrorResult(result)) { + let error = result.error; + // If we have a pending action error, we report it at the highest-route + // that throws a loader error, and then clear it out to indicate that + // it was consumed + if (pendingError !== undefined) { + error = pendingError; + pendingError = undefined; + } + errors = errors || {}; + if (skipLoaderErrorBubbling) { + errors[id] = error; + } else { + // Look upwards from the matched route for the closest ancestor error + // boundary, defaulting to the root match. Prefer higher error values + // if lower errors bubble to the same boundary + let boundaryMatch = findNearestBoundary(matches, id); + if (errors[boundaryMatch.route.id] == null) { + errors[boundaryMatch.route.id] = error; + } + } + + // Clear our any prior loaderData for the throwing route + loaderData[id] = undefined; + + // Once we find our first (highest) error, we set the status code and + // prevent deeper status codes from overriding + if (!foundError) { + foundError = true; + statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + if (isDeferredResult(result)) { + activeDeferreds.set(id, result.deferredData); + loaderData[id] = result.deferredData.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode != null && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + loaderData[id] = result.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } + } + }); + + // If we didn't consume the pending action error (i.e., all loaders + // resolved), then consume it here. Also clear out any loaderData for the + // throwing route + if (pendingError !== undefined && pendingActionResult) { + errors = { + [pendingActionResult[0]]: pendingError + }; + loaderData[pendingActionResult[0]] = undefined; + } + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; + } + function processLoaderData(state, matches, matchesToLoad, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble + ); + + // Process results from our revalidating fetchers + for (let index = 0; index < revalidatingFetchers.length; index++) { + let { + key, + match, + controller + } = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; + + // Process fetcher non-redirect errors + if (controller && controller.signal.aborted) { + // Nothing to do for aborted fetchers + continue; + } else if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id); + if (!(errors && errors[boundaryMatch.route.id])) { + errors = _extends({}, errors, { + [boundaryMatch.route.id]: result.error + }); + } + state.fetchers.delete(key); + } else if (isRedirectResult(result)) { + // Should never get here, redirects should get processed above, but we + // keep this to type narrow to a success result in the else + invariant(false, "Unhandled fetcher revalidation redirect"); + } else if (isDeferredResult(result)) { + // Should never get here, deferred data should be awaited for fetchers + // in resolveDeferredResults + invariant(false, "Unhandled fetcher deferred data"); + } else { + let doneFetcher = getDoneFetcher(result.data); + state.fetchers.set(key, doneFetcher); + } + } + return { + loaderData, + errors + }; + } + function mergeLoaderData(loaderData, newLoaderData, matches, errors) { + let mergedLoaderData = _extends({}, newLoaderData); + for (let match of matches) { + let id = match.route.id; + if (newLoaderData.hasOwnProperty(id)) { + if (newLoaderData[id] !== undefined) { + mergedLoaderData[id] = newLoaderData[id]; + } + } else if (loaderData[id] !== undefined && match.route.loader) { + // Preserve existing keys not included in newLoaderData and where a loader + // wasn't removed by HMR + mergedLoaderData[id] = loaderData[id]; + } + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + return mergedLoaderData; + } + function getActionDataForCommit(pendingActionResult) { + if (!pendingActionResult) { + return {}; + } + return isErrorResult(pendingActionResult[1]) ? { + // Clear out prior actionData on errors + actionData: {} + } : { + actionData: { + [pendingActionResult[0]]: pendingActionResult[1].data + } + }; + } + + // Find the nearest error boundary, looking upwards from the leaf route (or the + // route specified by routeId) for the closest ancestor error boundary, + // defaulting to the root match + function findNearestBoundary(matches, routeId) { + let eligibleMatches = routeId ? matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1) : [...matches]; + return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0]; + } + function getShortCircuitMatches(routes) { + // Prefer a root layout route if present, otherwise shim in a route object + let route = routes.length === 1 ? routes[0] : routes.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; + } + function getInternalRouterError(status, _temp5) { + let { + pathname, + routeId, + method, + type, + message + } = _temp5 === void 0 ? {} : _temp5; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + if (status === 400) { + statusText = "Bad Request"; + if (type === "route-discovery") { + errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnMiss()` " + ("function threw the following error:\n" + message); + } else if (method && pathname && routeId) { + errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (type === "defer-action") { + errorMessage = "defer() is not supported in actions"; + } else if (type === "invalid-body") { + errorMessage = "Unable to encode submission body"; + } + } else if (status === 403) { + statusText = "Forbidden"; + errorMessage = "Route \"" + routeId + "\" does not match URL \"" + pathname + "\""; + } else if (status === 404) { + statusText = "Not Found"; + errorMessage = "No route matches URL \"" + pathname + "\""; + } else if (status === 405) { + statusText = "Method Not Allowed"; + if (method && pathname && routeId) { + errorMessage = "You made a " + method.toUpperCase() + " request to \"" + pathname + "\" but " + ("did not provide an `action` for route \"" + routeId + "\", ") + "so there is no way to handle the request."; + } else if (method) { + errorMessage = "Invalid request method \"" + method.toUpperCase() + "\""; + } + } + return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true); + } + + // Find any returned redirect errors, starting from the lowest match + function findRedirect(results) { + for (let i = results.length - 1; i >= 0; i--) { + let result = results[i]; + if (isRedirectResult(result)) { + return { + result, + idx: i + }; + } + } + } + function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); + } + function isHashChangeOnly(a, b) { + if (a.pathname !== b.pathname || a.search !== b.search) { + return false; + } + if (a.hash === "") { + // /page -> /page#hash + return b.hash !== ""; + } else if (a.hash === b.hash) { + // /page#hash -> /page#hash + return true; + } else if (b.hash !== "") { + // /page#hash -> /page#other + return true; + } + + // If the hash is removed the browser will re-perform a request to the server + // /page#hash -> /page + return false; + } + function isPromise(val) { + return typeof val === "object" && val != null && "then" in val; + } + function isHandlerResult(result) { + return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error); + } + function isRedirectHandlerResult(result) { + return isResponse(result.result) && redirectStatusCodes.has(result.result.status); + } + function isDeferredResult(result) { + return result.type === ResultType.deferred; + } + function isErrorResult(result) { + return result.type === ResultType.error; + } + function isRedirectResult(result) { + return (result && result.type) === ResultType.redirect; + } + function isDeferredData(value) { + let deferred = value; + return deferred && typeof deferred === "object" && typeof deferred.data === "object" && typeof deferred.subscribe === "function" && typeof deferred.cancel === "function" && typeof deferred.resolveData === "function"; + } + function isResponse(value) { + return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined"; + } + function isRedirectResponse(result) { + if (!isResponse(result)) { + return false; + } + let status = result.status; + let location = result.headers.get("Location"); + return status >= 300 && status <= 399 && location != null; + } + function isValidMethod(method) { + return validRequestMethods.has(method.toLowerCase()); + } + function isMutationMethod(method) { + return validMutationMethods.has(method.toLowerCase()); + } + async function resolveDeferredResults(currentMatches, matchesToLoad, results, signals, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + // If we don't have a match, then we can have a deferred result to do + // anything with. This is for revalidating fetchers where the route was + // removed during HMR + if (!match) { + continue; + } + let currentMatch = currentMatches.find(m => m.route.id === match.route.id); + let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined; + if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) { + // Note: we do not have to touch activeDeferreds here since we race them + // against the signal in resolveDeferredData and they'll get aborted + // there if needed + let signal = signals[index]; + invariant(signal, "Expected an AbortSignal for revalidating fetcher deferred result"); + await resolveDeferredData(result, signal, isFetcher).then(result => { + if (result) { + results[index] = result || results[index]; + } + }); + } + } + } + async function resolveDeferredData(result, signal, unwrap) { + if (unwrap === void 0) { + unwrap = false; + } + let aborted = await result.deferredData.resolveData(signal); + if (aborted) { + return; + } + if (unwrap) { + try { + return { + type: ResultType.data, + data: result.deferredData.unwrappedData + }; + } catch (e) { + // Handle any TrackedPromise._error values encountered while unwrapping + return { + type: ResultType.error, + error: e + }; + } + } + return { + type: ResultType.data, + data: result.deferredData.data + }; + } + function hasNakedIndexQuery(search) { + return new URLSearchParams(search).getAll("index").some(v => v === ""); + } + function getTargetMatch(matches, location) { + let search = typeof location === "string" ? parsePath(location).search : location.search; + if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) { + // Return the leaf index route when index is present + return matches[matches.length - 1]; + } + // Otherwise grab the deepest "path contributing" match (ignoring index and + // pathless layout routes) + let pathMatches = getPathContributingMatches(matches); + return pathMatches[pathMatches.length - 1]; + } + function getSubmissionFromNavigation(navigation) { + let { + formMethod, + formAction, + formEncType, + text, + formData, + json + } = navigation; + if (!formMethod || !formAction || !formEncType) { + return; + } + if (text != null) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json: undefined, + text + }; + } else if (formData != null) { + return { + formMethod, + formAction, + formEncType, + formData, + json: undefined, + text: undefined + }; + } else if (json !== undefined) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json, + text: undefined + }; + } + } + function getLoadingNavigation(location, submission) { + if (submission) { + let navigation = { + state: "loading", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; + } else { + let navigation = { + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined + }; + return navigation; + } + } + function getSubmittingNavigation(location, submission) { + let navigation = { + state: "submitting", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text + }; + return navigation; + } + function getLoadingFetcher(submission, data) { + if (submission) { + let fetcher = { + state: "loading", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data + }; + return fetcher; + } else { + let fetcher = { + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; + } + } + function getSubmittingFetcher(submission, existingFetcher) { + let fetcher = { + state: "submitting", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data: existingFetcher ? existingFetcher.data : undefined + }; + return fetcher; + } + function getDoneFetcher(data) { + let fetcher = { + state: "idle", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data + }; + return fetcher; + } + function restoreAppliedTransitions(_window, transitions) { + try { + let sessionPositions = _window.sessionStorage.getItem(TRANSITIONS_STORAGE_KEY); + if (sessionPositions) { + let json = JSON.parse(sessionPositions); + for (let [k, v] of Object.entries(json || {})) { + if (v && Array.isArray(v)) { + transitions.set(k, new Set(v || [])); + } + } + } + } catch (e) { + // no-op, use default empty object + } + } + function persistAppliedTransitions(_window, transitions) { + if (transitions.size > 0) { + let json = {}; + for (let [k, v] of transitions) { + json[k] = [...v]; + } + try { + _window.sessionStorage.setItem(TRANSITIONS_STORAGE_KEY, JSON.stringify(json)); + } catch (error) { + warning(false, "Failed to save applied view transitions in sessionStorage (" + error + ")."); + } + } + } + //#endregion + + exports.AbortedDeferredError = AbortedDeferredError; + exports.Action = Action; + exports.IDLE_BLOCKER = IDLE_BLOCKER; + exports.IDLE_FETCHER = IDLE_FETCHER; + exports.IDLE_NAVIGATION = IDLE_NAVIGATION; + exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL; + exports.UNSAFE_DeferredData = DeferredData; + exports.UNSAFE_ErrorResponseImpl = ErrorResponseImpl; + exports.UNSAFE_convertRouteMatchToUiMatch = convertRouteMatchToUiMatch; + exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes; + exports.UNSAFE_decodePath = decodePath; + exports.UNSAFE_getResolveToMatches = getResolveToMatches; + exports.UNSAFE_invariant = invariant; + exports.UNSAFE_warning = warning; + exports.createBrowserHistory = createBrowserHistory; + exports.createHashHistory = createHashHistory; + exports.createMemoryHistory = createMemoryHistory; + exports.createPath = createPath; + exports.createRouter = createRouter; + exports.createStaticHandler = createStaticHandler; + exports.defer = defer; + exports.generatePath = generatePath; + exports.getStaticContextFromError = getStaticContextFromError; + exports.getToPathname = getToPathname; + exports.isDeferredData = isDeferredData; + exports.isRouteErrorResponse = isRouteErrorResponse; + exports.joinPaths = joinPaths; + exports.json = json; + exports.matchPath = matchPath; + exports.matchRoutes = matchRoutes; + exports.normalizePathname = normalizePathname; + exports.parsePath = parsePath; + exports.redirect = redirect; + exports.redirectDocument = redirectDocument; + exports.resolvePath = resolvePath; + exports.resolveTo = resolveTo; + exports.stripBasename = stripBasename; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); +//# sourceMappingURL=router.umd.js.map diff --git a/node_modules/@remix-run/router/dist/router.umd.js.map b/node_modules/@remix-run/router/dist/router.umd.js.map new file mode 100644 index 0000000000..a4217ca959 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"router.umd.js","sources":["../history.ts","../utils.ts","../router.ts"],"sourcesContent":["////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Actions represent the type of change to a location value.\n */\nexport enum Action {\n /**\n * A POP indicates a change to an arbitrary index in the history stack, such\n * as a back or forward navigation. It does not describe the direction of the\n * navigation, only that the current index changed.\n *\n * Note: This is the default action for newly created history objects.\n */\n Pop = \"POP\",\n\n /**\n * A PUSH indicates a new entry being added to the history stack, such as when\n * a link is clicked and a new page loads. When this happens, all subsequent\n * entries in the stack are lost.\n */\n Push = \"PUSH\",\n\n /**\n * A REPLACE indicates the entry at the current index in the history stack\n * being replaced by a new one.\n */\n Replace = \"REPLACE\",\n}\n\n/**\n * The pathname, search, and hash values of a URL.\n */\nexport interface Path {\n /**\n * A URL pathname, beginning with a /.\n */\n pathname: string;\n\n /**\n * A URL search string, beginning with a ?.\n */\n search: string;\n\n /**\n * A URL fragment identifier, beginning with a #.\n */\n hash: string;\n}\n\n// TODO: (v7) Change the Location generic default from `any` to `unknown` and\n// remove Remix `useLocation` wrapper.\n\n/**\n * An entry in a history stack. A location contains information about the\n * URL path, as well as possibly some arbitrary state and a key.\n */\nexport interface Location extends Path {\n /**\n * A value of arbitrary data associated with this location.\n */\n state: State;\n\n /**\n * A unique string associated with this location. May be used to safely store\n * and retrieve data in some other storage API, like `localStorage`.\n *\n * Note: This value is always \"default\" on the initial location.\n */\n key: string;\n}\n\n/**\n * A change to the current location.\n */\nexport interface Update {\n /**\n * The action that triggered the change.\n */\n action: Action;\n\n /**\n * The new location.\n */\n location: Location;\n\n /**\n * The delta between this location and the former location in the history stack\n */\n delta: number | null;\n}\n\n/**\n * A function that receives notifications about location changes.\n */\nexport interface Listener {\n (update: Update): void;\n}\n\n/**\n * Describes a location that is the destination of some navigation, either via\n * `history.push` or `history.replace`. This may be either a URL or the pieces\n * of a URL path.\n */\nexport type To = string | Partial;\n\n/**\n * A history is an interface to the navigation stack. The history serves as the\n * source of truth for the current location, as well as provides a set of\n * methods that may be used to change it.\n *\n * It is similar to the DOM's `window.history` object, but with a smaller, more\n * focused API.\n */\nexport interface History {\n /**\n * The last action that modified the current location. This will always be\n * Action.Pop when a history instance is first created. This value is mutable.\n */\n readonly action: Action;\n\n /**\n * The current location. This value is mutable.\n */\n readonly location: Location;\n\n /**\n * Returns a valid href for the given `to` value that may be used as\n * the value of an attribute.\n *\n * @param to - The destination URL\n */\n createHref(to: To): string;\n\n /**\n * Returns a URL for the given `to` value\n *\n * @param to - The destination URL\n */\n createURL(to: To): URL;\n\n /**\n * Encode a location the same way window.history would do (no-op for memory\n * history) so we ensure our PUSH/REPLACE navigations for data routers\n * behave the same as POP\n *\n * @param to Unencoded path\n */\n encodeLocation(to: To): Path;\n\n /**\n * Pushes a new location onto the history stack, increasing its length by one.\n * If there were any entries in the stack after the current one, they are\n * lost.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n push(to: To, state?: any): void;\n\n /**\n * Replaces the current location in the history stack with a new one. The\n * location that was replaced will no longer be available.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n replace(to: To, state?: any): void;\n\n /**\n * Navigates `n` entries backward/forward in the history stack relative to the\n * current index. For example, a \"back\" navigation would use go(-1).\n *\n * @param delta - The delta in the stack index\n */\n go(delta: number): void;\n\n /**\n * Sets up a listener that will be called whenever the current location\n * changes.\n *\n * @param listener - A function that will be called when the location changes\n * @returns unlisten - A function that may be used to stop listening\n */\n listen(listener: Listener): () => void;\n}\n\ntype HistoryState = {\n usr: any;\n key?: string;\n idx: number;\n};\n\nconst PopStateEventType = \"popstate\";\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Memory History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A user-supplied object that describes a location. Used when providing\n * entries to `createMemoryHistory` via its `initialEntries` option.\n */\nexport type InitialEntry = string | Partial;\n\nexport type MemoryHistoryOptions = {\n initialEntries?: InitialEntry[];\n initialIndex?: number;\n v5Compat?: boolean;\n};\n\n/**\n * A memory history stores locations in memory. This is useful in stateful\n * environments where there is no web browser, such as node tests or React\n * Native.\n */\nexport interface MemoryHistory extends History {\n /**\n * The current index in the history stack.\n */\n readonly index: number;\n}\n\n/**\n * Memory history stores the current location in memory. It is designed for use\n * in stateful non-browser environments like tests and React Native.\n */\nexport function createMemoryHistory(\n options: MemoryHistoryOptions = {}\n): MemoryHistory {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries: Location[]; // Declare so we can access from createMemoryLocation\n entries = initialEntries.map((entry, index) =>\n createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index === 0 ? \"default\" : undefined\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n function clampIndex(n: number): number {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation(): Location {\n return entries[index];\n }\n function createMemoryLocation(\n to: To,\n state: any = null,\n key?: string\n ): Location {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n\n function createHref(to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n let history: MemoryHistory = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref,\n createURL(to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation(to: To) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\",\n };\n },\n push(to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn: Listener) {\n listener = fn;\n return () => {\n listener = null;\n };\n },\n };\n\n return history;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Browser History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A browser history stores the current location in regular URLs in a web\n * browser environment. This is the standard for most web apps and provides the\n * cleanest URLs the browser's address bar.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory\n */\nexport interface BrowserHistory extends UrlHistory {}\n\nexport type BrowserHistoryOptions = UrlHistoryOptions;\n\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */\nexport function createBrowserHistory(\n options: BrowserHistoryOptions = {}\n): BrowserHistory {\n function createBrowserLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let { pathname, search, hash } = window.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createBrowserHref(window: Window, to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Hash History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A hash history stores the current location in the fragment identifier portion\n * of the URL in a web browser environment.\n *\n * This is ideal for apps that do not control the server for some reason\n * (because the fragment identifier is never sent to the server), including some\n * shared hosting environments that do not provide fine-grained controls over\n * which pages are served at which URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory\n */\nexport interface HashHistory extends UrlHistory {}\n\nexport type HashHistoryOptions = UrlHistoryOptions;\n\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */\nexport function createHashHistory(\n options: HashHistoryOptions = {}\n): HashHistory {\n function createHashLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n } = parsePath(window.location.hash.substr(1));\n\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route () since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createHashHref(window: Window, to: To) {\n let base = window.document.querySelector(\"base\");\n let href = \"\";\n\n if (base && base.getAttribute(\"href\")) {\n let url = window.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n\n function validateHashLocation(location: Location, to: To) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region UTILS\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @private\n */\nexport function invariant(value: boolean, message?: string): asserts value;\nexport function invariant(\n value: T | null | undefined,\n message?: string\n): asserts value is T;\nexport function invariant(value: any, message?: string) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\n\nexport function warning(cond: any, message: string) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience, so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\n\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n\n/**\n * For browser-based histories, we combine the state and key into an object\n */\nfunction getHistoryState(location: Location, index: number): HistoryState {\n return {\n usr: location.state,\n key: location.key,\n idx: index,\n };\n}\n\n/**\n * Creates a Location object with a unique key from the given Path\n */\nexport function createLocation(\n current: string | Location,\n to: To,\n state: any = null,\n key?: string\n): Readonly {\n let location: Readonly = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...(typeof to === \"string\" ? parsePath(to) : to),\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: (to && (to as Location).key) || key || createKey(),\n };\n return location;\n}\n\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */\nexport function createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n}: Partial) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */\nexport function parsePath(path: string): Partial {\n let parsedPath: Partial = {};\n\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n\n if (path) {\n parsedPath.pathname = path;\n }\n }\n\n return parsedPath;\n}\n\nexport interface UrlHistory extends History {}\n\nexport type UrlHistoryOptions = {\n window?: Window;\n v5Compat?: boolean;\n};\n\nfunction getUrlBasedHistory(\n getLocation: (window: Window, globalHistory: Window[\"history\"]) => Location,\n createHref: (window: Window, to: To) => string,\n validateLocation: ((location: Location, to: To) => void) | null,\n options: UrlHistoryOptions = {}\n): UrlHistory {\n let { window = document.defaultView!, v5Compat = false } = options;\n let globalHistory = window.history;\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n let index = getIndex()!;\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n\n function getIndex(): number {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n\n function push(to: To, state?: any) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window.location.assign(url);\n }\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n\n function replace(to: To, state?: any) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n\n function createURL(to: To): URL {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base =\n window.location.origin !== \"null\"\n ? window.location.origin\n : window.location.href;\n\n let href = typeof to === \"string\" ? to : createPath(to);\n // Treating this as a full URL will strip any trailing spaces so we need to\n // pre-encode them since they might be part of a matching splat param from\n // an ancestor route\n href = href.replace(/ $/, \"%20\");\n invariant(\n base,\n `No window.location.(origin|href) available to create URL for href: ${href}`\n );\n return new URL(href, base);\n }\n\n let history: History = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window, globalHistory);\n },\n listen(fn: Listener) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n\n return () => {\n window.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref(window, to);\n },\n createURL,\n encodeLocation(to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n },\n push,\n replace,\n go(n) {\n return globalHistory.go(n);\n },\n };\n\n return history;\n}\n\n//#endregion\n","import type { Location, Path, To } from \"./history\";\nimport { invariant, parsePath, warning } from \"./history\";\n\n/**\n * Map of routeId -> data returned from a loader/action/error\n */\nexport interface RouteData {\n [routeId: string]: any;\n}\n\nexport enum ResultType {\n data = \"data\",\n deferred = \"deferred\",\n redirect = \"redirect\",\n error = \"error\",\n}\n\n/**\n * Successful result from a loader or action\n */\nexport interface SuccessResult {\n type: ResultType.data;\n data: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Successful defer() result from a loader or action\n */\nexport interface DeferredResult {\n type: ResultType.deferred;\n deferredData: DeferredData;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Redirect result from a loader or action\n */\nexport interface RedirectResult {\n type: ResultType.redirect;\n // We keep the raw Response for redirects so we can return it verbatim\n response: Response;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Result from a loader or action - potentially successful or unsuccessful\n */\nexport type DataResult =\n | SuccessResult\n | DeferredResult\n | RedirectResult\n | ErrorResult;\n\n/**\n * Result from a loader or action called via dataStrategy\n */\nexport interface HandlerResult {\n type: \"data\" | \"error\";\n result: unknown; // data, Error, Response, DeferredData\n status?: number;\n}\n\ntype LowerCaseFormMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\ntype UpperCaseFormMethod = Uppercase;\n\n/**\n * Users can specify either lowercase or uppercase form methods on ``,\n * useSubmit(), ``, etc.\n */\nexport type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;\n\n/**\n * Active navigation/fetcher form methods are exposed in lowercase on the\n * RouterState\n */\nexport type FormMethod = LowerCaseFormMethod;\nexport type MutationFormMethod = Exclude;\n\n/**\n * In v7, active navigation/fetcher form methods are exposed in uppercase on the\n * RouterState. This is to align with the normalization done via fetch().\n */\nexport type V7_FormMethod = UpperCaseFormMethod;\nexport type V7_MutationFormMethod = Exclude;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\"\n | \"application/json\"\n | \"text/plain\";\n\n// Thanks https://github.com/sindresorhus/type-fest!\ntype JsonObject = { [Key in string]: JsonValue } & {\n [Key in string]?: JsonValue | undefined;\n};\ntype JsonArray = JsonValue[] | readonly JsonValue[];\ntype JsonPrimitive = string | number | boolean | null;\ntype JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport type Submission =\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n json: undefined;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: JsonValue;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: undefined;\n text: string;\n };\n\n/**\n * @private\n * Arguments passed to route loader/action functions. Same for now but we keep\n * this as a private implementation detail in case they diverge in the future.\n */\ninterface DataFunctionArgs {\n request: Request;\n params: Params;\n context?: Context;\n}\n\n// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:\n// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs\n// Also, make them a type alias instead of an interface\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Loaders and actions can return anything except `undefined` (`null` is a\n * valid return value if there is no data to return). Responses are preferred\n * and will ease any future migration to Remix\n */\ntype DataFunctionValue = Response | NonNullable | null;\n\ntype DataFunctionReturnValue = Promise | DataFunctionValue;\n\n/**\n * Route loader function signature\n */\nexport type LoaderFunction = {\n (\n args: LoaderFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n} & { hydrate?: boolean };\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (\n args: ActionFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n}\n\n/**\n * Arguments passed to shouldRevalidate function\n */\nexport interface ShouldRevalidateFunctionArgs {\n currentUrl: URL;\n currentParams: AgnosticDataRouteMatch[\"params\"];\n nextUrl: URL;\n nextParams: AgnosticDataRouteMatch[\"params\"];\n formMethod?: Submission[\"formMethod\"];\n formAction?: Submission[\"formAction\"];\n formEncType?: Submission[\"formEncType\"];\n text?: Submission[\"text\"];\n formData?: Submission[\"formData\"];\n json?: Submission[\"json\"];\n actionStatus?: number;\n actionResult?: any;\n defaultShouldRevalidate: boolean;\n}\n\n/**\n * Route shouldRevalidate function signature. This runs after any submission\n * (navigation or fetcher), so we flatten the navigation/fetcher submission\n * onto the arguments. It shouldn't matter whether it came from a navigation\n * or a fetcher, what really matters is the URLs and the formData since loaders\n * have to re-run based on the data models that were potentially mutated.\n */\nexport interface ShouldRevalidateFunction {\n (args: ShouldRevalidateFunctionArgs): boolean;\n}\n\n/**\n * Function provided by the framework-aware layers to set `hasErrorBoundary`\n * from the framework-aware `errorElement` prop\n *\n * @deprecated Use `mapRouteProperties` instead\n */\nexport interface DetectErrorBoundaryFunction {\n (route: AgnosticRouteObject): boolean;\n}\n\nexport interface DataStrategyMatch\n extends AgnosticRouteMatch {\n shouldLoad: boolean;\n resolve: (\n handlerOverride?: (\n handler: (ctx?: unknown) => DataFunctionReturnValue\n ) => Promise\n ) => Promise;\n}\n\nexport interface DataStrategyFunctionArgs\n extends DataFunctionArgs {\n matches: DataStrategyMatch[];\n}\n\nexport interface DataStrategyFunction {\n (args: DataStrategyFunctionArgs): Promise;\n}\n\nexport interface AgnosticPatchRoutesOnMissFunction<\n M extends AgnosticRouteMatch = AgnosticRouteMatch\n> {\n (opts: {\n path: string;\n matches: M[];\n patch: (routeId: string | null, children: AgnosticRouteObject[]) => void;\n }): void | Promise;\n}\n\n/**\n * Function provided by the framework-aware layers to set any framework-specific\n * properties from framework-agnostic properties\n */\nexport interface MapRoutePropertiesFunction {\n (route: AgnosticRouteObject): {\n hasErrorBoundary: boolean;\n } & Record;\n}\n\n/**\n * Keys we cannot change from within a lazy() function. We spread all other keys\n * onto the route. Either they're meaningful to the router, or they'll get\n * ignored.\n */\nexport type ImmutableRouteKey =\n | \"lazy\"\n | \"caseSensitive\"\n | \"path\"\n | \"id\"\n | \"index\"\n | \"children\";\n\nexport const immutableRouteKeys = new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\",\n]);\n\ntype RequireOne = Exclude<\n {\n [K in keyof T]: K extends Key ? Omit & Required> : never;\n }[keyof T],\n undefined\n>;\n\n/**\n * lazy() function to load a route definition, which can add non-matching\n * related properties to a route\n */\nexport interface LazyRouteFunction {\n (): Promise>>;\n}\n\n/**\n * Base RouteObject with common props shared by all types of routes\n */\ntype AgnosticBaseRouteObject = {\n caseSensitive?: boolean;\n path?: string;\n id?: string;\n loader?: LoaderFunction | boolean;\n action?: ActionFunction | boolean;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\n lazy?: LazyRouteFunction;\n};\n\n/**\n * Index routes must not have children\n */\nexport type AgnosticIndexRouteObject = AgnosticBaseRouteObject & {\n children?: undefined;\n index: true;\n};\n\n/**\n * Non-index routes may have children, but cannot have index\n */\nexport type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & {\n children?: AgnosticRouteObject[];\n index?: false;\n};\n\n/**\n * A route object represents a logical route, with (optionally) its child\n * routes organized in a tree-like structure.\n */\nexport type AgnosticRouteObject =\n | AgnosticIndexRouteObject\n | AgnosticNonIndexRouteObject;\n\nexport type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & {\n id: string;\n};\n\nexport type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & {\n children?: AgnosticDataRouteObject[];\n id: string;\n};\n\n/**\n * A data route object, which is just a RouteObject with a required unique ID\n */\nexport type AgnosticDataRouteObject =\n | AgnosticDataIndexRouteObject\n | AgnosticDataNonIndexRouteObject;\n\nexport type RouteManifest = Record;\n\n// Recursive helper for finding path parameters in the absence of wildcards\ntype _PathParam =\n // split path into individual path segments\n Path extends `${infer L}/${infer R}`\n ? _PathParam | _PathParam\n : // find params after `:`\n Path extends `:${infer Param}`\n ? Param extends `${infer Optional}?`\n ? Optional\n : Param\n : // otherwise, there aren't any params present\n never;\n\n/**\n * Examples:\n * \"/a/b/*\" -> \"*\"\n * \":a\" -> \"a\"\n * \"/a/:b\" -> \"b\"\n * \"/a/blahblahblah:b\" -> \"b\"\n * \"/:a/:b\" -> \"a\" | \"b\"\n * \"/:a/b/:c/*\" -> \"a\" | \"c\" | \"*\"\n */\nexport type PathParam =\n // check if path is just a wildcard\n Path extends \"*\" | \"/*\"\n ? \"*\"\n : // look for wildcard at the end of the path\n Path extends `${infer Rest}/*`\n ? \"*\" | _PathParam\n : // look for params in the absence of wildcards\n _PathParam;\n\n// Attempt to parse the given string segment. If it fails, then just return the\n// plain string type as a default fallback. Otherwise, return the union of the\n// parsed string literals that were referenced as dynamic segments in the route.\nexport type ParamParseKey =\n // if you could not find path params, fallback to `string`\n [PathParam] extends [never] ? string : PathParam;\n\n/**\n * The parameters that were parsed from the URL path.\n */\nexport type Params = {\n readonly [key in Key]: string | undefined;\n};\n\n/**\n * A RouteMatch contains info about how a route matched a URL.\n */\nexport interface AgnosticRouteMatch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObjectType;\n}\n\nexport interface AgnosticDataRouteMatch\n extends AgnosticRouteMatch {}\n\nfunction isIndexRoute(\n route: AgnosticRouteObject\n): route is AgnosticIndexRouteObject {\n return route.index === true;\n}\n\n// Walk the route tree generating unique IDs where necessary, so we are working\n// solely with AgnosticDataRouteObject's within the Router\nexport function convertRoutesToDataRoutes(\n routes: AgnosticRouteObject[],\n mapRouteProperties: MapRoutePropertiesFunction,\n parentPath: string[] = [],\n manifest: RouteManifest = {}\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n !manifest[id],\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n };\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n children: undefined,\n };\n manifest[id] = pathOrLayoutRoute;\n\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties,\n treePath,\n manifest\n );\n }\n\n return pathOrLayoutRoute;\n }\n });\n}\n\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/utils/match-routes\n */\nexport function matchRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename = \"/\"\n): AgnosticRouteMatch[] | null {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\n\nexport function matchRoutesImpl<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename: string,\n allowPartial: boolean\n): AgnosticRouteMatch[] | null {\n let location =\n typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n\n let pathname = stripBasename(location.pathname || \"/\", basename);\n\n if (pathname == null) {\n return null;\n }\n\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n\n return matches;\n}\n\nexport interface UIMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: Data;\n handle: Handle;\n}\n\nexport function convertRouteMatchToUiMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UIMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle,\n };\n}\n\ninterface RouteMeta<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n relativePath: string;\n caseSensitive: boolean;\n childrenIndex: number;\n route: RouteObjectType;\n}\n\ninterface RouteBranch<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n path: string;\n score: number;\n routesMeta: RouteMeta[];\n}\n\nfunction flattenRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n branches: RouteBranch[] = [],\n parentsMeta: RouteMeta[] = [],\n parentPath = \"\"\n): RouteBranch[] {\n let flattenRoute = (\n route: RouteObjectType,\n index: number,\n relativePath?: string\n ) => {\n let meta: RouteMeta = {\n relativePath:\n relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route,\n };\n\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path ` +\n `\"${parentPath}\" is not valid. An absolute child route path ` +\n `must start with the combined path of all its parent routes.`\n );\n\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n\n // Add the children before adding this route to the array, so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove ` +\n `all child routes from route path \"${path}\".`\n );\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta,\n });\n };\n routes.forEach((route, index) => {\n // coarse-grain check for optional params\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, exploded);\n }\n }\n });\n\n return branches;\n}\n\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */\nfunction explodeOptionalSegments(path: string): string[] {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n\n let [first, ...rest] = segments;\n\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [required, \"\"] : [required];\n }\n\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n\n let result: string[] = [];\n\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children, so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explode _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(\n ...restExploded.map((subpath) =>\n subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n\n // Then, if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n\n // for absolute paths, ensure `/` instead of empty segment\n return result.map((exploded) =>\n path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\n\nfunction rankRouteBranches(branches: RouteBranch[]): void {\n branches.sort((a, b) =>\n a.score !== b.score\n ? b.score - a.score // Higher score first\n : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\n\nconst paramRe = /^:[\\w-]+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s: string) => s === \"*\";\n\nfunction computeScore(path: string, index: boolean | undefined): number {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n\n if (index) {\n initialScore += indexRouteValue;\n }\n\n return segments\n .filter((s) => !isSplat(s))\n .reduce(\n (score, segment) =>\n score +\n (paramRe.test(segment)\n ? dynamicSegmentValue\n : segment === \"\"\n ? emptySegmentValue\n : staticSegmentValue),\n initialScore\n );\n}\n\nfunction compareIndexes(a: number[], b: number[]): number {\n let siblings =\n a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n\n return siblings\n ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\n\nfunction matchRouteBranch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n branch: RouteBranch,\n pathname: string,\n allowPartial = false\n): AgnosticRouteMatch[] | null {\n let { routesMeta } = branch;\n\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches: AgnosticRouteMatch[] = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname =\n matchedPathname === \"/\"\n ? pathname\n : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n\n let route = meta.route;\n\n if (\n !match &&\n end &&\n allowPartial &&\n !routesMeta[routesMeta.length - 1].route.index\n ) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false,\n },\n remainingPathname\n );\n }\n\n if (!match) {\n return null;\n }\n\n Object.assign(matchedParams, match.params);\n\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams as Params,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route,\n });\n\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n\n return matches;\n}\n\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/utils/generate-path\n */\nexport function generatePath(\n originalPath: Path,\n params: {\n [key in PathParam]: string | null;\n } = {} as any\n): string {\n let path: string = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\") as Path;\n }\n\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n\n const stringify = (p: any) =>\n p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n\n const segments = path\n .split(/\\/+/)\n .map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\" as PathParam;\n // Apply the splat\n return stringify(params[star]);\n }\n\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key as PathParam];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return stringify(param);\n }\n\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })\n // Remove empty segments\n .filter((segment) => !!segment);\n\n return prefix + segments.join(\"/\");\n}\n\n/**\n * A PathPattern is used to match on some portion of a URL pathname.\n */\nexport interface PathPattern {\n /**\n * A string to match against a URL pathname. May contain `:id`-style segments\n * to indicate placeholders for dynamic parameters. May also end with `/*` to\n * indicate matching the rest of the URL pathname.\n */\n path: Path;\n /**\n * Should be `true` if the static portions of the `path` should be matched in\n * the same case.\n */\n caseSensitive?: boolean;\n /**\n * Should be `true` if this pattern should match the entire URL pathname.\n */\n end?: boolean;\n}\n\n/**\n * A PathMatch contains info about how a PathPattern matched on a URL pathname.\n */\nexport interface PathMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The pattern that was used to match.\n */\n pattern: PathPattern;\n}\n\ntype Mutable = {\n -readonly [P in keyof T]: T[P];\n};\n\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/utils/match-path\n */\nexport function matchPath<\n ParamKey extends ParamParseKey,\n Path extends string\n>(\n pattern: PathPattern | Path,\n pathname: string\n): PathMatch | null {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n\n let match = pathname.match(matcher);\n if (!match) return null;\n\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params: Params = compiledParams.reduce>(\n (memo, { paramName, isOptional }, index) => {\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname\n .slice(0, matchedPathname.length - splatValue.length)\n .replace(/(.)\\/+$/, \"$1\");\n }\n\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo[paramName] = undefined;\n } else {\n memo[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\ntype CompiledPathParam = { paramName: string; isOptional?: boolean };\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, CompiledPathParam[]] {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n\n let params: CompiledPathParam[] = [];\n let regexpSource =\n \"^\" +\n path\n .replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (_: string, paramName: string, isOptional) => {\n params.push({ paramName, isOptional: isOptional != null });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n }\n );\n\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource +=\n path === \"*\" || path === \"/*\"\n ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex, so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n // Nothing to match for \"\" or \"/\"\n }\n\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n\n return [matcher, params];\n}\n\nexport function decodePath(value: string) {\n try {\n return value\n .split(\"/\")\n .map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\"))\n .join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is is a ` +\n `malformed URL segment. This is probably due to a bad percent ` +\n `encoding (${error}).`\n );\n\n return value;\n }\n}\n\n/**\n * @private\n */\nexport function stripBasename(\n pathname: string,\n basename: string\n): string | null {\n if (basename === \"/\") return pathname;\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\")\n ? basename.length - 1\n : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n\n return pathname.slice(startIndex) || \"/\";\n}\n\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/utils/resolve-path\n */\nexport function resolvePath(to: To, fromPathname = \"/\"): Path {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\",\n } = typeof to === \"string\" ? parsePath(to) : to;\n\n let pathname = toPathname\n ? toPathname.startsWith(\"/\")\n ? toPathname\n : resolvePathname(toPathname, fromPathname)\n : fromPathname;\n\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash),\n };\n}\n\nfunction resolvePathname(relativePath: string, fromPathname: string): string {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\n\nfunction getInvalidPathError(\n char: string,\n field: string,\n dest: string,\n path: Partial\n) {\n return (\n `Cannot include a '${char}' character in a manually specified ` +\n `\\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the ` +\n `\\`to.${dest}\\` field. Alternatively you may provide the full path as ` +\n `a string in and the router will parse it for you.`\n );\n}\n\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * \n * \n * \n *\n * \n * \n * }> // <-- Does not contribute\n * // <-- Does not contribute\n * \n * \n */\nexport function getPathContributingMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[]) {\n return matches.filter(\n (match, index) =>\n index === 0 || (match.route.path && match.route.path.length > 0)\n );\n}\n\n// Return the array of pathnames for the current route matches - used to\n// generate the routePathnames input for resolveTo()\nexport function getResolveToMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[], v7_relativeSplatPath: boolean) {\n let pathMatches = getPathContributingMatches(matches);\n\n // When v7_relativeSplatPath is enabled, use the full pathname for the leaf\n // match so we include splat values for \".\" links. See:\n // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329\n if (v7_relativeSplatPath) {\n return pathMatches.map((match, idx) =>\n idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n }\n\n return pathMatches.map((match) => match.pathnameBase);\n}\n\n/**\n * @private\n */\nexport function resolveTo(\n toArg: To,\n routePathnames: string[],\n locationPathname: string,\n isPathRelative = false\n): Path {\n let to: Partial;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n\n let from: string;\n\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n // With relative=\"route\" (the default), each leading .. segment means\n // \"go up one route\" instead of \"go up one URL segment\". This is a key\n // difference from how works and a major reason we call this a\n // \"to\" value instead of a \"href\".\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n\n let path = resolvePath(to, from);\n\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash =\n toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash =\n (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (\n !path.pathname.endsWith(\"/\") &&\n (hasExplicitTrailingSlash || hasCurrentTrailingSlash)\n ) {\n path.pathname += \"/\";\n }\n\n return path;\n}\n\n/**\n * @private\n */\nexport function getToPathname(to: To): string | undefined {\n // Empty strings should be treated the same as / paths\n return to === \"\" || (to as Path).pathname === \"\"\n ? \"/\"\n : typeof to === \"string\"\n ? parsePath(to).pathname\n : to.pathname;\n}\n\n/**\n * @private\n */\nexport const joinPaths = (paths: string[]): string =>\n paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n\n/**\n * @private\n */\nexport const normalizePathname = (pathname: string): string =>\n pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n\n/**\n * @private\n */\nexport const normalizeSearch = (search: string): string =>\n !search || search === \"?\"\n ? \"\"\n : search.startsWith(\"?\")\n ? search\n : \"?\" + search;\n\n/**\n * @private\n */\nexport const normalizeHash = (hash: string): string =>\n !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n\nexport type JsonFunction = (\n data: Data,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n */\nexport const json: JsonFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n\n return new Response(JSON.stringify(data), {\n ...responseInit,\n headers,\n });\n};\n\nexport interface TrackedPromise extends Promise {\n _tracked?: boolean;\n _data?: any;\n _error?: any;\n}\n\nexport class AbortedDeferredError extends Error {}\n\nexport class DeferredData {\n private pendingKeysSet: Set = new Set();\n private controller: AbortController;\n private abortPromise: Promise;\n private unlistenAbortSignal: () => void;\n private subscribers: Set<(aborted: boolean, settledKey?: string) => void> =\n new Set();\n data: Record;\n init?: ResponseInit;\n deferredKeys: string[] = [];\n\n constructor(data: Record, responseInit?: ResponseInit) {\n invariant(\n data && typeof data === \"object\" && !Array.isArray(data),\n \"defer() only accepts plain objects\"\n );\n\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject: (e: AbortedDeferredError) => void;\n this.abortPromise = new Promise((_, r) => (reject = r));\n this.controller = new AbortController();\n let onAbort = () =>\n reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = () =>\n this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n\n this.data = Object.entries(data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: this.trackPromise(key, value),\n }),\n {}\n );\n\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n\n this.init = responseInit;\n }\n\n private trackPromise(\n key: string,\n value: Promise | unknown\n ): TrackedPromise | unknown {\n if (!(value instanceof Promise)) {\n return value;\n }\n\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise: TrackedPromise = Promise.race([value, this.abortPromise]).then(\n (data) => this.onSettle(promise, key, undefined, data as unknown),\n (error) => this.onSettle(promise, key, error as unknown)\n );\n\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(() => {});\n\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n return promise;\n }\n\n private onSettle(\n promise: TrackedPromise,\n key: string,\n error: unknown,\n data?: unknown\n ): unknown {\n if (\n this.controller.signal.aborted &&\n error instanceof AbortedDeferredError\n ) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", { get: () => error });\n return Promise.reject(error);\n }\n\n this.pendingKeysSet.delete(key);\n\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error(\n `Deferred data for key \"${key}\" resolved/rejected with \\`undefined\\`, ` +\n `you must resolve/reject with a value or \\`null\\`.`\n );\n Object.defineProperty(promise, \"_error\", { get: () => undefinedError });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", { get: () => error });\n this.emit(false, key);\n return Promise.reject(error);\n }\n\n Object.defineProperty(promise, \"_data\", { get: () => data });\n this.emit(false, key);\n return data;\n }\n\n private emit(aborted: boolean, settledKey?: string) {\n this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));\n }\n\n subscribe(fn: (aborted: boolean, settledKey?: string) => void) {\n this.subscribers.add(fn);\n return () => this.subscribers.delete(fn);\n }\n\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n\n async resolveData(signal: AbortSignal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = () => this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise((resolve) => {\n this.subscribe((aborted) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n\n get unwrappedData() {\n invariant(\n this.data !== null && this.done,\n \"Can only unwrap data on initialized and settled deferreds\"\n );\n\n return Object.entries(this.data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: unwrapTrackedPromise(value),\n }),\n {}\n );\n }\n\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\n\nfunction isTrackedPromise(value: any): value is TrackedPromise {\n return (\n value instanceof Promise && (value as TrackedPromise)._tracked === true\n );\n}\n\nfunction unwrapTrackedPromise(value: any) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\n\nexport type DeferFunction = (\n data: Record,\n init?: number | ResponseInit\n) => DeferredData;\n\nexport const defer: DeferFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n return new DeferredData(data, responseInit);\n};\n\nexport type RedirectFunction = (\n url: string,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirect: RedirectFunction = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...responseInit,\n headers,\n });\n};\n\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirectDocument: RedirectFunction = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n\nexport type ErrorResponse = {\n status: number;\n statusText: string;\n data: any;\n};\n\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n *\n * We don't export the class for public use since it's an implementation\n * detail, but we export the interface above so folks can build their own\n * abstractions around instances via isRouteErrorResponse()\n */\nexport class ErrorResponseImpl implements ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n private error?: Error;\n private internal: boolean;\n\n constructor(\n status: number,\n statusText: string | undefined,\n data: any,\n internal = false\n ) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */\nexport function isRouteErrorResponse(error: any): error is ErrorResponse {\n return (\n error != null &&\n typeof error.status === \"number\" &&\n typeof error.statusText === \"string\" &&\n typeof error.internal === \"boolean\" &&\n \"data\" in error\n );\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n warning,\n} from \"./history\";\nimport type {\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DataStrategyMatch,\n AgnosticRouteObject,\n DataResult,\n DataStrategyFunction,\n DataStrategyFunctionArgs,\n DeferredData,\n DeferredResult,\n DetectErrorBoundaryFunction,\n ErrorResult,\n FormEncType,\n FormMethod,\n HTMLFormMethod,\n HandlerResult,\n ImmutableRouteKey,\n MapRoutePropertiesFunction,\n MutationFormMethod,\n RedirectResult,\n RouteData,\n RouteManifest,\n ShouldRevalidateFunctionArgs,\n Submission,\n SuccessResult,\n UIMatch,\n V7_FormMethod,\n V7_MutationFormMethod,\n AgnosticPatchRoutesOnMissFunction,\n} from \"./utils\";\nimport {\n ErrorResponseImpl,\n ResultType,\n convertRouteMatchToUiMatch,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n getResolveToMatches,\n immutableRouteKeys,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n matchRoutesImpl,\n resolveTo,\n stripBasename,\n} from \"./utils\";\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A Router instance manages all navigation and data loading/mutations\n */\nexport interface Router {\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the basename for the router\n */\n get basename(): RouterInit[\"basename\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the future config for the router\n */\n get future(): FutureConfig;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the current state of the router\n */\n get state(): RouterState;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the routes for this router instance\n */\n get routes(): AgnosticDataRouteObject[];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the window associated with the router\n */\n get window(): RouterInit[\"window\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Initialize the router, including adding history listeners and kicking off\n * initial data fetches. Returns a function to cleanup listeners and abort\n * any in-progress loads\n */\n initialize(): Router;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Subscribe to router.state updates\n *\n * @param fn function to call with the new state\n */\n subscribe(fn: RouterSubscriber): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Enable scroll restoration behavior in the router\n *\n * @param savedScrollPositions Object that will manage positions, in case\n * it's being restored from sessionStorage\n * @param getScrollPosition Function to get the active Y scroll position\n * @param getKey Function to get the key to use for restoration\n */\n enableScrollRestoration(\n savedScrollPositions: Record,\n getScrollPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Navigate forward/backward in the history stack\n * @param to Delta to move in the history stack\n */\n navigate(to: number): Promise;\n\n /**\n * Navigate to the given path\n * @param to Path to navigate to\n * @param opts Navigation options (method, submission, etc.)\n */\n navigate(to: To | null, opts?: RouterNavigateOptions): Promise;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a fetcher load/submission\n *\n * @param key Fetcher key\n * @param routeId Route that owns the fetcher\n * @param href href to fetch\n * @param opts Fetcher options, (method, submission, etc.)\n */\n fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a revalidation of all current route loaders and fetcher loads\n */\n revalidate(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to create an href for the given location\n * @param location\n */\n createHref(location: Location | URL): string;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to URL encode a destination path according to the internal\n * history implementation\n * @param to\n */\n encodeLocation(to: To): Path;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get/create a fetcher for the given key\n * @param key\n */\n getFetcher(key: string): Fetcher;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete the fetcher for a given key\n * @param key\n */\n deleteFetcher(key: string): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Cleanup listeners and abort any in-progress loads\n */\n dispose(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get a navigation blocker\n * @param key The identifier for the blocker\n * @param fn The blocker function implementation\n */\n getBlocker(key: string, fn: BlockerFunction): Blocker;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete a navigation blocker\n * @param key The identifier for the blocker\n */\n deleteBlocker(key: string): void;\n\n /**\n * @internal\n * PRIVATE DO NOT USE\n *\n * Patch additional children routes into an existing parent route\n * @param routeId The parent route id or a callback function accepting `patch`\n * to perform batch patching\n * @param children The additional children routes\n */\n patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * HMR needs to pass in-flight route updates to React Router\n * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute)\n */\n _internalSetRoutes(routes: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal fetch AbortControllers accessed by unit tests\n */\n _internalFetchControllers: Map;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal pending DeferredData instances accessed by unit tests\n */\n _internalActiveDeferreds: Map;\n}\n\n/**\n * State maintained internally by the router. During a navigation, all states\n * reflect the the \"old\" location unless otherwise noted.\n */\nexport interface RouterState {\n /**\n * The action of the most recent navigation\n */\n historyAction: HistoryAction;\n\n /**\n * The current location reflected by the router\n */\n location: Location;\n\n /**\n * The current set of route matches\n */\n matches: AgnosticDataRouteMatch[];\n\n /**\n * Tracks whether we've completed our initial data load\n */\n initialized: boolean;\n\n /**\n * Current scroll position we should start at for a new view\n * - number -> scroll position to restore to\n * - false -> do not restore scroll at all (used during submissions)\n * - null -> don't have a saved position, scroll to hash or top of page\n */\n restoreScrollPosition: number | false | null;\n\n /**\n * Indicate whether this navigation should skip resetting the scroll position\n * if we are unable to restore the scroll position\n */\n preventScrollReset: boolean;\n\n /**\n * Tracks the state of the current navigation\n */\n navigation: Navigation;\n\n /**\n * Tracks any in-progress revalidations\n */\n revalidation: RevalidationState;\n\n /**\n * Data from the loaders for the current matches\n */\n loaderData: RouteData;\n\n /**\n * Data from the action for the current matches\n */\n actionData: RouteData | null;\n\n /**\n * Errors caught from loaders for the current matches\n */\n errors: RouteData | null;\n\n /**\n * Map of current fetchers\n */\n fetchers: Map;\n\n /**\n * Map of current blockers\n */\n blockers: Map;\n}\n\n/**\n * Data that can be passed into hydrate a Router from SSR\n */\nexport type HydrationState = Partial<\n Pick\n>;\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface FutureConfig {\n v7_fetcherPersist: boolean;\n v7_normalizeFormMethod: boolean;\n v7_partialHydration: boolean;\n v7_prependBasename: boolean;\n v7_relativeSplatPath: boolean;\n v7_skipActionErrorRevalidation: boolean;\n}\n\n/**\n * Initialization options for createRouter\n */\nexport interface RouterInit {\n routes: AgnosticRouteObject[];\n history: History;\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n hydrationData?: HydrationState;\n window?: Window;\n unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction;\n unstable_dataStrategy?: DataStrategyFunction;\n}\n\n/**\n * State returned from a server-side query() call\n */\nexport interface StaticHandlerContext {\n basename: Router[\"basename\"];\n location: RouterState[\"location\"];\n matches: RouterState[\"matches\"];\n loaderData: RouterState[\"loaderData\"];\n actionData: RouterState[\"actionData\"];\n errors: RouterState[\"errors\"];\n statusCode: number;\n loaderHeaders: Record;\n actionHeaders: Record;\n activeDeferreds: Record | null;\n _deepestRenderedBoundaryId?: string | null;\n}\n\n/**\n * A StaticHandler instance manages a singular SSR navigation/fetch event\n */\nexport interface StaticHandler {\n dataRoutes: AgnosticDataRouteObject[];\n query(\n request: Request,\n opts?: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: {\n routeId?: string;\n requestContext?: unknown;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n}\n\ntype ViewTransitionOpts = {\n currentLocation: Location;\n nextLocation: Location;\n};\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (\n state: RouterState,\n opts: {\n deletedFetchers: string[];\n unstable_viewTransitionOpts?: ViewTransitionOpts;\n unstable_flushSync: boolean;\n }\n ): void;\n}\n\n/**\n * Function signature for determining the key to be used in scroll restoration\n * for a given location\n */\nexport interface GetScrollRestorationKeyFunction {\n (location: Location, matches: UIMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\nexport type RelativeRoutingType = \"route\" | \"path\";\n\n// Allowed for any navigation or fetch\ntype BaseNavigateOrFetchOptions = {\n preventScrollReset?: boolean;\n relative?: RelativeRoutingType;\n unstable_flushSync?: boolean;\n};\n\n// Only allowed for navigations\ntype BaseNavigateOptions = BaseNavigateOrFetchOptions & {\n replace?: boolean;\n state?: any;\n fromRouteId?: string;\n unstable_viewTransition?: boolean;\n};\n\n// Only allowed for submission navigations\ntype BaseSubmissionOptions = {\n formMethod?: HTMLFormMethod;\n formEncType?: FormEncType;\n} & (\n | { formData: FormData; body?: undefined }\n | { formData?: undefined; body: any }\n);\n\n/**\n * Options for a navigate() call for a normal (non-submission) navigation\n */\ntype LinkNavigateOptions = BaseNavigateOptions;\n\n/**\n * Options for a navigate() call for a submission navigation\n */\ntype SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to navigate() for a navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options for a fetch() load\n */\ntype LoadFetchOptions = BaseNavigateOrFetchOptions;\n\n/**\n * Options for a fetch() submission\n */\ntype SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions;\n\n/**\n * Potential states for state.navigation\n */\nexport type NavigationStates = {\n Idle: {\n state: \"idle\";\n location: undefined;\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n formData: undefined;\n json: undefined;\n text: undefined;\n };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n text: Submission[\"text\"] | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n text: Submission[\"text\"];\n };\n};\n\nexport type Navigation = NavigationStates[keyof NavigationStates];\n\nexport type RevalidationState = \"idle\" | \"loading\";\n\n/**\n * Potential states for fetchers\n */\ntype FetcherStates = {\n Idle: {\n state: \"idle\";\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n text: undefined;\n formData: undefined;\n json: undefined;\n data: TData | undefined;\n };\n Loading: {\n state: \"loading\";\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n text: Submission[\"text\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n data: TData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n text: Submission[\"text\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n data: TData | undefined;\n };\n};\n\nexport type Fetcher =\n FetcherStates[keyof FetcherStates];\n\ninterface BlockerBlocked {\n state: \"blocked\";\n reset(): void;\n proceed(): void;\n location: Location;\n}\n\ninterface BlockerUnblocked {\n state: \"unblocked\";\n reset: undefined;\n proceed: undefined;\n location: undefined;\n}\n\ninterface BlockerProceeding {\n state: \"proceeding\";\n reset: undefined;\n proceed: undefined;\n location: Location;\n}\n\nexport type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;\n\nexport type BlockerFunction = (args: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n}) => boolean;\n\ninterface ShortCircuitable {\n /**\n * startNavigation does not need to complete the navigation because we\n * redirected or got interrupted\n */\n shortCircuited?: boolean;\n}\n\ntype PendingActionResult = [string, SuccessResult | ErrorResult];\n\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * Tuple for the returned or thrown value from the current action. The routeId\n * is the action route for success and the bubbled boundary route for errors.\n */\n pendingActionResult?: PendingActionResult;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * loaderData returned from the current set of loaders\n */\n loaderData?: RouterState[\"loaderData\"];\n /**\n * errors thrown from the current set of loaders\n */\n errors?: RouterState[\"errors\"];\n}\n\n/**\n * Cached info for active fetcher.load() instances so they can participate\n * in revalidation\n */\ninterface FetchLoadMatch {\n routeId: string;\n path: string;\n}\n\n/**\n * Identified fetcher.load() calls that need to be revalidated\n */\ninterface RevalidatingFetcher extends FetchLoadMatch {\n key: string;\n match: AgnosticDataRouteMatch | null;\n matches: AgnosticDataRouteMatch[] | null;\n controller: AbortController | null;\n}\n\nconst validMutationMethodsArr: MutationFormMethod[] = [\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n];\nconst validMutationMethods = new Set(\n validMutationMethodsArr\n);\n\nconst validRequestMethodsArr: FormMethod[] = [\n \"get\",\n ...validMutationMethodsArr,\n];\nconst validRequestMethods = new Set(validRequestMethodsArr);\n\nconst redirectStatusCodes = new Set([301, 302, 303, 307, 308]);\nconst redirectPreserveMethodStatusCodes = new Set([307, 308]);\n\nexport const IDLE_NAVIGATION: NavigationStates[\"Idle\"] = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_FETCHER: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\nconst defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary),\n});\n\nconst TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Create a router and listen to history POP navigations\n */\nexport function createRouter(init: RouterInit): Router {\n const routerWindow = init.window\n ? init.window\n : typeof window !== \"undefined\"\n ? window\n : undefined;\n const isBrowser =\n typeof routerWindow !== \"undefined\" &&\n typeof routerWindow.document !== \"undefined\" &&\n typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n\n // Routes keyed by ID\n let manifest: RouteManifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined;\n let basename = init.basename || \"/\";\n let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;\n let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss;\n\n // Config driven behavior flags\n let future: FutureConfig = {\n v7_fetcherPersist: false,\n v7_normalizeFormMethod: false,\n v7_partialHydration: false,\n v7_prependBasename: false,\n v7_relativeSplatPath: false,\n v7_skipActionErrorRevalidation: false,\n ...init.future,\n };\n // Cleanup function for history\n let unlistenHistory: (() => void) | null = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions: Record | null = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey: GetScrollRestorationKeyFunction | null = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition: GetScrollPositionFunction | null = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null && !patchRoutesOnMissImpl) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname,\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n }\n\n // In SPA apps, if the user provided a patchRoutesOnMiss implementation and\n // our initial match is a splat route, clear them out so we run through lazy\n // discovery on hydration in case there's a more accurate lazy route match.\n // In SSR apps (with `hydrationData`), we expect that the server will send\n // up the proper matched routes so we don't want to run lazy discovery on\n // initial hydration and want to hydrate into the splat route.\n if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n\n let initialized: boolean;\n if (!initialMatches) {\n // We need to run patchRoutesOnMiss in initialize()\n initialized = false;\n initialMatches = [];\n } else if (initialMatches.some((m) => m.route.lazy)) {\n // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n initialized = false;\n } else if (!initialMatches.some((m) => m.route.loader)) {\n // If we've got no loaders to run, then we're good to go\n initialized = true;\n } else if (future.v7_partialHydration) {\n // If partial hydration is enabled, we're initialized so long as we were\n // provided with hydrationData for every route with a loader, and no loaders\n // were marked for explicit hydration\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n let isRouteInitialized = (m: AgnosticDataRouteMatch) => {\n // No loader, nothing to initialize\n if (!m.route.loader) {\n return true;\n }\n // Explicitly opting-in to running on hydration\n if (\n typeof m.route.loader === \"function\" &&\n m.route.loader.hydrate === true\n ) {\n return false;\n }\n // Otherwise, initialized if hydrated with data or an error\n return (\n (loaderData && loaderData[m.route.id] !== undefined) ||\n (errors && errors[m.route.id] !== undefined)\n );\n };\n\n // If errors exist, don't consider routes below the boundary\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors![m.route.id] !== undefined\n );\n initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);\n } else {\n initialized = initialMatches.every(isRouteInitialized);\n }\n } else {\n // Without partial hydration - we're initialized if we were provided any\n // hydrationData - which is expected to be complete\n initialized = init.hydrationData != null;\n }\n\n let router: Router;\n let state: RouterState = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: (init.hydrationData && init.hydrationData.loaderData) || {},\n actionData: (init.hydrationData && init.hydrationData.actionData) || null,\n errors: (init.hydrationData && init.hydrationData.errors) || initialErrors,\n fetchers: new Map(),\n blockers: new Map(),\n };\n\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction: HistoryAction = HistoryAction.Pop;\n\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n\n // AbortController for the active navigation\n let pendingNavigationController: AbortController | null;\n\n // Should the current navigation enable document.startViewTransition?\n let pendingViewTransitionEnabled = false;\n\n // Store applied view transitions so we can apply them on POP\n let appliedViewTransitions: Map> = new Map<\n string,\n Set\n >();\n\n // Cleanup function for persisting applied transitions to sessionStorage\n let removePageHideEventListener: (() => void) | null = null;\n\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes: string[] = [];\n\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads: string[] = [];\n\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n\n // Ref-count mounted fetchers so we know when it's ok to clean them up\n let activeFetchers = new Map();\n\n // Fetchers that have requested a delete when using v7_fetcherPersist,\n // they'll be officially removed after they return to idle\n let deletedFetchers = new Set();\n\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n\n // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so\n // that we only kick them off once for a given combo\n let pendingPatchRoutes = new Map<\n string,\n ReturnType\n >();\n\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let ignoreNextHistoryUpdate = false;\n\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (ignoreNextHistoryUpdate) {\n ignoreNextHistoryUpdate = false;\n return;\n }\n\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location \" +\n \"that was not created by @remix-run/router. This will fail silently in \" +\n \"production. This can happen if you are navigating outside the router \" +\n \"via `window.history.pushState`/`window.location.hash` instead of using \" +\n \"router navigation APIs. This can also happen if you are using \" +\n \"createHashRouter and the user manually changes the URL.\"\n );\n\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n ignoreNextHistoryUpdate = true;\n init.history.go(delta * -1);\n\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location,\n });\n // Re-do the same POP navigation we just blocked\n init.history.go(delta);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n if (isBrowser) {\n // FIXME: This feels gross. How can we cleanup the lines between\n // scrollRestoration/appliedTransitions persistance?\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () =>\n persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () =>\n routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location, {\n initialHydration: true,\n });\n }\n\n return router;\n }\n\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n\n // Subscribe to state updates for the router\n function subscribe(fn: RouterSubscriber) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n\n // Update our state and notify the calling context of the change\n function updateState(\n newState: Partial,\n opts: {\n flushSync?: boolean;\n viewTransitionOpts?: ViewTransitionOpts;\n } = {}\n ): void {\n state = {\n ...state,\n ...newState,\n };\n\n // Prep fetcher cleanup so we can tell the UI which fetcher data entries\n // can be removed\n let completedFetchers: string[] = [];\n let deletedFetchersKeys: string[] = [];\n\n if (future.v7_fetcherPersist) {\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (deletedFetchers.has(key)) {\n // Unmounted from the UI and can be totally removed\n deletedFetchersKeys.push(key);\n } else {\n // Returned to idle but still mounted in the UI, so semi-remains for\n // revalidations and such\n completedFetchers.push(key);\n }\n }\n });\n }\n\n // Iterate over a local copy so that if flushSync is used and we end up\n // removing and adding a new subscriber due to the useCallback dependencies,\n // we don't get ourselves into a loop calling the new subscriber immediately\n [...subscribers].forEach((subscriber) =>\n subscriber(state, {\n deletedFetchers: deletedFetchersKeys,\n unstable_viewTransitionOpts: opts.viewTransitionOpts,\n unstable_flushSync: opts.flushSync === true,\n })\n );\n\n // Remove idle fetchers from state since we only care about in-flight fetchers.\n if (future.v7_fetcherPersist) {\n completedFetchers.forEach((key) => state.fetchers.delete(key));\n deletedFetchersKeys.forEach((key) => deleteFetcher(key));\n }\n }\n\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(\n location: Location,\n newState: Partial>,\n { flushSync }: { flushSync?: boolean } = {}\n ): void {\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload =\n state.actionData != null &&\n state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n state.navigation.state === \"loading\" &&\n location.state?._isRedirect !== true;\n\n let actionData: RouteData | null;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData\n ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n )\n : state.loaderData;\n\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset =\n pendingPreventScrollReset === true ||\n (state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n location.state?._isRedirect !== true);\n\n // Commit any in-flight routes at the end of the HMR revalidation \"navigation\"\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n\n if (isUninterruptedRevalidation) {\n // If this was an uninterrupted revalidation then do not touch history\n } else if (pendingAction === HistoryAction.Pop) {\n // Do nothing for POP - URL has already been updated\n } else if (pendingAction === HistoryAction.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === HistoryAction.Replace) {\n init.history.replace(location, location.state);\n }\n\n let viewTransitionOpts: ViewTransitionOpts | undefined;\n\n // On POP, enable transitions if they were enabled on the original navigation\n if (pendingAction === HistoryAction.Pop) {\n // Forward takes precedence so they behave like the original navigation\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n // If we don't have a previous forward nav, assume we're popping back to\n // the new location and enable if that location previously enabled\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location,\n };\n }\n } else if (pendingViewTransitionEnabled) {\n // Store the applied transition on PUSH/REPLACE\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n }\n\n updateState(\n {\n ...newState, // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(\n location,\n newState.matches || state.matches\n ),\n preventScrollReset,\n blockers,\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true,\n }\n );\n\n // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n cancelledFetcherLoads = [];\n }\n\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(\n to: number | To | null,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n to,\n future.v7_relativeSplatPath,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n false,\n normalizedPath,\n opts\n );\n\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation),\n };\n\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n\n let historyAction = HistoryAction.Push;\n\n if (userReplace === true) {\n historyAction = HistoryAction.Replace;\n } else if (userReplace === false) {\n // no-op\n } else if (\n submission != null &&\n isMutationMethod(submission.formMethod) &&\n submission.formAction === state.location.pathname + state.location.search\n ) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = HistoryAction.Replace;\n }\n\n let preventScrollReset =\n opts && \"preventScrollReset\" in opts\n ? opts.preventScrollReset === true\n : undefined;\n\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n });\n\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation,\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.unstable_viewTransition,\n flushSync,\n });\n }\n\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true,\n });\n return;\n }\n\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n { overrideNavigation: state.navigation }\n );\n }\n\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(\n historyAction: HistoryAction,\n location: Location,\n opts?: {\n initialHydration?: boolean;\n submission?: Submission;\n fetcherSubmission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponseImpl;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: boolean;\n enableViewTransition?: boolean;\n flushSync?: boolean;\n }\n ): Promise {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation =\n (opts && opts.startUninterruptedRevalidation) === true;\n\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n },\n { flushSync }\n );\n return;\n }\n\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial load will always\n // be \"same hash\". For example, on /page#hash and submit a \n // which will default to a navigation to /page\n if (\n state.initialized &&\n !isRevalidationRequired &&\n isHashChangeOnly(state.location, location) &&\n !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))\n ) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let pendingActionResult: PendingActionResult | undefined;\n\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: ResultType.error, error: opts.pendingError },\n ];\n } else if (\n opts &&\n opts.submission &&\n isMutationMethod(opts.submission.formMethod)\n ) {\n // Call action if we received an action submission\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n fogOfWar.active,\n { replace: opts.replace, flushSync }\n );\n\n if (actionResult.shortCircuited) {\n return;\n }\n\n // If we received a 404 from handleAction, it's because we couldn't lazily\n // discover the destination route so we don't want to call loaders\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (\n isErrorResult(result) &&\n isRouteErrorResponse(result.error) &&\n result.error.status === 404\n ) {\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error,\n },\n });\n return;\n }\n }\n\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n // No need to do fog of war matching again on loader execution\n fogOfWar.active = false;\n\n // Create a GET request for the loaders\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n\n // Call loaders\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors,\n } = await handleLoaders(\n request,\n location,\n matches,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult\n );\n\n if (shortCircuited) {\n return;\n }\n\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors,\n });\n }\n\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(\n request: Request,\n location: Location,\n submission: Submission,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n opts: { replace?: boolean; flushSync?: boolean } = {}\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n // Call our action and get the result\n let result: DataResult;\n let actionMatch = getTargetMatch(matches, location);\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id,\n }),\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches\n );\n result = results[0];\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n\n if (isRedirectResult(result)) {\n let replace: boolean;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n let location = normalizeRedirectLocation(\n result.response.headers.get(\"Location\")!,\n new URL(request.url),\n basename\n );\n replace = location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, {\n submission,\n replace,\n });\n return { shortCircuited: true };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n\n // By default, all submissions to the current location are REPLACE\n // navigations, but if the action threw an error that'll be rendered in\n // an errorElement, we fall back to PUSH so that the user can use the\n // back button to get back to the pre-submission form location to try\n // again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n matches,\n pendingActionResult: [boundaryMatch.route.id, result],\n };\n }\n\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result],\n };\n }\n\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n overrideNavigation?: Navigation,\n submission?: Submission,\n fetcherSubmission?: Submission,\n replace?: boolean,\n initialHydration?: boolean,\n flushSync?: boolean,\n pendingActionResult?: PendingActionResult\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation =\n overrideNavigation || getLoadingNavigation(location, submission);\n\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission =\n submission ||\n fetcherSubmission ||\n getSubmissionFromNavigation(loadingNavigation);\n\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n // If we have partialHydration enabled, then don't update the state for the\n // initial data load since it's not a \"navigation\"\n let shouldUpdateNavigationState =\n !isUninterruptedRevalidation &&\n (!future.v7_partialHydration || !initialHydration);\n\n // When fog of war is enabled, we enter our `loading` state earlier so we\n // can discover new routes during the `loading` state. We skip this if\n // we've already run actions since we would have done our matching already.\n // If the children() function threw then, we want to proceed with the\n // partial matches it discovered.\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...(actionData !== undefined ? { actionData } : {}),\n },\n {\n flushSync,\n }\n );\n }\n\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: error,\n },\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n future.v7_partialHydration && initialHydration === true,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n pendingActionResult\n );\n\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds(\n (routeId) =>\n !(matches && matches.some((m) => m.route.id === routeId)) ||\n (matchesToLoad && matchesToLoad.some((m) => m.route.id === routeId))\n );\n\n pendingNavigationLoadId = ++incrementingLoadId;\n\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? { [pendingActionResult[0]]: pendingActionResult[1].error }\n : null,\n ...getActionDataForCommit(pendingActionResult),\n ...(updatedFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n\n if (shouldUpdateNavigationState) {\n let updates: Partial = {};\n if (!isFogOfWar) {\n // Only update navigation/actionNData if we didn't already do it above\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== undefined) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n\n revalidatingFetchers.forEach((rf) => {\n if (fetchControllers.has(rf.key)) {\n abortFetcher(rf.key);\n }\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n request\n );\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n await startRedirectNavigation(request, redirect.result, {\n replace,\n });\n return { shortCircuited: true };\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n matchesToLoad,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId) => {\n deferredData.subscribe((aborted) => {\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n\n // During partial hydration, preserve SSR errors for routes that don't re-run\n if (future.v7_partialHydration && initialHydration && state.errors) {\n Object.entries(state.errors)\n .filter(([id]) => !matchesToLoad.some((m) => m.route.id === id))\n .forEach(([routeId, error]) => {\n errors = Object.assign(errors || {}, { [routeId]: error });\n });\n }\n\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers =\n updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n\n return {\n matches,\n loaderData,\n errors,\n ...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n };\n }\n\n function getUpdatedActionData(\n pendingActionResult: PendingActionResult | undefined\n ): Record | null | undefined {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n // This is cast to `any` currently because `RouteData`uses any and it\n // would be a breaking change to use any.\n // TODO: v7 - change `RouteData` to use `unknown` instead of `any`\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data as any,\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n\n function getUpdatedRevalidatingFetchers(\n revalidatingFetchers: RevalidatingFetcher[]\n ) {\n revalidatingFetchers.forEach((rf) => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n fetcher ? fetcher.data : undefined\n );\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ) {\n if (isServer) {\n throw new Error(\n \"router.fetch() was called during the server render, but it shouldn't be. \" +\n \"You are likely calling a useFetcher() method in the body of your component. \" +\n \"Try moving it to a useEffect or a callback.\"\n );\n }\n\n if (fetchControllers.has(key)) abortFetcher(key);\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n href,\n future.v7_relativeSplatPath,\n routeId,\n opts?.relative\n );\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n true,\n normalizedPath,\n opts\n );\n\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n\n let match = getTargetMatch(matches, path);\n\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, { routeId, path });\n handleFetcherLoader(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n }\n\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n requestMatches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n function detectAndHandle405Error(m: AgnosticDataRouteMatch) {\n if (!m.route.action && !m.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error, { flushSync });\n return true;\n }\n return false;\n }\n\n if (!isFogOfWar && detectAndHandle405Error(match)) {\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync,\n });\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n match = getTargetMatch(requestMatches, path);\n\n if (detectAndHandle405Error(match)) {\n return;\n }\n }\n }\n\n // Call the action for the fetcher\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let actionResults = await callDataStrategy(\n \"action\",\n fetchRequest,\n [match],\n requestMatches\n );\n let actionResult = actionResults[0];\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n\n // When using v7_fetcherPersist, we don't want errors bubbling up to the UI\n // or redirects processed for unmounted fetchers so we just revert them to\n // idle\n if (future.v7_fetcherPersist && deletedFetchers.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // Let SuccessResult's fall through for revalidation\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, {\n fetcherSubmission: submission,\n });\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(routesToUse, state.navigation.location, basename)\n : state.matches;\n\n invariant(matches, \"Didn't find any matches after fetcher action\");\n\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n false,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n [match.route.id, actionResult]\n );\n\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers\n .filter((rf) => rf.key !== key)\n .forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n existingFetcher ? existingFetcher.data : undefined\n );\n state.fetchers.set(staleKey, revalidatingFetcher);\n if (fetchControllers.has(staleKey)) {\n abortFetcher(staleKey);\n }\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n revalidationRequest\n );\n\n if (abortController.signal.aborted) {\n return;\n }\n\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n return startRedirectNavigation(revalidationRequest, redirect.result);\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n state.matches,\n matchesToLoad,\n loaderResults,\n undefined,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n\n abortStaleFetchLoads(loadId);\n\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (\n state.navigation.state === \"loading\" &&\n loadId > pendingNavigationLoadId\n ) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers),\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: new Map(state.fetchers),\n });\n isRevalidationRequired = false;\n }\n }\n\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : undefined\n ),\n { flushSync }\n );\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n match = getTargetMatch(matches, path);\n }\n }\n\n // Call the loader for this fetcher route match\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let results = await callDataStrategy(\n \"loader\",\n fetchRequest,\n [match],\n matches\n );\n let result = results[0];\n\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result =\n (await resolveDeferredData(result, fetchRequest.signal, true)) ||\n result;\n }\n\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n\n if (fetchRequest.signal.aborted) {\n return;\n }\n\n // We don't want errors bubbling up or redirects followed for unmounted\n // fetchers, so short circuit here if it was removed from the UI\n if (deletedFetchers.has(key)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result);\n return;\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */\n async function startRedirectNavigation(\n request: Request,\n redirect: RedirectResult,\n {\n submission,\n fetcherSubmission,\n replace,\n }: {\n submission?: Submission;\n fetcherSubmission?: Submission;\n replace?: boolean;\n } = {}\n ) {\n if (redirect.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n\n let location = redirect.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true,\n });\n\n if (isBrowser) {\n let isDocumentReload = false;\n\n if (redirect.response.headers.has(\"X-Remix-Reload-Document\")) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(location)) {\n const url = init.history.createURL(location);\n isDocumentReload =\n // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin ||\n // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n\n let redirectHistoryAction =\n replace === true ? HistoryAction.Replace : HistoryAction.Push;\n\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let { formMethod, formAction, formEncType } = state.navigation;\n if (\n !submission &&\n !fetcherSubmission &&\n formMethod &&\n formAction &&\n formEncType\n ) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n let activeSubmission = submission || fetcherSubmission;\n if (\n redirectPreserveMethodStatusCodes.has(redirect.response.status) &&\n activeSubmission &&\n isMutationMethod(activeSubmission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // If we have a navigation submission, we will preserve it through the\n // redirect navigation\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n submission\n );\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n }\n }\n\n // Utility wrapper for calling dataStrategy client-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[]\n ): Promise {\n try {\n let results = await callDataStrategyImpl(\n dataStrategyImpl,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n return {\n type: ResultType.redirect,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n ),\n };\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n } catch (e) {\n // If the outer dataStrategy method throws, just return the error for all\n // matches - and it'll naturally bubble to the root\n return matchesToLoad.map(() => ({\n type: ResultType.error,\n error: e,\n }));\n }\n }\n\n async function callLoadersAndMaybeResolveData(\n currentMatches: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n fetchersToLoad: RevalidatingFetcher[],\n request: Request\n ) {\n let [loaderResults, ...fetcherResults] = await Promise.all([\n matchesToLoad.length\n ? callDataStrategy(\"loader\", request, matchesToLoad, matches)\n : [],\n ...fetchersToLoad.map((f) => {\n if (f.matches && f.match && f.controller) {\n let fetcherRequest = createClientSideRequest(\n init.history,\n f.path,\n f.controller.signal\n );\n return callDataStrategy(\n \"loader\",\n fetcherRequest,\n [f.match],\n f.matches\n ).then((r) => r[0]);\n } else {\n return Promise.resolve({\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path,\n }),\n });\n }\n }),\n ]);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n loaderResults.map(() => request.signal),\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map((f) => f.match),\n fetcherResults,\n fetchersToLoad.map((f) => (f.controller ? f.controller.signal : null)),\n true\n ),\n ]);\n\n return {\n loaderResults,\n fetcherResults,\n };\n }\n\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.push(key);\n abortFetcher(key);\n }\n });\n }\n\n function updateFetcherState(\n key: string,\n fetcher: Fetcher,\n opts: { flushSync?: boolean } = {}\n ) {\n state.fetchers.set(key, fetcher);\n updateState(\n { fetchers: new Map(state.fetchers) },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function setFetcherError(\n key: string,\n routeId: string,\n error: any,\n opts: { flushSync?: boolean } = {}\n ) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function getFetcher(key: string): Fetcher {\n if (future.v7_fetcherPersist) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n // If this fetcher was previously marked for deletion, unmark it since we\n // have a new instance\n if (deletedFetchers.has(key)) {\n deletedFetchers.delete(key);\n }\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n\n function deleteFetcher(key: string): void {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (\n fetchControllers.has(key) &&\n !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))\n ) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n deletedFetchers.delete(key);\n state.fetchers.delete(key);\n }\n\n function deleteFetcherAndUpdateState(key: string): void {\n if (future.v7_fetcherPersist) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n deletedFetchers.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n } else {\n deleteFetcher(key);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n\n function abortFetcher(key: string) {\n let controller = fetchControllers.get(key);\n invariant(controller, `Expected fetch controller: ${key}`);\n controller.abort();\n fetchControllers.delete(key);\n }\n\n function markFetchersDone(keys: string[]) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): boolean {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n\n function abortStaleFetchLoads(landedId: number): boolean {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n\n function getBlocker(key: string, fn: BlockerFunction) {\n let blocker: Blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key: string, newBlocker: Blocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(\n (blocker.state === \"unblocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"proceeding\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"unblocked\") ||\n (blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\"),\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n }: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n }): string | undefined {\n if (blockerFunctions.size === 0) {\n return;\n }\n\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n\n function handleNavigational404(pathname: string) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n\n return { notFoundMatches: matches, route, error };\n }\n\n function handleDiscoverRouteError(\n pathname: string,\n discoverResult: DiscoverRoutesErrorResult\n ) {\n return {\n boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,\n error: getInternalRouterError(400, {\n type: \"route-discovery\",\n pathname,\n message:\n discoverResult.error != null && \"message\" in discoverResult.error\n ? discoverResult.error\n : String(discoverResult.error),\n }),\n };\n }\n\n function cancelActiveDeferreds(\n predicate?: (routeId: string) => boolean\n ): string[] {\n let cancelledRouteIds: string[] = [];\n activeDeferreds.forEach((dfd, routeId) => {\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the component\n function enableScrollRestoration(\n positions: Record,\n getPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered \n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n\n return () => {\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n\n function getScrollKey(location: Location, matches: AgnosticDataRouteMatch[]) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n\n function saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n function checkFogOfWar(\n matches: AgnosticDataRouteMatch[] | null,\n routesToUse: AgnosticDataRouteObject[],\n pathname: string\n ): { active: boolean; matches: AgnosticDataRouteMatch[] | null } {\n if (patchRoutesOnMissImpl) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n return { active: true, matches: fogMatches || [] };\n } else {\n let leafRoute = matches[matches.length - 1].route;\n if (\n leafRoute.path &&\n (leafRoute.path === \"*\" || leafRoute.path.endsWith(\"/*\"))\n ) {\n // If we matched a splat, it might only be because we haven't yet fetched\n // the children that would match with a higher score, so let's fetch\n // around and find out\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n\n return { active: false, matches: null };\n }\n\n type DiscoverRoutesSuccessResult = {\n type: \"success\";\n matches: AgnosticDataRouteMatch[] | null;\n };\n type DiscoverRoutesErrorResult = {\n type: \"error\";\n error: any;\n partialMatches: AgnosticDataRouteMatch[];\n };\n type DiscoverRoutesAbortedResult = { type: \"aborted\" };\n type DiscoverRoutesResult =\n | DiscoverRoutesSuccessResult\n | DiscoverRoutesErrorResult\n | DiscoverRoutesAbortedResult;\n\n async function discoverRoutes(\n matches: AgnosticDataRouteMatch[],\n pathname: string,\n signal: AbortSignal\n ): Promise {\n let partialMatches: AgnosticDataRouteMatch[] | null = matches;\n let route =\n partialMatches.length > 0\n ? partialMatches[partialMatches.length - 1].route\n : null;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n try {\n await loadLazyRouteChildren(\n patchRoutesOnMissImpl!,\n pathname,\n partialMatches,\n routesToUse,\n manifest,\n mapRouteProperties,\n pendingPatchRoutes,\n signal\n );\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n } finally {\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity so when we `updateState` at the end of\n // this navigation/fetch `router.routes` will be a new identity and\n // trigger a re-run of memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n }\n }\n\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n let matchedSplat = false;\n if (newMatches) {\n let leafRoute = newMatches[newMatches.length - 1].route;\n\n if (leafRoute.index) {\n // If we found an index route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n\n if (leafRoute.path && leafRoute.path.length > 0) {\n if (leafRoute.path === \"*\") {\n // If we found a splat route, we can't be sure there's not a\n // higher-scoring route down some partial matches trail so we need\n // to check that out\n matchedSplat = true;\n } else {\n // If we found a non-splat route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n\n let newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n // If we are no longer partially matching anything, this was either a\n // legit splat match above, or it's a 404. Also avoid loops if the\n // second pass results in the same partial matches\n if (\n !newPartialMatches ||\n partialMatches.map((m) => m.route.id).join(\"-\") ===\n newPartialMatches.map((m) => m.route.id).join(\"-\")\n ) {\n return { type: \"success\", matches: matchedSplat ? newMatches : null };\n }\n\n partialMatches = newPartialMatches;\n route = partialMatches[partialMatches.length - 1].route;\n if (route.path === \"*\") {\n // The splat is still our most accurate partial, so run with it\n return { type: \"success\", matches: partialMatches };\n }\n }\n }\n\n function _internalSetRoutes(newRoutes: AgnosticDataRouteObject[]) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties,\n undefined,\n manifest\n );\n }\n\n function patchRoutes(\n routeId: string | null,\n children: AgnosticRouteObject[]\n ): void {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n manifest,\n mapRouteProperties\n );\n\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity and trigger a reflow via `updateState`\n // to re-run memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to: To) => init.history.createHref(to),\n encodeLocation: (to: To) => init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher: deleteFetcherAndUpdateState,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface StaticHandlerFutureConfig {\n v7_relativeSplatPath: boolean;\n v7_throwAbortReason: boolean;\n}\n\nexport interface CreateStaticHandlerOptions {\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n}\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: CreateStaticHandlerOptions\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let manifest: RouteManifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (opts?.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts?.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Config driven behavior flags\n let future: StaticHandlerFutureConfig = {\n v7_relativeSplatPath: false,\n v7_throwAbortReason: false,\n ...(opts ? opts.future : null),\n };\n\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n *\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent\n * the bubbling of errors which allows single-fetch-type implementations\n * where the client will handle the bubbling and we may need to return data\n * for the handling route\n */\n async function query(\n request: Request,\n {\n requestContext,\n skipLoaderErrorBubbling,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null\n );\n if (isResponse(result)) {\n return result;\n }\n\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return { location, basename, ...result };\n }\n\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n *\n * - `opts.routeId` allows you to specify the specific route handler to call.\n * If not provided the handler will determine the proper route by matching\n * against `request.url`\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n */\n async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n routeId?: string;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let match = routeId\n ? matches.find((m) => m.route.id === routeId)\n : getTargetMatch(matches, location);\n\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId,\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n false,\n match\n );\n\n if (isResponse(result)) {\n return result;\n }\n\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n\n if (result.loaderData) {\n let data = Object.values(result.loaderData)[0];\n if (result.activeDeferreds?.[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n\n return undefined;\n }\n\n async function queryImpl(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null\n ): Promise | Response> {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(\n request,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch\n );\n return isResponse(result)\n ? result\n : {\n ...result,\n actionData: null,\n actionHeaders: {},\n };\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction for a\n // `queryRoute` call, we throw the `HandlerResult` to bail out early\n // and then return or throw the raw Response here accordingly\n if (isHandlerResult(e) && isResponse(e.result)) {\n if (e.type === ResultType.error) {\n throw e.result;\n }\n return e.result;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n\n async function submit(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n actionMatch: AgnosticDataRouteMatch,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id,\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n result = results[0];\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n }\n\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")!,\n },\n });\n }\n\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, { type: \"defer-action\" });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n }\n\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal,\n });\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = skipLoaderErrorBubbling\n ? actionMatch\n : findNearestBoundary(matches, actionMatch.route.id);\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null,\n [boundaryMatch.route.id, result]\n );\n\n // action status codes take precedence over loader status codes\n return {\n ...context,\n statusCode: isRouteErrorResponse(result.error)\n ? result.error.status\n : result.statusCode != null\n ? result.statusCode\n : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null\n );\n\n return {\n ...context,\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionHeaders: result.headers\n ? { [actionMatch.route.id]: result.headers }\n : {},\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null,\n pendingActionResult?: PendingActionResult\n ): Promise<\n | Omit<\n StaticHandlerContext,\n \"location\" | \"basename\" | \"actionData\" | \"actionHeaders\"\n >\n | Response\n > {\n let isRouteRequest = routeMatch != null;\n\n // Short circuit if we have no loaders to run (queryRoute())\n if (\n isRouteRequest &&\n !routeMatch?.route.loader &&\n !routeMatch?.route.lazy\n ) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id,\n });\n }\n\n let requestMatches = routeMatch\n ? [routeMatch]\n : pendingActionResult && isErrorResult(pendingActionResult[1])\n ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0])\n : matches;\n let matchesToLoad = requestMatches.filter(\n (m) => m.route.loader || m.route.lazy\n );\n\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce(\n (acc, m) => Object.assign(acc, { [m.route.id]: null }),\n {}\n ),\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? {\n [pendingActionResult[0]]: pendingActionResult[1].error,\n }\n : null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await callDataStrategy(\n \"loader\",\n request,\n matchesToLoad,\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n skipLoaderErrorBubbling\n );\n\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(\n matchesToLoad.map((match) => match.route.id)\n );\n matches.forEach((match) => {\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n\n return {\n ...context,\n matches,\n activeDeferreds:\n activeDeferreds.size > 0\n ? Object.fromEntries(activeDeferreds.entries())\n : null,\n };\n }\n\n // Utility wrapper for calling dataStrategy server-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n isRouteRequest: boolean,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null\n ): Promise {\n let results = await callDataStrategyImpl(\n unstable_dataStrategy || defaultDataStrategy,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties,\n requestContext\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n // Throw redirects and let the server handle them with an HTTP redirect\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n );\n }\n if (isResponse(result.result) && isRouteRequest) {\n // For SSR single-route requests, we want to hand Responses back\n // directly without unwrapping\n throw result;\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n }\n\n return {\n dataRoutes,\n query,\n queryRoute,\n };\n}\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */\nexport function getStaticContextFromError(\n routes: AgnosticDataRouteObject[],\n context: StaticHandlerContext,\n error: any\n) {\n let newContext: StaticHandlerContext = {\n ...context,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction throwStaticHandlerAbortedError(\n request: Request,\n isRouteRequest: boolean,\n future: StaticHandlerFutureConfig\n) {\n if (future.v7_throwAbortReason && request.signal.reason !== undefined) {\n throw request.signal.reason;\n }\n\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted: ${request.method} ${request.url}`);\n}\n\nfunction isSubmissionNavigation(\n opts: BaseNavigateOrFetchOptions\n): opts is SubmissionNavigateOptions {\n return (\n opts != null &&\n ((\"formData\" in opts && opts.formData != null) ||\n (\"body\" in opts && opts.body !== undefined))\n );\n}\n\nfunction normalizeTo(\n location: Path,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n prependBasename: boolean,\n to: To | null,\n v7_relativeSplatPath: boolean,\n fromRouteId?: string,\n relative?: RelativeRoutingType\n) {\n let contextualMatches: AgnosticDataRouteMatch[];\n let activeRouteMatch: AgnosticDataRouteMatch | undefined;\n if (fromRouteId) {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n\n // Resolve the relative path\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches, v7_relativeSplatPath),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n\n // Add an ?index param for matched index routes if we don't already have one\n if (\n (to == null || to === \"\" || to === \".\") &&\n activeRouteMatch &&\n activeRouteMatch.route.index &&\n !hasNakedIndexQuery(path.search)\n ) {\n path.search = path.search\n ? path.search.replace(/^\\?/, \"?index&\")\n : \"?index\";\n }\n\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname =\n path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n\n return createPath(path);\n}\n\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(\n normalizeFormMethod: boolean,\n isFetcher: boolean,\n path: string,\n opts?: BaseNavigateOrFetchOptions\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponseImpl;\n} {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod }),\n };\n }\n\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" }),\n });\n\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod\n ? (rawFormMethod.toUpperCase() as V7_FormMethod)\n : (rawFormMethod.toLowerCase() as FormMethod);\n let formAction = stripHashFromPath(path);\n\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n let text =\n typeof opts.body === \"string\"\n ? opts.body\n : opts.body instanceof FormData ||\n opts.body instanceof URLSearchParams\n ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\\n`,\n \"\"\n )\n : String(opts.body);\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text,\n },\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n try {\n let json =\n typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined,\n },\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n\n let searchParams: URLSearchParams;\n let formData: FormData;\n\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n\n let submission: Submission = {\n formMethod,\n formAction,\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n\n return { path: createPath(parsedPath), submission };\n}\n\n// Filter out all routes below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(\n matches: AgnosticDataRouteMatch[],\n boundaryId: string\n) {\n let boundaryMatches = matches;\n if (boundaryId) {\n let index = matches.findIndex((m) => m.route.id === boundaryId);\n if (index >= 0) {\n boundaryMatches = matches.slice(0, index);\n }\n }\n return boundaryMatches;\n}\n\nfunction getMatchesToLoad(\n history: History,\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n submission: Submission | undefined,\n location: Location,\n isInitialLoad: boolean,\n skipActionErrorRevalidation: boolean,\n isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n deletedFetchers: Set,\n fetchLoadMatches: Map,\n fetchRedirectIds: Set,\n routesToUse: AgnosticDataRouteObject[],\n basename: string | undefined,\n pendingActionResult?: PendingActionResult\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingActionResult\n ? isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : pendingActionResult[1].data\n : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[0]\n : undefined;\n let boundaryMatches = boundaryId\n ? getLoaderMatchesUntilBoundary(matches, boundaryId)\n : matches;\n\n // Don't revalidate loaders by default after action 4xx/5xx responses\n // when the flag is enabled. They can still opt-into revalidation via\n // `shouldRevalidate` via `actionResult`\n let actionStatus = pendingActionResult\n ? pendingActionResult[1].statusCode\n : undefined;\n let shouldSkipRevalidation =\n skipActionErrorRevalidation && actionStatus && actionStatus >= 400;\n\n let navigationMatches = boundaryMatches.filter((match, index) => {\n let { route } = match;\n if (route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n\n if (route.loader == null) {\n return false;\n }\n\n if (isInitialLoad) {\n if (typeof route.loader !== \"function\" || route.loader.hydrate) {\n return true;\n }\n return (\n state.loaderData[route.id] === undefined &&\n // Don't re-run if the loader ran and threw an error\n (!state.errors || state.errors[route.id] === undefined)\n );\n }\n\n // Always call the loader on new route instances and pending defer cancellations\n if (\n isNewLoader(state.loaderData, state.matches[index], match) ||\n cancelledDeferredRoutes.some((id) => id === match.route.id)\n ) {\n return true;\n }\n\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n\n return shouldRevalidateLoader(match, {\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired ||\n currentUrl.pathname + currentUrl.search ===\n nextUrl.pathname + nextUrl.search ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n isNewRouteInstance(currentRouteMatch, nextRouteMatch),\n });\n });\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches.forEach((f, key) => {\n // Don't revalidate:\n // - on initial load (shouldn't be any fetchers then anyway)\n // - if fetcher won't be present in the subsequent render\n // - no longer matches the URL (v7_fetcherPersist=false)\n // - was unmounted but persisted due to v7_fetcherPersist=true\n if (\n isInitialLoad ||\n !matches.some((m) => m.route.id === f.routeId) ||\n deletedFetchers.has(key)\n ) {\n return;\n }\n\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null,\n });\n return;\n }\n\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.includes(key)) {\n // Always revalidate if the fetcher was cancelled\n shouldRevalidate = true;\n } else if (\n fetcher &&\n fetcher.state !== \"idle\" &&\n fetcher.data === undefined\n ) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, {\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : isRevalidationRequired,\n });\n }\n\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController(),\n });\n }\n });\n\n return [navigationMatches, revalidatingFetchers];\n}\n\nfunction isNewLoader(\n currentLoaderData: RouteData,\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let isNew =\n // [a] -> [a, b]\n !currentMatch ||\n // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\n\nfunction isNewRouteInstance(\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname ||\n // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n (currentPath != null &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n loaderMatch: AgnosticDataRouteMatch,\n arg: ShouldRevalidateFunctionArgs\n) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return arg.defaultShouldRevalidate;\n}\n\n/**\n * Idempotent utility to execute patchRoutesOnMiss() to lazily load route\n * definitions and update the routes/routeManifest\n */\nasync function loadLazyRouteChildren(\n patchRoutesOnMissImpl: AgnosticPatchRoutesOnMissFunction,\n path: string,\n matches: AgnosticDataRouteMatch[],\n routes: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n pendingRouteChildren: Map>,\n signal: AbortSignal\n) {\n let key = [path, ...matches.map((m) => m.route.id)].join(\"-\");\n try {\n let pending = pendingRouteChildren.get(key);\n if (!pending) {\n pending = patchRoutesOnMissImpl({\n path,\n matches,\n patch: (routeId, children) => {\n if (!signal.aborted) {\n patchRoutesImpl(\n routeId,\n children,\n routes,\n manifest,\n mapRouteProperties\n );\n }\n },\n });\n pendingRouteChildren.set(key, pending);\n }\n\n if (pending && isPromise(pending)) {\n await pending;\n }\n } finally {\n pendingRouteChildren.delete(key);\n }\n}\n\nfunction patchRoutesImpl(\n routeId: string | null,\n children: AgnosticRouteObject[],\n routesToUse: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction\n) {\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [routeId, \"patch\", String(route.children?.length || \"0\")],\n manifest\n );\n if (route.children) {\n route.children.push(...dataChildren);\n } else {\n route.children = dataChildren;\n }\n } else {\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [\"patch\", String(routesToUse.length || \"0\")],\n manifest\n );\n routesToUse.push(...dataChildren);\n }\n}\n\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */\nasync function loadLazyRouteModule(\n route: AgnosticDataRouteObject,\n mapRouteProperties: MapRoutePropertiesFunction,\n manifest: RouteManifest\n) {\n if (!route.lazy) {\n return;\n }\n\n let lazyRoute = await route.lazy();\n\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates: Record = {};\n for (let lazyRouteProperty in lazyRoute) {\n let staticRouteValue =\n routeToUpdate[lazyRouteProperty as keyof typeof routeToUpdate];\n\n let isPropertyStaticallyDefined =\n staticRouteValue !== undefined &&\n // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n\n warning(\n !isPropertyStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" ` +\n `defined but its lazy function is also returning a value for this property. ` +\n `The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n\n if (\n !isPropertyStaticallyDefined &&\n !immutableRouteKeys.has(lazyRouteProperty as ImmutableRouteKey)\n ) {\n routeUpdates[lazyRouteProperty] =\n lazyRoute[lazyRouteProperty as keyof typeof lazyRoute];\n }\n }\n\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided\n // `mapRouteProperties` (or wrapped `detectErrorBoundary`) function to\n // set the framework-aware properties (`element`/`hasErrorBoundary`) since\n // the logic will differ between frameworks.\n ...mapRouteProperties(routeToUpdate),\n lazy: undefined,\n });\n}\n\n// Default implementation of `dataStrategy` which fetches all loaders in parallel\nfunction defaultDataStrategy(\n opts: DataStrategyFunctionArgs\n): ReturnType {\n return Promise.all(opts.matches.map((m) => m.resolve()));\n}\n\nasync function callDataStrategyImpl(\n dataStrategyImpl: DataStrategyFunction,\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n requestContext?: unknown\n): Promise {\n let routeIdsToLoad = matchesToLoad.reduce(\n (acc, m) => acc.add(m.route.id),\n new Set()\n );\n let loadedMatches = new Set();\n\n // Send all matches here to allow for a middleware-type implementation.\n // handler will be a no-op for unneeded routes and we filter those results\n // back out below.\n let results = await dataStrategyImpl({\n matches: matches.map((match) => {\n let shouldLoad = routeIdsToLoad.has(match.route.id);\n // `resolve` encapsulates the route.lazy, executing the\n // loader/action, and mapping return values/thrown errors to a\n // HandlerResult. Users can pass a callback to take fine-grained control\n // over the execution of the loader/action\n let resolve: DataStrategyMatch[\"resolve\"] = (handlerOverride) => {\n loadedMatches.add(match.route.id);\n return shouldLoad\n ? callLoaderOrAction(\n type,\n request,\n match,\n manifest,\n mapRouteProperties,\n handlerOverride,\n requestContext\n )\n : Promise.resolve({ type: ResultType.data, result: undefined });\n };\n\n return {\n ...match,\n shouldLoad,\n resolve,\n };\n }),\n request,\n params: matches[0].params,\n context: requestContext,\n });\n\n // Throw if any loadRoute implementations not called since they are what\n // ensures a route is fully loaded\n matches.forEach((m) =>\n invariant(\n loadedMatches.has(m.route.id),\n `\\`match.resolve()\\` was not called for route id \"${m.route.id}\". ` +\n \"You must call `match.resolve()` on every match passed to \" +\n \"`dataStrategy` to ensure all routes are properly loaded.\"\n )\n );\n\n // Filter out any middleware-only matches for which we didn't need to run handlers\n return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id));\n}\n\n// Default logic for calling a loader/action is the user has no specified a dataStrategy\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n handlerOverride: Parameters[0],\n staticContext?: unknown\n): Promise {\n let result: HandlerResult;\n let onReject: (() => void) | undefined;\n\n let runHandler = (\n handler: AgnosticRouteObject[\"loader\"] | AgnosticRouteObject[\"action\"]\n ): Promise => {\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n // This will never resolve so safe to type it as Promise to\n // satisfy the function return value\n let abortPromise = new Promise((_, r) => (reject = r));\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n let actualHandler = (ctx?: unknown) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean ` +\n `\"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n params: match.params,\n context: staticContext,\n },\n ...(ctx !== undefined ? [ctx] : [])\n );\n };\n\n let handlerPromise: Promise;\n if (handlerOverride) {\n handlerPromise = handlerOverride((ctx: unknown) => actualHandler(ctx));\n } else {\n handlerPromise = (async () => {\n try {\n let val = await actualHandler();\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n }\n\n return Promise.race([handlerPromise, abortPromise]);\n };\n\n try {\n let handler = match.route[type];\n\n if (match.route.lazy) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n loadLazyRouteModule(match.route, mapRouteProperties, manifest),\n ]);\n if (handlerError !== undefined) {\n throw handlerError;\n }\n result = value!;\n } else {\n // Load lazy route module, then run any returned handler\n await loadLazyRouteModule(match.route, mapRouteProperties, manifest);\n\n handler = match.route[type];\n if (handler) {\n // Handler still runs even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id,\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return { type: ResultType.data, result: undefined };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname,\n });\n } else {\n result = await runHandler(handler);\n }\n\n invariant(\n result.result !== undefined,\n `You defined ${type === \"action\" ? \"an action\" : \"a loader\"} for route ` +\n `\"${match.route.id}\" but didn't return anything from your \\`${type}\\` ` +\n `function. Please return a value or \\`null\\`.`\n );\n } catch (e) {\n // We should already be catching and converting normal handler executions to\n // HandlerResults and returning them, so anything that throws here is an\n // unexpected error we still need to wrap\n return { type: ResultType.error, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n\n return result;\n}\n\nasync function convertHandlerResultToDataResult(\n handlerResult: HandlerResult\n): Promise {\n let { result, type, status } = handlerResult;\n\n if (isResponse(result)) {\n let data: any;\n\n try {\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n if (result.body == null) {\n data = null;\n } else {\n data = await result.json();\n }\n } else {\n data = await result.text();\n }\n } catch (e) {\n return { type: ResultType.error, error: e };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(result.status, result.statusText, data),\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : status,\n };\n }\n\n if (isDeferredData(result)) {\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: result.init?.status,\n headers: result.init?.headers && new Headers(result.init.headers),\n };\n }\n\n return { type: ResultType.data, data: result, statusCode: status };\n}\n\n// Support relative routing in internal redirects\nfunction normalizeRelativeRoutingRedirectResponse(\n response: Response,\n request: Request,\n routeId: string,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n v7_relativeSplatPath: boolean\n) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n true,\n location,\n v7_relativeSplatPath\n );\n response.headers.set(\"Location\", location);\n }\n\n return response;\n}\n\nfunction normalizeRedirectLocation(\n location: string,\n currentUrl: URL,\n basename: string\n): string {\n if (ABSOLUTE_URL_REGEX.test(location)) {\n // Strip off the protocol+origin for same-origin + same-basename absolute redirects\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\")\n ? new URL(currentUrl.protocol + normalizedLocation)\n : new URL(normalizedLocation);\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n return location;\n}\n\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(\n history: History,\n location: string | Location,\n signal: AbortSignal,\n submission?: Submission\n): Request {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init: RequestInit = { signal };\n\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (\n formEncType === \"application/x-www-form-urlencoded\" &&\n submission.formData\n ) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n\n return new Request(url, init);\n}\n\nfunction convertFormDataToSearchParams(formData: FormData): URLSearchParams {\n let searchParams = new URLSearchParams();\n\n for (let [key, value] of formData.entries()) {\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n\n return searchParams;\n}\n\nfunction convertSearchParamsToFormData(\n searchParams: URLSearchParams\n): FormData {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n activeDeferreds: Map,\n skipLoaderErrorBubbling: boolean\n): {\n loaderData: RouterState[\"loaderData\"];\n errors: RouterState[\"errors\"] | null;\n statusCode: number;\n loaderHeaders: Record;\n} {\n // Fill in loaderData/errors from our loaders\n let loaderData: RouterState[\"loaderData\"] = {};\n let errors: RouterState[\"errors\"] | null = null;\n let statusCode: number | undefined;\n let foundError = false;\n let loaderHeaders: Record = {};\n let pendingError =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : undefined;\n\n // Process loader results into state.loaderData/state.errors\n results.forEach((result, index) => {\n let id = matchesToLoad[index].route.id;\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError !== undefined) {\n error = pendingError;\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n // Look upwards from the matched route for the closest ancestor error\n // boundary, defaulting to the root match. Prefer higher error values\n // if lower errors bubble to the same boundary\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error)\n ? result.error.status\n : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (\n result.statusCode != null &&\n result.statusCode !== 200 &&\n !foundError\n ) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n }\n });\n\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError !== undefined && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n loaderData[pendingActionResult[0]] = undefined;\n }\n\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders,\n };\n}\n\nfunction processLoaderData(\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n revalidatingFetchers: RevalidatingFetcher[],\n fetcherResults: DataResult[],\n activeDeferreds: Map\n): {\n loaderData: RouterState[\"loaderData\"];\n errors?: RouterState[\"errors\"];\n} {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n false // This method is only called client side so we always want to bubble\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let { key, match, controller } = revalidatingFetchers[index];\n invariant(\n fetcherResults !== undefined && fetcherResults[index] !== undefined,\n \"Did not find corresponding fetcher result\"\n );\n let result = fetcherResults[index];\n\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n // Nothing to do for aborted fetchers\n continue;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error,\n };\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n return { loaderData, errors };\n}\n\nfunction mergeLoaderData(\n loaderData: RouteData,\n newLoaderData: RouteData,\n matches: AgnosticDataRouteMatch[],\n errors: RouteData | null | undefined\n): RouteData {\n let mergedLoaderData = { ...newLoaderData };\n for (let match of matches) {\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n } else {\n // No-op - this is so we ignore existing data if we have a key in the\n // incoming object with an undefined value, which is how we unset a prior\n // loaderData if we encounter a loader error\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n\n if (errors && errors.hasOwnProperty(id)) {\n // Don't keep any loader data below the boundary\n break;\n }\n }\n return mergedLoaderData;\n}\n\nfunction getActionDataForCommit(\n pendingActionResult: PendingActionResult | undefined\n) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1])\n ? {\n // Clear out prior actionData on errors\n actionData: {},\n }\n : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data,\n },\n };\n}\n\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(\n matches: AgnosticDataRouteMatch[],\n routeId?: string\n): AgnosticDataRouteMatch {\n let eligibleMatches = routeId\n ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1)\n : [...matches];\n return (\n eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) ||\n matches[0]\n );\n}\n\nfunction getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {\n matches: AgnosticDataRouteMatch[];\n route: AgnosticDataRouteObject;\n} {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route =\n routes.length === 1\n ? routes[0]\n : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`,\n };\n\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route,\n },\n ],\n route,\n };\n}\n\nfunction getInternalRouterError(\n status: number,\n {\n pathname,\n routeId,\n method,\n type,\n message,\n }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\" | \"invalid-body\" | \"route-discovery\";\n message?: string;\n } = {}\n) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n\n if (status === 400) {\n statusText = \"Bad Request\";\n if (type === \"route-discovery\") {\n errorMessage =\n `Unable to match URL \"${pathname}\" - the \\`unstable_patchRoutesOnMiss()\\` ` +\n `function threw the following error:\\n${message}`;\n } else if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method} request to \"${pathname}\" but ` +\n `did not provide a \\`loader\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method.toUpperCase()} request to \"${pathname}\" but ` +\n `did not provide an \\`action\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\n\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(\n results: DataResult[]\n): { result: RedirectResult; idx: number } | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return { result, idx: i };\n }\n }\n}\n\nfunction stripHashFromPath(path: To) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\n\nfunction isHashChangeOnly(a: Location, b: Location): boolean {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\n\nfunction isPromise(val: unknown): val is Promise {\n return typeof val === \"object\" && val != null && \"then\" in val;\n}\n\nfunction isHandlerResult(result: unknown): result is HandlerResult {\n return (\n result != null &&\n typeof result === \"object\" &&\n \"type\" in result &&\n \"result\" in result &&\n (result.type === ResultType.data || result.type === ResultType.error)\n );\n}\n\nfunction isRedirectHandlerResult(result: HandlerResult) {\n return (\n isResponse(result.result) && redirectStatusCodes.has(result.result.status)\n );\n}\n\nfunction isDeferredResult(result: DataResult): result is DeferredResult {\n return result.type === ResultType.deferred;\n}\n\nfunction isErrorResult(result: DataResult): result is ErrorResult {\n return result.type === ResultType.error;\n}\n\nfunction isRedirectResult(result?: DataResult): result is RedirectResult {\n return (result && result.type) === ResultType.redirect;\n}\n\nexport function isDeferredData(value: any): value is DeferredData {\n let deferred: DeferredData = value;\n return (\n deferred &&\n typeof deferred === \"object\" &&\n typeof deferred.data === \"object\" &&\n typeof deferred.subscribe === \"function\" &&\n typeof deferred.cancel === \"function\" &&\n typeof deferred.resolveData === \"function\"\n );\n}\n\nfunction isResponse(value: any): value is Response {\n return (\n value != null &&\n typeof value.status === \"number\" &&\n typeof value.statusText === \"string\" &&\n typeof value.headers === \"object\" &&\n typeof value.body !== \"undefined\"\n );\n}\n\nfunction isRedirectResponse(result: any): result is Response {\n if (!isResponse(result)) {\n return false;\n }\n\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\n\nfunction isValidMethod(method: string): method is FormMethod | V7_FormMethod {\n return validRequestMethods.has(method.toLowerCase() as FormMethod);\n}\n\nfunction isMutationMethod(\n method: string\n): method is MutationFormMethod | V7_MutationFormMethod {\n return validMutationMethods.has(method.toLowerCase() as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: (AgnosticDataRouteMatch | null)[],\n results: DataResult[],\n signals: (AbortSignal | null)[],\n isFetcher: boolean,\n currentLoaderData?: RouteData\n) {\n for (let index = 0; index < results.length; index++) {\n let result = results[index];\n let match = matchesToLoad[index];\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n\n let currentMatch = currentMatches.find(\n (m) => m.route.id === match!.route.id\n );\n let isRevalidatingLoader =\n currentMatch != null &&\n !isNewRouteInstance(currentMatch, match) &&\n (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n\n if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n let signal = signals[index];\n invariant(\n signal,\n \"Expected an AbortSignal for revalidating fetcher deferred result\"\n );\n await resolveDeferredData(result, signal, isFetcher).then((result) => {\n if (result) {\n results[index] = result || results[index];\n }\n });\n }\n }\n}\n\nasync function resolveDeferredData(\n result: DeferredResult,\n signal: AbortSignal,\n unwrap = false\n): Promise {\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData,\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e,\n };\n }\n }\n\n return {\n type: ResultType.data,\n data: result.deferredData.data,\n };\n}\n\nfunction hasNakedIndexQuery(search: string): boolean {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\n\nfunction getTargetMatch(\n matches: AgnosticDataRouteMatch[],\n location: Location | string\n) {\n let search =\n typeof location === \"string\" ? parsePath(location).search : location.search;\n if (\n matches[matches.length - 1].route.index &&\n hasNakedIndexQuery(search || \"\")\n ) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\n\nfunction getSubmissionFromNavigation(\n navigation: Navigation\n): Submission | undefined {\n let { formMethod, formAction, formEncType, text, formData, json } =\n navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text,\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined,\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined,\n };\n }\n}\n\nfunction getLoadingNavigation(\n location: Location,\n submission?: Submission\n): NavigationStates[\"Loading\"] {\n if (submission) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n } else {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n };\n return navigation;\n }\n}\n\nfunction getSubmittingNavigation(\n location: Location,\n submission: Submission\n): NavigationStates[\"Submitting\"] {\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n}\n\nfunction getLoadingFetcher(\n submission?: Submission,\n data?: Fetcher[\"data\"]\n): FetcherStates[\"Loading\"] {\n if (submission) {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data,\n };\n return fetcher;\n } else {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n }\n}\n\nfunction getSubmittingFetcher(\n submission: Submission,\n existingFetcher?: Fetcher\n): FetcherStates[\"Submitting\"] {\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined,\n };\n return fetcher;\n}\n\nfunction getDoneFetcher(data: Fetcher[\"data\"]): FetcherStates[\"Idle\"] {\n let fetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n}\n\nfunction restoreAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n // no-op, use default empty object\n }\n}\n\nfunction persistAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n if (transitions.size > 0) {\n let json: Record = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\n//#endregion\n"],"names":["Action","PopStateEventType","createMemoryHistory","options","initialEntries","initialIndex","v5Compat","entries","map","entry","index","createMemoryLocation","state","undefined","clampIndex","length","action","Pop","listener","n","Math","min","max","getCurrentLocation","to","key","location","createLocation","pathname","warning","charAt","JSON","stringify","createHref","createPath","history","createURL","URL","encodeLocation","path","parsePath","search","hash","push","Push","nextLocation","splice","delta","replace","Replace","go","nextIndex","listen","fn","createBrowserHistory","createBrowserLocation","window","globalHistory","usr","createBrowserHref","getUrlBasedHistory","createHashHistory","createHashLocation","substr","startsWith","createHashHref","base","document","querySelector","href","getAttribute","url","hashIndex","indexOf","slice","validateHashLocation","invariant","value","message","Error","cond","console","warn","e","createKey","random","toString","getHistoryState","idx","current","_extends","_ref","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","historyState","pushState","error","DOMException","name","assign","origin","addEventListener","removeEventListener","ResultType","immutableRouteKeys","Set","isIndexRoute","route","convertRoutesToDataRoutes","routes","mapRouteProperties","parentPath","manifest","treePath","String","id","join","children","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","matchRoutesImpl","allowPartial","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","decoded","decodePath","matchRouteBranch","convertRouteMatchToUiMatch","match","loaderData","params","data","handle","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","joinPaths","routesMeta","concat","score","computeScore","forEach","_route$path","includes","exploded","explodeOptionalSegments","segments","split","first","rest","isOptional","endsWith","required","restExploded","result","subpath","sort","a","b","compareIndexes","paramRe","dynamicSegmentValue","indexRouteValue","emptySegmentValue","staticSegmentValue","splatPenalty","isSplat","s","initialScore","some","filter","reduce","segment","test","siblings","every","branch","matchedParams","matchedPathname","end","remainingPathname","matchPath","Object","pathnameBase","normalizePathname","generatePath","originalPath","prefix","p","array","isLastSegment","star","keyMatch","optional","param","pattern","matcher","compiledParams","compilePath","captureGroups","memo","paramName","splatValue","regexpSource","_","RegExp","v","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","getResolveToMatches","v7_relativeSplatPath","pathMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","init","responseInit","status","headers","Headers","has","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","_ref2","trackPromise","done","add","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","undefinedError","emit","settledKey","subscriber","subscribe","cancel","abort","k","resolveData","resolve","size","unwrappedData","_ref3","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","redirectDocument","response","ErrorResponseImpl","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","text","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","ABSOLUTE_URL_REGEX","defaultMapRouteProperties","hasErrorBoundary","Boolean","TRANSITIONS_STORAGE_KEY","createRouter","routerWindow","isBrowser","createElement","isServer","detectErrorBoundary","dataRoutes","inFlightDataRoutes","dataStrategyImpl","unstable_dataStrategy","defaultDataStrategy","patchRoutesOnMissImpl","unstable_patchRoutesOnMiss","future","v7_fetcherPersist","v7_normalizeFormMethod","v7_partialHydration","v7_prependBasename","v7_skipActionErrorRevalidation","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","fogOfWar","checkFogOfWar","active","initialized","m","lazy","loader","errors","isRouteInitialized","hydrate","findIndex","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","actionData","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","pendingViewTransitionEnabled","appliedViewTransitions","removePageHideEventListener","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeFetchers","deletedFetchers","activeDeferreds","blockerFunctions","pendingPatchRoutes","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","updateState","startNavigation","restoreAppliedTransitions","_saveAppliedTransitions","persistAppliedTransitions","initialHydration","dispose","clear","deleteFetcher","deleteBlocker","newState","opts","completedFetchers","deletedFetchersKeys","fetcher","unstable_viewTransitionOpts","viewTransitionOpts","unstable_flushSync","flushSync","completeNavigation","_temp","_location$state","_location$state2","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","priorPaths","toPaths","getSavedScrollPosition","navigate","normalizedPath","normalizeTo","fromRouteId","relative","submission","normalizeNavigateOptions","userReplace","pendingError","enableViewTransition","unstable_viewTransition","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","routesToUse","loadingNavigation","notFoundMatches","handleNavigational404","isHashChangeOnly","request","createClientSideRequest","pendingActionResult","findNearestBoundary","type","actionResult","handleAction","shortCircuited","routeId","isErrorResult","getLoadingNavigation","updatedMatches","handleLoaders","fetcherSubmission","getActionDataForCommit","isFogOfWar","getSubmittingNavigation","discoverResult","discoverRoutes","boundaryId","handleDiscoverRouteError","partialMatches","actionMatch","getTargetMatch","method","results","callDataStrategy","isRedirectResult","normalizeRedirectLocation","startRedirectNavigation","isDeferredResult","boundaryMatch","activeSubmission","getSubmissionFromNavigation","shouldUpdateNavigationState","getUpdatedActionData","matchesToLoad","revalidatingFetchers","getMatchesToLoad","cancelActiveDeferreds","updatedFetchers","markFetchRedirectsDone","updates","getUpdatedRevalidatingFetchers","rf","abortFetcher","abortPendingFetchRevalidations","f","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","fetcherKey","processLoaderData","deferredData","didAbortFetchLoads","abortStaleFetchLoads","shouldUpdateFetchers","revalidatingFetcher","getLoadingFetcher","fetch","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","detectAndHandle405Error","existingFetcher","updateFetcherState","getSubmittingFetcher","abortController","fetchRequest","originatingLoadId","actionResults","getDoneFetcher","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","_temp2","redirectLocation","isDocumentReload","redirectHistoryAction","callDataStrategyImpl","all","isRedirectHandlerResult","normalizeRelativeRoutingRedirectResponse","convertHandlerResultToDataResult","currentMatches","fetchersToLoad","fetcherRequest","resolveDeferredResults","getFetcher","deleteFetcherAndUpdateState","count","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","_ref4","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","getScrollKey","fogMatches","leafRoute","isNonHMR","loadLazyRouteChildren","newMatches","matchedSplat","newPartialMatches","_internalSetRoutes","newRoutes","patchRoutes","patchRoutesImpl","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","v7_throwAbortReason","query","_temp3","requestContext","skipLoaderErrorBubbling","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","_temp4","find","values","_result$activeDeferre","routeMatch","submit","loadRouteData","isHandlerResult","isRedirectResponse","isRouteRequest","throwStaticHandlerAbortedError","Location","loaderRequest","Request","context","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","reason","isSubmissionNavigation","body","prependBasename","contextualMatches","activeRouteMatch","hasNakedIndexQuery","normalizeFormMethod","isFetcher","getInvalidBodyError","rawFormMethod","toUpperCase","stripHashFromPath","FormData","URLSearchParams","_ref5","parse","searchParams","convertFormDataToSearchParams","convertSearchParamsToFormData","append","boundaryMatches","isInitialLoad","skipActionErrorRevalidation","currentUrl","nextUrl","actionStatus","shouldSkipRevalidation","navigationMatches","isNewLoader","currentRouteMatch","nextRouteMatch","shouldRevalidateLoader","currentParams","nextParams","defaultShouldRevalidate","isNewRouteInstance","fetcherMatches","fetcherMatch","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","currentPath","loaderMatch","arg","routeChoice","pendingRouteChildren","pending","patch","isPromise","_route$children","dataChildren","loadLazyRouteModule","lazyRoute","routeToUpdate","routeUpdates","lazyRouteProperty","staticRouteValue","isPropertyStaticallyDefined","routeIdsToLoad","loadedMatches","shouldLoad","handlerOverride","callLoaderOrAction","staticContext","onReject","runHandler","handler","actualHandler","ctx","handlerPromise","val","handlerError","handlerResult","contentType","isDeferredData","_result$init","_result$init2","deferred","trimmedMatches","normalizedLocation","protocol","isSameBasename","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","_temp5","errorMessage","signals","isRevalidatingLoader","unwrap","getAll","_window","transitions","sessionPositions","sessionStorage","getItem","setItem"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@remix-run/router/dist/router.umd.min.js b/node_modules/@remix-run/router/dist/router.umd.min.js new file mode 100644 index 0000000000..0717823546 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.min.js @@ -0,0 +1,12 @@ +/** + * @remix-run/router v1.18.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).RemixRouter={})}(this,(function(e){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0&&(t.hash=e.substr(r),e=e.substr(0,r));let a=e.indexOf("?");a>=0&&(t.search=e.substr(a),e=e.substr(0,a)),e&&(t.pathname=e)}return t}function c(e,o,u,c){void 0===c&&(c={});let{window:d=document.defaultView,v5Compat:h=!1}=c,f=d.history,p=r.Pop,m=null,y=v();function v(){return(f.state||{idx:null}).idx}function g(){p=r.Pop;let e=v(),t=null==e?null:e-y;y=e,m&&m({action:p,location:w.location,delta:t})}function b(e){let t="null"!==d.location.origin?d.location.origin:d.location.href,r="string"==typeof e?e:l(e);return r=r.replace(/ $/,"%20"),n(t,"No window.location.(origin|href) available to create URL for href: "+r),new URL(r,t)}null==y&&(y=0,f.replaceState(t({},f.state,{idx:y}),""));let w={get action(){return p},get location(){return e(d,f)},listen(e){if(m)throw new Error("A history only accepts one active listener");return d.addEventListener(a,g),m=e,()=>{d.removeEventListener(a,g),m=null}},createHref:e=>o(d,e),createURL:b,encodeLocation(e){let t=b(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(e,t){p=r.Push;let a=s(w.location,e,t);u&&u(a,e),y=v()+1;let n=i(a,y),o=w.createHref(a);try{f.pushState(n,"",o)}catch(e){if(e instanceof DOMException&&"DataCloneError"===e.name)throw e;d.location.assign(o)}h&&m&&m({action:p,location:w.location,delta:1})},replace:function(e,t){p=r.Replace;let a=s(w.location,e,t);u&&u(a,e),y=v();let n=i(a,y),o=w.createHref(a);f.replaceState(n,"",o),h&&m&&m({action:p,location:w.location,delta:0})},go:e=>f.go(e)};return w}let d=function(e){return e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error",e}({});const h=new Set(["lazy","caseSensitive","path","id","index","children"]);function f(e,r,a,o){return void 0===a&&(a=[]),void 0===o&&(o={}),e.map(((e,i)=>{let s=[...a,String(i)],l="string"==typeof e.id?e.id:s.join("-");if(n(!0!==e.index||!e.children,"Cannot specify children on an index route"),n(!o[l],'Found a route id collision on id "'+l+"\". Route id's must be globally unique within Data Router usages"),function(e){return!0===e.index}(e)){let a=t({},e,r(e),{id:l});return o[l]=a,a}{let a=t({},e,r(e),{id:l,children:void 0});return o[l]=a,e.children&&(a.children=f(e.children,r,s,o)),a}}))}function p(e,t,r){return void 0===r&&(r="/"),m(e,t,r,!1)}function m(e,t,r,a){let n=P(("string"==typeof t?u(t):t).pathname||"/",r);if(null==n)return null;let o=v(e);!function(e){e.sort(((e,t)=>e.score!==t.score?t.score-e.score:function(e,t){return e.length===t.length&&e.slice(0,-1).every(((e,r)=>e===t[r]))?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((e=>e.childrenIndex)),t.routesMeta.map((e=>e.childrenIndex)))))}(o);let i=null;for(let e=0;null==i&&e{let s={relativePath:void 0===i?e.path||"":i,caseSensitive:!0===e.caseSensitive,childrenIndex:o,route:e};s.relativePath.startsWith("/")&&(n(s.relativePath.startsWith(a),'Absolute route path "'+s.relativePath+'" nested under path "'+a+'" is not valid. An absolute child route path must start with the combined path of all its parent routes.'),s.relativePath=s.relativePath.slice(a.length));let l=_([a,s.relativePath]),u=r.concat(s);e.children&&e.children.length>0&&(n(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+l+'".'),v(e.children,t,u,l)),(null!=e.path||e.index)&&t.push({path:l,score:D(l,e.index),routesMeta:u})};return e.forEach(((e,t)=>{var r;if(""!==e.path&&null!=(r=e.path)&&r.includes("?"))for(let r of g(e.path))o(e,t,r);else o(e,t)})),t}function g(e){let t=e.split("/");if(0===t.length)return[];let[r,...a]=t,n=r.endsWith("?"),o=r.replace(/\?$/,"");if(0===a.length)return n?[o,""]:[o];let i=g(a.join("/")),s=[];return s.push(...i.map((e=>""===e?o:[o,e].join("/")))),n&&s.push(...i),s.map((t=>e.startsWith("/")&&""===t?"/":t))}const b=/^:[\w-]+$/,w=e=>"*"===e;function D(e,t){let r=e.split("/"),a=r.length;return r.some(w)&&(a+=-2),t&&(a+=2),r.filter((e=>!w(e))).reduce(((e,t)=>e+(b.test(t)?3:""===t?1:10)),a)}function S(e,t,r){void 0===r&&(r=!1);let{routesMeta:a}=e,n={},o="/",i=[];for(let e=0;e(a.push({paramName:t,isOptional:null!=r}),r?"/?([^\\/]+)?":"/([^\\/]+)")));e.endsWith("*")?(a.push({paramName:"*"}),n+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?n+="\\/*$":""!==e&&"/"!==e&&(n+="(?:(?=\\/|$))");return[new RegExp(n,t?void 0:"i"),a]}(e.path,e.caseSensitive,e.end),n=t.match(r);if(!n)return null;let i=n[0],s=i.replace(/(.)\/+$/,"$1"),l=n.slice(1);return{params:a.reduce(((e,t,r)=>{let{paramName:a,isOptional:n}=t;if("*"===a){let e=l[r]||"";s=i.slice(0,i.length-e.length).replace(/(.)\/+$/,"$1")}const o=l[r];return e[a]=n&&!o?void 0:(o||"").replace(/%2F/g,"/"),e}),{}),pathname:i,pathnameBase:s,pattern:e}}function R(e){try{return e.split("/").map((e=>decodeURIComponent(e).replace(/\//g,"%2F"))).join("/")}catch(t){return o(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent encoding ('+t+")."),e}}function P(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,a=e.charAt(r);return a&&"/"!==a?null:e.slice(r)||"/"}function x(e,t){void 0===t&&(t="/");let{pathname:r,search:a="",hash:n=""}="string"==typeof e?u(e):e,o=r?r.startsWith("/")?r:function(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?r.length>1&&r.pop():"."!==e&&r.push(e)})),r.length>1?r.join("/"):"/"}(r,t):t;return{pathname:o,search:C(a),hash:U(n)}}function A(e,t,r,a){return"Cannot include a '"+e+"' character in a manually specified `to."+t+"` field ["+JSON.stringify(a)+"]. Please separate it out to the `to."+r+'` field. Alternatively you may provide the full path as a string in and the router will parse it for you.'}function L(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function M(e,t){let r=L(e);return t?r.map(((e,t)=>t===r.length-1?e.pathname:e.pathnameBase)):r.map((e=>e.pathnameBase))}function j(e,r,a,o){let i;void 0===o&&(o=!1),"string"==typeof e?i=u(e):(i=t({},e),n(!i.pathname||!i.pathname.includes("?"),A("?","pathname","search",i)),n(!i.pathname||!i.pathname.includes("#"),A("#","pathname","hash",i)),n(!i.search||!i.search.includes("#"),A("#","search","hash",i)));let s,l=""===e||""===i.pathname,c=l?"/":i.pathname;if(null==c)s=a;else{let e=r.length-1;if(!o&&c.startsWith("..")){let t=c.split("/");for(;".."===t[0];)t.shift(),e-=1;i.pathname=t.join("/")}s=e>=0?r[e]:"/"}let d=x(i,s),h=c&&"/"!==c&&c.endsWith("/"),f=(l||"."===c)&&a.endsWith("/");return d.pathname.endsWith("/")||!h&&!f||(d.pathname+="/"),d}const _=e=>e.join("/").replace(/\/\/+/g,"/"),k=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),C=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",U=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";class T extends Error{}class O{constructor(e,t){let r;this.pendingKeysSet=new Set,this.subscribers=new Set,this.deferredKeys=[],n(e&&"object"==typeof e&&!Array.isArray(e),"defer() only accepts plain objects"),this.abortPromise=new Promise(((e,t)=>r=t)),this.controller=new AbortController;let a=()=>r(new T("Deferred data aborted"));this.unlistenAbortSignal=()=>this.controller.signal.removeEventListener("abort",a),this.controller.signal.addEventListener("abort",a),this.data=Object.entries(e).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:this.trackPromise(r,a)})}),{}),this.done&&this.unlistenAbortSignal(),this.init=t}trackPromise(e,t){if(!(t instanceof Promise))return t;this.deferredKeys.push(e),this.pendingKeysSet.add(e);let r=Promise.race([t,this.abortPromise]).then((t=>this.onSettle(r,e,void 0,t)),(t=>this.onSettle(r,e,t)));return r.catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),r}onSettle(e,t,r,a){if(this.controller.signal.aborted&&r instanceof T)return this.unlistenAbortSignal(),Object.defineProperty(e,"_error",{get:()=>r}),Promise.reject(r);if(this.pendingKeysSet.delete(t),this.done&&this.unlistenAbortSignal(),void 0===r&&void 0===a){let r=new Error('Deferred data for key "'+t+'" resolved/rejected with `undefined`, you must resolve/reject with a value or `null`.');return Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)}return void 0===a?(Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)):(Object.defineProperty(e,"_data",{get:()=>a}),this.emit(!1,t),a)}emit(e,t){this.subscribers.forEach((r=>r(e,t)))}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}cancel(){this.controller.abort(),this.pendingKeysSet.forEach(((e,t)=>this.pendingKeysSet.delete(t))),this.emit(!0)}async resolveData(e){let t=!1;if(!this.done){let r=()=>this.cancel();e.addEventListener("abort",r),t=await new Promise((t=>{this.subscribe((a=>{e.removeEventListener("abort",r),(a||this.done)&&t(a)}))}))}return t}get done(){return 0===this.pendingKeysSet.size}get unwrappedData(){return n(null!==this.data&&this.done,"Can only unwrap data on initialized and settled deferreds"),Object.entries(this.data).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:I(a)})}),{})}get pendingKeys(){return Array.from(this.pendingKeysSet)}}function I(e){if(!function(e){return e instanceof Promise&&!0===e._tracked}(e))return e;if(e._error)throw e._error;return e._data}const H=function(e,r){void 0===r&&(r=302);let a=r;"number"==typeof a?a={status:a}:void 0===a.status&&(a.status=302);let n=new Headers(a.headers);return n.set("Location",e),new Response(null,t({},a,{headers:n}))};class F{constructor(e,t,r,a){void 0===a&&(a=!1),this.status=e,this.statusText=t||"",this.internal=a,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function z(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"boolean"==typeof e.internal&&"data"in e}const N=["post","put","patch","delete"],B=new Set(N),W=["get",...N],$=new Set(W),q=new Set([301,302,303,307,308]),K=new Set([307,308]),Y={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},J={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},V={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},X=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,G=e=>({hasErrorBoundary:Boolean(e.hasErrorBoundary)}),Q="remix-router-transitions";const Z=Symbol("deferred");function ee(e,t,r){if(r.v7_throwAbortReason&&void 0!==e.signal.reason)throw e.signal.reason;throw new Error((t?"queryRoute":"query")+"() call aborted: "+e.method+" "+e.url)}function te(e,t,r,a,n,o,i,s){let u,c;if(i){u=[];for(let e of t)if(u.push(e),e.route.id===i){c=e;break}}else u=t,c=t[t.length-1];let d=j(n||".",M(u,o),P(e.pathname,r)||e.pathname,"path"===s);return null==n&&(d.search=e.search,d.hash=e.hash),null!=n&&""!==n&&"."!==n||!c||!c.route.index||Ie(d.search)||(d.search=d.search?d.search.replace(/^\?/,"?index&"):"?index"),a&&"/"!==r&&(d.pathname="/"===d.pathname?r:_([r,d.pathname])),l(d)}function re(e,t,r,a){if(!a||!function(e){return null!=e&&("formData"in e&&null!=e.formData||"body"in e&&void 0!==e.body)}(a))return{path:r};if(a.formMethod&&!Ce(a.formMethod))return{path:r,error:Re(405,{method:a.formMethod})};let o,i,s=()=>({path:r,error:Re(400,{type:"invalid-body"})}),c=a.formMethod||"get",d=e?c.toUpperCase():c.toLowerCase(),h=xe(r);if(void 0!==a.body){if("text/plain"===a.formEncType){if(!Ue(d))return s();let e="string"==typeof a.body?a.body:a.body instanceof FormData||a.body instanceof URLSearchParams?Array.from(a.body.entries()).reduce(((e,t)=>{let[r,a]=t;return""+e+r+"="+a+"\n"}),""):String(a.body);return{path:r,submission:{formMethod:d,formAction:h,formEncType:a.formEncType,formData:void 0,json:void 0,text:e}}}if("application/json"===a.formEncType){if(!Ue(d))return s();try{let e="string"==typeof a.body?JSON.parse(a.body):a.body;return{path:r,submission:{formMethod:d,formAction:h,formEncType:a.formEncType,formData:void 0,json:e,text:void 0}}}catch(e){return s()}}}if(n("function"==typeof FormData,"FormData is not available in this environment"),a.formData)o=ye(a.formData),i=a.formData;else if(a.body instanceof FormData)o=ye(a.body),i=a.body;else if(a.body instanceof URLSearchParams)o=a.body,i=ve(o);else if(null==a.body)o=new URLSearchParams,i=new FormData;else try{o=new URLSearchParams(a.body),i=ve(o)}catch(e){return s()}let f={formMethod:d,formAction:h,formEncType:a&&a.formEncType||"application/x-www-form-urlencoded",formData:i,json:void 0,text:void 0};if(Ue(f.formMethod))return{path:r,submission:f};let p=u(r);return t&&p.search&&Ie(p.search)&&o.append("index",""),p.search="?"+o,{path:l(p),submission:f}}function ae(e,t){let r=e;if(t){let a=e.findIndex((e=>e.route.id===t));a>=0&&(r=e.slice(0,a))}return r}function ne(e,r,a,n,o,i,s,l,u,c,d,h,f,m,y,v){let g=v?Me(v[1])?v[1].error:v[1].data:void 0,b=e.createURL(r.location),w=e.createURL(o),D=v&&Me(v[1])?v[0]:void 0,S=D?ae(a,D):a,E=v?v[1].statusCode:void 0,R=s&&E&&E>=400,P=S.filter(((e,a)=>{let{route:o}=e;if(o.lazy)return!0;if(null==o.loader)return!1;if(i)return!("function"==typeof o.loader&&!o.loader.hydrate)||void 0===r.loaderData[o.id]&&(!r.errors||void 0===r.errors[o.id]);if(function(e,t,r){let a=!t||r.route.id!==t.route.id,n=void 0===e[r.route.id];return a||n}(r.loaderData,r.matches[a],e)||u.some((t=>t===e.route.id)))return!0;let s=r.matches[a],c=e;return ie(e,t({currentUrl:b,currentParams:s.params,nextUrl:w,nextParams:c.params},n,{actionResult:g,actionStatus:E,defaultShouldRevalidate:!R&&(l||b.pathname+b.search===w.pathname+w.search||b.search!==w.search||oe(s,c))}))})),x=[];return h.forEach(((e,o)=>{if(i||!a.some((t=>t.route.id===e.routeId))||d.has(o))return;let s=p(m,e.path,y);if(!s)return void x.push({key:o,routeId:e.routeId,path:e.path,matches:null,match:null,controller:null});let u=r.fetchers.get(o),h=He(s,e.path),v=!1;v=!f.has(o)&&(!!c.includes(o)||(u&&"idle"!==u.state&&void 0===u.data?l:ie(h,t({currentUrl:b,currentParams:r.matches[r.matches.length-1].params,nextUrl:w,nextParams:a[a.length-1].params},n,{actionResult:g,actionStatus:E,defaultShouldRevalidate:!R&&l})))),v&&x.push({key:o,routeId:e.routeId,path:e.path,matches:s,match:h,controller:new AbortController})})),[P,x]}function oe(e,t){let r=e.route.path;return e.pathname!==t.pathname||null!=r&&r.endsWith("*")&&e.params["*"]!==t.params["*"]}function ie(e,t){if(e.route.shouldRevalidate){let r=e.route.shouldRevalidate(t);if("boolean"==typeof r)return r}return t.defaultShouldRevalidate}async function se(e,t,r,a,n,o,i,s){let l=[t,...r.map((e=>e.route.id))].join("-");try{let c=i.get(l);c||(c=e({path:t,matches:r,patch:(e,t)=>{s.aborted||le(e,t,a,n,o)}}),i.set(l,c)),c&&("object"==typeof(u=c)&&null!=u&&"then"in u)&&await c}finally{i.delete(l)}var u}function le(e,t,r,a,o){if(e){var i;let r=a[e];n(r,"No route found to patch children into: routeId = "+e);let s=f(t,o,[e,"patch",String((null==(i=r.children)?void 0:i.length)||"0")],a);r.children?r.children.push(...s):r.children=s}else{let e=f(t,o,["patch",String(r.length||"0")],a);r.push(...e)}}async function ue(e,r,a){if(!e.lazy)return;let i=await e.lazy();if(!e.lazy)return;let s=a[e.id];n(s,"No route found in manifest");let l={};for(let e in i){let t=void 0!==s[e]&&"hasErrorBoundary"!==e;o(!t,'Route "'+s.id+'" has a static property "'+e+'" defined but its lazy function is also returning a value for this property. The lazy route property "'+e+'" will be ignored.'),t||h.has(e)||(l[e]=i[e])}Object.assign(s,l),Object.assign(s,t({},r(s),{lazy:void 0}))}function ce(e){return Promise.all(e.matches.map((e=>e.resolve())))}async function de(e,r,a,o,i,s,l,u){let c=o.reduce(((e,t)=>e.add(t.route.id)),new Set),h=new Set,f=await e({matches:i.map((e=>{let o=c.has(e.route.id);return t({},e,{shouldLoad:o,resolve:t=>(h.add(e.route.id),o?async function(e,t,r,a,o,i,s){let l,u,c=a=>{let n,o=new Promise(((e,t)=>n=t));u=()=>n(),t.signal.addEventListener("abort",u);let l,c=n=>"function"!=typeof a?Promise.reject(new Error('You cannot call the handler for a route which defines a boolean "'+e+'" [routeId: '+r.route.id+"]")):a({request:t,params:r.params,context:s},...void 0!==n?[n]:[]);return l=i?i((e=>c(e))):(async()=>{try{return{type:"data",result:await c()}}catch(e){return{type:"error",result:e}}})(),Promise.race([l,o])};try{let i=r.route[e];if(r.route.lazy)if(i){let e,[t]=await Promise.all([c(i).catch((t=>{e=t})),ue(r.route,o,a)]);if(void 0!==e)throw e;l=t}else{if(await ue(r.route,o,a),i=r.route[e],!i){if("action"===e){let e=new URL(t.url),a=e.pathname+e.search;throw Re(405,{method:t.method,pathname:a,routeId:r.route.id})}return{type:d.data,result:void 0}}l=await c(i)}else{if(!i){let e=new URL(t.url);throw Re(404,{pathname:e.pathname+e.search})}l=await c(i)}n(void 0!==l.result,"You defined "+("action"===e?"an action":"a loader")+' for route "'+r.route.id+"\" but didn't return anything from your `"+e+"` function. Please return a value or `null`.")}catch(e){return{type:d.error,result:e}}finally{u&&t.signal.removeEventListener("abort",u)}return l}(r,a,e,s,l,t,u):Promise.resolve({type:d.data,result:void 0}))})})),request:a,params:i[0].params,context:u});return i.forEach((e=>n(h.has(e.route.id),'`match.resolve()` was not called for route id "'+e.route.id+'". You must call `match.resolve()` on every match passed to `dataStrategy` to ensure all routes are properly loaded.'))),f.filter(((e,t)=>c.has(i[t].route.id)))}async function he(e){let{result:t,type:r,status:a}=e;if(ke(t)){let e;try{let r=t.headers.get("Content-Type");e=r&&/\bapplication\/json\b/.test(r)?null==t.body?null:await t.json():await t.text()}catch(e){return{type:d.error,error:e}}return r===d.error?{type:d.error,error:new F(t.status,t.statusText,e),statusCode:t.status,headers:t.headers}:{type:d.data,data:e,statusCode:t.status,headers:t.headers}}return r===d.error?{type:d.error,error:t,statusCode:z(t)?t.status:a}:_e(t)?{type:d.deferred,deferredData:t,statusCode:null==(n=t.init)?void 0:n.status,headers:(null==(o=t.init)?void 0:o.headers)&&new Headers(t.init.headers)}:{type:d.data,data:t,statusCode:a};var n,o}function fe(e,t,r,a,o,i){let s=e.headers.get("Location");if(n(s,"Redirects returned/thrown from loaders/actions must have a Location header"),!X.test(s)){let n=a.slice(0,a.findIndex((e=>e.route.id===r))+1);s=te(new URL(t.url),n,o,!0,s,i),e.headers.set("Location",s)}return e}function pe(e,t,r){if(X.test(e)){let a=e,n=a.startsWith("//")?new URL(t.protocol+a):new URL(a),o=null!=P(n.pathname,r);if(n.origin===t.origin&&o)return n.pathname+n.search+n.hash}return e}function me(e,t,r,a){let n=e.createURL(xe(t)).toString(),o={signal:r};if(a&&Ue(a.formMethod)){let{formMethod:e,formEncType:t}=a;o.method=e.toUpperCase(),"application/json"===t?(o.headers=new Headers({"Content-Type":t}),o.body=JSON.stringify(a.json)):"text/plain"===t?o.body=a.text:"application/x-www-form-urlencoded"===t&&a.formData?o.body=ye(a.formData):o.body=a.formData}return new Request(n,o)}function ye(e){let t=new URLSearchParams;for(let[r,a]of e.entries())t.append(r,"string"==typeof a?a:a.name);return t}function ve(e){let t=new FormData;for(let[r,a]of e.entries())t.append(r,a);return t}function ge(e,t,r,a,o,i){let s,l={},u=null,c=!1,d={},h=a&&Me(a[1])?a[1].error:void 0;return r.forEach(((r,a)=>{let f=t[a].route.id;if(n(!je(r),"Cannot handle redirect results in processLoaderData"),Me(r)){let t=r.error;if(void 0!==h&&(t=h,h=void 0),u=u||{},i)u[f]=t;else{let r=Se(e,f);null==u[r.route.id]&&(u[r.route.id]=t)}l[f]=void 0,c||(c=!0,s=z(r.error)?r.error.status:500),r.headers&&(d[f]=r.headers)}else Le(r)?(o.set(f,r.deferredData),l[f]=r.deferredData.data,null==r.statusCode||200===r.statusCode||c||(s=r.statusCode),r.headers&&(d[f]=r.headers)):(l[f]=r.data,r.statusCode&&200!==r.statusCode&&!c&&(s=r.statusCode),r.headers&&(d[f]=r.headers))})),void 0!==h&&a&&(u={[a[0]]:h},l[a[0]]=void 0),{loaderData:l,errors:u,statusCode:s||200,loaderHeaders:d}}function be(e,r,a,o,i,s,l,u){let{loaderData:c,errors:d}=ge(r,a,o,i,u,!1);for(let r=0;re.route.id===t))+1):[...e]).reverse().find((e=>!0===e.route.hasErrorBoundary))||e[0]}function Ee(e){let t=1===e.length?e[0]:e.find((e=>e.index||!e.path||"/"===e.path))||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function Re(e,t){let{pathname:r,routeId:a,method:n,type:o,message:i}=void 0===t?{}:t,s="Unknown Server Error",l="Unknown @remix-run/router error";return 400===e?(s="Bad Request","route-discovery"===o?l='Unable to match URL "'+r+'" - the `unstable_patchRoutesOnMiss()` function threw the following error:\n'+i:n&&r&&a?l="You made a "+n+' request to "'+r+'" but did not provide a `loader` for route "'+a+'", so there is no way to handle the request.':"defer-action"===o?l="defer() is not supported in actions":"invalid-body"===o&&(l="Unable to encode submission body")):403===e?(s="Forbidden",l='Route "'+a+'" does not match URL "'+r+'"'):404===e?(s="Not Found",l='No route matches URL "'+r+'"'):405===e&&(s="Method Not Allowed",n&&r&&a?l="You made a "+n.toUpperCase()+' request to "'+r+'" but did not provide an `action` for route "'+a+'", so there is no way to handle the request.':n&&(l='Invalid request method "'+n.toUpperCase()+'"')),new F(e||500,s,new Error(l),!0)}function Pe(e){for(let t=e.length-1;t>=0;t--){let r=e[t];if(je(r))return{result:r,idx:t}}}function xe(e){return l(t({},"string"==typeof e?u(e):e,{hash:""}))}function Ae(e){return ke(e.result)&&q.has(e.result.status)}function Le(e){return e.type===d.deferred}function Me(e){return e.type===d.error}function je(e){return(e&&e.type)===d.redirect}function _e(e){let t=e;return t&&"object"==typeof t&&"object"==typeof t.data&&"function"==typeof t.subscribe&&"function"==typeof t.cancel&&"function"==typeof t.resolveData}function ke(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"object"==typeof e.headers&&void 0!==e.body}function Ce(e){return $.has(e.toLowerCase())}function Ue(e){return B.has(e.toLowerCase())}async function Te(e,t,r,a,o,i){for(let s=0;se.route.id===u.route.id)),d=null!=c&&!oe(c,u)&&void 0!==(i&&i[u.route.id]);if(Le(l)&&(o||d)){let e=a[s];n(e,"Expected an AbortSignal for revalidating fetcher deferred result"),await Oe(l,e,o).then((e=>{e&&(r[s]=e||r[s])}))}}}async function Oe(e,t,r){if(void 0===r&&(r=!1),!await e.deferredData.resolveData(t)){if(r)try{return{type:d.data,data:e.deferredData.unwrappedData}}catch(e){return{type:d.error,error:e}}return{type:d.data,data:e.deferredData.data}}}function Ie(e){return new URLSearchParams(e).getAll("index").some((e=>""===e))}function He(e,t){let r="string"==typeof t?u(t).search:t.search;if(e[e.length-1].route.index&&Ie(r||""))return e[e.length-1];let a=L(e);return a[a.length-1]}function Fe(e){let{formMethod:t,formAction:r,formEncType:a,text:n,formData:o,json:i}=e;if(t&&r&&a)return null!=n?{formMethod:t,formAction:r,formEncType:a,formData:void 0,json:void 0,text:n}:null!=o?{formMethod:t,formAction:r,formEncType:a,formData:o,json:void 0,text:void 0}:void 0!==i?{formMethod:t,formAction:r,formEncType:a,formData:void 0,json:i,text:void 0}:void 0}function ze(e,t){if(t){return{state:"loading",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}return{state:"loading",location:e,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function Ne(e,t){return{state:"submitting",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}function Be(e,t){if(e){return{state:"loading",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t}}return{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:t}}function We(e){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}e.AbortedDeferredError=T,e.Action=r,e.IDLE_BLOCKER=V,e.IDLE_FETCHER=J,e.IDLE_NAVIGATION=Y,e.UNSAFE_DEFERRED_SYMBOL=Z,e.UNSAFE_DeferredData=O,e.UNSAFE_ErrorResponseImpl=F,e.UNSAFE_convertRouteMatchToUiMatch=y,e.UNSAFE_convertRoutesToDataRoutes=f,e.UNSAFE_decodePath=R,e.UNSAFE_getResolveToMatches=M,e.UNSAFE_invariant=n,e.UNSAFE_warning=o,e.createBrowserHistory=function(e){return void 0===e&&(e={}),c((function(e,t){let{pathname:r,search:a,hash:n}=e.location;return s("",{pathname:r,search:a,hash:n},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){return"string"==typeof t?t:l(t)}),null,e)},e.createHashHistory=function(e){return void 0===e&&(e={}),c((function(e,t){let{pathname:r="/",search:a="",hash:n=""}=u(e.location.hash.substr(1));return r.startsWith("/")||r.startsWith(".")||(r="/"+r),s("",{pathname:r,search:a,hash:n},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){let r=e.document.querySelector("base"),a="";if(r&&r.getAttribute("href")){let t=e.location.href,r=t.indexOf("#");a=-1===r?t:t.slice(0,r)}return a+"#"+("string"==typeof t?t:l(t))}),(function(e,t){o("/"===e.pathname.charAt(0),"relative pathnames are not supported in hash history.push("+JSON.stringify(t)+")")}),e)},e.createMemoryHistory=function(e){void 0===e&&(e={});let t,{initialEntries:a=["/"],initialIndex:n,v5Compat:i=!1}=e;t=a.map(((e,t)=>m(e,"string"==typeof e?null:e.state,0===t?"default":void 0)));let c=f(null==n?t.length-1:n),d=r.Pop,h=null;function f(e){return Math.min(Math.max(e,0),t.length-1)}function p(){return t[c]}function m(e,r,a){void 0===r&&(r=null);let n=s(t?p().pathname:"/",e,r,a);return o("/"===n.pathname.charAt(0),"relative pathnames are not supported in memory history: "+JSON.stringify(e)),n}function y(e){return"string"==typeof e?e:l(e)}return{get index(){return c},get action(){return d},get location(){return p()},createHref:y,createURL:e=>new URL(y(e),"http://localhost"),encodeLocation(e){let t="string"==typeof e?u(e):e;return{pathname:t.pathname||"",search:t.search||"",hash:t.hash||""}},push(e,a){d=r.Push;let n=m(e,a);c+=1,t.splice(c,t.length,n),i&&h&&h({action:d,location:n,delta:1})},replace(e,a){d=r.Replace;let n=m(e,a);t[c]=n,i&&h&&h({action:d,location:n,delta:0})},go(e){d=r.Pop;let a=f(c+e),n=t[a];c=a,h&&h({action:d,location:n,delta:e})},listen:e=>(h=e,()=>{h=null})}},e.createPath=l,e.createRouter=function(e){const a=e.window?e.window:"undefined"!=typeof window?window:void 0,i=void 0!==a&&void 0!==a.document&&void 0!==a.document.createElement,l=!i;let u;if(n(e.routes.length>0,"You must provide a non-empty routes array to createRouter"),e.mapRouteProperties)u=e.mapRouteProperties;else if(e.detectErrorBoundary){let t=e.detectErrorBoundary;u=e=>({hasErrorBoundary:t(e)})}else u=G;let c,h,v,g={},b=f(e.routes,u,void 0,g),w=e.basename||"/",D=e.unstable_dataStrategy||ce,S=e.unstable_patchRoutesOnMiss,E=t({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},e.future),R=null,x=new Set,A=null,L=null,M=null,j=null!=e.hydrationData,_=p(b,e.history.location,w),k=null;if(null==_&&!S){let t=Re(404,{pathname:e.history.location.pathname}),{matches:r,route:a}=Ee(b);_=r,k={[a.id]:t}}if(_&&S&&!e.hydrationData){dt(_,b,e.history.location.pathname).active&&(_=null)}if(_)if(_.some((e=>e.route.lazy)))h=!1;else if(_.some((e=>e.route.loader)))if(E.v7_partialHydration){let t=e.hydrationData?e.hydrationData.loaderData:null,r=e.hydrationData?e.hydrationData.errors:null,a=e=>!e.route.loader||("function"!=typeof e.route.loader||!0!==e.route.loader.hydrate)&&(t&&void 0!==t[e.route.id]||r&&void 0!==r[e.route.id]);if(r){let e=_.findIndex((e=>void 0!==r[e.route.id]));h=_.slice(0,e+1).every(a)}else h=_.every(a)}else h=null!=e.hydrationData;else h=!0;else h=!1,_=[];let C,U={historyAction:e.history.action,location:e.history.location,matches:_,initialized:h,navigation:Y,restoreScrollPosition:null==e.hydrationData&&null,preventScrollReset:!1,revalidation:"idle",loaderData:e.hydrationData&&e.hydrationData.loaderData||{},actionData:e.hydrationData&&e.hydrationData.actionData||null,errors:e.hydrationData&&e.hydrationData.errors||k,fetchers:new Map,blockers:new Map},T=r.Pop,O=!1,I=!1,H=new Map,F=null,N=!1,B=!1,W=[],$=[],q=new Map,Z=0,ee=-1,ae=new Map,oe=new Set,ie=new Map,ue=new Map,ye=new Set,ve=new Map,ge=new Map,xe=new Map,_e=!1;function ke(e,r){void 0===r&&(r={}),U=t({},U,e);let a=[],n=[];E.v7_fetcherPersist&&U.fetchers.forEach(((e,t)=>{"idle"===e.state&&(ye.has(t)?n.push(t):a.push(t))})),[...x].forEach((e=>e(U,{deletedFetchers:n,unstable_viewTransitionOpts:r.viewTransitionOpts,unstable_flushSync:!0===r.flushSync}))),E.v7_fetcherPersist&&(a.forEach((e=>U.fetchers.delete(e))),n.forEach((e=>Qe(e))))}function Ce(a,n,o){var i,s;let l,{flushSync:u}=void 0===o?{}:o,d=null!=U.actionData&&null!=U.navigation.formMethod&&Ue(U.navigation.formMethod)&&"loading"===U.navigation.state&&!0!==(null==(i=a.state)?void 0:i._isRedirect);l=n.actionData?Object.keys(n.actionData).length>0?n.actionData:null:d?U.actionData:null;let h=n.loaderData?we(U.loaderData,n.loaderData,n.matches||[],n.errors):U.loaderData,f=U.blockers;f.size>0&&(f=new Map(f),f.forEach(((e,t)=>f.set(t,V))));let p,m=!0===O||null!=U.navigation.formMethod&&Ue(U.navigation.formMethod)&&!0!==(null==(s=a.state)?void 0:s._isRedirect);if(c&&(b=c,c=void 0),N||T===r.Pop||(T===r.Push?e.history.push(a,a.state):T===r.Replace&&e.history.replace(a,a.state)),T===r.Pop){let e=H.get(U.location.pathname);e&&e.has(a.pathname)?p={currentLocation:U.location,nextLocation:a}:H.has(a.pathname)&&(p={currentLocation:a,nextLocation:U.location})}else if(I){let e=H.get(U.location.pathname);e?e.add(a.pathname):(e=new Set([a.pathname]),H.set(U.location.pathname,e)),p={currentLocation:U.location,nextLocation:a}}ke(t({},n,{actionData:l,loaderData:h,historyAction:T,location:a,initialized:!0,navigation:Y,revalidation:"idle",restoreScrollPosition:ct(a,n.matches||U.matches),preventScrollReset:m,blockers:f}),{viewTransitionOpts:p,flushSync:!0===u}),T=r.Pop,O=!1,I=!1,N=!1,B=!1,W=[],$=[]}async function Ie(a,n,o){C&&C.abort(),C=null,T=a,N=!0===(o&&o.startUninterruptedRevalidation),function(e,t){if(A&&M){let r=ut(e,t);A[r]=M()}}(U.location,U.matches),O=!0===(o&&o.preventScrollReset),I=!0===(o&&o.enableViewTransition);let i=c||b,s=o&&o.overrideNavigation,l=p(i,n,w),u=!0===(o&&o.flushSync),h=dt(l,i,n.pathname);if(h.active&&h.matches&&(l=h.matches),!l){let{error:e,notFoundMatches:t,route:r}=it(n.pathname);return void Ce(n,{matches:t,loaderData:{},errors:{[r.id]:e}},{flushSync:u})}if(U.initialized&&!B&&function(e,t){if(e.pathname!==t.pathname||e.search!==t.search)return!1;if(""===e.hash)return""!==t.hash;if(e.hash===t.hash)return!0;if(""!==t.hash)return!0;return!1}(U.location,n)&&!(o&&o.submission&&Ue(o.submission.formMethod)))return void Ce(n,{matches:l},{flushSync:u});C=new AbortController;let f,m=me(e.history,n,C.signal,o&&o.submission);if(o&&o.pendingError)f=[Se(l).route.id,{type:d.error,error:o.pendingError}];else if(o&&o.submission&&Ue(o.submission.formMethod)){let t=await async function(e,t,a,n,o,i){void 0===i&&(i={});let s;if(Je(),ke({navigation:Ne(t,a)},{flushSync:!0===i.flushSync}),o){let r=await ht(n,t.pathname,e.signal);if("aborted"===r.type)return{shortCircuited:!0};if("error"===r.type){let{boundaryId:e,error:a}=st(t.pathname,r);return{matches:r.partialMatches,pendingActionResult:[e,{type:d.error,error:a}]}}if(!r.matches){let{notFoundMatches:e,error:r,route:a}=it(t.pathname);return{matches:e,pendingActionResult:[a.id,{type:d.error,error:r}]}}n=r.matches}let l=He(n,t);if(l.route.action||l.route.lazy){if(s=(await Ke("action",e,[l],n))[0],e.signal.aborted)return{shortCircuited:!0}}else s={type:d.error,error:Re(405,{method:e.method,pathname:t.pathname,routeId:l.route.id})};if(je(s)){let t;if(i&&null!=i.replace)t=i.replace;else{t=pe(s.response.headers.get("Location"),new URL(e.url),w)===U.location.pathname+U.location.search}return await qe(e,s,{submission:a,replace:t}),{shortCircuited:!0}}if(Le(s))throw Re(400,{type:"defer-action"});if(Me(s)){let e=Se(n,l.route.id);return!0!==(i&&i.replace)&&(T=r.Push),{matches:n,pendingActionResult:[e.route.id,s]}}return{matches:n,pendingActionResult:[l.route.id,s]}}(m,n,o.submission,l,h.active,{replace:o.replace,flushSync:u});if(t.shortCircuited)return;if(t.pendingActionResult){let[e,r]=t.pendingActionResult;if(Me(r)&&z(r.error)&&404===r.error.status)return C=null,void Ce(n,{matches:t.matches,loaderData:{},errors:{[e]:r.error}})}l=t.matches||l,f=t.pendingActionResult,s=ze(n,o.submission),u=!1,h.active=!1,m=me(e.history,m.url,m.signal)}let{shortCircuited:y,matches:v,loaderData:g,errors:D}=await async function(r,a,n,o,i,s,l,u,d,h,f){let p=i||ze(a,s),m=s||l||Fe(p),y=!(N||E.v7_partialHydration&&d);if(o){if(y){let e=$e(f);ke(t({navigation:p},void 0!==e?{actionData:e}:{}),{flushSync:h})}let e=await ht(n,a.pathname,r.signal);if("aborted"===e.type)return{shortCircuited:!0};if("error"===e.type){let{boundaryId:t,error:r}=st(a.pathname,e);return{matches:e.partialMatches,loaderData:{},errors:{[t]:r}}}if(!e.matches){let{error:e,notFoundMatches:t,route:r}=it(a.pathname);return{matches:t,loaderData:{},errors:{[r.id]:e}}}n=e.matches}let v=c||b,[g,D]=ne(e.history,U,n,m,a,E.v7_partialHydration&&!0===d,E.v7_skipActionErrorRevalidation,B,W,$,ye,ie,oe,v,w,f);if(lt((e=>!(n&&n.some((t=>t.route.id===e)))||g&&g.some((t=>t.route.id===e)))),ee=++Z,0===g.length&&0===D.length){let e=tt();return Ce(a,t({matches:n,loaderData:{},errors:f&&Me(f[1])?{[f[0]]:f[1].error}:null},De(f),e?{fetchers:new Map(U.fetchers)}:{}),{flushSync:h}),{shortCircuited:!0}}if(y){let e={};if(!o){e.navigation=p;let t=$e(f);void 0!==t&&(e.actionData=t)}D.length>0&&(e.fetchers=function(e){return e.forEach((e=>{let t=U.fetchers.get(e.key),r=Be(void 0,t?t.data:void 0);U.fetchers.set(e.key,r)})),new Map(U.fetchers)}(D)),ke(e,{flushSync:h})}D.forEach((e=>{q.has(e.key)&&Ze(e.key),e.controller&&q.set(e.key,e.controller)}));let S=()=>D.forEach((e=>Ze(e.key)));C&&C.signal.addEventListener("abort",S);let{loaderResults:R,fetcherResults:P}=await Ye(U.matches,n,g,D,r);if(r.signal.aborted)return{shortCircuited:!0};C&&C.signal.removeEventListener("abort",S);D.forEach((e=>q.delete(e.key)));let x=Pe([...R,...P]);if(x){if(x.idx>=g.length){let e=D[x.idx-g.length].key;oe.add(e)}return await qe(r,x.result,{replace:u}),{shortCircuited:!0}}let{loaderData:A,errors:L}=be(U,n,g,R,f,D,P,ve);ve.forEach(((e,t)=>{e.subscribe((r=>{(r||e.done)&&ve.delete(t)}))})),E.v7_partialHydration&&d&&U.errors&&Object.entries(U.errors).filter((e=>{let[t]=e;return!g.some((e=>e.route.id===t))})).forEach((e=>{let[t,r]=e;L=Object.assign(L||{},{[t]:r})}));let M=tt(),j=rt(ee),_=M||j||D.length>0;return t({matches:n,loaderData:A,errors:L},_?{fetchers:new Map(U.fetchers)}:{})}(m,n,l,h.active,s,o&&o.submission,o&&o.fetcherSubmission,o&&o.replace,o&&!0===o.initialHydration,u,f);y||(C=null,Ce(n,t({matches:v||l},De(f),{loaderData:g,errors:D})))}function $e(e){return e&&!Me(e[1])?{[e[0]]:e[1].data}:U.actionData?0===Object.keys(U.actionData).length?null:U.actionData:void 0}async function qe(o,l,u){let{submission:c,fetcherSubmission:d,replace:h}=void 0===u?{}:u;l.response.headers.has("X-Remix-Revalidate")&&(B=!0);let f=l.response.headers.get("Location");n(f,"Expected a Location header on the redirect Response"),f=pe(f,new URL(o.url),w);let p=s(U.location,f,{_isRedirect:!0});if(i){let t=!1;if(l.response.headers.has("X-Remix-Reload-Document"))t=!0;else if(X.test(f)){const r=e.history.createURL(f);t=r.origin!==a.location.origin||null==P(r.pathname,w)}if(t)return void(h?a.location.replace(f):a.location.assign(f))}C=null;let m=!0===h?r.Replace:r.Push,{formMethod:y,formAction:v,formEncType:g}=U.navigation;!c&&!d&&y&&v&&g&&(c=Fe(U.navigation));let b=c||d;if(K.has(l.response.status)&&b&&Ue(b.formMethod))await Ie(m,p,{submission:t({},b,{formAction:f}),preventScrollReset:O});else{let e=ze(p,c);await Ie(m,p,{overrideNavigation:e,fetcherSubmission:d,preventScrollReset:O})}}async function Ke(e,t,r,a){try{let n=await de(D,e,t,r,a,g,u);return await Promise.all(n.map(((e,n)=>{if(Ae(e)){let o=e.result;return{type:d.redirect,response:fe(o,t,r[n].route.id,a,w,E.v7_relativeSplatPath)}}return he(e)})))}catch(e){return r.map((()=>({type:d.error,error:e})))}}async function Ye(t,r,a,n,o){let[i,...s]=await Promise.all([a.length?Ke("loader",o,a,r):[],...n.map((t=>{if(t.matches&&t.match&&t.controller){return Ke("loader",me(e.history,t.path,t.controller.signal),[t.match],t.matches).then((e=>e[0]))}return Promise.resolve({type:d.error,error:Re(404,{pathname:t.path})})}))]);return await Promise.all([Te(t,a,i,i.map((()=>o.signal)),!1,U.loaderData),Te(t,n.map((e=>e.match)),s,n.map((e=>e.controller?e.controller.signal:null)),!0)]),{loaderResults:i,fetcherResults:s}}function Je(){B=!0,W.push(...lt()),ie.forEach(((e,t)=>{q.has(t)&&($.push(t),Ze(t))}))}function Ve(e,t,r){void 0===r&&(r={}),U.fetchers.set(e,t),ke({fetchers:new Map(U.fetchers)},{flushSync:!0===(r&&r.flushSync)})}function Xe(e,t,r,a){void 0===a&&(a={});let n=Se(U.matches,t);Qe(e),ke({errors:{[n.route.id]:r},fetchers:new Map(U.fetchers)},{flushSync:!0===(a&&a.flushSync)})}function Ge(e){return E.v7_fetcherPersist&&(ue.set(e,(ue.get(e)||0)+1),ye.has(e)&&ye.delete(e)),U.fetchers.get(e)||J}function Qe(e){let t=U.fetchers.get(e);!q.has(e)||t&&"loading"===t.state&&ae.has(e)||Ze(e),ie.delete(e),ae.delete(e),oe.delete(e),ye.delete(e),U.fetchers.delete(e)}function Ze(e){let t=q.get(e);n(t,"Expected fetch controller: "+e),t.abort(),q.delete(e)}function et(e){for(let t of e){let e=We(Ge(t).data);U.fetchers.set(t,e)}}function tt(){let e=[],t=!1;for(let r of oe){let a=U.fetchers.get(r);n(a,"Expected fetcher: "+r),"loading"===a.state&&(oe.delete(r),e.push(r),t=!0)}return et(e),t}function rt(e){let t=[];for(let[r,a]of ae)if(a0}function at(e){U.blockers.delete(e),ge.delete(e)}function nt(e,t){let r=U.blockers.get(e)||V;n("unblocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"proceeding"===t.state||"blocked"===r.state&&"unblocked"===t.state||"proceeding"===r.state&&"unblocked"===t.state,"Invalid blocker state transition: "+r.state+" -> "+t.state);let a=new Map(U.blockers);a.set(e,t),ke({blockers:a})}function ot(e){let{currentLocation:t,nextLocation:r,historyAction:a}=e;if(0===ge.size)return;ge.size>1&&o(!1,"A router only supports one blocker at a time");let n=Array.from(ge.entries()),[i,s]=n[n.length-1],l=U.blockers.get(i);return l&&"proceeding"===l.state?void 0:s({currentLocation:t,nextLocation:r,historyAction:a})?i:void 0}function it(e){let t=Re(404,{pathname:e}),r=c||b,{matches:a,route:n}=Ee(r);return lt(),{notFoundMatches:a,route:n,error:t}}function st(e,t){return{boundaryId:Se(t.partialMatches).route.id,error:Re(400,{type:"route-discovery",pathname:e,message:null!=t.error&&"message"in t.error?t.error:String(t.error)})}}function lt(e){let t=[];return ve.forEach(((r,a)=>{e&&!e(a)||(r.cancel(),t.push(a),ve.delete(a))})),t}function ut(e,t){if(L){return L(e,t.map((e=>y(e,U.loaderData))))||e.key}return e.key}function ct(e,t){if(A){let r=ut(e,t),a=A[r];if("number"==typeof a)return a}return null}function dt(e,t,r){if(S){if(!e){return{active:!0,matches:m(t,r,w,!0)||[]}}{let a=e[e.length-1].route;if(a.path&&("*"===a.path||a.path.endsWith("/*"))){return{active:!0,matches:m(t,r,w,!0)}}}}return{active:!1,matches:null}}async function ht(e,t,r){let a=e,n=a.length>0?a[a.length-1].route:null;for(;;){let e=null==c,o=c||b;try{await se(S,t,a,o,g,u,xe,r)}catch(e){return{type:"error",error:e,partialMatches:a}}finally{e&&(b=[...b])}if(r.aborted)return{type:"aborted"};let i=p(o,t,w),s=!1;if(i){let e=i[i.length-1].route;if(e.index)return{type:"success",matches:i};if(e.path&&e.path.length>0){if("*"!==e.path)return{type:"success",matches:i};s=!0}}let l=m(o,t,w,!0);if(!l||a.map((e=>e.route.id)).join("-")===l.map((e=>e.route.id)).join("-"))return{type:"success",matches:s?i:null};if(a=l,n=a[a.length-1].route,"*"===n.path)return{type:"success",matches:a}}}return v={get basename(){return w},get future(){return E},get state(){return U},get routes(){return b},get window(){return a},initialize:function(){if(R=e.history.listen((t=>{let{action:r,location:a,delta:n}=t;if(_e)return void(_e=!1);o(0===ge.size||null!=n,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let i=ot({currentLocation:U.location,nextLocation:a,historyAction:r});return i&&null!=n?(_e=!0,e.history.go(-1*n),void nt(i,{state:"blocked",location:a,proceed(){nt(i,{state:"proceeding",proceed:void 0,reset:void 0,location:a}),e.history.go(n)},reset(){let e=new Map(U.blockers);e.set(i,V),ke({blockers:e})}})):Ie(r,a)})),i){!function(e,t){try{let r=e.sessionStorage.getItem(Q);if(r){let e=JSON.parse(r);for(let[r,a]of Object.entries(e||{}))a&&Array.isArray(a)&&t.set(r,new Set(a||[]))}}catch(e){}}(a,H);let e=()=>function(e,t){if(t.size>0){let r={};for(let[e,a]of t)r[e]=[...a];try{e.sessionStorage.setItem(Q,JSON.stringify(r))}catch(e){o(!1,"Failed to save applied view transitions in sessionStorage ("+e+").")}}}(a,H);a.addEventListener("pagehide",e),F=()=>a.removeEventListener("pagehide",e)}return U.initialized||Ie(r.Pop,U.location,{initialHydration:!0}),v},subscribe:function(e){return x.add(e),()=>x.delete(e)},enableScrollRestoration:function(e,t,r){if(A=e,M=t,L=r||null,!j&&U.navigation===Y){j=!0;let e=ct(U.location,U.matches);null!=e&&ke({restoreScrollPosition:e})}return()=>{A=null,M=null,L=null}},navigate:async function a(n,o){if("number"==typeof n)return void e.history.go(n);let i=te(U.location,U.matches,w,E.v7_prependBasename,n,E.v7_relativeSplatPath,null==o?void 0:o.fromRouteId,null==o?void 0:o.relative),{path:l,submission:u,error:c}=re(E.v7_normalizeFormMethod,!1,i,o),d=U.location,h=s(U.location,l,o&&o.state);h=t({},h,e.history.encodeLocation(h));let f=o&&null!=o.replace?o.replace:void 0,p=r.Push;!0===f?p=r.Replace:!1===f||null!=u&&Ue(u.formMethod)&&u.formAction===U.location.pathname+U.location.search&&(p=r.Replace);let m=o&&"preventScrollReset"in o?!0===o.preventScrollReset:void 0,y=!0===(o&&o.unstable_flushSync),v=ot({currentLocation:d,nextLocation:h,historyAction:p});if(!v)return await Ie(p,h,{submission:u,pendingError:c,preventScrollReset:m,replace:o&&o.replace,enableViewTransition:o&&o.unstable_viewTransition,flushSync:y});nt(v,{state:"blocked",location:h,proceed(){nt(v,{state:"proceeding",proceed:void 0,reset:void 0,location:h}),a(n,o)},reset(){let e=new Map(U.blockers);e.set(v,V),ke({blockers:e})}})},fetch:function(t,r,a,o){if(l)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");q.has(t)&&Ze(t);let i=!0===(o&&o.unstable_flushSync),s=c||b,u=te(U.location,U.matches,w,E.v7_prependBasename,a,E.v7_relativeSplatPath,r,null==o?void 0:o.relative),d=p(s,u,w),h=dt(d,s,u);if(h.active&&h.matches&&(d=h.matches),!d)return void Xe(t,r,Re(404,{pathname:u}),{flushSync:i});let{path:f,submission:m,error:y}=re(E.v7_normalizeFormMethod,!0,u,o);if(y)return void Xe(t,r,y,{flushSync:i});let v=He(d,f);O=!0===(o&&o.preventScrollReset),m&&Ue(m.formMethod)?async function(t,r,a,o,i,s,l,u){function d(e){if(!e.route.action&&!e.route.lazy){let e=Re(405,{method:u.formMethod,pathname:a,routeId:r});return Xe(t,r,e,{flushSync:l}),!0}return!1}if(Je(),ie.delete(t),!s&&d(o))return;let h=U.fetchers.get(t);Ve(t,function(e,t){return{state:"submitting",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t?t.data:void 0}}(u,h),{flushSync:l});let f=new AbortController,m=me(e.history,a,f.signal,u);if(s){let e=await ht(i,a,m.signal);if("aborted"===e.type)return;if("error"===e.type){let{error:n}=st(a,e);return void Xe(t,r,n,{flushSync:l})}if(!e.matches)return void Xe(t,r,Re(404,{pathname:a}),{flushSync:l});if(d(o=He(i=e.matches,a)))return}q.set(t,f);let y=Z,v=(await Ke("action",m,[o],i))[0];if(m.signal.aborted)return void(q.get(t)===f&&q.delete(t));if(E.v7_fetcherPersist&&ye.has(t)){if(je(v)||Me(v))return void Ve(t,We(void 0))}else{if(je(v))return q.delete(t),ee>y?void Ve(t,We(void 0)):(oe.add(t),Ve(t,Be(u)),qe(m,v,{fetcherSubmission:u}));if(Me(v))return void Xe(t,r,v.error)}if(Le(v))throw Re(400,{type:"defer-action"});let g=U.navigation.location||U.location,D=me(e.history,g,f.signal),S=c||b,R="idle"!==U.navigation.state?p(S,U.navigation.location,w):U.matches;n(R,"Didn't find any matches after fetcher action");let P=++Z;ae.set(t,P);let x=Be(u,v.data);U.fetchers.set(t,x);let[A,L]=ne(e.history,U,R,u,g,!1,E.v7_skipActionErrorRevalidation,B,W,$,ye,ie,oe,S,w,[o.route.id,v]);L.filter((e=>e.key!==t)).forEach((e=>{let t=e.key,r=U.fetchers.get(t),a=Be(void 0,r?r.data:void 0);U.fetchers.set(t,a),q.has(t)&&Ze(t),e.controller&&q.set(t,e.controller)})),ke({fetchers:new Map(U.fetchers)});let M=()=>L.forEach((e=>Ze(e.key)));f.signal.addEventListener("abort",M);let{loaderResults:j,fetcherResults:_}=await Ye(U.matches,R,A,L,D);if(f.signal.aborted)return;f.signal.removeEventListener("abort",M),ae.delete(t),q.delete(t),L.forEach((e=>q.delete(e.key)));let k=Pe([...j,..._]);if(k){if(k.idx>=A.length){let e=L[k.idx-A.length].key;oe.add(e)}return qe(D,k.result)}let{loaderData:O,errors:I}=be(U,U.matches,A,j,void 0,L,_,ve);if(U.fetchers.has(t)){let e=We(v.data);U.fetchers.set(t,e)}rt(P),"loading"===U.navigation.state&&P>ee?(n(T,"Expected pending action"),C&&C.abort(),Ce(U.navigation.location,{matches:R,loaderData:O,errors:I,fetchers:new Map(U.fetchers)})):(ke({errors:I,loaderData:we(U.loaderData,O,R,I),fetchers:new Map(U.fetchers)}),B=!1)}(t,r,f,v,d,h.active,i,m):(ie.set(t,{routeId:r,path:f}),async function(t,r,a,o,i,s,l,u){let c=U.fetchers.get(t);Ve(t,Be(u,c?c.data:void 0),{flushSync:l});let d=new AbortController,h=me(e.history,a,d.signal);if(s){let e=await ht(i,a,h.signal);if("aborted"===e.type)return;if("error"===e.type){let{error:n}=st(a,e);return void Xe(t,r,n,{flushSync:l})}if(!e.matches)return void Xe(t,r,Re(404,{pathname:a}),{flushSync:l});o=He(i=e.matches,a)}q.set(t,d);let f=Z,p=(await Ke("loader",h,[o],i))[0];Le(p)&&(p=await Oe(p,h.signal,!0)||p);q.get(t)===d&&q.delete(t);if(h.signal.aborted)return;if(ye.has(t))return void Ve(t,We(void 0));if(je(p))return ee>f?void Ve(t,We(void 0)):(oe.add(t),void await qe(h,p));if(Me(p))return void Xe(t,r,p.error);n(!Le(p),"Unhandled fetcher deferred data"),Ve(t,We(p.data))}(t,r,f,v,d,h.active,i,m))},revalidate:function(){Je(),ke({revalidation:"loading"}),"submitting"!==U.navigation.state&&("idle"!==U.navigation.state?Ie(T||U.historyAction,U.navigation.location,{overrideNavigation:U.navigation}):Ie(U.historyAction,U.location,{startUninterruptedRevalidation:!0}))},createHref:t=>e.history.createHref(t),encodeLocation:t=>e.history.encodeLocation(t),getFetcher:Ge,deleteFetcher:function(e){if(E.v7_fetcherPersist){let t=(ue.get(e)||0)-1;t<=0?(ue.delete(e),ye.add(e)):ue.set(e,t)}else Qe(e);ke({fetchers:new Map(U.fetchers)})},dispose:function(){R&&R(),F&&F(),x.clear(),C&&C.abort(),U.fetchers.forEach(((e,t)=>Qe(t))),U.blockers.forEach(((e,t)=>at(t)))},getBlocker:function(e,t){let r=U.blockers.get(e)||V;return ge.get(e)!==t&&ge.set(e,t),r},deleteBlocker:at,patchRoutes:function(e,t){let r=null==c;le(e,t,c||b,g,u),r&&(b=[...b],ke({}))},_internalFetchControllers:q,_internalActiveDeferreds:ve,_internalSetRoutes:function(e){g={},c=f(e,u,void 0,g)}},v},e.createStaticHandler=function(e,r){n(e.length>0,"You must provide a non-empty routes array to createStaticHandler");let a,o={},i=(r?r.basename:null)||"/";if(null!=r&&r.mapRouteProperties)a=r.mapRouteProperties;else if(null!=r&&r.detectErrorBoundary){let e=r.detectErrorBoundary;a=t=>({hasErrorBoundary:e(t)})}else a=G;let u=t({v7_relativeSplatPath:!1,v7_throwAbortReason:!1},r?r.future:null),c=f(e,a,void 0,o);async function h(e,r,a,o,i,s,l){n(e.signal,"query()/queryRoute() requests must contain an AbortController signal");try{if(Ue(e.method.toLowerCase())){let n=await async function(e,r,a,n,o,i,s){let l;if(a.route.action||a.route.lazy){l=(await y("action",e,[a],r,s,n,o))[0],e.signal.aborted&&ee(e,s,u)}else{let t=Re(405,{method:e.method,pathname:new URL(e.url).pathname,routeId:a.route.id});if(s)throw t;l={type:d.error,error:t}}if(je(l))throw new Response(null,{status:l.response.status,headers:{Location:l.response.headers.get("Location")}});if(Le(l)){let e=Re(400,{type:"defer-action"});if(s)throw e;l={type:d.error,error:e}}if(s){if(Me(l))throw l.error;return{matches:[a],loaderData:{},actionData:{[a.route.id]:l.data},errors:null,statusCode:200,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}let c=new Request(e.url,{headers:e.headers,redirect:e.redirect,signal:e.signal});if(Me(l)){let e=i?a:Se(r,a.route.id);return t({},await m(c,r,n,o,i,null,[e.route.id,l]),{statusCode:z(l.error)?l.error.status:null!=l.statusCode?l.statusCode:500,actionData:null,actionHeaders:t({},l.headers?{[a.route.id]:l.headers}:{})})}return t({},await m(c,r,n,o,i,null),{actionData:{[a.route.id]:l.data}},l.statusCode?{statusCode:l.statusCode}:{},{actionHeaders:l.headers?{[a.route.id]:l.headers}:{}})}(e,a,l||He(a,r),o,i,s,null!=l);return n}let n=await m(e,a,o,i,s,l);return ke(n)?n:t({},n,{actionData:null,actionHeaders:{}})}catch(e){if(function(e){return null!=e&&"object"==typeof e&&"type"in e&&"result"in e&&(e.type===d.data||e.type===d.error)}(e)&&ke(e.result)){if(e.type===d.error)throw e.result;return e.result}if(function(e){if(!ke(e))return!1;let t=e.status,r=e.headers.get("Location");return t>=300&&t<=399&&null!=r}(e))return e;throw e}}async function m(e,r,a,n,o,i,s){let l=null!=i;if(l&&(null==i||!i.route.loader)&&(null==i||!i.route.lazy))throw Re(400,{method:e.method,pathname:new URL(e.url).pathname,routeId:null==i?void 0:i.route.id});let c=(i?[i]:s&&Me(s[1])?ae(r,s[0]):r).filter((e=>e.route.loader||e.route.lazy));if(0===c.length)return{matches:r,loaderData:r.reduce(((e,t)=>Object.assign(e,{[t.route.id]:null})),{}),errors:s&&Me(s[1])?{[s[0]]:s[1].error}:null,statusCode:200,loaderHeaders:{},activeDeferreds:null};let d=await y("loader",e,c,r,l,a,n);e.signal.aborted&&ee(e,l,u);let h=new Map,f=ge(r,c,d,s,h,o),p=new Set(c.map((e=>e.route.id)));return r.forEach((e=>{p.has(e.route.id)||(f.loaderData[e.route.id]=null)})),t({},f,{matches:r,activeDeferreds:h.size>0?Object.fromEntries(h.entries()):null})}async function y(e,t,r,n,s,l,c){let d=await de(c||ce,e,t,r,n,o,a,l);return await Promise.all(d.map(((e,a)=>{if(Ae(e)){throw fe(e.result,t,r[a].route.id,n,i,u.v7_relativeSplatPath)}if(ke(e.result)&&s)throw e;return he(e)})))}return{dataRoutes:c,query:async function(e,r){let{requestContext:a,skipLoaderErrorBubbling:n,unstable_dataStrategy:o}=void 0===r?{}:r,u=new URL(e.url),d=e.method,f=s("",l(u),null,"default"),m=p(c,f,i);if(!Ce(d)&&"HEAD"!==d){let e=Re(405,{method:d}),{matches:t,route:r}=Ee(c);return{basename:i,location:f,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(!m){let e=Re(404,{pathname:f.pathname}),{matches:t,route:r}=Ee(c);return{basename:i,location:f,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}let y=await h(e,f,m,a,o||null,!0===n,null);return ke(y)?y:t({location:f,basename:i},y)},queryRoute:async function(e,t){let{routeId:r,requestContext:a,unstable_dataStrategy:n}=void 0===t?{}:t,o=new URL(e.url),u=e.method,d=s("",l(o),null,"default"),f=p(c,d,i);if(!Ce(u)&&"HEAD"!==u&&"OPTIONS"!==u)throw Re(405,{method:u});if(!f)throw Re(404,{pathname:d.pathname});let m=r?f.find((e=>e.route.id===r)):He(f,d);if(r&&!m)throw Re(403,{pathname:d.pathname,routeId:r});if(!m)throw Re(404,{pathname:d.pathname});let y=await h(e,d,f,a,n||null,!1,m);if(ke(y))return y;let v=y.errors?Object.values(y.errors)[0]:void 0;if(void 0!==v)throw v;if(y.actionData)return Object.values(y.actionData)[0];if(y.loaderData){var g;let e=Object.values(y.loaderData)[0];return null!=(g=y.activeDeferreds)&&g[m.route.id]&&(e[Z]=y.activeDeferreds[m.route.id]),e}}}},e.defer=function(e,t){return void 0===t&&(t={}),new O(e,"number"==typeof t?{status:t}:t)},e.generatePath=function(e,t){void 0===t&&(t={});let r=e;r.endsWith("*")&&"*"!==r&&!r.endsWith("/*")&&(o(!1,'Route path "'+r+'" will be treated as if it were "'+r.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+r.replace(/\*$/,"/*")+'".'),r=r.replace(/\*$/,"/*"));const a=r.startsWith("/")?"/":"",i=e=>null==e?"":"string"==typeof e?e:String(e);return a+r.split(/\/+/).map(((e,r,a)=>{if(r===a.length-1&&"*"===e){return i(t["*"])}const o=e.match(/^:([\w-]+)(\??)$/);if(o){const[,e,r]=o;let a=t[e];return n("?"===r||null!=a,'Missing ":'+e+'" param'),i(a)}return e.replace(/\?$/g,"")})).filter((e=>!!e)).join("/")},e.getStaticContextFromError=function(e,r,a){return t({},r,{statusCode:z(a)?a.status:500,errors:{[r._deepestRenderedBoundaryId||e[0].id]:a}})},e.getToPathname=function(e){return""===e||""===e.pathname?"/":"string"==typeof e?u(e).pathname:e.pathname},e.isDeferredData=_e,e.isRouteErrorResponse=z,e.joinPaths=_,e.json=function(e,r){void 0===r&&(r={});let a="number"==typeof r?{status:r}:r,n=new Headers(a.headers);return n.has("Content-Type")||n.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),t({},a,{headers:n}))},e.matchPath=E,e.matchRoutes=p,e.normalizePathname=k,e.parsePath=u,e.redirect=H,e.redirectDocument=(e,t)=>{let r=H(e,t);return r.headers.set("X-Remix-Reload-Document","true"),r},e.resolvePath=x,e.resolveTo=j,e.stripBasename=P,Object.defineProperty(e,"__esModule",{value:!0})})); +//# sourceMappingURL=router.umd.min.js.map diff --git a/node_modules/@remix-run/router/dist/router.umd.min.js.map b/node_modules/@remix-run/router/dist/router.umd.min.js.map new file mode 100644 index 0000000000..a361da2190 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"router.umd.min.js","sources":["../history.ts","../utils.ts","../router.ts"],"sourcesContent":["////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Actions represent the type of change to a location value.\n */\nexport enum Action {\n /**\n * A POP indicates a change to an arbitrary index in the history stack, such\n * as a back or forward navigation. It does not describe the direction of the\n * navigation, only that the current index changed.\n *\n * Note: This is the default action for newly created history objects.\n */\n Pop = \"POP\",\n\n /**\n * A PUSH indicates a new entry being added to the history stack, such as when\n * a link is clicked and a new page loads. When this happens, all subsequent\n * entries in the stack are lost.\n */\n Push = \"PUSH\",\n\n /**\n * A REPLACE indicates the entry at the current index in the history stack\n * being replaced by a new one.\n */\n Replace = \"REPLACE\",\n}\n\n/**\n * The pathname, search, and hash values of a URL.\n */\nexport interface Path {\n /**\n * A URL pathname, beginning with a /.\n */\n pathname: string;\n\n /**\n * A URL search string, beginning with a ?.\n */\n search: string;\n\n /**\n * A URL fragment identifier, beginning with a #.\n */\n hash: string;\n}\n\n// TODO: (v7) Change the Location generic default from `any` to `unknown` and\n// remove Remix `useLocation` wrapper.\n\n/**\n * An entry in a history stack. A location contains information about the\n * URL path, as well as possibly some arbitrary state and a key.\n */\nexport interface Location extends Path {\n /**\n * A value of arbitrary data associated with this location.\n */\n state: State;\n\n /**\n * A unique string associated with this location. May be used to safely store\n * and retrieve data in some other storage API, like `localStorage`.\n *\n * Note: This value is always \"default\" on the initial location.\n */\n key: string;\n}\n\n/**\n * A change to the current location.\n */\nexport interface Update {\n /**\n * The action that triggered the change.\n */\n action: Action;\n\n /**\n * The new location.\n */\n location: Location;\n\n /**\n * The delta between this location and the former location in the history stack\n */\n delta: number | null;\n}\n\n/**\n * A function that receives notifications about location changes.\n */\nexport interface Listener {\n (update: Update): void;\n}\n\n/**\n * Describes a location that is the destination of some navigation, either via\n * `history.push` or `history.replace`. This may be either a URL or the pieces\n * of a URL path.\n */\nexport type To = string | Partial;\n\n/**\n * A history is an interface to the navigation stack. The history serves as the\n * source of truth for the current location, as well as provides a set of\n * methods that may be used to change it.\n *\n * It is similar to the DOM's `window.history` object, but with a smaller, more\n * focused API.\n */\nexport interface History {\n /**\n * The last action that modified the current location. This will always be\n * Action.Pop when a history instance is first created. This value is mutable.\n */\n readonly action: Action;\n\n /**\n * The current location. This value is mutable.\n */\n readonly location: Location;\n\n /**\n * Returns a valid href for the given `to` value that may be used as\n * the value of an attribute.\n *\n * @param to - The destination URL\n */\n createHref(to: To): string;\n\n /**\n * Returns a URL for the given `to` value\n *\n * @param to - The destination URL\n */\n createURL(to: To): URL;\n\n /**\n * Encode a location the same way window.history would do (no-op for memory\n * history) so we ensure our PUSH/REPLACE navigations for data routers\n * behave the same as POP\n *\n * @param to Unencoded path\n */\n encodeLocation(to: To): Path;\n\n /**\n * Pushes a new location onto the history stack, increasing its length by one.\n * If there were any entries in the stack after the current one, they are\n * lost.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n push(to: To, state?: any): void;\n\n /**\n * Replaces the current location in the history stack with a new one. The\n * location that was replaced will no longer be available.\n *\n * @param to - The new URL\n * @param state - Data to associate with the new location\n */\n replace(to: To, state?: any): void;\n\n /**\n * Navigates `n` entries backward/forward in the history stack relative to the\n * current index. For example, a \"back\" navigation would use go(-1).\n *\n * @param delta - The delta in the stack index\n */\n go(delta: number): void;\n\n /**\n * Sets up a listener that will be called whenever the current location\n * changes.\n *\n * @param listener - A function that will be called when the location changes\n * @returns unlisten - A function that may be used to stop listening\n */\n listen(listener: Listener): () => void;\n}\n\ntype HistoryState = {\n usr: any;\n key?: string;\n idx: number;\n};\n\nconst PopStateEventType = \"popstate\";\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Memory History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A user-supplied object that describes a location. Used when providing\n * entries to `createMemoryHistory` via its `initialEntries` option.\n */\nexport type InitialEntry = string | Partial;\n\nexport type MemoryHistoryOptions = {\n initialEntries?: InitialEntry[];\n initialIndex?: number;\n v5Compat?: boolean;\n};\n\n/**\n * A memory history stores locations in memory. This is useful in stateful\n * environments where there is no web browser, such as node tests or React\n * Native.\n */\nexport interface MemoryHistory extends History {\n /**\n * The current index in the history stack.\n */\n readonly index: number;\n}\n\n/**\n * Memory history stores the current location in memory. It is designed for use\n * in stateful non-browser environments like tests and React Native.\n */\nexport function createMemoryHistory(\n options: MemoryHistoryOptions = {}\n): MemoryHistory {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries: Location[]; // Declare so we can access from createMemoryLocation\n entries = initialEntries.map((entry, index) =>\n createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index === 0 ? \"default\" : undefined\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n function clampIndex(n: number): number {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation(): Location {\n return entries[index];\n }\n function createMemoryLocation(\n to: To,\n state: any = null,\n key?: string\n ): Location {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n\n function createHref(to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n let history: MemoryHistory = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref,\n createURL(to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation(to: To) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\",\n };\n },\n push(to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn: Listener) {\n listener = fn;\n return () => {\n listener = null;\n };\n },\n };\n\n return history;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Browser History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A browser history stores the current location in regular URLs in a web\n * browser environment. This is the standard for most web apps and provides the\n * cleanest URLs the browser's address bar.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory\n */\nexport interface BrowserHistory extends UrlHistory {}\n\nexport type BrowserHistoryOptions = UrlHistoryOptions;\n\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */\nexport function createBrowserHistory(\n options: BrowserHistoryOptions = {}\n): BrowserHistory {\n function createBrowserLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let { pathname, search, hash } = window.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createBrowserHref(window: Window, to: To) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Hash History\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A hash history stores the current location in the fragment identifier portion\n * of the URL in a web browser environment.\n *\n * This is ideal for apps that do not control the server for some reason\n * (because the fragment identifier is never sent to the server), including some\n * shared hosting environments that do not provide fine-grained controls over\n * which pages are served at which URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory\n */\nexport interface HashHistory extends UrlHistory {}\n\nexport type HashHistoryOptions = UrlHistoryOptions;\n\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */\nexport function createHashHistory(\n options: HashHistoryOptions = {}\n): HashHistory {\n function createHashLocation(\n window: Window,\n globalHistory: Window[\"history\"]\n ) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n } = parsePath(window.location.hash.substr(1));\n\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route () since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n (globalHistory.state && globalHistory.state.usr) || null,\n (globalHistory.state && globalHistory.state.key) || \"default\"\n );\n }\n\n function createHashHref(window: Window, to: To) {\n let base = window.document.querySelector(\"base\");\n let href = \"\";\n\n if (base && base.getAttribute(\"href\")) {\n let url = window.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n\n function validateHashLocation(location: Location, to: To) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region UTILS\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @private\n */\nexport function invariant(value: boolean, message?: string): asserts value;\nexport function invariant(\n value: T | null | undefined,\n message?: string\n): asserts value is T;\nexport function invariant(value: any, message?: string) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\n\nexport function warning(cond: any, message: string) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience, so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\n\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n\n/**\n * For browser-based histories, we combine the state and key into an object\n */\nfunction getHistoryState(location: Location, index: number): HistoryState {\n return {\n usr: location.state,\n key: location.key,\n idx: index,\n };\n}\n\n/**\n * Creates a Location object with a unique key from the given Path\n */\nexport function createLocation(\n current: string | Location,\n to: To,\n state: any = null,\n key?: string\n): Readonly {\n let location: Readonly = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...(typeof to === \"string\" ? parsePath(to) : to),\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: (to && (to as Location).key) || key || createKey(),\n };\n return location;\n}\n\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */\nexport function createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n}: Partial) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */\nexport function parsePath(path: string): Partial {\n let parsedPath: Partial = {};\n\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n\n if (path) {\n parsedPath.pathname = path;\n }\n }\n\n return parsedPath;\n}\n\nexport interface UrlHistory extends History {}\n\nexport type UrlHistoryOptions = {\n window?: Window;\n v5Compat?: boolean;\n};\n\nfunction getUrlBasedHistory(\n getLocation: (window: Window, globalHistory: Window[\"history\"]) => Location,\n createHref: (window: Window, to: To) => string,\n validateLocation: ((location: Location, to: To) => void) | null,\n options: UrlHistoryOptions = {}\n): UrlHistory {\n let { window = document.defaultView!, v5Compat = false } = options;\n let globalHistory = window.history;\n let action = Action.Pop;\n let listener: Listener | null = null;\n\n let index = getIndex()!;\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n\n function getIndex(): number {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n\n function push(to: To, state?: any) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window.location.assign(url);\n }\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n\n function replace(to: To, state?: any) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n\n function createURL(to: To): URL {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base =\n window.location.origin !== \"null\"\n ? window.location.origin\n : window.location.href;\n\n let href = typeof to === \"string\" ? to : createPath(to);\n // Treating this as a full URL will strip any trailing spaces so we need to\n // pre-encode them since they might be part of a matching splat param from\n // an ancestor route\n href = href.replace(/ $/, \"%20\");\n invariant(\n base,\n `No window.location.(origin|href) available to create URL for href: ${href}`\n );\n return new URL(href, base);\n }\n\n let history: History = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window, globalHistory);\n },\n listen(fn: Listener) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n\n return () => {\n window.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref(window, to);\n },\n createURL,\n encodeLocation(to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n },\n push,\n replace,\n go(n) {\n return globalHistory.go(n);\n },\n };\n\n return history;\n}\n\n//#endregion\n","import type { Location, Path, To } from \"./history\";\nimport { invariant, parsePath, warning } from \"./history\";\n\n/**\n * Map of routeId -> data returned from a loader/action/error\n */\nexport interface RouteData {\n [routeId: string]: any;\n}\n\nexport enum ResultType {\n data = \"data\",\n deferred = \"deferred\",\n redirect = \"redirect\",\n error = \"error\",\n}\n\n/**\n * Successful result from a loader or action\n */\nexport interface SuccessResult {\n type: ResultType.data;\n data: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Successful defer() result from a loader or action\n */\nexport interface DeferredResult {\n type: ResultType.deferred;\n deferredData: DeferredData;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Redirect result from a loader or action\n */\nexport interface RedirectResult {\n type: ResultType.redirect;\n // We keep the raw Response for redirects so we can return it verbatim\n response: Response;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: unknown;\n statusCode?: number;\n headers?: Headers;\n}\n\n/**\n * Result from a loader or action - potentially successful or unsuccessful\n */\nexport type DataResult =\n | SuccessResult\n | DeferredResult\n | RedirectResult\n | ErrorResult;\n\n/**\n * Result from a loader or action called via dataStrategy\n */\nexport interface HandlerResult {\n type: \"data\" | \"error\";\n result: unknown; // data, Error, Response, DeferredData\n status?: number;\n}\n\ntype LowerCaseFormMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\ntype UpperCaseFormMethod = Uppercase;\n\n/**\n * Users can specify either lowercase or uppercase form methods on ``,\n * useSubmit(), ``, etc.\n */\nexport type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;\n\n/**\n * Active navigation/fetcher form methods are exposed in lowercase on the\n * RouterState\n */\nexport type FormMethod = LowerCaseFormMethod;\nexport type MutationFormMethod = Exclude;\n\n/**\n * In v7, active navigation/fetcher form methods are exposed in uppercase on the\n * RouterState. This is to align with the normalization done via fetch().\n */\nexport type V7_FormMethod = UpperCaseFormMethod;\nexport type V7_MutationFormMethod = Exclude;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\"\n | \"application/json\"\n | \"text/plain\";\n\n// Thanks https://github.com/sindresorhus/type-fest!\ntype JsonObject = { [Key in string]: JsonValue } & {\n [Key in string]?: JsonValue | undefined;\n};\ntype JsonArray = JsonValue[] | readonly JsonValue[];\ntype JsonPrimitive = string | number | boolean | null;\ntype JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport type Submission =\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n json: undefined;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: JsonValue;\n text: undefined;\n }\n | {\n formMethod: FormMethod | V7_FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: undefined;\n json: undefined;\n text: string;\n };\n\n/**\n * @private\n * Arguments passed to route loader/action functions. Same for now but we keep\n * this as a private implementation detail in case they diverge in the future.\n */\ninterface DataFunctionArgs {\n request: Request;\n params: Params;\n context?: Context;\n}\n\n// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:\n// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs\n// Also, make them a type alias instead of an interface\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs\n extends DataFunctionArgs {}\n\n/**\n * Loaders and actions can return anything except `undefined` (`null` is a\n * valid return value if there is no data to return). Responses are preferred\n * and will ease any future migration to Remix\n */\ntype DataFunctionValue = Response | NonNullable | null;\n\ntype DataFunctionReturnValue = Promise | DataFunctionValue;\n\n/**\n * Route loader function signature\n */\nexport type LoaderFunction = {\n (\n args: LoaderFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n} & { hydrate?: boolean };\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (\n args: ActionFunctionArgs,\n handlerCtx?: unknown\n ): DataFunctionReturnValue;\n}\n\n/**\n * Arguments passed to shouldRevalidate function\n */\nexport interface ShouldRevalidateFunctionArgs {\n currentUrl: URL;\n currentParams: AgnosticDataRouteMatch[\"params\"];\n nextUrl: URL;\n nextParams: AgnosticDataRouteMatch[\"params\"];\n formMethod?: Submission[\"formMethod\"];\n formAction?: Submission[\"formAction\"];\n formEncType?: Submission[\"formEncType\"];\n text?: Submission[\"text\"];\n formData?: Submission[\"formData\"];\n json?: Submission[\"json\"];\n actionStatus?: number;\n actionResult?: any;\n defaultShouldRevalidate: boolean;\n}\n\n/**\n * Route shouldRevalidate function signature. This runs after any submission\n * (navigation or fetcher), so we flatten the navigation/fetcher submission\n * onto the arguments. It shouldn't matter whether it came from a navigation\n * or a fetcher, what really matters is the URLs and the formData since loaders\n * have to re-run based on the data models that were potentially mutated.\n */\nexport interface ShouldRevalidateFunction {\n (args: ShouldRevalidateFunctionArgs): boolean;\n}\n\n/**\n * Function provided by the framework-aware layers to set `hasErrorBoundary`\n * from the framework-aware `errorElement` prop\n *\n * @deprecated Use `mapRouteProperties` instead\n */\nexport interface DetectErrorBoundaryFunction {\n (route: AgnosticRouteObject): boolean;\n}\n\nexport interface DataStrategyMatch\n extends AgnosticRouteMatch {\n shouldLoad: boolean;\n resolve: (\n handlerOverride?: (\n handler: (ctx?: unknown) => DataFunctionReturnValue\n ) => Promise\n ) => Promise;\n}\n\nexport interface DataStrategyFunctionArgs\n extends DataFunctionArgs {\n matches: DataStrategyMatch[];\n}\n\nexport interface DataStrategyFunction {\n (args: DataStrategyFunctionArgs): Promise;\n}\n\nexport interface AgnosticPatchRoutesOnMissFunction<\n M extends AgnosticRouteMatch = AgnosticRouteMatch\n> {\n (opts: {\n path: string;\n matches: M[];\n patch: (routeId: string | null, children: AgnosticRouteObject[]) => void;\n }): void | Promise;\n}\n\n/**\n * Function provided by the framework-aware layers to set any framework-specific\n * properties from framework-agnostic properties\n */\nexport interface MapRoutePropertiesFunction {\n (route: AgnosticRouteObject): {\n hasErrorBoundary: boolean;\n } & Record;\n}\n\n/**\n * Keys we cannot change from within a lazy() function. We spread all other keys\n * onto the route. Either they're meaningful to the router, or they'll get\n * ignored.\n */\nexport type ImmutableRouteKey =\n | \"lazy\"\n | \"caseSensitive\"\n | \"path\"\n | \"id\"\n | \"index\"\n | \"children\";\n\nexport const immutableRouteKeys = new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\",\n]);\n\ntype RequireOne = Exclude<\n {\n [K in keyof T]: K extends Key ? Omit & Required> : never;\n }[keyof T],\n undefined\n>;\n\n/**\n * lazy() function to load a route definition, which can add non-matching\n * related properties to a route\n */\nexport interface LazyRouteFunction {\n (): Promise>>;\n}\n\n/**\n * Base RouteObject with common props shared by all types of routes\n */\ntype AgnosticBaseRouteObject = {\n caseSensitive?: boolean;\n path?: string;\n id?: string;\n loader?: LoaderFunction | boolean;\n action?: ActionFunction | boolean;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\n lazy?: LazyRouteFunction;\n};\n\n/**\n * Index routes must not have children\n */\nexport type AgnosticIndexRouteObject = AgnosticBaseRouteObject & {\n children?: undefined;\n index: true;\n};\n\n/**\n * Non-index routes may have children, but cannot have index\n */\nexport type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & {\n children?: AgnosticRouteObject[];\n index?: false;\n};\n\n/**\n * A route object represents a logical route, with (optionally) its child\n * routes organized in a tree-like structure.\n */\nexport type AgnosticRouteObject =\n | AgnosticIndexRouteObject\n | AgnosticNonIndexRouteObject;\n\nexport type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & {\n id: string;\n};\n\nexport type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & {\n children?: AgnosticDataRouteObject[];\n id: string;\n};\n\n/**\n * A data route object, which is just a RouteObject with a required unique ID\n */\nexport type AgnosticDataRouteObject =\n | AgnosticDataIndexRouteObject\n | AgnosticDataNonIndexRouteObject;\n\nexport type RouteManifest = Record;\n\n// Recursive helper for finding path parameters in the absence of wildcards\ntype _PathParam =\n // split path into individual path segments\n Path extends `${infer L}/${infer R}`\n ? _PathParam | _PathParam\n : // find params after `:`\n Path extends `:${infer Param}`\n ? Param extends `${infer Optional}?`\n ? Optional\n : Param\n : // otherwise, there aren't any params present\n never;\n\n/**\n * Examples:\n * \"/a/b/*\" -> \"*\"\n * \":a\" -> \"a\"\n * \"/a/:b\" -> \"b\"\n * \"/a/blahblahblah:b\" -> \"b\"\n * \"/:a/:b\" -> \"a\" | \"b\"\n * \"/:a/b/:c/*\" -> \"a\" | \"c\" | \"*\"\n */\nexport type PathParam =\n // check if path is just a wildcard\n Path extends \"*\" | \"/*\"\n ? \"*\"\n : // look for wildcard at the end of the path\n Path extends `${infer Rest}/*`\n ? \"*\" | _PathParam\n : // look for params in the absence of wildcards\n _PathParam;\n\n// Attempt to parse the given string segment. If it fails, then just return the\n// plain string type as a default fallback. Otherwise, return the union of the\n// parsed string literals that were referenced as dynamic segments in the route.\nexport type ParamParseKey =\n // if you could not find path params, fallback to `string`\n [PathParam] extends [never] ? string : PathParam;\n\n/**\n * The parameters that were parsed from the URL path.\n */\nexport type Params = {\n readonly [key in Key]: string | undefined;\n};\n\n/**\n * A RouteMatch contains info about how a route matched a URL.\n */\nexport interface AgnosticRouteMatch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObjectType;\n}\n\nexport interface AgnosticDataRouteMatch\n extends AgnosticRouteMatch {}\n\nfunction isIndexRoute(\n route: AgnosticRouteObject\n): route is AgnosticIndexRouteObject {\n return route.index === true;\n}\n\n// Walk the route tree generating unique IDs where necessary, so we are working\n// solely with AgnosticDataRouteObject's within the Router\nexport function convertRoutesToDataRoutes(\n routes: AgnosticRouteObject[],\n mapRouteProperties: MapRoutePropertiesFunction,\n parentPath: string[] = [],\n manifest: RouteManifest = {}\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n !manifest[id],\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n };\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n ...mapRouteProperties(route),\n id,\n children: undefined,\n };\n manifest[id] = pathOrLayoutRoute;\n\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties,\n treePath,\n manifest\n );\n }\n\n return pathOrLayoutRoute;\n }\n });\n}\n\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/utils/match-routes\n */\nexport function matchRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename = \"/\"\n): AgnosticRouteMatch[] | null {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\n\nexport function matchRoutesImpl<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n locationArg: Partial | string,\n basename: string,\n allowPartial: boolean\n): AgnosticRouteMatch[] | null {\n let location =\n typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n\n let pathname = stripBasename(location.pathname || \"/\", basename);\n\n if (pathname == null) {\n return null;\n }\n\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n\n return matches;\n}\n\nexport interface UIMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: Data;\n handle: Handle;\n}\n\nexport function convertRouteMatchToUiMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UIMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle,\n };\n}\n\ninterface RouteMeta<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n relativePath: string;\n caseSensitive: boolean;\n childrenIndex: number;\n route: RouteObjectType;\n}\n\ninterface RouteBranch<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n> {\n path: string;\n score: number;\n routesMeta: RouteMeta[];\n}\n\nfunction flattenRoutes<\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n routes: RouteObjectType[],\n branches: RouteBranch[] = [],\n parentsMeta: RouteMeta[] = [],\n parentPath = \"\"\n): RouteBranch[] {\n let flattenRoute = (\n route: RouteObjectType,\n index: number,\n relativePath?: string\n ) => {\n let meta: RouteMeta = {\n relativePath:\n relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route,\n };\n\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path ` +\n `\"${parentPath}\" is not valid. An absolute child route path ` +\n `must start with the combined path of all its parent routes.`\n );\n\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n\n // Add the children before adding this route to the array, so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove ` +\n `all child routes from route path \"${path}\".`\n );\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta,\n });\n };\n routes.forEach((route, index) => {\n // coarse-grain check for optional params\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, exploded);\n }\n }\n });\n\n return branches;\n}\n\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */\nfunction explodeOptionalSegments(path: string): string[] {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n\n let [first, ...rest] = segments;\n\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [required, \"\"] : [required];\n }\n\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n\n let result: string[] = [];\n\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children, so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explode _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(\n ...restExploded.map((subpath) =>\n subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n\n // Then, if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n\n // for absolute paths, ensure `/` instead of empty segment\n return result.map((exploded) =>\n path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\n\nfunction rankRouteBranches(branches: RouteBranch[]): void {\n branches.sort((a, b) =>\n a.score !== b.score\n ? b.score - a.score // Higher score first\n : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\n\nconst paramRe = /^:[\\w-]+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s: string) => s === \"*\";\n\nfunction computeScore(path: string, index: boolean | undefined): number {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n\n if (index) {\n initialScore += indexRouteValue;\n }\n\n return segments\n .filter((s) => !isSplat(s))\n .reduce(\n (score, segment) =>\n score +\n (paramRe.test(segment)\n ? dynamicSegmentValue\n : segment === \"\"\n ? emptySegmentValue\n : staticSegmentValue),\n initialScore\n );\n}\n\nfunction compareIndexes(a: number[], b: number[]): number {\n let siblings =\n a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n\n return siblings\n ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\n\nfunction matchRouteBranch<\n ParamKey extends string = string,\n RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject\n>(\n branch: RouteBranch,\n pathname: string,\n allowPartial = false\n): AgnosticRouteMatch[] | null {\n let { routesMeta } = branch;\n\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches: AgnosticRouteMatch[] = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname =\n matchedPathname === \"/\"\n ? pathname\n : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n\n let route = meta.route;\n\n if (\n !match &&\n end &&\n allowPartial &&\n !routesMeta[routesMeta.length - 1].route.index\n ) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false,\n },\n remainingPathname\n );\n }\n\n if (!match) {\n return null;\n }\n\n Object.assign(matchedParams, match.params);\n\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams as Params,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route,\n });\n\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n\n return matches;\n}\n\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/utils/generate-path\n */\nexport function generatePath(\n originalPath: Path,\n params: {\n [key in PathParam]: string | null;\n } = {} as any\n): string {\n let path: string = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\") as Path;\n }\n\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n\n const stringify = (p: any) =>\n p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n\n const segments = path\n .split(/\\/+/)\n .map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\" as PathParam;\n // Apply the splat\n return stringify(params[star]);\n }\n\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key as PathParam];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return stringify(param);\n }\n\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })\n // Remove empty segments\n .filter((segment) => !!segment);\n\n return prefix + segments.join(\"/\");\n}\n\n/**\n * A PathPattern is used to match on some portion of a URL pathname.\n */\nexport interface PathPattern {\n /**\n * A string to match against a URL pathname. May contain `:id`-style segments\n * to indicate placeholders for dynamic parameters. May also end with `/*` to\n * indicate matching the rest of the URL pathname.\n */\n path: Path;\n /**\n * Should be `true` if the static portions of the `path` should be matched in\n * the same case.\n */\n caseSensitive?: boolean;\n /**\n * Should be `true` if this pattern should match the entire URL pathname.\n */\n end?: boolean;\n}\n\n/**\n * A PathMatch contains info about how a PathPattern matched on a URL pathname.\n */\nexport interface PathMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The pattern that was used to match.\n */\n pattern: PathPattern;\n}\n\ntype Mutable = {\n -readonly [P in keyof T]: T[P];\n};\n\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/utils/match-path\n */\nexport function matchPath<\n ParamKey extends ParamParseKey,\n Path extends string\n>(\n pattern: PathPattern | Path,\n pathname: string\n): PathMatch | null {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n\n let match = pathname.match(matcher);\n if (!match) return null;\n\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params: Params = compiledParams.reduce>(\n (memo, { paramName, isOptional }, index) => {\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname\n .slice(0, matchedPathname.length - splatValue.length)\n .replace(/(.)\\/+$/, \"$1\");\n }\n\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo[paramName] = undefined;\n } else {\n memo[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\ntype CompiledPathParam = { paramName: string; isOptional?: boolean };\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, CompiledPathParam[]] {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were ` +\n `\"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must ` +\n `always follow a \\`/\\` in the pattern. To get rid of this warning, ` +\n `please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n\n let params: CompiledPathParam[] = [];\n let regexpSource =\n \"^\" +\n path\n .replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (_: string, paramName: string, isOptional) => {\n params.push({ paramName, isOptional: isOptional != null });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n }\n );\n\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource +=\n path === \"*\" || path === \"/*\"\n ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex, so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n // Nothing to match for \"\" or \"/\"\n }\n\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n\n return [matcher, params];\n}\n\nexport function decodePath(value: string) {\n try {\n return value\n .split(\"/\")\n .map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\"))\n .join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is is a ` +\n `malformed URL segment. This is probably due to a bad percent ` +\n `encoding (${error}).`\n );\n\n return value;\n }\n}\n\n/**\n * @private\n */\nexport function stripBasename(\n pathname: string,\n basename: string\n): string | null {\n if (basename === \"/\") return pathname;\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\")\n ? basename.length - 1\n : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n\n return pathname.slice(startIndex) || \"/\";\n}\n\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/utils/resolve-path\n */\nexport function resolvePath(to: To, fromPathname = \"/\"): Path {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\",\n } = typeof to === \"string\" ? parsePath(to) : to;\n\n let pathname = toPathname\n ? toPathname.startsWith(\"/\")\n ? toPathname\n : resolvePathname(toPathname, fromPathname)\n : fromPathname;\n\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash),\n };\n}\n\nfunction resolvePathname(relativePath: string, fromPathname: string): string {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\n\nfunction getInvalidPathError(\n char: string,\n field: string,\n dest: string,\n path: Partial\n) {\n return (\n `Cannot include a '${char}' character in a manually specified ` +\n `\\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the ` +\n `\\`to.${dest}\\` field. Alternatively you may provide the full path as ` +\n `a string in and the router will parse it for you.`\n );\n}\n\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * \n * \n * \n *\n * \n * \n * }> // <-- Does not contribute\n * // <-- Does not contribute\n * \n * \n */\nexport function getPathContributingMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[]) {\n return matches.filter(\n (match, index) =>\n index === 0 || (match.route.path && match.route.path.length > 0)\n );\n}\n\n// Return the array of pathnames for the current route matches - used to\n// generate the routePathnames input for resolveTo()\nexport function getResolveToMatches<\n T extends AgnosticRouteMatch = AgnosticRouteMatch\n>(matches: T[], v7_relativeSplatPath: boolean) {\n let pathMatches = getPathContributingMatches(matches);\n\n // When v7_relativeSplatPath is enabled, use the full pathname for the leaf\n // match so we include splat values for \".\" links. See:\n // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329\n if (v7_relativeSplatPath) {\n return pathMatches.map((match, idx) =>\n idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n }\n\n return pathMatches.map((match) => match.pathnameBase);\n}\n\n/**\n * @private\n */\nexport function resolveTo(\n toArg: To,\n routePathnames: string[],\n locationPathname: string,\n isPathRelative = false\n): Path {\n let to: Partial;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n\n let from: string;\n\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n // With relative=\"route\" (the default), each leading .. segment means\n // \"go up one route\" instead of \"go up one URL segment\". This is a key\n // difference from how works and a major reason we call this a\n // \"to\" value instead of a \"href\".\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n\n let path = resolvePath(to, from);\n\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash =\n toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash =\n (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (\n !path.pathname.endsWith(\"/\") &&\n (hasExplicitTrailingSlash || hasCurrentTrailingSlash)\n ) {\n path.pathname += \"/\";\n }\n\n return path;\n}\n\n/**\n * @private\n */\nexport function getToPathname(to: To): string | undefined {\n // Empty strings should be treated the same as / paths\n return to === \"\" || (to as Path).pathname === \"\"\n ? \"/\"\n : typeof to === \"string\"\n ? parsePath(to).pathname\n : to.pathname;\n}\n\n/**\n * @private\n */\nexport const joinPaths = (paths: string[]): string =>\n paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n\n/**\n * @private\n */\nexport const normalizePathname = (pathname: string): string =>\n pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n\n/**\n * @private\n */\nexport const normalizeSearch = (search: string): string =>\n !search || search === \"?\"\n ? \"\"\n : search.startsWith(\"?\")\n ? search\n : \"?\" + search;\n\n/**\n * @private\n */\nexport const normalizeHash = (hash: string): string =>\n !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n\nexport type JsonFunction = (\n data: Data,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n */\nexport const json: JsonFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n\n return new Response(JSON.stringify(data), {\n ...responseInit,\n headers,\n });\n};\n\nexport interface TrackedPromise extends Promise {\n _tracked?: boolean;\n _data?: any;\n _error?: any;\n}\n\nexport class AbortedDeferredError extends Error {}\n\nexport class DeferredData {\n private pendingKeysSet: Set = new Set();\n private controller: AbortController;\n private abortPromise: Promise;\n private unlistenAbortSignal: () => void;\n private subscribers: Set<(aborted: boolean, settledKey?: string) => void> =\n new Set();\n data: Record;\n init?: ResponseInit;\n deferredKeys: string[] = [];\n\n constructor(data: Record, responseInit?: ResponseInit) {\n invariant(\n data && typeof data === \"object\" && !Array.isArray(data),\n \"defer() only accepts plain objects\"\n );\n\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject: (e: AbortedDeferredError) => void;\n this.abortPromise = new Promise((_, r) => (reject = r));\n this.controller = new AbortController();\n let onAbort = () =>\n reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = () =>\n this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n\n this.data = Object.entries(data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: this.trackPromise(key, value),\n }),\n {}\n );\n\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n\n this.init = responseInit;\n }\n\n private trackPromise(\n key: string,\n value: Promise | unknown\n ): TrackedPromise | unknown {\n if (!(value instanceof Promise)) {\n return value;\n }\n\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise: TrackedPromise = Promise.race([value, this.abortPromise]).then(\n (data) => this.onSettle(promise, key, undefined, data as unknown),\n (error) => this.onSettle(promise, key, error as unknown)\n );\n\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(() => {});\n\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n return promise;\n }\n\n private onSettle(\n promise: TrackedPromise,\n key: string,\n error: unknown,\n data?: unknown\n ): unknown {\n if (\n this.controller.signal.aborted &&\n error instanceof AbortedDeferredError\n ) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", { get: () => error });\n return Promise.reject(error);\n }\n\n this.pendingKeysSet.delete(key);\n\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error(\n `Deferred data for key \"${key}\" resolved/rejected with \\`undefined\\`, ` +\n `you must resolve/reject with a value or \\`null\\`.`\n );\n Object.defineProperty(promise, \"_error\", { get: () => undefinedError });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", { get: () => error });\n this.emit(false, key);\n return Promise.reject(error);\n }\n\n Object.defineProperty(promise, \"_data\", { get: () => data });\n this.emit(false, key);\n return data;\n }\n\n private emit(aborted: boolean, settledKey?: string) {\n this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));\n }\n\n subscribe(fn: (aborted: boolean, settledKey?: string) => void) {\n this.subscribers.add(fn);\n return () => this.subscribers.delete(fn);\n }\n\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n\n async resolveData(signal: AbortSignal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = () => this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise((resolve) => {\n this.subscribe((aborted) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n\n get unwrappedData() {\n invariant(\n this.data !== null && this.done,\n \"Can only unwrap data on initialized and settled deferreds\"\n );\n\n return Object.entries(this.data).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key]: unwrapTrackedPromise(value),\n }),\n {}\n );\n }\n\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\n\nfunction isTrackedPromise(value: any): value is TrackedPromise {\n return (\n value instanceof Promise && (value as TrackedPromise)._tracked === true\n );\n}\n\nfunction unwrapTrackedPromise(value: any) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\n\nexport type DeferFunction = (\n data: Record,\n init?: number | ResponseInit\n) => DeferredData;\n\nexport const defer: DeferFunction = (data, init = {}) => {\n let responseInit = typeof init === \"number\" ? { status: init } : init;\n\n return new DeferredData(data, responseInit);\n};\n\nexport type RedirectFunction = (\n url: string,\n init?: number | ResponseInit\n) => Response;\n\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirect: RedirectFunction = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...responseInit,\n headers,\n });\n};\n\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nexport const redirectDocument: RedirectFunction = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n\nexport type ErrorResponse = {\n status: number;\n statusText: string;\n data: any;\n};\n\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n *\n * We don't export the class for public use since it's an implementation\n * detail, but we export the interface above so folks can build their own\n * abstractions around instances via isRouteErrorResponse()\n */\nexport class ErrorResponseImpl implements ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n private error?: Error;\n private internal: boolean;\n\n constructor(\n status: number,\n statusText: string | undefined,\n data: any,\n internal = false\n ) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */\nexport function isRouteErrorResponse(error: any): error is ErrorResponse {\n return (\n error != null &&\n typeof error.status === \"number\" &&\n typeof error.statusText === \"string\" &&\n typeof error.internal === \"boolean\" &&\n \"data\" in error\n );\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n warning,\n} from \"./history\";\nimport type {\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DataStrategyMatch,\n AgnosticRouteObject,\n DataResult,\n DataStrategyFunction,\n DataStrategyFunctionArgs,\n DeferredData,\n DeferredResult,\n DetectErrorBoundaryFunction,\n ErrorResult,\n FormEncType,\n FormMethod,\n HTMLFormMethod,\n HandlerResult,\n ImmutableRouteKey,\n MapRoutePropertiesFunction,\n MutationFormMethod,\n RedirectResult,\n RouteData,\n RouteManifest,\n ShouldRevalidateFunctionArgs,\n Submission,\n SuccessResult,\n UIMatch,\n V7_FormMethod,\n V7_MutationFormMethod,\n AgnosticPatchRoutesOnMissFunction,\n} from \"./utils\";\nimport {\n ErrorResponseImpl,\n ResultType,\n convertRouteMatchToUiMatch,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n getResolveToMatches,\n immutableRouteKeys,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n matchRoutesImpl,\n resolveTo,\n stripBasename,\n} from \"./utils\";\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * A Router instance manages all navigation and data loading/mutations\n */\nexport interface Router {\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the basename for the router\n */\n get basename(): RouterInit[\"basename\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the future config for the router\n */\n get future(): FutureConfig;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the current state of the router\n */\n get state(): RouterState;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the routes for this router instance\n */\n get routes(): AgnosticDataRouteObject[];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Return the window associated with the router\n */\n get window(): RouterInit[\"window\"];\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Initialize the router, including adding history listeners and kicking off\n * initial data fetches. Returns a function to cleanup listeners and abort\n * any in-progress loads\n */\n initialize(): Router;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Subscribe to router.state updates\n *\n * @param fn function to call with the new state\n */\n subscribe(fn: RouterSubscriber): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Enable scroll restoration behavior in the router\n *\n * @param savedScrollPositions Object that will manage positions, in case\n * it's being restored from sessionStorage\n * @param getScrollPosition Function to get the active Y scroll position\n * @param getKey Function to get the key to use for restoration\n */\n enableScrollRestoration(\n savedScrollPositions: Record,\n getScrollPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ): () => void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Navigate forward/backward in the history stack\n * @param to Delta to move in the history stack\n */\n navigate(to: number): Promise;\n\n /**\n * Navigate to the given path\n * @param to Path to navigate to\n * @param opts Navigation options (method, submission, etc.)\n */\n navigate(to: To | null, opts?: RouterNavigateOptions): Promise;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a fetcher load/submission\n *\n * @param key Fetcher key\n * @param routeId Route that owns the fetcher\n * @param href href to fetch\n * @param opts Fetcher options, (method, submission, etc.)\n */\n fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Trigger a revalidation of all current route loaders and fetcher loads\n */\n revalidate(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to create an href for the given location\n * @param location\n */\n createHref(location: Location | URL): string;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Utility function to URL encode a destination path according to the internal\n * history implementation\n * @param to\n */\n encodeLocation(to: To): Path;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get/create a fetcher for the given key\n * @param key\n */\n getFetcher(key: string): Fetcher;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete the fetcher for a given key\n * @param key\n */\n deleteFetcher(key: string): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Cleanup listeners and abort any in-progress loads\n */\n dispose(): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Get a navigation blocker\n * @param key The identifier for the blocker\n * @param fn The blocker function implementation\n */\n getBlocker(key: string, fn: BlockerFunction): Blocker;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Delete a navigation blocker\n * @param key The identifier for the blocker\n */\n deleteBlocker(key: string): void;\n\n /**\n * @internal\n * PRIVATE DO NOT USE\n *\n * Patch additional children routes into an existing parent route\n * @param routeId The parent route id or a callback function accepting `patch`\n * to perform batch patching\n * @param children The additional children routes\n */\n patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * HMR needs to pass in-flight route updates to React Router\n * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute)\n */\n _internalSetRoutes(routes: AgnosticRouteObject[]): void;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal fetch AbortControllers accessed by unit tests\n */\n _internalFetchControllers: Map;\n\n /**\n * @internal\n * PRIVATE - DO NOT USE\n *\n * Internal pending DeferredData instances accessed by unit tests\n */\n _internalActiveDeferreds: Map;\n}\n\n/**\n * State maintained internally by the router. During a navigation, all states\n * reflect the the \"old\" location unless otherwise noted.\n */\nexport interface RouterState {\n /**\n * The action of the most recent navigation\n */\n historyAction: HistoryAction;\n\n /**\n * The current location reflected by the router\n */\n location: Location;\n\n /**\n * The current set of route matches\n */\n matches: AgnosticDataRouteMatch[];\n\n /**\n * Tracks whether we've completed our initial data load\n */\n initialized: boolean;\n\n /**\n * Current scroll position we should start at for a new view\n * - number -> scroll position to restore to\n * - false -> do not restore scroll at all (used during submissions)\n * - null -> don't have a saved position, scroll to hash or top of page\n */\n restoreScrollPosition: number | false | null;\n\n /**\n * Indicate whether this navigation should skip resetting the scroll position\n * if we are unable to restore the scroll position\n */\n preventScrollReset: boolean;\n\n /**\n * Tracks the state of the current navigation\n */\n navigation: Navigation;\n\n /**\n * Tracks any in-progress revalidations\n */\n revalidation: RevalidationState;\n\n /**\n * Data from the loaders for the current matches\n */\n loaderData: RouteData;\n\n /**\n * Data from the action for the current matches\n */\n actionData: RouteData | null;\n\n /**\n * Errors caught from loaders for the current matches\n */\n errors: RouteData | null;\n\n /**\n * Map of current fetchers\n */\n fetchers: Map;\n\n /**\n * Map of current blockers\n */\n blockers: Map;\n}\n\n/**\n * Data that can be passed into hydrate a Router from SSR\n */\nexport type HydrationState = Partial<\n Pick\n>;\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface FutureConfig {\n v7_fetcherPersist: boolean;\n v7_normalizeFormMethod: boolean;\n v7_partialHydration: boolean;\n v7_prependBasename: boolean;\n v7_relativeSplatPath: boolean;\n v7_skipActionErrorRevalidation: boolean;\n}\n\n/**\n * Initialization options for createRouter\n */\nexport interface RouterInit {\n routes: AgnosticRouteObject[];\n history: History;\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n hydrationData?: HydrationState;\n window?: Window;\n unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction;\n unstable_dataStrategy?: DataStrategyFunction;\n}\n\n/**\n * State returned from a server-side query() call\n */\nexport interface StaticHandlerContext {\n basename: Router[\"basename\"];\n location: RouterState[\"location\"];\n matches: RouterState[\"matches\"];\n loaderData: RouterState[\"loaderData\"];\n actionData: RouterState[\"actionData\"];\n errors: RouterState[\"errors\"];\n statusCode: number;\n loaderHeaders: Record;\n actionHeaders: Record;\n activeDeferreds: Record | null;\n _deepestRenderedBoundaryId?: string | null;\n}\n\n/**\n * A StaticHandler instance manages a singular SSR navigation/fetch event\n */\nexport interface StaticHandler {\n dataRoutes: AgnosticDataRouteObject[];\n query(\n request: Request,\n opts?: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: {\n routeId?: string;\n requestContext?: unknown;\n unstable_dataStrategy?: DataStrategyFunction;\n }\n ): Promise;\n}\n\ntype ViewTransitionOpts = {\n currentLocation: Location;\n nextLocation: Location;\n};\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (\n state: RouterState,\n opts: {\n deletedFetchers: string[];\n unstable_viewTransitionOpts?: ViewTransitionOpts;\n unstable_flushSync: boolean;\n }\n ): void;\n}\n\n/**\n * Function signature for determining the key to be used in scroll restoration\n * for a given location\n */\nexport interface GetScrollRestorationKeyFunction {\n (location: Location, matches: UIMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\nexport type RelativeRoutingType = \"route\" | \"path\";\n\n// Allowed for any navigation or fetch\ntype BaseNavigateOrFetchOptions = {\n preventScrollReset?: boolean;\n relative?: RelativeRoutingType;\n unstable_flushSync?: boolean;\n};\n\n// Only allowed for navigations\ntype BaseNavigateOptions = BaseNavigateOrFetchOptions & {\n replace?: boolean;\n state?: any;\n fromRouteId?: string;\n unstable_viewTransition?: boolean;\n};\n\n// Only allowed for submission navigations\ntype BaseSubmissionOptions = {\n formMethod?: HTMLFormMethod;\n formEncType?: FormEncType;\n} & (\n | { formData: FormData; body?: undefined }\n | { formData?: undefined; body: any }\n);\n\n/**\n * Options for a navigate() call for a normal (non-submission) navigation\n */\ntype LinkNavigateOptions = BaseNavigateOptions;\n\n/**\n * Options for a navigate() call for a submission navigation\n */\ntype SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to navigate() for a navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options for a fetch() load\n */\ntype LoadFetchOptions = BaseNavigateOrFetchOptions;\n\n/**\n * Options for a fetch() submission\n */\ntype SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions;\n\n/**\n * Potential states for state.navigation\n */\nexport type NavigationStates = {\n Idle: {\n state: \"idle\";\n location: undefined;\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n formData: undefined;\n json: undefined;\n text: undefined;\n };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n text: Submission[\"text\"] | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n text: Submission[\"text\"];\n };\n};\n\nexport type Navigation = NavigationStates[keyof NavigationStates];\n\nexport type RevalidationState = \"idle\" | \"loading\";\n\n/**\n * Potential states for fetchers\n */\ntype FetcherStates = {\n Idle: {\n state: \"idle\";\n formMethod: undefined;\n formAction: undefined;\n formEncType: undefined;\n text: undefined;\n formData: undefined;\n json: undefined;\n data: TData | undefined;\n };\n Loading: {\n state: \"loading\";\n formMethod: Submission[\"formMethod\"] | undefined;\n formAction: Submission[\"formAction\"] | undefined;\n formEncType: Submission[\"formEncType\"] | undefined;\n text: Submission[\"text\"] | undefined;\n formData: Submission[\"formData\"] | undefined;\n json: Submission[\"json\"] | undefined;\n data: TData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: Submission[\"formMethod\"];\n formAction: Submission[\"formAction\"];\n formEncType: Submission[\"formEncType\"];\n text: Submission[\"text\"];\n formData: Submission[\"formData\"];\n json: Submission[\"json\"];\n data: TData | undefined;\n };\n};\n\nexport type Fetcher =\n FetcherStates[keyof FetcherStates];\n\ninterface BlockerBlocked {\n state: \"blocked\";\n reset(): void;\n proceed(): void;\n location: Location;\n}\n\ninterface BlockerUnblocked {\n state: \"unblocked\";\n reset: undefined;\n proceed: undefined;\n location: undefined;\n}\n\ninterface BlockerProceeding {\n state: \"proceeding\";\n reset: undefined;\n proceed: undefined;\n location: Location;\n}\n\nexport type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;\n\nexport type BlockerFunction = (args: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n}) => boolean;\n\ninterface ShortCircuitable {\n /**\n * startNavigation does not need to complete the navigation because we\n * redirected or got interrupted\n */\n shortCircuited?: boolean;\n}\n\ntype PendingActionResult = [string, SuccessResult | ErrorResult];\n\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * Tuple for the returned or thrown value from the current action. The routeId\n * is the action route for success and the bubbled boundary route for errors.\n */\n pendingActionResult?: PendingActionResult;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\n /**\n * Route matches which may have been updated from fog of war discovery\n */\n matches?: RouterState[\"matches\"];\n /**\n * loaderData returned from the current set of loaders\n */\n loaderData?: RouterState[\"loaderData\"];\n /**\n * errors thrown from the current set of loaders\n */\n errors?: RouterState[\"errors\"];\n}\n\n/**\n * Cached info for active fetcher.load() instances so they can participate\n * in revalidation\n */\ninterface FetchLoadMatch {\n routeId: string;\n path: string;\n}\n\n/**\n * Identified fetcher.load() calls that need to be revalidated\n */\ninterface RevalidatingFetcher extends FetchLoadMatch {\n key: string;\n match: AgnosticDataRouteMatch | null;\n matches: AgnosticDataRouteMatch[] | null;\n controller: AbortController | null;\n}\n\nconst validMutationMethodsArr: MutationFormMethod[] = [\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n];\nconst validMutationMethods = new Set(\n validMutationMethodsArr\n);\n\nconst validRequestMethodsArr: FormMethod[] = [\n \"get\",\n ...validMutationMethodsArr,\n];\nconst validRequestMethods = new Set(validRequestMethodsArr);\n\nconst redirectStatusCodes = new Set([301, 302, 303, 307, 308]);\nconst redirectPreserveMethodStatusCodes = new Set([307, 308]);\n\nexport const IDLE_NAVIGATION: NavigationStates[\"Idle\"] = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_FETCHER: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\nconst defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary),\n});\n\nconst TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Create a router and listen to history POP navigations\n */\nexport function createRouter(init: RouterInit): Router {\n const routerWindow = init.window\n ? init.window\n : typeof window !== \"undefined\"\n ? window\n : undefined;\n const isBrowser =\n typeof routerWindow !== \"undefined\" &&\n typeof routerWindow.document !== \"undefined\" &&\n typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n\n // Routes keyed by ID\n let manifest: RouteManifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined;\n let basename = init.basename || \"/\";\n let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;\n let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss;\n\n // Config driven behavior flags\n let future: FutureConfig = {\n v7_fetcherPersist: false,\n v7_normalizeFormMethod: false,\n v7_partialHydration: false,\n v7_prependBasename: false,\n v7_relativeSplatPath: false,\n v7_skipActionErrorRevalidation: false,\n ...init.future,\n };\n // Cleanup function for history\n let unlistenHistory: (() => void) | null = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions: Record | null = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey: GetScrollRestorationKeyFunction | null = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition: GetScrollPositionFunction | null = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null && !patchRoutesOnMissImpl) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname,\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n }\n\n // In SPA apps, if the user provided a patchRoutesOnMiss implementation and\n // our initial match is a splat route, clear them out so we run through lazy\n // discovery on hydration in case there's a more accurate lazy route match.\n // In SSR apps (with `hydrationData`), we expect that the server will send\n // up the proper matched routes so we don't want to run lazy discovery on\n // initial hydration and want to hydrate into the splat route.\n if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n\n let initialized: boolean;\n if (!initialMatches) {\n // We need to run patchRoutesOnMiss in initialize()\n initialized = false;\n initialMatches = [];\n } else if (initialMatches.some((m) => m.route.lazy)) {\n // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n initialized = false;\n } else if (!initialMatches.some((m) => m.route.loader)) {\n // If we've got no loaders to run, then we're good to go\n initialized = true;\n } else if (future.v7_partialHydration) {\n // If partial hydration is enabled, we're initialized so long as we were\n // provided with hydrationData for every route with a loader, and no loaders\n // were marked for explicit hydration\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n let isRouteInitialized = (m: AgnosticDataRouteMatch) => {\n // No loader, nothing to initialize\n if (!m.route.loader) {\n return true;\n }\n // Explicitly opting-in to running on hydration\n if (\n typeof m.route.loader === \"function\" &&\n m.route.loader.hydrate === true\n ) {\n return false;\n }\n // Otherwise, initialized if hydrated with data or an error\n return (\n (loaderData && loaderData[m.route.id] !== undefined) ||\n (errors && errors[m.route.id] !== undefined)\n );\n };\n\n // If errors exist, don't consider routes below the boundary\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors![m.route.id] !== undefined\n );\n initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);\n } else {\n initialized = initialMatches.every(isRouteInitialized);\n }\n } else {\n // Without partial hydration - we're initialized if we were provided any\n // hydrationData - which is expected to be complete\n initialized = init.hydrationData != null;\n }\n\n let router: Router;\n let state: RouterState = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: (init.hydrationData && init.hydrationData.loaderData) || {},\n actionData: (init.hydrationData && init.hydrationData.actionData) || null,\n errors: (init.hydrationData && init.hydrationData.errors) || initialErrors,\n fetchers: new Map(),\n blockers: new Map(),\n };\n\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction: HistoryAction = HistoryAction.Pop;\n\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n\n // AbortController for the active navigation\n let pendingNavigationController: AbortController | null;\n\n // Should the current navigation enable document.startViewTransition?\n let pendingViewTransitionEnabled = false;\n\n // Store applied view transitions so we can apply them on POP\n let appliedViewTransitions: Map> = new Map<\n string,\n Set\n >();\n\n // Cleanup function for persisting applied transitions to sessionStorage\n let removePageHideEventListener: (() => void) | null = null;\n\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes: string[] = [];\n\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads: string[] = [];\n\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n\n // Ref-count mounted fetchers so we know when it's ok to clean them up\n let activeFetchers = new Map();\n\n // Fetchers that have requested a delete when using v7_fetcherPersist,\n // they'll be officially removed after they return to idle\n let deletedFetchers = new Set();\n\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n\n // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so\n // that we only kick them off once for a given combo\n let pendingPatchRoutes = new Map<\n string,\n ReturnType\n >();\n\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let ignoreNextHistoryUpdate = false;\n\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (ignoreNextHistoryUpdate) {\n ignoreNextHistoryUpdate = false;\n return;\n }\n\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location \" +\n \"that was not created by @remix-run/router. This will fail silently in \" +\n \"production. This can happen if you are navigating outside the router \" +\n \"via `window.history.pushState`/`window.location.hash` instead of using \" +\n \"router navigation APIs. This can also happen if you are using \" +\n \"createHashRouter and the user manually changes the URL.\"\n );\n\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n ignoreNextHistoryUpdate = true;\n init.history.go(delta * -1);\n\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location,\n });\n // Re-do the same POP navigation we just blocked\n init.history.go(delta);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n if (isBrowser) {\n // FIXME: This feels gross. How can we cleanup the lines between\n // scrollRestoration/appliedTransitions persistance?\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () =>\n persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () =>\n routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location, {\n initialHydration: true,\n });\n }\n\n return router;\n }\n\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n\n // Subscribe to state updates for the router\n function subscribe(fn: RouterSubscriber) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n\n // Update our state and notify the calling context of the change\n function updateState(\n newState: Partial,\n opts: {\n flushSync?: boolean;\n viewTransitionOpts?: ViewTransitionOpts;\n } = {}\n ): void {\n state = {\n ...state,\n ...newState,\n };\n\n // Prep fetcher cleanup so we can tell the UI which fetcher data entries\n // can be removed\n let completedFetchers: string[] = [];\n let deletedFetchersKeys: string[] = [];\n\n if (future.v7_fetcherPersist) {\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (deletedFetchers.has(key)) {\n // Unmounted from the UI and can be totally removed\n deletedFetchersKeys.push(key);\n } else {\n // Returned to idle but still mounted in the UI, so semi-remains for\n // revalidations and such\n completedFetchers.push(key);\n }\n }\n });\n }\n\n // Iterate over a local copy so that if flushSync is used and we end up\n // removing and adding a new subscriber due to the useCallback dependencies,\n // we don't get ourselves into a loop calling the new subscriber immediately\n [...subscribers].forEach((subscriber) =>\n subscriber(state, {\n deletedFetchers: deletedFetchersKeys,\n unstable_viewTransitionOpts: opts.viewTransitionOpts,\n unstable_flushSync: opts.flushSync === true,\n })\n );\n\n // Remove idle fetchers from state since we only care about in-flight fetchers.\n if (future.v7_fetcherPersist) {\n completedFetchers.forEach((key) => state.fetchers.delete(key));\n deletedFetchersKeys.forEach((key) => deleteFetcher(key));\n }\n }\n\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(\n location: Location,\n newState: Partial>,\n { flushSync }: { flushSync?: boolean } = {}\n ): void {\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload =\n state.actionData != null &&\n state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n state.navigation.state === \"loading\" &&\n location.state?._isRedirect !== true;\n\n let actionData: RouteData | null;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData\n ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n )\n : state.loaderData;\n\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset =\n pendingPreventScrollReset === true ||\n (state.navigation.formMethod != null &&\n isMutationMethod(state.navigation.formMethod) &&\n location.state?._isRedirect !== true);\n\n // Commit any in-flight routes at the end of the HMR revalidation \"navigation\"\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n\n if (isUninterruptedRevalidation) {\n // If this was an uninterrupted revalidation then do not touch history\n } else if (pendingAction === HistoryAction.Pop) {\n // Do nothing for POP - URL has already been updated\n } else if (pendingAction === HistoryAction.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === HistoryAction.Replace) {\n init.history.replace(location, location.state);\n }\n\n let viewTransitionOpts: ViewTransitionOpts | undefined;\n\n // On POP, enable transitions if they were enabled on the original navigation\n if (pendingAction === HistoryAction.Pop) {\n // Forward takes precedence so they behave like the original navigation\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n // If we don't have a previous forward nav, assume we're popping back to\n // the new location and enable if that location previously enabled\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location,\n };\n }\n } else if (pendingViewTransitionEnabled) {\n // Store the applied transition on PUSH/REPLACE\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location,\n };\n }\n\n updateState(\n {\n ...newState, // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(\n location,\n newState.matches || state.matches\n ),\n preventScrollReset,\n blockers,\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true,\n }\n );\n\n // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n cancelledFetcherLoads = [];\n }\n\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(\n to: number | To | null,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n to,\n future.v7_relativeSplatPath,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n false,\n normalizedPath,\n opts\n );\n\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation),\n };\n\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n\n let historyAction = HistoryAction.Push;\n\n if (userReplace === true) {\n historyAction = HistoryAction.Replace;\n } else if (userReplace === false) {\n // no-op\n } else if (\n submission != null &&\n isMutationMethod(submission.formMethod) &&\n submission.formAction === state.location.pathname + state.location.search\n ) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = HistoryAction.Replace;\n }\n\n let preventScrollReset =\n opts && \"preventScrollReset\" in opts\n ? opts.preventScrollReset === true\n : undefined;\n\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n });\n\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey!, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation,\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey!, IDLE_BLOCKER);\n updateState({ blockers });\n },\n });\n return;\n }\n\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.unstable_viewTransition,\n flushSync,\n });\n }\n\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true,\n });\n return;\n }\n\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n { overrideNavigation: state.navigation }\n );\n }\n\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(\n historyAction: HistoryAction,\n location: Location,\n opts?: {\n initialHydration?: boolean;\n submission?: Submission;\n fetcherSubmission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponseImpl;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: boolean;\n enableViewTransition?: boolean;\n flushSync?: boolean;\n }\n ): Promise {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation =\n (opts && opts.startUninterruptedRevalidation) === true;\n\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n },\n { flushSync }\n );\n return;\n }\n\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial load will always\n // be \"same hash\". For example, on /page#hash and submit a \n // which will default to a navigation to /page\n if (\n state.initialized &&\n !isRevalidationRequired &&\n isHashChangeOnly(state.location, location) &&\n !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))\n ) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let pendingActionResult: PendingActionResult | undefined;\n\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: ResultType.error, error: opts.pendingError },\n ];\n } else if (\n opts &&\n opts.submission &&\n isMutationMethod(opts.submission.formMethod)\n ) {\n // Call action if we received an action submission\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n fogOfWar.active,\n { replace: opts.replace, flushSync }\n );\n\n if (actionResult.shortCircuited) {\n return;\n }\n\n // If we received a 404 from handleAction, it's because we couldn't lazily\n // discover the destination route so we don't want to call loaders\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (\n isErrorResult(result) &&\n isRouteErrorResponse(result.error) &&\n result.error.status === 404\n ) {\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error,\n },\n });\n return;\n }\n }\n\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n // No need to do fog of war matching again on loader execution\n fogOfWar.active = false;\n\n // Create a GET request for the loaders\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n\n // Call loaders\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors,\n } = await handleLoaders(\n request,\n location,\n matches,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult\n );\n\n if (shortCircuited) {\n return;\n }\n\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors,\n });\n }\n\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(\n request: Request,\n location: Location,\n submission: Submission,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n opts: { replace?: boolean; flushSync?: boolean } = {}\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: ResultType.error,\n error,\n },\n ],\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n // Call our action and get the result\n let result: DataResult;\n let actionMatch = getTargetMatch(matches, location);\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id,\n }),\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches\n );\n result = results[0];\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n\n if (isRedirectResult(result)) {\n let replace: boolean;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n let location = normalizeRedirectLocation(\n result.response.headers.get(\"Location\")!,\n new URL(request.url),\n basename\n );\n replace = location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, {\n submission,\n replace,\n });\n return { shortCircuited: true };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n\n // By default, all submissions to the current location are REPLACE\n // navigations, but if the action threw an error that'll be rendered in\n // an errorElement, we fall back to PUSH so that the user can use the\n // back button to get back to the pre-submission form location to try\n // again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n matches,\n pendingActionResult: [boundaryMatch.route.id, result],\n };\n }\n\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result],\n };\n }\n\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n overrideNavigation?: Navigation,\n submission?: Submission,\n fetcherSubmission?: Submission,\n replace?: boolean,\n initialHydration?: boolean,\n flushSync?: boolean,\n pendingActionResult?: PendingActionResult\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation =\n overrideNavigation || getLoadingNavigation(location, submission);\n\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission =\n submission ||\n fetcherSubmission ||\n getSubmissionFromNavigation(loadingNavigation);\n\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n // If we have partialHydration enabled, then don't update the state for the\n // initial data load since it's not a \"navigation\"\n let shouldUpdateNavigationState =\n !isUninterruptedRevalidation &&\n (!future.v7_partialHydration || !initialHydration);\n\n // When fog of war is enabled, we enter our `loading` state earlier so we\n // can discover new routes during the `loading` state. We skip this if\n // we've already run actions since we would have done our matching already.\n // If the children() function threw then, we want to proceed with the\n // partial matches it discovered.\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...(actionData !== undefined ? { actionData } : {}),\n },\n {\n flushSync,\n }\n );\n }\n\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n let { boundaryId, error } = handleDiscoverRouteError(\n location.pathname,\n discoverResult\n );\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: error,\n },\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n future.v7_partialHydration && initialHydration === true,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n pendingActionResult\n );\n\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds(\n (routeId) =>\n !(matches && matches.some((m) => m.route.id === routeId)) ||\n (matchesToLoad && matchesToLoad.some((m) => m.route.id === routeId))\n );\n\n pendingNavigationLoadId = ++incrementingLoadId;\n\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? { [pendingActionResult[0]]: pendingActionResult[1].error }\n : null,\n ...getActionDataForCommit(pendingActionResult),\n ...(updatedFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n\n if (shouldUpdateNavigationState) {\n let updates: Partial = {};\n if (!isFogOfWar) {\n // Only update navigation/actionNData if we didn't already do it above\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== undefined) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n\n revalidatingFetchers.forEach((rf) => {\n if (fetchControllers.has(rf.key)) {\n abortFetcher(rf.key);\n }\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n request\n );\n\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n await startRedirectNavigation(request, redirect.result, {\n replace,\n });\n return { shortCircuited: true };\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n matchesToLoad,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId) => {\n deferredData.subscribe((aborted) => {\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n\n // During partial hydration, preserve SSR errors for routes that don't re-run\n if (future.v7_partialHydration && initialHydration && state.errors) {\n Object.entries(state.errors)\n .filter(([id]) => !matchesToLoad.some((m) => m.route.id === id))\n .forEach(([routeId, error]) => {\n errors = Object.assign(errors || {}, { [routeId]: error });\n });\n }\n\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers =\n updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n\n return {\n matches,\n loaderData,\n errors,\n ...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}),\n };\n }\n\n function getUpdatedActionData(\n pendingActionResult: PendingActionResult | undefined\n ): Record | null | undefined {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n // This is cast to `any` currently because `RouteData`uses any and it\n // would be a breaking change to use any.\n // TODO: v7 - change `RouteData` to use `unknown` instead of `any`\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data as any,\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n\n function getUpdatedRevalidatingFetchers(\n revalidatingFetchers: RevalidatingFetcher[]\n ) {\n revalidatingFetchers.forEach((rf) => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n fetcher ? fetcher.data : undefined\n );\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(\n key: string,\n routeId: string,\n href: string | null,\n opts?: RouterFetchOptions\n ) {\n if (isServer) {\n throw new Error(\n \"router.fetch() was called during the server render, but it shouldn't be. \" +\n \"You are likely calling a useFetcher() method in the body of your component. \" +\n \"Try moving it to a useEffect or a callback.\"\n );\n }\n\n if (fetchControllers.has(key)) abortFetcher(key);\n let flushSync = (opts && opts.unstable_flushSync) === true;\n\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n future.v7_prependBasename,\n href,\n future.v7_relativeSplatPath,\n routeId,\n opts?.relative\n );\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(\n future.v7_normalizeFormMethod,\n true,\n normalizedPath,\n opts\n );\n\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n\n let match = getTargetMatch(matches, path);\n\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, { routeId, path });\n handleFetcherLoader(\n key,\n routeId,\n path,\n match,\n matches,\n fogOfWar.active,\n flushSync,\n submission\n );\n }\n\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n requestMatches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n function detectAndHandle405Error(m: AgnosticDataRouteMatch) {\n if (!m.route.action && !m.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error, { flushSync });\n return true;\n }\n return false;\n }\n\n if (!isFogOfWar && detectAndHandle405Error(match)) {\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync,\n });\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n match = getTargetMatch(requestMatches, path);\n\n if (detectAndHandle405Error(match)) {\n return;\n }\n }\n }\n\n // Call the action for the fetcher\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let actionResults = await callDataStrategy(\n \"action\",\n fetchRequest,\n [match],\n requestMatches\n );\n let actionResult = actionResults[0];\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n\n // When using v7_fetcherPersist, we don't want errors bubbling up to the UI\n // or redirects processed for unmounted fetchers so we just revert them to\n // idle\n if (future.v7_fetcherPersist && deletedFetchers.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // Let SuccessResult's fall through for revalidation\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, {\n fetcherSubmission: submission,\n });\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(routesToUse, state.navigation.location, basename)\n : state.matches;\n\n invariant(matches, \"Didn't find any matches after fetcher action\");\n\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n false,\n future.v7_skipActionErrorRevalidation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n deletedFetchers,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n [match.route.id, actionResult]\n );\n\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers\n .filter((rf) => rf.key !== key)\n .forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n undefined,\n existingFetcher ? existingFetcher.data : undefined\n );\n state.fetchers.set(staleKey, revalidatingFetcher);\n if (fetchControllers.has(staleKey)) {\n abortFetcher(staleKey);\n }\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let abortPendingFetchRevalidations = () =>\n revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n let { loaderResults, fetcherResults } =\n await callLoadersAndMaybeResolveData(\n state.matches,\n matches,\n matchesToLoad,\n revalidatingFetchers,\n revalidationRequest\n );\n\n if (abortController.signal.aborted) {\n return;\n }\n\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n\n let redirect = findRedirect([...loaderResults, ...fetcherResults]);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey =\n revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n return startRedirectNavigation(revalidationRequest, redirect.result);\n }\n\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(\n state,\n state.matches,\n matchesToLoad,\n loaderResults,\n undefined,\n revalidatingFetchers,\n fetcherResults,\n activeDeferreds\n );\n\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n\n abortStaleFetchLoads(loadId);\n\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (\n state.navigation.state === \"loading\" &&\n loadId > pendingNavigationLoadId\n ) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers),\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: new Map(state.fetchers),\n });\n isRevalidationRequired = false;\n }\n }\n\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(\n key: string,\n routeId: string,\n path: string,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n isFogOfWar: boolean,\n flushSync: boolean,\n submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : undefined\n ),\n { flushSync }\n );\n\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n path,\n fetchRequest.signal\n );\n\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n let { error } = handleDiscoverRouteError(path, discoverResult);\n setFetcherError(key, routeId, error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n match = getTargetMatch(matches, path);\n }\n }\n\n // Call the loader for this fetcher route match\n fetchControllers.set(key, abortController);\n\n let originatingLoadId = incrementingLoadId;\n let results = await callDataStrategy(\n \"loader\",\n fetchRequest,\n [match],\n matches\n );\n let result = results[0];\n\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result =\n (await resolveDeferredData(result, fetchRequest.signal, true)) ||\n result;\n }\n\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n\n if (fetchRequest.signal.aborted) {\n return;\n }\n\n // We don't want errors bubbling up or redirects followed for unmounted\n // fetchers, so short circuit here if it was removed from the UI\n if (deletedFetchers.has(key)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result);\n return;\n }\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */\n async function startRedirectNavigation(\n request: Request,\n redirect: RedirectResult,\n {\n submission,\n fetcherSubmission,\n replace,\n }: {\n submission?: Submission;\n fetcherSubmission?: Submission;\n replace?: boolean;\n } = {}\n ) {\n if (redirect.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n\n let location = redirect.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true,\n });\n\n if (isBrowser) {\n let isDocumentReload = false;\n\n if (redirect.response.headers.has(\"X-Remix-Reload-Document\")) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(location)) {\n const url = init.history.createURL(location);\n isDocumentReload =\n // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin ||\n // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n\n let redirectHistoryAction =\n replace === true ? HistoryAction.Replace : HistoryAction.Push;\n\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let { formMethod, formAction, formEncType } = state.navigation;\n if (\n !submission &&\n !fetcherSubmission &&\n formMethod &&\n formAction &&\n formEncType\n ) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n let activeSubmission = submission || fetcherSubmission;\n if (\n redirectPreserveMethodStatusCodes.has(redirect.response.status) &&\n activeSubmission &&\n isMutationMethod(activeSubmission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // If we have a navigation submission, we will preserve it through the\n // redirect navigation\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n submission\n );\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n }\n }\n\n // Utility wrapper for calling dataStrategy client-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[]\n ): Promise {\n try {\n let results = await callDataStrategyImpl(\n dataStrategyImpl,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n return {\n type: ResultType.redirect,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n ),\n };\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n } catch (e) {\n // If the outer dataStrategy method throws, just return the error for all\n // matches - and it'll naturally bubble to the root\n return matchesToLoad.map(() => ({\n type: ResultType.error,\n error: e,\n }));\n }\n }\n\n async function callLoadersAndMaybeResolveData(\n currentMatches: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n fetchersToLoad: RevalidatingFetcher[],\n request: Request\n ) {\n let [loaderResults, ...fetcherResults] = await Promise.all([\n matchesToLoad.length\n ? callDataStrategy(\"loader\", request, matchesToLoad, matches)\n : [],\n ...fetchersToLoad.map((f) => {\n if (f.matches && f.match && f.controller) {\n let fetcherRequest = createClientSideRequest(\n init.history,\n f.path,\n f.controller.signal\n );\n return callDataStrategy(\n \"loader\",\n fetcherRequest,\n [f.match],\n f.matches\n ).then((r) => r[0]);\n } else {\n return Promise.resolve({\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path,\n }),\n });\n }\n }),\n ]);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n loaderResults.map(() => request.signal),\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map((f) => f.match),\n fetcherResults,\n fetchersToLoad.map((f) => (f.controller ? f.controller.signal : null)),\n true\n ),\n ]);\n\n return {\n loaderResults,\n fetcherResults,\n };\n }\n\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.push(key);\n abortFetcher(key);\n }\n });\n }\n\n function updateFetcherState(\n key: string,\n fetcher: Fetcher,\n opts: { flushSync?: boolean } = {}\n ) {\n state.fetchers.set(key, fetcher);\n updateState(\n { fetchers: new Map(state.fetchers) },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function setFetcherError(\n key: string,\n routeId: string,\n error: any,\n opts: { flushSync?: boolean } = {}\n ) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n\n function getFetcher(key: string): Fetcher {\n if (future.v7_fetcherPersist) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n // If this fetcher was previously marked for deletion, unmark it since we\n // have a new instance\n if (deletedFetchers.has(key)) {\n deletedFetchers.delete(key);\n }\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n\n function deleteFetcher(key: string): void {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (\n fetchControllers.has(key) &&\n !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))\n ) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n deletedFetchers.delete(key);\n state.fetchers.delete(key);\n }\n\n function deleteFetcherAndUpdateState(key: string): void {\n if (future.v7_fetcherPersist) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n deletedFetchers.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n } else {\n deleteFetcher(key);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n\n function abortFetcher(key: string) {\n let controller = fetchControllers.get(key);\n invariant(controller, `Expected fetch controller: ${key}`);\n controller.abort();\n fetchControllers.delete(key);\n }\n\n function markFetchersDone(keys: string[]) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): boolean {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n\n function abortStaleFetchLoads(landedId: number): boolean {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n\n function getBlocker(key: string, fn: BlockerFunction) {\n let blocker: Blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key: string, newBlocker: Blocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(\n (blocker.state === \"unblocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"blocked\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"proceeding\") ||\n (blocker.state === \"blocked\" && newBlocker.state === \"unblocked\") ||\n (blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\"),\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\n }: {\n currentLocation: Location;\n nextLocation: Location;\n historyAction: HistoryAction;\n }): string | undefined {\n if (blockerFunctions.size === 0) {\n return;\n }\n\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n\n function handleNavigational404(pathname: string) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n\n return { notFoundMatches: matches, route, error };\n }\n\n function handleDiscoverRouteError(\n pathname: string,\n discoverResult: DiscoverRoutesErrorResult\n ) {\n return {\n boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,\n error: getInternalRouterError(400, {\n type: \"route-discovery\",\n pathname,\n message:\n discoverResult.error != null && \"message\" in discoverResult.error\n ? discoverResult.error\n : String(discoverResult.error),\n }),\n };\n }\n\n function cancelActiveDeferreds(\n predicate?: (routeId: string) => boolean\n ): string[] {\n let cancelledRouteIds: string[] = [];\n activeDeferreds.forEach((dfd, routeId) => {\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the component\n function enableScrollRestoration(\n positions: Record,\n getPosition: GetScrollPositionFunction,\n getKey?: GetScrollRestorationKeyFunction\n ) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered \n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n\n return () => {\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n\n function getScrollKey(location: Location, matches: AgnosticDataRouteMatch[]) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n\n function saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n function checkFogOfWar(\n matches: AgnosticDataRouteMatch[] | null,\n routesToUse: AgnosticDataRouteObject[],\n pathname: string\n ): { active: boolean; matches: AgnosticDataRouteMatch[] | null } {\n if (patchRoutesOnMissImpl) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n return { active: true, matches: fogMatches || [] };\n } else {\n let leafRoute = matches[matches.length - 1].route;\n if (\n leafRoute.path &&\n (leafRoute.path === \"*\" || leafRoute.path.endsWith(\"/*\"))\n ) {\n // If we matched a splat, it might only be because we haven't yet fetched\n // the children that would match with a higher score, so let's fetch\n // around and find out\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n\n return { active: false, matches: null };\n }\n\n type DiscoverRoutesSuccessResult = {\n type: \"success\";\n matches: AgnosticDataRouteMatch[] | null;\n };\n type DiscoverRoutesErrorResult = {\n type: \"error\";\n error: any;\n partialMatches: AgnosticDataRouteMatch[];\n };\n type DiscoverRoutesAbortedResult = { type: \"aborted\" };\n type DiscoverRoutesResult =\n | DiscoverRoutesSuccessResult\n | DiscoverRoutesErrorResult\n | DiscoverRoutesAbortedResult;\n\n async function discoverRoutes(\n matches: AgnosticDataRouteMatch[],\n pathname: string,\n signal: AbortSignal\n ): Promise {\n let partialMatches: AgnosticDataRouteMatch[] | null = matches;\n let route =\n partialMatches.length > 0\n ? partialMatches[partialMatches.length - 1].route\n : null;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n try {\n await loadLazyRouteChildren(\n patchRoutesOnMissImpl!,\n pathname,\n partialMatches,\n routesToUse,\n manifest,\n mapRouteProperties,\n pendingPatchRoutes,\n signal\n );\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n } finally {\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity so when we `updateState` at the end of\n // this navigation/fetch `router.routes` will be a new identity and\n // trigger a re-run of memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n }\n }\n\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n let matchedSplat = false;\n if (newMatches) {\n let leafRoute = newMatches[newMatches.length - 1].route;\n\n if (leafRoute.index) {\n // If we found an index route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n\n if (leafRoute.path && leafRoute.path.length > 0) {\n if (leafRoute.path === \"*\") {\n // If we found a splat route, we can't be sure there's not a\n // higher-scoring route down some partial matches trail so we need\n // to check that out\n matchedSplat = true;\n } else {\n // If we found a non-splat route, we can stop\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n\n let newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n\n // If we are no longer partially matching anything, this was either a\n // legit splat match above, or it's a 404. Also avoid loops if the\n // second pass results in the same partial matches\n if (\n !newPartialMatches ||\n partialMatches.map((m) => m.route.id).join(\"-\") ===\n newPartialMatches.map((m) => m.route.id).join(\"-\")\n ) {\n return { type: \"success\", matches: matchedSplat ? newMatches : null };\n }\n\n partialMatches = newPartialMatches;\n route = partialMatches[partialMatches.length - 1].route;\n if (route.path === \"*\") {\n // The splat is still our most accurate partial, so run with it\n return { type: \"success\", matches: partialMatches };\n }\n }\n }\n\n function _internalSetRoutes(newRoutes: AgnosticDataRouteObject[]) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties,\n undefined,\n manifest\n );\n }\n\n function patchRoutes(\n routeId: string | null,\n children: AgnosticRouteObject[]\n ): void {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n manifest,\n mapRouteProperties\n );\n\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity and trigger a reflow via `updateState`\n // to re-run memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to: To) => init.history.createHref(to),\n encodeLocation: (to: To) => init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher: deleteFetcherAndUpdateState,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\n/**\n * Future flags to toggle new feature behavior\n */\nexport interface StaticHandlerFutureConfig {\n v7_relativeSplatPath: boolean;\n v7_throwAbortReason: boolean;\n}\n\nexport interface CreateStaticHandlerOptions {\n basename?: string;\n /**\n * @deprecated Use `mapRouteProperties` instead\n */\n detectErrorBoundary?: DetectErrorBoundaryFunction;\n mapRouteProperties?: MapRoutePropertiesFunction;\n future?: Partial;\n}\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: CreateStaticHandlerOptions\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let manifest: RouteManifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties: MapRoutePropertiesFunction;\n if (opts?.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts?.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = (route) => ({\n hasErrorBoundary: detectErrorBoundary(route),\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Config driven behavior flags\n let future: StaticHandlerFutureConfig = {\n v7_relativeSplatPath: false,\n v7_throwAbortReason: false,\n ...(opts ? opts.future : null),\n };\n\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties,\n undefined,\n manifest\n );\n\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n *\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent\n * the bubbling of errors which allows single-fetch-type implementations\n * where the client will handle the bubbling and we may need to return data\n * for the handling route\n */\n async function query(\n request: Request,\n {\n requestContext,\n skipLoaderErrorBubbling,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n skipLoaderErrorBubbling?: boolean;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error,\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null\n );\n if (isResponse(result)) {\n return result;\n }\n\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return { location, basename, ...result };\n }\n\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n *\n * - `opts.routeId` allows you to specify the specific route handler to call.\n * If not provided the handler will determine the proper route by matching\n * against `request.url`\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n */\n async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n unstable_dataStrategy,\n }: {\n requestContext?: unknown;\n routeId?: string;\n unstable_dataStrategy?: DataStrategyFunction;\n } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let match = routeId\n ? matches.find((m) => m.route.id === routeId)\n : getTargetMatch(matches, location);\n\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId,\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n unstable_dataStrategy || null,\n false,\n match\n );\n\n if (isResponse(result)) {\n return result;\n }\n\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n\n if (result.loaderData) {\n let data = Object.values(result.loaderData)[0];\n if (result.activeDeferreds?.[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n\n return undefined;\n }\n\n async function queryImpl(\n request: Request,\n location: Location,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null\n ): Promise | Response> {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(\n request,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch\n );\n return isResponse(result)\n ? result\n : {\n ...result,\n actionData: null,\n actionHeaders: {},\n };\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction for a\n // `queryRoute` call, we throw the `HandlerResult` to bail out early\n // and then return or throw the raw Response here accordingly\n if (isHandlerResult(e) && isResponse(e.result)) {\n if (e.type === ResultType.error) {\n throw e.result;\n }\n return e.result;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n\n async function submit(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n actionMatch: AgnosticDataRouteMatch,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id,\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n } else {\n let results = await callDataStrategy(\n \"action\",\n request,\n [actionMatch],\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n result = results[0];\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n }\n\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")!,\n },\n });\n }\n\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, { type: \"defer-action\" });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error,\n };\n }\n\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null,\n };\n }\n\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal,\n });\n\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = skipLoaderErrorBubbling\n ? actionMatch\n : findNearestBoundary(matches, actionMatch.route.id);\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null,\n [boundaryMatch.route.id, result]\n );\n\n // action status codes take precedence over loader status codes\n return {\n ...context,\n statusCode: isRouteErrorResponse(result.error)\n ? result.error.status\n : result.statusCode != null\n ? result.statusCode\n : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n let context = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n unstable_dataStrategy,\n skipLoaderErrorBubbling,\n null\n );\n\n return {\n ...context,\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionHeaders: result.headers\n ? { [actionMatch.route.id]: result.headers }\n : {},\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null,\n skipLoaderErrorBubbling: boolean,\n routeMatch: AgnosticDataRouteMatch | null,\n pendingActionResult?: PendingActionResult\n ): Promise<\n | Omit<\n StaticHandlerContext,\n \"location\" | \"basename\" | \"actionData\" | \"actionHeaders\"\n >\n | Response\n > {\n let isRouteRequest = routeMatch != null;\n\n // Short circuit if we have no loaders to run (queryRoute())\n if (\n isRouteRequest &&\n !routeMatch?.route.loader &&\n !routeMatch?.route.lazy\n ) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id,\n });\n }\n\n let requestMatches = routeMatch\n ? [routeMatch]\n : pendingActionResult && isErrorResult(pendingActionResult[1])\n ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0])\n : matches;\n let matchesToLoad = requestMatches.filter(\n (m) => m.route.loader || m.route.lazy\n );\n\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce(\n (acc, m) => Object.assign(acc, { [m.route.id]: null }),\n {}\n ),\n errors:\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? {\n [pendingActionResult[0]]: pendingActionResult[1].error,\n }\n : null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await callDataStrategy(\n \"loader\",\n request,\n matchesToLoad,\n matches,\n isRouteRequest,\n requestContext,\n unstable_dataStrategy\n );\n\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n skipLoaderErrorBubbling\n );\n\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(\n matchesToLoad.map((match) => match.route.id)\n );\n matches.forEach((match) => {\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n\n return {\n ...context,\n matches,\n activeDeferreds:\n activeDeferreds.size > 0\n ? Object.fromEntries(activeDeferreds.entries())\n : null,\n };\n }\n\n // Utility wrapper for calling dataStrategy server-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n isRouteRequest: boolean,\n requestContext: unknown,\n unstable_dataStrategy: DataStrategyFunction | null\n ): Promise {\n let results = await callDataStrategyImpl(\n unstable_dataStrategy || defaultDataStrategy,\n type,\n request,\n matchesToLoad,\n matches,\n manifest,\n mapRouteProperties,\n requestContext\n );\n\n return await Promise.all(\n results.map((result, i) => {\n if (isRedirectHandlerResult(result)) {\n let response = result.result as Response;\n // Throw redirects and let the server handle them with an HTTP redirect\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n matchesToLoad[i].route.id,\n matches,\n basename,\n future.v7_relativeSplatPath\n );\n }\n if (isResponse(result.result) && isRouteRequest) {\n // For SSR single-route requests, we want to hand Responses back\n // directly without unwrapping\n throw result;\n }\n\n return convertHandlerResultToDataResult(result);\n })\n );\n }\n\n return {\n dataRoutes,\n query,\n queryRoute,\n };\n}\n\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */\nexport function getStaticContextFromError(\n routes: AgnosticDataRouteObject[],\n context: StaticHandlerContext,\n error: any\n) {\n let newContext: StaticHandlerContext = {\n ...context,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction throwStaticHandlerAbortedError(\n request: Request,\n isRouteRequest: boolean,\n future: StaticHandlerFutureConfig\n) {\n if (future.v7_throwAbortReason && request.signal.reason !== undefined) {\n throw request.signal.reason;\n }\n\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted: ${request.method} ${request.url}`);\n}\n\nfunction isSubmissionNavigation(\n opts: BaseNavigateOrFetchOptions\n): opts is SubmissionNavigateOptions {\n return (\n opts != null &&\n ((\"formData\" in opts && opts.formData != null) ||\n (\"body\" in opts && opts.body !== undefined))\n );\n}\n\nfunction normalizeTo(\n location: Path,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n prependBasename: boolean,\n to: To | null,\n v7_relativeSplatPath: boolean,\n fromRouteId?: string,\n relative?: RelativeRoutingType\n) {\n let contextualMatches: AgnosticDataRouteMatch[];\n let activeRouteMatch: AgnosticDataRouteMatch | undefined;\n if (fromRouteId) {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n\n // Resolve the relative path\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches, v7_relativeSplatPath),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n\n // Add an ?index param for matched index routes if we don't already have one\n if (\n (to == null || to === \"\" || to === \".\") &&\n activeRouteMatch &&\n activeRouteMatch.route.index &&\n !hasNakedIndexQuery(path.search)\n ) {\n path.search = path.search\n ? path.search.replace(/^\\?/, \"?index&\")\n : \"?index\";\n }\n\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname =\n path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n\n return createPath(path);\n}\n\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(\n normalizeFormMethod: boolean,\n isFetcher: boolean,\n path: string,\n opts?: BaseNavigateOrFetchOptions\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponseImpl;\n} {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod }),\n };\n }\n\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" }),\n });\n\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod\n ? (rawFormMethod.toUpperCase() as V7_FormMethod)\n : (rawFormMethod.toLowerCase() as FormMethod);\n let formAction = stripHashFromPath(path);\n\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n let text =\n typeof opts.body === \"string\"\n ? opts.body\n : opts.body instanceof FormData ||\n opts.body instanceof URLSearchParams\n ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\\n`,\n \"\"\n )\n : String(opts.body);\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text,\n },\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n\n try {\n let json =\n typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined,\n },\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n\n let searchParams: URLSearchParams;\n let formData: FormData;\n\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n\n let submission: Submission = {\n formMethod,\n formAction,\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n\n return { path: createPath(parsedPath), submission };\n}\n\n// Filter out all routes below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(\n matches: AgnosticDataRouteMatch[],\n boundaryId: string\n) {\n let boundaryMatches = matches;\n if (boundaryId) {\n let index = matches.findIndex((m) => m.route.id === boundaryId);\n if (index >= 0) {\n boundaryMatches = matches.slice(0, index);\n }\n }\n return boundaryMatches;\n}\n\nfunction getMatchesToLoad(\n history: History,\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n submission: Submission | undefined,\n location: Location,\n isInitialLoad: boolean,\n skipActionErrorRevalidation: boolean,\n isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n deletedFetchers: Set,\n fetchLoadMatches: Map,\n fetchRedirectIds: Set,\n routesToUse: AgnosticDataRouteObject[],\n basename: string | undefined,\n pendingActionResult?: PendingActionResult\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingActionResult\n ? isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : pendingActionResult[1].data\n : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[0]\n : undefined;\n let boundaryMatches = boundaryId\n ? getLoaderMatchesUntilBoundary(matches, boundaryId)\n : matches;\n\n // Don't revalidate loaders by default after action 4xx/5xx responses\n // when the flag is enabled. They can still opt-into revalidation via\n // `shouldRevalidate` via `actionResult`\n let actionStatus = pendingActionResult\n ? pendingActionResult[1].statusCode\n : undefined;\n let shouldSkipRevalidation =\n skipActionErrorRevalidation && actionStatus && actionStatus >= 400;\n\n let navigationMatches = boundaryMatches.filter((match, index) => {\n let { route } = match;\n if (route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n\n if (route.loader == null) {\n return false;\n }\n\n if (isInitialLoad) {\n if (typeof route.loader !== \"function\" || route.loader.hydrate) {\n return true;\n }\n return (\n state.loaderData[route.id] === undefined &&\n // Don't re-run if the loader ran and threw an error\n (!state.errors || state.errors[route.id] === undefined)\n );\n }\n\n // Always call the loader on new route instances and pending defer cancellations\n if (\n isNewLoader(state.loaderData, state.matches[index], match) ||\n cancelledDeferredRoutes.some((id) => id === match.route.id)\n ) {\n return true;\n }\n\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n\n return shouldRevalidateLoader(match, {\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired ||\n currentUrl.pathname + currentUrl.search ===\n nextUrl.pathname + nextUrl.search ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n isNewRouteInstance(currentRouteMatch, nextRouteMatch),\n });\n });\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches.forEach((f, key) => {\n // Don't revalidate:\n // - on initial load (shouldn't be any fetchers then anyway)\n // - if fetcher won't be present in the subsequent render\n // - no longer matches the URL (v7_fetcherPersist=false)\n // - was unmounted but persisted due to v7_fetcherPersist=true\n if (\n isInitialLoad ||\n !matches.some((m) => m.route.id === f.routeId) ||\n deletedFetchers.has(key)\n ) {\n return;\n }\n\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null,\n });\n return;\n }\n\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.includes(key)) {\n // Always revalidate if the fetcher was cancelled\n shouldRevalidate = true;\n } else if (\n fetcher &&\n fetcher.state !== \"idle\" &&\n fetcher.data === undefined\n ) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, {\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params,\n ...submission,\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation\n ? false\n : isRevalidationRequired,\n });\n }\n\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController(),\n });\n }\n });\n\n return [navigationMatches, revalidatingFetchers];\n}\n\nfunction isNewLoader(\n currentLoaderData: RouteData,\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let isNew =\n // [a] -> [a, b]\n !currentMatch ||\n // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\n\nfunction isNewRouteInstance(\n currentMatch: AgnosticDataRouteMatch,\n match: AgnosticDataRouteMatch\n) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname ||\n // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n (currentPath != null &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n loaderMatch: AgnosticDataRouteMatch,\n arg: ShouldRevalidateFunctionArgs\n) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return arg.defaultShouldRevalidate;\n}\n\n/**\n * Idempotent utility to execute patchRoutesOnMiss() to lazily load route\n * definitions and update the routes/routeManifest\n */\nasync function loadLazyRouteChildren(\n patchRoutesOnMissImpl: AgnosticPatchRoutesOnMissFunction,\n path: string,\n matches: AgnosticDataRouteMatch[],\n routes: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n pendingRouteChildren: Map>,\n signal: AbortSignal\n) {\n let key = [path, ...matches.map((m) => m.route.id)].join(\"-\");\n try {\n let pending = pendingRouteChildren.get(key);\n if (!pending) {\n pending = patchRoutesOnMissImpl({\n path,\n matches,\n patch: (routeId, children) => {\n if (!signal.aborted) {\n patchRoutesImpl(\n routeId,\n children,\n routes,\n manifest,\n mapRouteProperties\n );\n }\n },\n });\n pendingRouteChildren.set(key, pending);\n }\n\n if (pending && isPromise(pending)) {\n await pending;\n }\n } finally {\n pendingRouteChildren.delete(key);\n }\n}\n\nfunction patchRoutesImpl(\n routeId: string | null,\n children: AgnosticRouteObject[],\n routesToUse: AgnosticDataRouteObject[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction\n) {\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [routeId, \"patch\", String(route.children?.length || \"0\")],\n manifest\n );\n if (route.children) {\n route.children.push(...dataChildren);\n } else {\n route.children = dataChildren;\n }\n } else {\n let dataChildren = convertRoutesToDataRoutes(\n children,\n mapRouteProperties,\n [\"patch\", String(routesToUse.length || \"0\")],\n manifest\n );\n routesToUse.push(...dataChildren);\n }\n}\n\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */\nasync function loadLazyRouteModule(\n route: AgnosticDataRouteObject,\n mapRouteProperties: MapRoutePropertiesFunction,\n manifest: RouteManifest\n) {\n if (!route.lazy) {\n return;\n }\n\n let lazyRoute = await route.lazy();\n\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates: Record = {};\n for (let lazyRouteProperty in lazyRoute) {\n let staticRouteValue =\n routeToUpdate[lazyRouteProperty as keyof typeof routeToUpdate];\n\n let isPropertyStaticallyDefined =\n staticRouteValue !== undefined &&\n // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n\n warning(\n !isPropertyStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" ` +\n `defined but its lazy function is also returning a value for this property. ` +\n `The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n\n if (\n !isPropertyStaticallyDefined &&\n !immutableRouteKeys.has(lazyRouteProperty as ImmutableRouteKey)\n ) {\n routeUpdates[lazyRouteProperty] =\n lazyRoute[lazyRouteProperty as keyof typeof lazyRoute];\n }\n }\n\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided\n // `mapRouteProperties` (or wrapped `detectErrorBoundary`) function to\n // set the framework-aware properties (`element`/`hasErrorBoundary`) since\n // the logic will differ between frameworks.\n ...mapRouteProperties(routeToUpdate),\n lazy: undefined,\n });\n}\n\n// Default implementation of `dataStrategy` which fetches all loaders in parallel\nfunction defaultDataStrategy(\n opts: DataStrategyFunctionArgs\n): ReturnType {\n return Promise.all(opts.matches.map((m) => m.resolve()));\n}\n\nasync function callDataStrategyImpl(\n dataStrategyImpl: DataStrategyFunction,\n type: \"loader\" | \"action\",\n request: Request,\n matchesToLoad: AgnosticDataRouteMatch[],\n matches: AgnosticDataRouteMatch[],\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n requestContext?: unknown\n): Promise {\n let routeIdsToLoad = matchesToLoad.reduce(\n (acc, m) => acc.add(m.route.id),\n new Set()\n );\n let loadedMatches = new Set();\n\n // Send all matches here to allow for a middleware-type implementation.\n // handler will be a no-op for unneeded routes and we filter those results\n // back out below.\n let results = await dataStrategyImpl({\n matches: matches.map((match) => {\n let shouldLoad = routeIdsToLoad.has(match.route.id);\n // `resolve` encapsulates the route.lazy, executing the\n // loader/action, and mapping return values/thrown errors to a\n // HandlerResult. Users can pass a callback to take fine-grained control\n // over the execution of the loader/action\n let resolve: DataStrategyMatch[\"resolve\"] = (handlerOverride) => {\n loadedMatches.add(match.route.id);\n return shouldLoad\n ? callLoaderOrAction(\n type,\n request,\n match,\n manifest,\n mapRouteProperties,\n handlerOverride,\n requestContext\n )\n : Promise.resolve({ type: ResultType.data, result: undefined });\n };\n\n return {\n ...match,\n shouldLoad,\n resolve,\n };\n }),\n request,\n params: matches[0].params,\n context: requestContext,\n });\n\n // Throw if any loadRoute implementations not called since they are what\n // ensures a route is fully loaded\n matches.forEach((m) =>\n invariant(\n loadedMatches.has(m.route.id),\n `\\`match.resolve()\\` was not called for route id \"${m.route.id}\". ` +\n \"You must call `match.resolve()` on every match passed to \" +\n \"`dataStrategy` to ensure all routes are properly loaded.\"\n )\n );\n\n // Filter out any middleware-only matches for which we didn't need to run handlers\n return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id));\n}\n\n// Default logic for calling a loader/action is the user has no specified a dataStrategy\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n manifest: RouteManifest,\n mapRouteProperties: MapRoutePropertiesFunction,\n handlerOverride: Parameters[0],\n staticContext?: unknown\n): Promise {\n let result: HandlerResult;\n let onReject: (() => void) | undefined;\n\n let runHandler = (\n handler: AgnosticRouteObject[\"loader\"] | AgnosticRouteObject[\"action\"]\n ): Promise => {\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n // This will never resolve so safe to type it as Promise to\n // satisfy the function return value\n let abortPromise = new Promise((_, r) => (reject = r));\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n let actualHandler = (ctx?: unknown) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean ` +\n `\"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n params: match.params,\n context: staticContext,\n },\n ...(ctx !== undefined ? [ctx] : [])\n );\n };\n\n let handlerPromise: Promise;\n if (handlerOverride) {\n handlerPromise = handlerOverride((ctx: unknown) => actualHandler(ctx));\n } else {\n handlerPromise = (async () => {\n try {\n let val = await actualHandler();\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n }\n\n return Promise.race([handlerPromise, abortPromise]);\n };\n\n try {\n let handler = match.route[type];\n\n if (match.route.lazy) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n loadLazyRouteModule(match.route, mapRouteProperties, manifest),\n ]);\n if (handlerError !== undefined) {\n throw handlerError;\n }\n result = value!;\n } else {\n // Load lazy route module, then run any returned handler\n await loadLazyRouteModule(match.route, mapRouteProperties, manifest);\n\n handler = match.route[type];\n if (handler) {\n // Handler still runs even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id,\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return { type: ResultType.data, result: undefined };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname,\n });\n } else {\n result = await runHandler(handler);\n }\n\n invariant(\n result.result !== undefined,\n `You defined ${type === \"action\" ? \"an action\" : \"a loader\"} for route ` +\n `\"${match.route.id}\" but didn't return anything from your \\`${type}\\` ` +\n `function. Please return a value or \\`null\\`.`\n );\n } catch (e) {\n // We should already be catching and converting normal handler executions to\n // HandlerResults and returning them, so anything that throws here is an\n // unexpected error we still need to wrap\n return { type: ResultType.error, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n\n return result;\n}\n\nasync function convertHandlerResultToDataResult(\n handlerResult: HandlerResult\n): Promise {\n let { result, type, status } = handlerResult;\n\n if (isResponse(result)) {\n let data: any;\n\n try {\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n if (result.body == null) {\n data = null;\n } else {\n data = await result.json();\n }\n } else {\n data = await result.text();\n }\n } catch (e) {\n return { type: ResultType.error, error: e };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(result.status, result.statusText, data),\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers,\n };\n }\n\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : status,\n };\n }\n\n if (isDeferredData(result)) {\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: result.init?.status,\n headers: result.init?.headers && new Headers(result.init.headers),\n };\n }\n\n return { type: ResultType.data, data: result, statusCode: status };\n}\n\n// Support relative routing in internal redirects\nfunction normalizeRelativeRoutingRedirectResponse(\n response: Response,\n request: Request,\n routeId: string,\n matches: AgnosticDataRouteMatch[],\n basename: string,\n v7_relativeSplatPath: boolean\n) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n true,\n location,\n v7_relativeSplatPath\n );\n response.headers.set(\"Location\", location);\n }\n\n return response;\n}\n\nfunction normalizeRedirectLocation(\n location: string,\n currentUrl: URL,\n basename: string\n): string {\n if (ABSOLUTE_URL_REGEX.test(location)) {\n // Strip off the protocol+origin for same-origin + same-basename absolute redirects\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\")\n ? new URL(currentUrl.protocol + normalizedLocation)\n : new URL(normalizedLocation);\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n return location;\n}\n\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(\n history: History,\n location: string | Location,\n signal: AbortSignal,\n submission?: Submission\n): Request {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init: RequestInit = { signal };\n\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (\n formEncType === \"application/x-www-form-urlencoded\" &&\n submission.formData\n ) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n\n return new Request(url, init);\n}\n\nfunction convertFormDataToSearchParams(formData: FormData): URLSearchParams {\n let searchParams = new URLSearchParams();\n\n for (let [key, value] of formData.entries()) {\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n\n return searchParams;\n}\n\nfunction convertSearchParamsToFormData(\n searchParams: URLSearchParams\n): FormData {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n activeDeferreds: Map,\n skipLoaderErrorBubbling: boolean\n): {\n loaderData: RouterState[\"loaderData\"];\n errors: RouterState[\"errors\"] | null;\n statusCode: number;\n loaderHeaders: Record;\n} {\n // Fill in loaderData/errors from our loaders\n let loaderData: RouterState[\"loaderData\"] = {};\n let errors: RouterState[\"errors\"] | null = null;\n let statusCode: number | undefined;\n let foundError = false;\n let loaderHeaders: Record = {};\n let pendingError =\n pendingActionResult && isErrorResult(pendingActionResult[1])\n ? pendingActionResult[1].error\n : undefined;\n\n // Process loader results into state.loaderData/state.errors\n results.forEach((result, index) => {\n let id = matchesToLoad[index].route.id;\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError !== undefined) {\n error = pendingError;\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n // Look upwards from the matched route for the closest ancestor error\n // boundary, defaulting to the root match. Prefer higher error values\n // if lower errors bubble to the same boundary\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error)\n ? result.error.status\n : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (\n result.statusCode != null &&\n result.statusCode !== 200 &&\n !foundError\n ) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n }\n });\n\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError !== undefined && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n loaderData[pendingActionResult[0]] = undefined;\n }\n\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders,\n };\n}\n\nfunction processLoaderData(\n state: RouterState,\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingActionResult: PendingActionResult | undefined,\n revalidatingFetchers: RevalidatingFetcher[],\n fetcherResults: DataResult[],\n activeDeferreds: Map\n): {\n loaderData: RouterState[\"loaderData\"];\n errors?: RouterState[\"errors\"];\n} {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n matchesToLoad,\n results,\n pendingActionResult,\n activeDeferreds,\n false // This method is only called client side so we always want to bubble\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let { key, match, controller } = revalidatingFetchers[index];\n invariant(\n fetcherResults !== undefined && fetcherResults[index] !== undefined,\n \"Did not find corresponding fetcher result\"\n );\n let result = fetcherResults[index];\n\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n // Nothing to do for aborted fetchers\n continue;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error,\n };\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n return { loaderData, errors };\n}\n\nfunction mergeLoaderData(\n loaderData: RouteData,\n newLoaderData: RouteData,\n matches: AgnosticDataRouteMatch[],\n errors: RouteData | null | undefined\n): RouteData {\n let mergedLoaderData = { ...newLoaderData };\n for (let match of matches) {\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n } else {\n // No-op - this is so we ignore existing data if we have a key in the\n // incoming object with an undefined value, which is how we unset a prior\n // loaderData if we encounter a loader error\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n\n if (errors && errors.hasOwnProperty(id)) {\n // Don't keep any loader data below the boundary\n break;\n }\n }\n return mergedLoaderData;\n}\n\nfunction getActionDataForCommit(\n pendingActionResult: PendingActionResult | undefined\n) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1])\n ? {\n // Clear out prior actionData on errors\n actionData: {},\n }\n : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data,\n },\n };\n}\n\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(\n matches: AgnosticDataRouteMatch[],\n routeId?: string\n): AgnosticDataRouteMatch {\n let eligibleMatches = routeId\n ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1)\n : [...matches];\n return (\n eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) ||\n matches[0]\n );\n}\n\nfunction getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {\n matches: AgnosticDataRouteMatch[];\n route: AgnosticDataRouteObject;\n} {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route =\n routes.length === 1\n ? routes[0]\n : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`,\n };\n\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route,\n },\n ],\n route,\n };\n}\n\nfunction getInternalRouterError(\n status: number,\n {\n pathname,\n routeId,\n method,\n type,\n message,\n }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\" | \"invalid-body\" | \"route-discovery\";\n message?: string;\n } = {}\n) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n\n if (status === 400) {\n statusText = \"Bad Request\";\n if (type === \"route-discovery\") {\n errorMessage =\n `Unable to match URL \"${pathname}\" - the \\`unstable_patchRoutesOnMiss()\\` ` +\n `function threw the following error:\\n${message}`;\n } else if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method} request to \"${pathname}\" but ` +\n `did not provide a \\`loader\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage =\n `You made a ${method.toUpperCase()} request to \"${pathname}\" but ` +\n `did not provide an \\`action\\` for route \"${routeId}\", ` +\n `so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\n\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(\n results: DataResult[]\n): { result: RedirectResult; idx: number } | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return { result, idx: i };\n }\n }\n}\n\nfunction stripHashFromPath(path: To) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\n\nfunction isHashChangeOnly(a: Location, b: Location): boolean {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\n\nfunction isPromise(val: unknown): val is Promise {\n return typeof val === \"object\" && val != null && \"then\" in val;\n}\n\nfunction isHandlerResult(result: unknown): result is HandlerResult {\n return (\n result != null &&\n typeof result === \"object\" &&\n \"type\" in result &&\n \"result\" in result &&\n (result.type === ResultType.data || result.type === ResultType.error)\n );\n}\n\nfunction isRedirectHandlerResult(result: HandlerResult) {\n return (\n isResponse(result.result) && redirectStatusCodes.has(result.result.status)\n );\n}\n\nfunction isDeferredResult(result: DataResult): result is DeferredResult {\n return result.type === ResultType.deferred;\n}\n\nfunction isErrorResult(result: DataResult): result is ErrorResult {\n return result.type === ResultType.error;\n}\n\nfunction isRedirectResult(result?: DataResult): result is RedirectResult {\n return (result && result.type) === ResultType.redirect;\n}\n\nexport function isDeferredData(value: any): value is DeferredData {\n let deferred: DeferredData = value;\n return (\n deferred &&\n typeof deferred === \"object\" &&\n typeof deferred.data === \"object\" &&\n typeof deferred.subscribe === \"function\" &&\n typeof deferred.cancel === \"function\" &&\n typeof deferred.resolveData === \"function\"\n );\n}\n\nfunction isResponse(value: any): value is Response {\n return (\n value != null &&\n typeof value.status === \"number\" &&\n typeof value.statusText === \"string\" &&\n typeof value.headers === \"object\" &&\n typeof value.body !== \"undefined\"\n );\n}\n\nfunction isRedirectResponse(result: any): result is Response {\n if (!isResponse(result)) {\n return false;\n }\n\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\n\nfunction isValidMethod(method: string): method is FormMethod | V7_FormMethod {\n return validRequestMethods.has(method.toLowerCase() as FormMethod);\n}\n\nfunction isMutationMethod(\n method: string\n): method is MutationFormMethod | V7_MutationFormMethod {\n return validMutationMethods.has(method.toLowerCase() as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: (AgnosticDataRouteMatch | null)[],\n results: DataResult[],\n signals: (AbortSignal | null)[],\n isFetcher: boolean,\n currentLoaderData?: RouteData\n) {\n for (let index = 0; index < results.length; index++) {\n let result = results[index];\n let match = matchesToLoad[index];\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n\n let currentMatch = currentMatches.find(\n (m) => m.route.id === match!.route.id\n );\n let isRevalidatingLoader =\n currentMatch != null &&\n !isNewRouteInstance(currentMatch, match) &&\n (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n\n if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n let signal = signals[index];\n invariant(\n signal,\n \"Expected an AbortSignal for revalidating fetcher deferred result\"\n );\n await resolveDeferredData(result, signal, isFetcher).then((result) => {\n if (result) {\n results[index] = result || results[index];\n }\n });\n }\n }\n}\n\nasync function resolveDeferredData(\n result: DeferredResult,\n signal: AbortSignal,\n unwrap = false\n): Promise {\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData,\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e,\n };\n }\n }\n\n return {\n type: ResultType.data,\n data: result.deferredData.data,\n };\n}\n\nfunction hasNakedIndexQuery(search: string): boolean {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\n\nfunction getTargetMatch(\n matches: AgnosticDataRouteMatch[],\n location: Location | string\n) {\n let search =\n typeof location === \"string\" ? parsePath(location).search : location.search;\n if (\n matches[matches.length - 1].route.index &&\n hasNakedIndexQuery(search || \"\")\n ) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\n\nfunction getSubmissionFromNavigation(\n navigation: Navigation\n): Submission | undefined {\n let { formMethod, formAction, formEncType, text, formData, json } =\n navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text,\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined,\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined,\n };\n }\n}\n\nfunction getLoadingNavigation(\n location: Location,\n submission?: Submission\n): NavigationStates[\"Loading\"] {\n if (submission) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n } else {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n };\n return navigation;\n }\n}\n\nfunction getSubmittingNavigation(\n location: Location,\n submission: Submission\n): NavigationStates[\"Submitting\"] {\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n };\n return navigation;\n}\n\nfunction getLoadingFetcher(\n submission?: Submission,\n data?: Fetcher[\"data\"]\n): FetcherStates[\"Loading\"] {\n if (submission) {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data,\n };\n return fetcher;\n } else {\n let fetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n }\n}\n\nfunction getSubmittingFetcher(\n submission: Submission,\n existingFetcher?: Fetcher\n): FetcherStates[\"Submitting\"] {\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined,\n };\n return fetcher;\n}\n\nfunction getDoneFetcher(data: Fetcher[\"data\"]): FetcherStates[\"Idle\"] {\n let fetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n };\n return fetcher;\n}\n\nfunction restoreAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n // no-op, use default empty object\n }\n}\n\nfunction persistAppliedTransitions(\n _window: Window,\n transitions: Map>\n) {\n if (transitions.size > 0) {\n let json: Record = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\n//#endregion\n"],"names":["Action","PopStateEventType","invariant","value","message","Error","warning","cond","console","warn","e","getHistoryState","location","index","usr","state","key","idx","createLocation","current","to","_extends","pathname","search","hash","parsePath","Math","random","toString","substr","createPath","_ref","charAt","path","parsedPath","hashIndex","indexOf","searchIndex","getUrlBasedHistory","getLocation","createHref","validateLocation","options","window","document","defaultView","v5Compat","globalHistory","history","action","Pop","listener","getIndex","handlePop","nextIndex","delta","createURL","base","origin","href","replace","URL","replaceState","listen","fn","addEventListener","removeEventListener","encodeLocation","url","push","Push","historyState","pushState","error","DOMException","name","assign","Replace","go","n","ResultType","immutableRouteKeys","Set","convertRoutesToDataRoutes","routes","mapRouteProperties","parentPath","manifest","map","route","treePath","String","id","join","children","isIndexRoute","indexRoute","pathOrLayoutRoute","undefined","matchRoutes","locationArg","basename","matchRoutesImpl","allowPartial","stripBasename","branches","flattenRoutes","sort","a","b","score","length","slice","every","i","compareIndexes","routesMeta","meta","childrenIndex","rankRouteBranches","matches","decoded","decodePath","matchRouteBranch","convertRouteMatchToUiMatch","match","loaderData","params","data","handle","parentsMeta","flattenRoute","relativePath","caseSensitive","startsWith","joinPaths","concat","computeScore","forEach","_route$path","includes","exploded","explodeOptionalSegments","segments","split","first","rest","isOptional","endsWith","required","restExploded","result","subpath","paramRe","isSplat","s","initialScore","some","filter","reduce","segment","test","branch","matchedParams","matchedPathname","end","remainingPathname","matchPath","Object","pathnameBase","normalizePathname","pattern","matcher","compiledParams","regexpSource","_","paramName","RegExp","compilePath","captureGroups","memo","splatValue","v","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","pop","resolvePathname","normalizeSearch","normalizeHash","getInvalidPathError","char","field","dest","JSON","stringify","getPathContributingMatches","getResolveToMatches","v7_relativeSplatPath","pathMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","from","isEmptyPath","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","paths","AbortedDeferredError","DeferredData","constructor","responseInit","reject","this","pendingKeysSet","subscribers","deferredKeys","Array","isArray","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","entries","acc","_ref2","trackPromise","done","init","add","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","undefinedError","emit","settledKey","subscriber","subscribe","cancel","abort","k","async","resolve","size","unwrappedData","_ref3","unwrapTrackedPromise","pendingKeys","_tracked","isTrackedPromise","_error","_data","defer","redirect","status","headers","Headers","set","Response","ErrorResponseImpl","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","json","text","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","ABSOLUTE_URL_REGEX","defaultMapRouteProperties","hasErrorBoundary","Boolean","TRANSITIONS_STORAGE_KEY","UNSAFE_DEFERRED_SYMBOL","Symbol","throwStaticHandlerAbortedError","request","isRouteRequest","future","v7_throwAbortReason","reason","method","normalizeTo","prependBasename","fromRouteId","relative","contextualMatches","activeRouteMatch","hasNakedIndexQuery","normalizeNavigateOptions","normalizeFormMethod","isFetcher","opts","body","isSubmissionNavigation","isValidMethod","getInternalRouterError","searchParams","getInvalidBodyError","type","rawFormMethod","toUpperCase","stripHashFromPath","isMutationMethod","FormData","URLSearchParams","_ref5","submission","parse","convertFormDataToSearchParams","convertSearchParamsToFormData","append","getLoaderMatchesUntilBoundary","boundaryId","boundaryMatches","findIndex","m","getMatchesToLoad","isInitialLoad","skipActionErrorRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","deletedFetchers","fetchLoadMatches","fetchRedirectIds","routesToUse","pendingActionResult","actionResult","isErrorResult","currentUrl","nextUrl","actionStatus","statusCode","shouldSkipRevalidation","navigationMatches","lazy","loader","hydrate","errors","currentLoaderData","currentMatch","isNew","isMissingData","isNewLoader","currentRouteMatch","nextRouteMatch","shouldRevalidateLoader","currentParams","nextParams","defaultShouldRevalidate","isNewRouteInstance","revalidatingFetchers","f","routeId","has","fetcherMatches","fetcher","fetchers","fetcherMatch","getTargetMatch","shouldRevalidate","currentPath","loaderMatch","arg","routeChoice","loadLazyRouteChildren","patchRoutesOnMissImpl","pendingRouteChildren","pending","patch","patchRoutesImpl","val","_route$children","dataChildren","loadLazyRouteModule","lazyRoute","routeToUpdate","routeUpdates","lazyRouteProperty","isPropertyStaticallyDefined","defaultDataStrategy","all","callDataStrategyImpl","dataStrategyImpl","matchesToLoad","requestContext","routeIdsToLoad","loadedMatches","results","shouldLoad","handlerOverride","staticContext","onReject","runHandler","handler","handlerPromise","actualHandler","ctx","context","handlerError","callLoaderOrAction","convertHandlerResultToDataResult","handlerResult","isResponse","contentType","isDeferredData","deferred","deferredData","_result$init","_result$init2","normalizeRelativeRoutingRedirectResponse","response","trimmedMatches","normalizeRedirectLocation","normalizedLocation","protocol","isSameBasename","createClientSideRequest","Request","processRouteLoaderData","activeDeferreds","skipLoaderErrorBubbling","foundError","loaderHeaders","pendingError","isRedirectResult","boundaryMatch","findNearestBoundary","isDeferredResult","processLoaderData","fetcherResults","doneFetcher","getDoneFetcher","mergeLoaderData","newLoaderData","mergedLoaderData","hasOwnProperty","getActionDataForCommit","actionData","reverse","find","getShortCircuitMatches","_temp5","errorMessage","findRedirect","isRedirectHandlerResult","resolveData","resolveDeferredResults","currentMatches","signals","isRevalidatingLoader","resolveDeferredData","unwrap","getAll","getSubmissionFromNavigation","navigation","getLoadingNavigation","getSubmittingNavigation","getLoadingFetcher","querySelector","getAttribute","initialEntries","initialIndex","entry","createMemoryLocation","clampIndex","min","max","getCurrentLocation","nextLocation","splice","routerWindow","isBrowser","createElement","isServer","detectErrorBoundary","inFlightDataRoutes","initialized","router","dataRoutes","unstable_dataStrategy","unstable_patchRoutesOnMiss","v7_fetcherPersist","v7_normalizeFormMethod","v7_partialHydration","v7_prependBasename","v7_skipActionErrorRevalidation","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","checkFogOfWar","active","isRouteInitialized","pendingNavigationController","historyAction","restoreScrollPosition","preventScrollReset","revalidation","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingViewTransitionEnabled","appliedViewTransitions","removePageHideEventListener","isUninterruptedRevalidation","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","activeFetchers","blockerFunctions","pendingPatchRoutes","ignoreNextHistoryUpdate","updateState","newState","completedFetchers","deletedFetchersKeys","unstable_viewTransitionOpts","viewTransitionOpts","unstable_flushSync","flushSync","deleteFetcher","completeNavigation","_temp","_location$state","_location$state2","isActionReload","_isRedirect","keys","priorPaths","currentLocation","toPaths","getSavedScrollPosition","startNavigation","startUninterruptedRevalidation","getScrollKey","saveScrollPosition","enableViewTransition","loadingNavigation","overrideNavigation","fogOfWar","notFoundMatches","handleNavigational404","isHashChangeOnly","isFogOfWar","interruptActiveLoads","discoverResult","discoverRoutes","shortCircuited","handleDiscoverRouteError","partialMatches","actionMatch","callDataStrategy","startRedirectNavigation","handleAction","updatedMatches","fetcherSubmission","initialHydration","activeSubmission","shouldUpdateNavigationState","getUpdatedActionData","cancelActiveDeferreds","updatedFetchers","markFetchRedirectsDone","updates","rf","revalidatingFetcher","getUpdatedRevalidatingFetchers","abortFetcher","abortPendingFetchRevalidations","loaderResults","callLoadersAndMaybeResolveData","fetcherKey","didAbortFetchLoads","abortStaleFetchLoads","shouldUpdateFetchers","handleLoaders","_temp2","redirectLocation","isDocumentReload","redirectHistoryAction","fetchersToLoad","updateFetcherState","setFetcherError","getFetcher","markFetchersDone","doneKeys","landedId","yeetedKeys","deleteBlocker","updateBlocker","newBlocker","blocker","shouldBlockNavigation","_ref4","blockerKey","blockerFunction","predicate","cancelledRouteIds","dfd","y","leafRoute","isNonHMR","newMatches","matchedSplat","newPartialMatches","initialize","_window","transitions","sessionPositions","sessionStorage","getItem","restoreAppliedTransitions","_saveAppliedTransitions","setItem","persistAppliedTransitions","enableScrollRestoration","positions","getPosition","getKey","navigate","normalizedPath","userReplace","unstable_viewTransition","fetch","requestMatches","detectAndHandle405Error","existingFetcher","getSubmittingFetcher","abortController","fetchRequest","originatingLoadId","revalidationRequest","loadId","loadFetcher","staleKey","handleFetcherAction","handleFetcherLoader","revalidate","count","dispose","clear","getBlocker","patchRoutes","_internalFetchControllers","_internalActiveDeferreds","_internalSetRoutes","newRoutes","queryImpl","routeMatch","Location","actionHeaders","loaderRequest","loadRouteData","submit","isHandlerResult","isRedirectResponse","executedLoaders","fromEntries","query","_temp3","methodNotAllowedMatches","queryRoute","_temp4","values","_result$activeDeferre","originalPath","prefix","p","array","keyMatch","optional","param","_deepestRenderedBoundaryId","redirectDocument"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@remix-run/router/dist/utils.d.ts b/node_modules/@remix-run/router/dist/utils.d.ts new file mode 100644 index 0000000000..5d4d1d9a68 --- /dev/null +++ b/node_modules/@remix-run/router/dist/utils.d.ts @@ -0,0 +1,529 @@ +import type { Location, Path, To } from "./history"; +/** + * Map of routeId -> data returned from a loader/action/error + */ +export interface RouteData { + [routeId: string]: any; +} +export declare enum ResultType { + data = "data", + deferred = "deferred", + redirect = "redirect", + error = "error" +} +/** + * Successful result from a loader or action + */ +export interface SuccessResult { + type: ResultType.data; + data: unknown; + statusCode?: number; + headers?: Headers; +} +/** + * Successful defer() result from a loader or action + */ +export interface DeferredResult { + type: ResultType.deferred; + deferredData: DeferredData; + statusCode?: number; + headers?: Headers; +} +/** + * Redirect result from a loader or action + */ +export interface RedirectResult { + type: ResultType.redirect; + response: Response; +} +/** + * Unsuccessful result from a loader or action + */ +export interface ErrorResult { + type: ResultType.error; + error: unknown; + statusCode?: number; + headers?: Headers; +} +/** + * Result from a loader or action - potentially successful or unsuccessful + */ +export type DataResult = SuccessResult | DeferredResult | RedirectResult | ErrorResult; +/** + * Result from a loader or action called via dataStrategy + */ +export interface HandlerResult { + type: "data" | "error"; + result: unknown; + status?: number; +} +type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete"; +type UpperCaseFormMethod = Uppercase; +/** + * Users can specify either lowercase or uppercase form methods on ``, + * useSubmit(), ``, etc. + */ +export type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod; +/** + * Active navigation/fetcher form methods are exposed in lowercase on the + * RouterState + */ +export type FormMethod = LowerCaseFormMethod; +export type MutationFormMethod = Exclude; +/** + * In v7, active navigation/fetcher form methods are exposed in uppercase on the + * RouterState. This is to align with the normalization done via fetch(). + */ +export type V7_FormMethod = UpperCaseFormMethod; +export type V7_MutationFormMethod = Exclude; +export type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data" | "application/json" | "text/plain"; +type JsonObject = { + [Key in string]: JsonValue; +} & { + [Key in string]?: JsonValue | undefined; +}; +type JsonArray = JsonValue[] | readonly JsonValue[]; +type JsonPrimitive = string | number | boolean | null; +type JsonValue = JsonPrimitive | JsonObject | JsonArray; +/** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ +export type Submission = { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + json: undefined; + text: undefined; +} | { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: undefined; + json: JsonValue; + text: undefined; +} | { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: undefined; + json: undefined; + text: string; +}; +/** + * @private + * Arguments passed to route loader/action functions. Same for now but we keep + * this as a private implementation detail in case they diverge in the future. + */ +interface DataFunctionArgs { + request: Request; + params: Params; + context?: Context; +} +/** + * Arguments passed to loader functions + */ +export interface LoaderFunctionArgs extends DataFunctionArgs { +} +/** + * Arguments passed to action functions + */ +export interface ActionFunctionArgs extends DataFunctionArgs { +} +/** + * Loaders and actions can return anything except `undefined` (`null` is a + * valid return value if there is no data to return). Responses are preferred + * and will ease any future migration to Remix + */ +type DataFunctionValue = Response | NonNullable | null; +type DataFunctionReturnValue = Promise | DataFunctionValue; +/** + * Route loader function signature + */ +export type LoaderFunction = { + (args: LoaderFunctionArgs, handlerCtx?: unknown): DataFunctionReturnValue; +} & { + hydrate?: boolean; +}; +/** + * Route action function signature + */ +export interface ActionFunction { + (args: ActionFunctionArgs, handlerCtx?: unknown): DataFunctionReturnValue; +} +/** + * Arguments passed to shouldRevalidate function + */ +export interface ShouldRevalidateFunctionArgs { + currentUrl: URL; + currentParams: AgnosticDataRouteMatch["params"]; + nextUrl: URL; + nextParams: AgnosticDataRouteMatch["params"]; + formMethod?: Submission["formMethod"]; + formAction?: Submission["formAction"]; + formEncType?: Submission["formEncType"]; + text?: Submission["text"]; + formData?: Submission["formData"]; + json?: Submission["json"]; + actionStatus?: number; + actionResult?: any; + defaultShouldRevalidate: boolean; +} +/** + * Route shouldRevalidate function signature. This runs after any submission + * (navigation or fetcher), so we flatten the navigation/fetcher submission + * onto the arguments. It shouldn't matter whether it came from a navigation + * or a fetcher, what really matters is the URLs and the formData since loaders + * have to re-run based on the data models that were potentially mutated. + */ +export interface ShouldRevalidateFunction { + (args: ShouldRevalidateFunctionArgs): boolean; +} +/** + * Function provided by the framework-aware layers to set `hasErrorBoundary` + * from the framework-aware `errorElement` prop + * + * @deprecated Use `mapRouteProperties` instead + */ +export interface DetectErrorBoundaryFunction { + (route: AgnosticRouteObject): boolean; +} +export interface DataStrategyMatch extends AgnosticRouteMatch { + shouldLoad: boolean; + resolve: (handlerOverride?: (handler: (ctx?: unknown) => DataFunctionReturnValue) => Promise) => Promise; +} +export interface DataStrategyFunctionArgs extends DataFunctionArgs { + matches: DataStrategyMatch[]; +} +export interface DataStrategyFunction { + (args: DataStrategyFunctionArgs): Promise; +} +export interface AgnosticPatchRoutesOnMissFunction { + (opts: { + path: string; + matches: M[]; + patch: (routeId: string | null, children: AgnosticRouteObject[]) => void; + }): void | Promise; +} +/** + * Function provided by the framework-aware layers to set any framework-specific + * properties from framework-agnostic properties + */ +export interface MapRoutePropertiesFunction { + (route: AgnosticRouteObject): { + hasErrorBoundary: boolean; + } & Record; +} +/** + * Keys we cannot change from within a lazy() function. We spread all other keys + * onto the route. Either they're meaningful to the router, or they'll get + * ignored. + */ +export type ImmutableRouteKey = "lazy" | "caseSensitive" | "path" | "id" | "index" | "children"; +export declare const immutableRouteKeys: Set; +type RequireOne = Exclude<{ + [K in keyof T]: K extends Key ? Omit & Required> : never; +}[keyof T], undefined>; +/** + * lazy() function to load a route definition, which can add non-matching + * related properties to a route + */ +export interface LazyRouteFunction { + (): Promise>>; +} +/** + * Base RouteObject with common props shared by all types of routes + */ +type AgnosticBaseRouteObject = { + caseSensitive?: boolean; + path?: string; + id?: string; + loader?: LoaderFunction | boolean; + action?: ActionFunction | boolean; + hasErrorBoundary?: boolean; + shouldRevalidate?: ShouldRevalidateFunction; + handle?: any; + lazy?: LazyRouteFunction; +}; +/** + * Index routes must not have children + */ +export type AgnosticIndexRouteObject = AgnosticBaseRouteObject & { + children?: undefined; + index: true; +}; +/** + * Non-index routes may have children, but cannot have index + */ +export type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & { + children?: AgnosticRouteObject[]; + index?: false; +}; +/** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ +export type AgnosticRouteObject = AgnosticIndexRouteObject | AgnosticNonIndexRouteObject; +export type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & { + id: string; +}; +export type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & { + children?: AgnosticDataRouteObject[]; + id: string; +}; +/** + * A data route object, which is just a RouteObject with a required unique ID + */ +export type AgnosticDataRouteObject = AgnosticDataIndexRouteObject | AgnosticDataNonIndexRouteObject; +export type RouteManifest = Record; +type _PathParam = Path extends `${infer L}/${infer R}` ? _PathParam | _PathParam : Path extends `:${infer Param}` ? Param extends `${infer Optional}?` ? Optional : Param : never; +/** + * Examples: + * "/a/b/*" -> "*" + * ":a" -> "a" + * "/a/:b" -> "b" + * "/a/blahblahblah:b" -> "b" + * "/:a/:b" -> "a" | "b" + * "/:a/b/:c/*" -> "a" | "c" | "*" + */ +export type PathParam = Path extends "*" | "/*" ? "*" : Path extends `${infer Rest}/*` ? "*" | _PathParam : _PathParam; +export type ParamParseKey = [ + PathParam +] extends [never] ? string : PathParam; +/** + * The parameters that were parsed from the URL path. + */ +export type Params = { + readonly [key in Key]: string | undefined; +}; +/** + * A RouteMatch contains info about how a route matched a URL. + */ +export interface AgnosticRouteMatch { + /** + * The names and values of dynamic parameters in the URL. + */ + params: Params; + /** + * The portion of the URL pathname that was matched. + */ + pathname: string; + /** + * The portion of the URL pathname that was matched before child routes. + */ + pathnameBase: string; + /** + * The route object that was used to match. + */ + route: RouteObjectType; +} +export interface AgnosticDataRouteMatch extends AgnosticRouteMatch { +} +export declare function convertRoutesToDataRoutes(routes: AgnosticRouteObject[], mapRouteProperties: MapRoutePropertiesFunction, parentPath?: string[], manifest?: RouteManifest): AgnosticDataRouteObject[]; +/** + * Matches the given routes to a location and returns the match data. + * + * @see https://reactrouter.com/utils/match-routes + */ +export declare function matchRoutes(routes: RouteObjectType[], locationArg: Partial | string, basename?: string): AgnosticRouteMatch[] | null; +export declare function matchRoutesImpl(routes: RouteObjectType[], locationArg: Partial | string, basename: string, allowPartial: boolean): AgnosticRouteMatch[] | null; +export interface UIMatch { + id: string; + pathname: string; + params: AgnosticRouteMatch["params"]; + data: Data; + handle: Handle; +} +export declare function convertRouteMatchToUiMatch(match: AgnosticDataRouteMatch, loaderData: RouteData): UIMatch; +/** + * Returns a path with params interpolated. + * + * @see https://reactrouter.com/utils/generate-path + */ +export declare function generatePath(originalPath: Path, params?: { + [key in PathParam]: string | null; +}): string; +/** + * A PathPattern is used to match on some portion of a URL pathname. + */ +export interface PathPattern { + /** + * A string to match against a URL pathname. May contain `:id`-style segments + * to indicate placeholders for dynamic parameters. May also end with `/*` to + * indicate matching the rest of the URL pathname. + */ + path: Path; + /** + * Should be `true` if the static portions of the `path` should be matched in + * the same case. + */ + caseSensitive?: boolean; + /** + * Should be `true` if this pattern should match the entire URL pathname. + */ + end?: boolean; +} +/** + * A PathMatch contains info about how a PathPattern matched on a URL pathname. + */ +export interface PathMatch { + /** + * The names and values of dynamic parameters in the URL. + */ + params: Params; + /** + * The portion of the URL pathname that was matched. + */ + pathname: string; + /** + * The portion of the URL pathname that was matched before child routes. + */ + pathnameBase: string; + /** + * The pattern that was used to match. + */ + pattern: PathPattern; +} +/** + * Performs pattern matching on a URL pathname and returns information about + * the match. + * + * @see https://reactrouter.com/utils/match-path + */ +export declare function matchPath, Path extends string>(pattern: PathPattern | Path, pathname: string): PathMatch | null; +export declare function decodePath(value: string): string; +/** + * @private + */ +export declare function stripBasename(pathname: string, basename: string): string | null; +/** + * Returns a resolved path object relative to the given pathname. + * + * @see https://reactrouter.com/utils/resolve-path + */ +export declare function resolvePath(to: To, fromPathname?: string): Path; +/** + * @private + * + * When processing relative navigation we want to ignore ancestor routes that + * do not contribute to the path, such that index/pathless layout routes don't + * interfere. + * + * For example, when moving a route element into an index route and/or a + * pathless layout route, relative link behavior contained within should stay + * the same. Both of the following examples should link back to the root: + * + * + * + * + * + * + * + * }> // <-- Does not contribute + * // <-- Does not contribute + * + * + */ +export declare function getPathContributingMatches(matches: T[]): T[]; +export declare function getResolveToMatches(matches: T[], v7_relativeSplatPath: boolean): string[]; +/** + * @private + */ +export declare function resolveTo(toArg: To, routePathnames: string[], locationPathname: string, isPathRelative?: boolean): Path; +/** + * @private + */ +export declare function getToPathname(to: To): string | undefined; +/** + * @private + */ +export declare const joinPaths: (paths: string[]) => string; +/** + * @private + */ +export declare const normalizePathname: (pathname: string) => string; +/** + * @private + */ +export declare const normalizeSearch: (search: string) => string; +/** + * @private + */ +export declare const normalizeHash: (hash: string) => string; +export type JsonFunction = (data: Data, init?: number | ResponseInit) => Response; +/** + * This is a shortcut for creating `application/json` responses. Converts `data` + * to JSON and sets the `Content-Type` header. + */ +export declare const json: JsonFunction; +export interface TrackedPromise extends Promise { + _tracked?: boolean; + _data?: any; + _error?: any; +} +export declare class AbortedDeferredError extends Error { +} +export declare class DeferredData { + private pendingKeysSet; + private controller; + private abortPromise; + private unlistenAbortSignal; + private subscribers; + data: Record; + init?: ResponseInit; + deferredKeys: string[]; + constructor(data: Record, responseInit?: ResponseInit); + private trackPromise; + private onSettle; + private emit; + subscribe(fn: (aborted: boolean, settledKey?: string) => void): () => boolean; + cancel(): void; + resolveData(signal: AbortSignal): Promise; + get done(): boolean; + get unwrappedData(): {}; + get pendingKeys(): string[]; +} +export type DeferFunction = (data: Record, init?: number | ResponseInit) => DeferredData; +export declare const defer: DeferFunction; +export type RedirectFunction = (url: string, init?: number | ResponseInit) => Response; +/** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +export declare const redirect: RedirectFunction; +/** + * A redirect response that will force a document reload to the new location. + * Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +export declare const redirectDocument: RedirectFunction; +export type ErrorResponse = { + status: number; + statusText: string; + data: any; +}; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + * + * We don't export the class for public use since it's an implementation + * detail, but we export the interface above so folks can build their own + * abstractions around instances via isRouteErrorResponse() + */ +export declare class ErrorResponseImpl implements ErrorResponse { + status: number; + statusText: string; + data: any; + private error?; + private internal; + constructor(status: number, statusText: string | undefined, data: any, internal?: boolean); +} +/** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response thrown from an action/loader + */ +export declare function isRouteErrorResponse(error: any): error is ErrorResponse; +export {}; diff --git a/node_modules/@remix-run/router/history.ts b/node_modules/@remix-run/router/history.ts new file mode 100644 index 0000000000..335645db1c --- /dev/null +++ b/node_modules/@remix-run/router/history.ts @@ -0,0 +1,746 @@ +//////////////////////////////////////////////////////////////////////////////// +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// + +/** + * Actions represent the type of change to a location value. + */ +export enum Action { + /** + * A POP indicates a change to an arbitrary index in the history stack, such + * as a back or forward navigation. It does not describe the direction of the + * navigation, only that the current index changed. + * + * Note: This is the default action for newly created history objects. + */ + Pop = "POP", + + /** + * A PUSH indicates a new entry being added to the history stack, such as when + * a link is clicked and a new page loads. When this happens, all subsequent + * entries in the stack are lost. + */ + Push = "PUSH", + + /** + * A REPLACE indicates the entry at the current index in the history stack + * being replaced by a new one. + */ + Replace = "REPLACE", +} + +/** + * The pathname, search, and hash values of a URL. + */ +export interface Path { + /** + * A URL pathname, beginning with a /. + */ + pathname: string; + + /** + * A URL search string, beginning with a ?. + */ + search: string; + + /** + * A URL fragment identifier, beginning with a #. + */ + hash: string; +} + +// TODO: (v7) Change the Location generic default from `any` to `unknown` and +// remove Remix `useLocation` wrapper. + +/** + * An entry in a history stack. A location contains information about the + * URL path, as well as possibly some arbitrary state and a key. + */ +export interface Location extends Path { + /** + * A value of arbitrary data associated with this location. + */ + state: State; + + /** + * A unique string associated with this location. May be used to safely store + * and retrieve data in some other storage API, like `localStorage`. + * + * Note: This value is always "default" on the initial location. + */ + key: string; +} + +/** + * A change to the current location. + */ +export interface Update { + /** + * The action that triggered the change. + */ + action: Action; + + /** + * The new location. + */ + location: Location; + + /** + * The delta between this location and the former location in the history stack + */ + delta: number | null; +} + +/** + * A function that receives notifications about location changes. + */ +export interface Listener { + (update: Update): void; +} + +/** + * Describes a location that is the destination of some navigation, either via + * `history.push` or `history.replace`. This may be either a URL or the pieces + * of a URL path. + */ +export type To = string | Partial; + +/** + * A history is an interface to the navigation stack. The history serves as the + * source of truth for the current location, as well as provides a set of + * methods that may be used to change it. + * + * It is similar to the DOM's `window.history` object, but with a smaller, more + * focused API. + */ +export interface History { + /** + * The last action that modified the current location. This will always be + * Action.Pop when a history instance is first created. This value is mutable. + */ + readonly action: Action; + + /** + * The current location. This value is mutable. + */ + readonly location: Location; + + /** + * Returns a valid href for the given `to` value that may be used as + * the value of an attribute. + * + * @param to - The destination URL + */ + createHref(to: To): string; + + /** + * Returns a URL for the given `to` value + * + * @param to - The destination URL + */ + createURL(to: To): URL; + + /** + * Encode a location the same way window.history would do (no-op for memory + * history) so we ensure our PUSH/REPLACE navigations for data routers + * behave the same as POP + * + * @param to Unencoded path + */ + encodeLocation(to: To): Path; + + /** + * Pushes a new location onto the history stack, increasing its length by one. + * If there were any entries in the stack after the current one, they are + * lost. + * + * @param to - The new URL + * @param state - Data to associate with the new location + */ + push(to: To, state?: any): void; + + /** + * Replaces the current location in the history stack with a new one. The + * location that was replaced will no longer be available. + * + * @param to - The new URL + * @param state - Data to associate with the new location + */ + replace(to: To, state?: any): void; + + /** + * Navigates `n` entries backward/forward in the history stack relative to the + * current index. For example, a "back" navigation would use go(-1). + * + * @param delta - The delta in the stack index + */ + go(delta: number): void; + + /** + * Sets up a listener that will be called whenever the current location + * changes. + * + * @param listener - A function that will be called when the location changes + * @returns unlisten - A function that may be used to stop listening + */ + listen(listener: Listener): () => void; +} + +type HistoryState = { + usr: any; + key?: string; + idx: number; +}; + +const PopStateEventType = "popstate"; +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Memory History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A user-supplied object that describes a location. Used when providing + * entries to `createMemoryHistory` via its `initialEntries` option. + */ +export type InitialEntry = string | Partial; + +export type MemoryHistoryOptions = { + initialEntries?: InitialEntry[]; + initialIndex?: number; + v5Compat?: boolean; +}; + +/** + * A memory history stores locations in memory. This is useful in stateful + * environments where there is no web browser, such as node tests or React + * Native. + */ +export interface MemoryHistory extends History { + /** + * The current index in the history stack. + */ + readonly index: number; +} + +/** + * Memory history stores the current location in memory. It is designed for use + * in stateful non-browser environments like tests and React Native. + */ +export function createMemoryHistory( + options: MemoryHistoryOptions = {} +): MemoryHistory { + let { initialEntries = ["/"], initialIndex, v5Compat = false } = options; + let entries: Location[]; // Declare so we can access from createMemoryLocation + entries = initialEntries.map((entry, index) => + createMemoryLocation( + entry, + typeof entry === "string" ? null : entry.state, + index === 0 ? "default" : undefined + ) + ); + let index = clampIndex( + initialIndex == null ? entries.length - 1 : initialIndex + ); + let action = Action.Pop; + let listener: Listener | null = null; + + function clampIndex(n: number): number { + return Math.min(Math.max(n, 0), entries.length - 1); + } + function getCurrentLocation(): Location { + return entries[index]; + } + function createMemoryLocation( + to: To, + state: any = null, + key?: string + ): Location { + let location = createLocation( + entries ? getCurrentLocation().pathname : "/", + to, + state, + key + ); + warning( + location.pathname.charAt(0) === "/", + `relative pathnames are not supported in memory history: ${JSON.stringify( + to + )}` + ); + return location; + } + + function createHref(to: To) { + return typeof to === "string" ? to : createPath(to); + } + + let history: MemoryHistory = { + get index() { + return index; + }, + get action() { + return action; + }, + get location() { + return getCurrentLocation(); + }, + createHref, + createURL(to) { + return new URL(createHref(to), "http://localhost"); + }, + encodeLocation(to: To) { + let path = typeof to === "string" ? parsePath(to) : to; + return { + pathname: path.pathname || "", + search: path.search || "", + hash: path.hash || "", + }; + }, + push(to, state) { + action = Action.Push; + let nextLocation = createMemoryLocation(to, state); + index += 1; + entries.splice(index, entries.length, nextLocation); + if (v5Compat && listener) { + listener({ action, location: nextLocation, delta: 1 }); + } + }, + replace(to, state) { + action = Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + if (v5Compat && listener) { + listener({ action, location: nextLocation, delta: 0 }); + } + }, + go(delta) { + action = Action.Pop; + let nextIndex = clampIndex(index + delta); + let nextLocation = entries[nextIndex]; + index = nextIndex; + if (listener) { + listener({ action, location: nextLocation, delta }); + } + }, + listen(fn: Listener) { + listener = fn; + return () => { + listener = null; + }; + }, + }; + + return history; +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Browser History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A browser history stores the current location in regular URLs in a web + * browser environment. This is the standard for most web apps and provides the + * cleanest URLs the browser's address bar. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory + */ +export interface BrowserHistory extends UrlHistory {} + +export type BrowserHistoryOptions = UrlHistoryOptions; + +/** + * Browser history stores the location in regular URLs. This is the standard for + * most web apps, but it requires some configuration on the server to ensure you + * serve the same app at multiple URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory + */ +export function createBrowserHistory( + options: BrowserHistoryOptions = {} +): BrowserHistory { + function createBrowserLocation( + window: Window, + globalHistory: Window["history"] + ) { + let { pathname, search, hash } = window.location; + return createLocation( + "", + { pathname, search, hash }, + // state defaults to `null` because `window.history.state` does + (globalHistory.state && globalHistory.state.usr) || null, + (globalHistory.state && globalHistory.state.key) || "default" + ); + } + + function createBrowserHref(window: Window, to: To) { + return typeof to === "string" ? to : createPath(to); + } + + return getUrlBasedHistory( + createBrowserLocation, + createBrowserHref, + null, + options + ); +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Hash History +//////////////////////////////////////////////////////////////////////////////// + +/** + * A hash history stores the current location in the fragment identifier portion + * of the URL in a web browser environment. + * + * This is ideal for apps that do not control the server for some reason + * (because the fragment identifier is never sent to the server), including some + * shared hosting environments that do not provide fine-grained controls over + * which pages are served at which URLs. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory + */ +export interface HashHistory extends UrlHistory {} + +export type HashHistoryOptions = UrlHistoryOptions; + +/** + * Hash history stores the location in window.location.hash. This makes it ideal + * for situations where you don't want to send the location to the server for + * some reason, either because you do cannot configure it or the URL space is + * reserved for something else. + * + * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory + */ +export function createHashHistory( + options: HashHistoryOptions = {} +): HashHistory { + function createHashLocation( + window: Window, + globalHistory: Window["history"] + ) { + let { + pathname = "/", + search = "", + hash = "", + } = parsePath(window.location.hash.substr(1)); + + // Hash URL should always have a leading / just like window.location.pathname + // does, so if an app ends up at a route like /#something then we add a + // leading slash so all of our path-matching behaves the same as if it would + // in a browser router. This is particularly important when there exists a + // root splat route () since that matches internally against + // "/*" and we'd expect /#something to 404 in a hash router app. + if (!pathname.startsWith("/") && !pathname.startsWith(".")) { + pathname = "/" + pathname; + } + + return createLocation( + "", + { pathname, search, hash }, + // state defaults to `null` because `window.history.state` does + (globalHistory.state && globalHistory.state.usr) || null, + (globalHistory.state && globalHistory.state.key) || "default" + ); + } + + function createHashHref(window: Window, to: To) { + let base = window.document.querySelector("base"); + let href = ""; + + if (base && base.getAttribute("href")) { + let url = window.location.href; + let hashIndex = url.indexOf("#"); + href = hashIndex === -1 ? url : url.slice(0, hashIndex); + } + + return href + "#" + (typeof to === "string" ? to : createPath(to)); + } + + function validateHashLocation(location: Location, to: To) { + warning( + location.pathname.charAt(0) === "/", + `relative pathnames are not supported in hash history.push(${JSON.stringify( + to + )})` + ); + } + + return getUrlBasedHistory( + createHashLocation, + createHashHref, + validateHashLocation, + options + ); +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region UTILS +//////////////////////////////////////////////////////////////////////////////// + +/** + * @private + */ +export function invariant(value: boolean, message?: string): asserts value; +export function invariant( + value: T | null | undefined, + message?: string +): asserts value is T; +export function invariant(value: any, message?: string) { + if (value === false || value === null || typeof value === "undefined") { + throw new Error(message); + } +} + +export function warning(cond: any, message: string) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + + try { + // Welcome to debugging history! + // + // This error is thrown as a convenience, so you can more easily + // find the source for a warning that appears in the console by + // enabling "pause on exceptions" in your JavaScript debugger. + throw new Error(message); + // eslint-disable-next-line no-empty + } catch (e) {} + } +} + +function createKey() { + return Math.random().toString(36).substr(2, 8); +} + +/** + * For browser-based histories, we combine the state and key into an object + */ +function getHistoryState(location: Location, index: number): HistoryState { + return { + usr: location.state, + key: location.key, + idx: index, + }; +} + +/** + * Creates a Location object with a unique key from the given Path + */ +export function createLocation( + current: string | Location, + to: To, + state: any = null, + key?: string +): Readonly { + let location: Readonly = { + pathname: typeof current === "string" ? current : current.pathname, + search: "", + hash: "", + ...(typeof to === "string" ? parsePath(to) : to), + state, + // TODO: This could be cleaned up. push/replace should probably just take + // full Locations now and avoid the need to run through this flow at all + // But that's a pretty big refactor to the current test suite so going to + // keep as is for the time being and just let any incoming keys take precedence + key: (to && (to as Location).key) || key || createKey(), + }; + return location; +} + +/** + * Creates a string URL path from the given pathname, search, and hash components. + */ +export function createPath({ + pathname = "/", + search = "", + hash = "", +}: Partial) { + if (search && search !== "?") + pathname += search.charAt(0) === "?" ? search : "?" + search; + if (hash && hash !== "#") + pathname += hash.charAt(0) === "#" ? hash : "#" + hash; + return pathname; +} + +/** + * Parses a string URL path into its separate pathname, search, and hash components. + */ +export function parsePath(path: string): Partial { + let parsedPath: Partial = {}; + + if (path) { + let hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + parsedPath.hash = path.substr(hashIndex); + path = path.substr(0, hashIndex); + } + + let searchIndex = path.indexOf("?"); + if (searchIndex >= 0) { + parsedPath.search = path.substr(searchIndex); + path = path.substr(0, searchIndex); + } + + if (path) { + parsedPath.pathname = path; + } + } + + return parsedPath; +} + +export interface UrlHistory extends History {} + +export type UrlHistoryOptions = { + window?: Window; + v5Compat?: boolean; +}; + +function getUrlBasedHistory( + getLocation: (window: Window, globalHistory: Window["history"]) => Location, + createHref: (window: Window, to: To) => string, + validateLocation: ((location: Location, to: To) => void) | null, + options: UrlHistoryOptions = {} +): UrlHistory { + let { window = document.defaultView!, v5Compat = false } = options; + let globalHistory = window.history; + let action = Action.Pop; + let listener: Listener | null = null; + + let index = getIndex()!; + // Index should only be null when we initialize. If not, it's because the + // user called history.pushState or history.replaceState directly, in which + // case we should log a warning as it will result in bugs. + if (index == null) { + index = 0; + globalHistory.replaceState({ ...globalHistory.state, idx: index }, ""); + } + + function getIndex(): number { + let state = globalHistory.state || { idx: null }; + return state.idx; + } + + function handlePop() { + action = Action.Pop; + let nextIndex = getIndex(); + let delta = nextIndex == null ? null : nextIndex - index; + index = nextIndex; + if (listener) { + listener({ action, location: history.location, delta }); + } + } + + function push(to: To, state?: any) { + action = Action.Push; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + + index = getIndex() + 1; + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + + // try...catch because iOS limits us to 100 pushState calls :/ + try { + globalHistory.pushState(historyState, "", url); + } catch (error) { + // If the exception is because `state` can't be serialized, let that throw + // outwards just like a replace call would so the dev knows the cause + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + if (error instanceof DOMException && error.name === "DataCloneError") { + throw error; + } + // They are going to lose state here, but there is no real + // way to warn them about it since the page will refresh... + window.location.assign(url); + } + + if (v5Compat && listener) { + listener({ action, location: history.location, delta: 1 }); + } + } + + function replace(to: To, state?: any) { + action = Action.Replace; + let location = createLocation(history.location, to, state); + if (validateLocation) validateLocation(location, to); + + index = getIndex(); + let historyState = getHistoryState(location, index); + let url = history.createHref(location); + globalHistory.replaceState(historyState, "", url); + + if (v5Compat && listener) { + listener({ action, location: history.location, delta: 0 }); + } + } + + function createURL(to: To): URL { + // window.location.origin is "null" (the literal string value) in Firefox + // under certain conditions, notably when serving from a local HTML file + // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297 + let base = + window.location.origin !== "null" + ? window.location.origin + : window.location.href; + + let href = typeof to === "string" ? to : createPath(to); + // Treating this as a full URL will strip any trailing spaces so we need to + // pre-encode them since they might be part of a matching splat param from + // an ancestor route + href = href.replace(/ $/, "%20"); + invariant( + base, + `No window.location.(origin|href) available to create URL for href: ${href}` + ); + return new URL(href, base); + } + + let history: History = { + get action() { + return action; + }, + get location() { + return getLocation(window, globalHistory); + }, + listen(fn: Listener) { + if (listener) { + throw new Error("A history only accepts one active listener"); + } + window.addEventListener(PopStateEventType, handlePop); + listener = fn; + + return () => { + window.removeEventListener(PopStateEventType, handlePop); + listener = null; + }; + }, + createHref(to) { + return createHref(window, to); + }, + createURL, + encodeLocation(to) { + // Encode a Location the same way window.location would + let url = createURL(to); + return { + pathname: url.pathname, + search: url.search, + hash: url.hash, + }; + }, + push, + replace, + go(n) { + return globalHistory.go(n); + }, + }; + + return history; +} + +//#endregion diff --git a/node_modules/@remix-run/router/index.ts b/node_modules/@remix-run/router/index.ts new file mode 100644 index 0000000000..172b95644d --- /dev/null +++ b/node_modules/@remix-run/router/index.ts @@ -0,0 +1,102 @@ +export type { + ActionFunction, + ActionFunctionArgs, + AgnosticDataIndexRouteObject, + AgnosticDataNonIndexRouteObject, + AgnosticDataRouteMatch, + AgnosticDataRouteObject, + AgnosticIndexRouteObject, + AgnosticNonIndexRouteObject, + AgnosticRouteMatch, + AgnosticRouteObject, + DataStrategyFunction as unstable_DataStrategyFunction, + DataStrategyFunctionArgs as unstable_DataStrategyFunctionArgs, + DataStrategyMatch as unstable_DataStrategyMatch, + ErrorResponse, + FormEncType, + FormMethod, + HandlerResult as unstable_HandlerResult, + HTMLFormMethod, + JsonFunction, + LazyRouteFunction, + LoaderFunction, + LoaderFunctionArgs, + ParamParseKey, + Params, + AgnosticPatchRoutesOnMissFunction as unstable_AgnosticPatchRoutesOnMissFunction, + PathMatch, + PathParam, + PathPattern, + RedirectFunction, + ShouldRevalidateFunction, + ShouldRevalidateFunctionArgs, + TrackedPromise, + UIMatch, + V7_FormMethod, +} from "./utils"; + +export { + AbortedDeferredError, + defer, + generatePath, + getToPathname, + isRouteErrorResponse, + joinPaths, + json, + matchPath, + matchRoutes, + normalizePathname, + redirect, + redirectDocument, + resolvePath, + resolveTo, + stripBasename, +} from "./utils"; + +export type { + BrowserHistory, + BrowserHistoryOptions, + HashHistory, + HashHistoryOptions, + History, + InitialEntry, + Location, + MemoryHistory, + MemoryHistoryOptions, + Path, + To, +} from "./history"; + +export { + Action, + createBrowserHistory, + createHashHistory, + createMemoryHistory, + createPath, + parsePath, +} from "./history"; + +export * from "./router"; + +/////////////////////////////////////////////////////////////////////////////// +// DANGER! PLEASE READ ME! +// We consider these exports an implementation detail and do not guarantee +// against any breaking changes, regardless of the semver release. Use with +// extreme caution and only if you understand the consequences. Godspeed. +/////////////////////////////////////////////////////////////////////////////// + +/** @internal */ +export type { RouteManifest as UNSAFE_RouteManifest } from "./utils"; +export { + DeferredData as UNSAFE_DeferredData, + ErrorResponseImpl as UNSAFE_ErrorResponseImpl, + convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, + convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, + decodePath as UNSAFE_decodePath, + getResolveToMatches as UNSAFE_getResolveToMatches, +} from "./utils"; + +export { + invariant as UNSAFE_invariant, + warning as UNSAFE_warning, +} from "./history"; diff --git a/node_modules/@remix-run/router/package.json b/node_modules/@remix-run/router/package.json new file mode 100644 index 0000000000..100ceb6c58 --- /dev/null +++ b/node_modules/@remix-run/router/package.json @@ -0,0 +1,67 @@ +{ + "_from": "@remix-run/router@1.18.0", + "_id": "@remix-run/router@1.18.0", + "_inBundle": false, + "_integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "_location": "/@remix-run/router", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "@remix-run/router@1.18.0", + "name": "@remix-run/router", + "escapedName": "@remix-run%2frouter", + "scope": "@remix-run", + "rawSpec": "1.18.0", + "saveSpec": null, + "fetchSpec": "1.18.0" + }, + "_requiredBy": [ + "/react-router", + "/react-router-dom" + ], + "_resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "_shasum": "20b033d1f542a100c1d57cfd18ecf442d1784732", + "_spec": "@remix-run/router@1.18.0", + "_where": "/Users/khushhalichauhan/L-square-QTify/node_modules/react-router-dom", + "author": { + "name": "Remix Software", + "email": "hello@remix.run" + }, + "bugs": { + "url": "https://github.com/remix-run/react-router/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Nested/Data-driven/Framework-agnostic Routing", + "engines": { + "node": ">=14.0.0" + }, + "files": [ + "dist/", + "*.ts", + "CHANGELOG.md" + ], + "homepage": "https://github.com/remix-run/react-router#readme", + "keywords": [ + "remix", + "router", + "location" + ], + "license": "MIT", + "main": "./dist/router.cjs.js", + "module": "./dist/router.js", + "name": "@remix-run/router", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/remix-run/react-router.git", + "directory": "packages/router" + }, + "sideEffects": false, + "types": "./dist/index.d.ts", + "unpkg": "./dist/router.umd.min.js", + "version": "1.18.0" +} diff --git a/node_modules/@remix-run/router/router.ts b/node_modules/@remix-run/router/router.ts new file mode 100644 index 0000000000..8a26b859b8 --- /dev/null +++ b/node_modules/@remix-run/router/router.ts @@ -0,0 +1,5809 @@ +import type { History, Location, Path, To } from "./history"; +import { + Action as HistoryAction, + createLocation, + createPath, + invariant, + parsePath, + warning, +} from "./history"; +import type { + AgnosticDataRouteMatch, + AgnosticDataRouteObject, + DataStrategyMatch, + AgnosticRouteObject, + DataResult, + DataStrategyFunction, + DataStrategyFunctionArgs, + DeferredData, + DeferredResult, + DetectErrorBoundaryFunction, + ErrorResult, + FormEncType, + FormMethod, + HTMLFormMethod, + HandlerResult, + ImmutableRouteKey, + MapRoutePropertiesFunction, + MutationFormMethod, + RedirectResult, + RouteData, + RouteManifest, + ShouldRevalidateFunctionArgs, + Submission, + SuccessResult, + UIMatch, + V7_FormMethod, + V7_MutationFormMethod, + AgnosticPatchRoutesOnMissFunction, +} from "./utils"; +import { + ErrorResponseImpl, + ResultType, + convertRouteMatchToUiMatch, + convertRoutesToDataRoutes, + getPathContributingMatches, + getResolveToMatches, + immutableRouteKeys, + isRouteErrorResponse, + joinPaths, + matchRoutes, + matchRoutesImpl, + resolveTo, + stripBasename, +} from "./utils"; + +//////////////////////////////////////////////////////////////////////////////// +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// + +/** + * A Router instance manages all navigation and data loading/mutations + */ +export interface Router { + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the basename for the router + */ + get basename(): RouterInit["basename"]; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the future config for the router + */ + get future(): FutureConfig; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the current state of the router + */ + get state(): RouterState; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the routes for this router instance + */ + get routes(): AgnosticDataRouteObject[]; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Return the window associated with the router + */ + get window(): RouterInit["window"]; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Initialize the router, including adding history listeners and kicking off + * initial data fetches. Returns a function to cleanup listeners and abort + * any in-progress loads + */ + initialize(): Router; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Subscribe to router.state updates + * + * @param fn function to call with the new state + */ + subscribe(fn: RouterSubscriber): () => void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Enable scroll restoration behavior in the router + * + * @param savedScrollPositions Object that will manage positions, in case + * it's being restored from sessionStorage + * @param getScrollPosition Function to get the active Y scroll position + * @param getKey Function to get the key to use for restoration + */ + enableScrollRestoration( + savedScrollPositions: Record, + getScrollPosition: GetScrollPositionFunction, + getKey?: GetScrollRestorationKeyFunction + ): () => void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Navigate forward/backward in the history stack + * @param to Delta to move in the history stack + */ + navigate(to: number): Promise; + + /** + * Navigate to the given path + * @param to Path to navigate to + * @param opts Navigation options (method, submission, etc.) + */ + navigate(to: To | null, opts?: RouterNavigateOptions): Promise; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Trigger a fetcher load/submission + * + * @param key Fetcher key + * @param routeId Route that owns the fetcher + * @param href href to fetch + * @param opts Fetcher options, (method, submission, etc.) + */ + fetch( + key: string, + routeId: string, + href: string | null, + opts?: RouterFetchOptions + ): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Trigger a revalidation of all current route loaders and fetcher loads + */ + revalidate(): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Utility function to create an href for the given location + * @param location + */ + createHref(location: Location | URL): string; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Utility function to URL encode a destination path according to the internal + * history implementation + * @param to + */ + encodeLocation(to: To): Path; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Get/create a fetcher for the given key + * @param key + */ + getFetcher(key: string): Fetcher; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Delete the fetcher for a given key + * @param key + */ + deleteFetcher(key: string): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Cleanup listeners and abort any in-progress loads + */ + dispose(): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Get a navigation blocker + * @param key The identifier for the blocker + * @param fn The blocker function implementation + */ + getBlocker(key: string, fn: BlockerFunction): Blocker; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Delete a navigation blocker + * @param key The identifier for the blocker + */ + deleteBlocker(key: string): void; + + /** + * @internal + * PRIVATE DO NOT USE + * + * Patch additional children routes into an existing parent route + * @param routeId The parent route id or a callback function accepting `patch` + * to perform batch patching + * @param children The additional children routes + */ + patchRoutes(routeId: string | null, children: AgnosticRouteObject[]): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * HMR needs to pass in-flight route updates to React Router + * TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute) + */ + _internalSetRoutes(routes: AgnosticRouteObject[]): void; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Internal fetch AbortControllers accessed by unit tests + */ + _internalFetchControllers: Map; + + /** + * @internal + * PRIVATE - DO NOT USE + * + * Internal pending DeferredData instances accessed by unit tests + */ + _internalActiveDeferreds: Map; +} + +/** + * State maintained internally by the router. During a navigation, all states + * reflect the the "old" location unless otherwise noted. + */ +export interface RouterState { + /** + * The action of the most recent navigation + */ + historyAction: HistoryAction; + + /** + * The current location reflected by the router + */ + location: Location; + + /** + * The current set of route matches + */ + matches: AgnosticDataRouteMatch[]; + + /** + * Tracks whether we've completed our initial data load + */ + initialized: boolean; + + /** + * Current scroll position we should start at for a new view + * - number -> scroll position to restore to + * - false -> do not restore scroll at all (used during submissions) + * - null -> don't have a saved position, scroll to hash or top of page + */ + restoreScrollPosition: number | false | null; + + /** + * Indicate whether this navigation should skip resetting the scroll position + * if we are unable to restore the scroll position + */ + preventScrollReset: boolean; + + /** + * Tracks the state of the current navigation + */ + navigation: Navigation; + + /** + * Tracks any in-progress revalidations + */ + revalidation: RevalidationState; + + /** + * Data from the loaders for the current matches + */ + loaderData: RouteData; + + /** + * Data from the action for the current matches + */ + actionData: RouteData | null; + + /** + * Errors caught from loaders for the current matches + */ + errors: RouteData | null; + + /** + * Map of current fetchers + */ + fetchers: Map; + + /** + * Map of current blockers + */ + blockers: Map; +} + +/** + * Data that can be passed into hydrate a Router from SSR + */ +export type HydrationState = Partial< + Pick +>; + +/** + * Future flags to toggle new feature behavior + */ +export interface FutureConfig { + v7_fetcherPersist: boolean; + v7_normalizeFormMethod: boolean; + v7_partialHydration: boolean; + v7_prependBasename: boolean; + v7_relativeSplatPath: boolean; + v7_skipActionErrorRevalidation: boolean; +} + +/** + * Initialization options for createRouter + */ +export interface RouterInit { + routes: AgnosticRouteObject[]; + history: History; + basename?: string; + /** + * @deprecated Use `mapRouteProperties` instead + */ + detectErrorBoundary?: DetectErrorBoundaryFunction; + mapRouteProperties?: MapRoutePropertiesFunction; + future?: Partial; + hydrationData?: HydrationState; + window?: Window; + unstable_patchRoutesOnMiss?: AgnosticPatchRoutesOnMissFunction; + unstable_dataStrategy?: DataStrategyFunction; +} + +/** + * State returned from a server-side query() call + */ +export interface StaticHandlerContext { + basename: Router["basename"]; + location: RouterState["location"]; + matches: RouterState["matches"]; + loaderData: RouterState["loaderData"]; + actionData: RouterState["actionData"]; + errors: RouterState["errors"]; + statusCode: number; + loaderHeaders: Record; + actionHeaders: Record; + activeDeferreds: Record | null; + _deepestRenderedBoundaryId?: string | null; +} + +/** + * A StaticHandler instance manages a singular SSR navigation/fetch event + */ +export interface StaticHandler { + dataRoutes: AgnosticDataRouteObject[]; + query( + request: Request, + opts?: { + requestContext?: unknown; + skipLoaderErrorBubbling?: boolean; + unstable_dataStrategy?: DataStrategyFunction; + } + ): Promise; + queryRoute( + request: Request, + opts?: { + routeId?: string; + requestContext?: unknown; + unstable_dataStrategy?: DataStrategyFunction; + } + ): Promise; +} + +type ViewTransitionOpts = { + currentLocation: Location; + nextLocation: Location; +}; + +/** + * Subscriber function signature for changes to router state + */ +export interface RouterSubscriber { + ( + state: RouterState, + opts: { + deletedFetchers: string[]; + unstable_viewTransitionOpts?: ViewTransitionOpts; + unstable_flushSync: boolean; + } + ): void; +} + +/** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ +export interface GetScrollRestorationKeyFunction { + (location: Location, matches: UIMatch[]): string | null; +} + +/** + * Function signature for determining the current scroll position + */ +export interface GetScrollPositionFunction { + (): number; +} + +export type RelativeRoutingType = "route" | "path"; + +// Allowed for any navigation or fetch +type BaseNavigateOrFetchOptions = { + preventScrollReset?: boolean; + relative?: RelativeRoutingType; + unstable_flushSync?: boolean; +}; + +// Only allowed for navigations +type BaseNavigateOptions = BaseNavigateOrFetchOptions & { + replace?: boolean; + state?: any; + fromRouteId?: string; + unstable_viewTransition?: boolean; +}; + +// Only allowed for submission navigations +type BaseSubmissionOptions = { + formMethod?: HTMLFormMethod; + formEncType?: FormEncType; +} & ( + | { formData: FormData; body?: undefined } + | { formData?: undefined; body: any } +); + +/** + * Options for a navigate() call for a normal (non-submission) navigation + */ +type LinkNavigateOptions = BaseNavigateOptions; + +/** + * Options for a navigate() call for a submission navigation + */ +type SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOptions; + +/** + * Options to pass to navigate() for a navigation + */ +export type RouterNavigateOptions = + | LinkNavigateOptions + | SubmissionNavigateOptions; + +/** + * Options for a fetch() load + */ +type LoadFetchOptions = BaseNavigateOrFetchOptions; + +/** + * Options for a fetch() submission + */ +type SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOptions; + +/** + * Options to pass to fetch() + */ +export type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions; + +/** + * Potential states for state.navigation + */ +export type NavigationStates = { + Idle: { + state: "idle"; + location: undefined; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + formData: undefined; + json: undefined; + text: undefined; + }; + Loading: { + state: "loading"; + location: Location; + formMethod: Submission["formMethod"] | undefined; + formAction: Submission["formAction"] | undefined; + formEncType: Submission["formEncType"] | undefined; + formData: Submission["formData"] | undefined; + json: Submission["json"] | undefined; + text: Submission["text"] | undefined; + }; + Submitting: { + state: "submitting"; + location: Location; + formMethod: Submission["formMethod"]; + formAction: Submission["formAction"]; + formEncType: Submission["formEncType"]; + formData: Submission["formData"]; + json: Submission["json"]; + text: Submission["text"]; + }; +}; + +export type Navigation = NavigationStates[keyof NavigationStates]; + +export type RevalidationState = "idle" | "loading"; + +/** + * Potential states for fetchers + */ +type FetcherStates = { + Idle: { + state: "idle"; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + text: undefined; + formData: undefined; + json: undefined; + data: TData | undefined; + }; + Loading: { + state: "loading"; + formMethod: Submission["formMethod"] | undefined; + formAction: Submission["formAction"] | undefined; + formEncType: Submission["formEncType"] | undefined; + text: Submission["text"] | undefined; + formData: Submission["formData"] | undefined; + json: Submission["json"] | undefined; + data: TData | undefined; + }; + Submitting: { + state: "submitting"; + formMethod: Submission["formMethod"]; + formAction: Submission["formAction"]; + formEncType: Submission["formEncType"]; + text: Submission["text"]; + formData: Submission["formData"]; + json: Submission["json"]; + data: TData | undefined; + }; +}; + +export type Fetcher = + FetcherStates[keyof FetcherStates]; + +interface BlockerBlocked { + state: "blocked"; + reset(): void; + proceed(): void; + location: Location; +} + +interface BlockerUnblocked { + state: "unblocked"; + reset: undefined; + proceed: undefined; + location: undefined; +} + +interface BlockerProceeding { + state: "proceeding"; + reset: undefined; + proceed: undefined; + location: Location; +} + +export type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding; + +export type BlockerFunction = (args: { + currentLocation: Location; + nextLocation: Location; + historyAction: HistoryAction; +}) => boolean; + +interface ShortCircuitable { + /** + * startNavigation does not need to complete the navigation because we + * redirected or got interrupted + */ + shortCircuited?: boolean; +} + +type PendingActionResult = [string, SuccessResult | ErrorResult]; + +interface HandleActionResult extends ShortCircuitable { + /** + * Route matches which may have been updated from fog of war discovery + */ + matches?: RouterState["matches"]; + /** + * Tuple for the returned or thrown value from the current action. The routeId + * is the action route for success and the bubbled boundary route for errors. + */ + pendingActionResult?: PendingActionResult; +} + +interface HandleLoadersResult extends ShortCircuitable { + /** + * Route matches which may have been updated from fog of war discovery + */ + matches?: RouterState["matches"]; + /** + * loaderData returned from the current set of loaders + */ + loaderData?: RouterState["loaderData"]; + /** + * errors thrown from the current set of loaders + */ + errors?: RouterState["errors"]; +} + +/** + * Cached info for active fetcher.load() instances so they can participate + * in revalidation + */ +interface FetchLoadMatch { + routeId: string; + path: string; +} + +/** + * Identified fetcher.load() calls that need to be revalidated + */ +interface RevalidatingFetcher extends FetchLoadMatch { + key: string; + match: AgnosticDataRouteMatch | null; + matches: AgnosticDataRouteMatch[] | null; + controller: AbortController | null; +} + +const validMutationMethodsArr: MutationFormMethod[] = [ + "post", + "put", + "patch", + "delete", +]; +const validMutationMethods = new Set( + validMutationMethodsArr +); + +const validRequestMethodsArr: FormMethod[] = [ + "get", + ...validMutationMethodsArr, +]; +const validRequestMethods = new Set(validRequestMethodsArr); + +const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); +const redirectPreserveMethodStatusCodes = new Set([307, 308]); + +export const IDLE_NAVIGATION: NavigationStates["Idle"] = { + state: "idle", + location: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, +}; + +export const IDLE_FETCHER: FetcherStates["Idle"] = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, +}; + +export const IDLE_BLOCKER: BlockerUnblocked = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined, +}; + +const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; + +const defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({ + hasErrorBoundary: Boolean(route.hasErrorBoundary), +}); + +const TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; + +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a router and listen to history POP navigations + */ +export function createRouter(init: RouterInit): Router { + const routerWindow = init.window + ? init.window + : typeof window !== "undefined" + ? window + : undefined; + const isBrowser = + typeof routerWindow !== "undefined" && + typeof routerWindow.document !== "undefined" && + typeof routerWindow.document.createElement !== "undefined"; + const isServer = !isBrowser; + + invariant( + init.routes.length > 0, + "You must provide a non-empty routes array to createRouter" + ); + + let mapRouteProperties: MapRoutePropertiesFunction; + if (init.mapRouteProperties) { + mapRouteProperties = init.mapRouteProperties; + } else if (init.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = init.detectErrorBoundary; + mapRouteProperties = (route) => ({ + hasErrorBoundary: detectErrorBoundary(route), + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + + // Routes keyed by ID + let manifest: RouteManifest = {}; + // Routes in tree format for matching + let dataRoutes = convertRoutesToDataRoutes( + init.routes, + mapRouteProperties, + undefined, + manifest + ); + let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined; + let basename = init.basename || "/"; + let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy; + let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss; + + // Config driven behavior flags + let future: FutureConfig = { + v7_fetcherPersist: false, + v7_normalizeFormMethod: false, + v7_partialHydration: false, + v7_prependBasename: false, + v7_relativeSplatPath: false, + v7_skipActionErrorRevalidation: false, + ...init.future, + }; + // Cleanup function for history + let unlistenHistory: (() => void) | null = null; + // Externally-provided functions to call on all state changes + let subscribers = new Set(); + // Externally-provided object to hold scroll restoration locations during routing + let savedScrollPositions: Record | null = null; + // Externally-provided function to get scroll restoration keys + let getScrollRestorationKey: GetScrollRestorationKeyFunction | null = null; + // Externally-provided function to get current scroll position + let getScrollPosition: GetScrollPositionFunction | null = null; + // One-time flag to control the initial hydration scroll restoration. Because + // we don't get the saved positions from until _after_ + // the initial render, we need to manually trigger a separate updateState to + // send along the restoreScrollPosition + // Set to true if we have `hydrationData` since we assume we were SSR'd and that + // SSR did the initial scroll restoration. + let initialScrollRestored = init.hydrationData != null; + + let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); + let initialErrors: RouteData | null = null; + + if (initialMatches == null && !patchRoutesOnMissImpl) { + // If we do not match a user-provided-route, fall back to the root + // to allow the error boundary to take over + let error = getInternalRouterError(404, { + pathname: init.history.location.pathname, + }); + let { matches, route } = getShortCircuitMatches(dataRoutes); + initialMatches = matches; + initialErrors = { [route.id]: error }; + } + + // In SPA apps, if the user provided a patchRoutesOnMiss implementation and + // our initial match is a splat route, clear them out so we run through lazy + // discovery on hydration in case there's a more accurate lazy route match. + // In SSR apps (with `hydrationData`), we expect that the server will send + // up the proper matched routes so we don't want to run lazy discovery on + // initial hydration and want to hydrate into the splat route. + if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) { + let fogOfWar = checkFogOfWar( + initialMatches, + dataRoutes, + init.history.location.pathname + ); + if (fogOfWar.active) { + initialMatches = null; + } + } + + let initialized: boolean; + if (!initialMatches) { + // We need to run patchRoutesOnMiss in initialize() + initialized = false; + initialMatches = []; + } else if (initialMatches.some((m) => m.route.lazy)) { + // All initialMatches need to be loaded before we're ready. If we have lazy + // functions around still then we'll need to run them in initialize() + initialized = false; + } else if (!initialMatches.some((m) => m.route.loader)) { + // If we've got no loaders to run, then we're good to go + initialized = true; + } else if (future.v7_partialHydration) { + // If partial hydration is enabled, we're initialized so long as we were + // provided with hydrationData for every route with a loader, and no loaders + // were marked for explicit hydration + let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; + let errors = init.hydrationData ? init.hydrationData.errors : null; + let isRouteInitialized = (m: AgnosticDataRouteMatch) => { + // No loader, nothing to initialize + if (!m.route.loader) { + return true; + } + // Explicitly opting-in to running on hydration + if ( + typeof m.route.loader === "function" && + m.route.loader.hydrate === true + ) { + return false; + } + // Otherwise, initialized if hydrated with data or an error + return ( + (loaderData && loaderData[m.route.id] !== undefined) || + (errors && errors[m.route.id] !== undefined) + ); + }; + + // If errors exist, don't consider routes below the boundary + if (errors) { + let idx = initialMatches.findIndex( + (m) => errors![m.route.id] !== undefined + ); + initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized); + } else { + initialized = initialMatches.every(isRouteInitialized); + } + } else { + // Without partial hydration - we're initialized if we were provided any + // hydrationData - which is expected to be complete + initialized = init.hydrationData != null; + } + + let router: Router; + let state: RouterState = { + historyAction: init.history.action, + location: init.history.location, + matches: initialMatches, + initialized, + navigation: IDLE_NAVIGATION, + // Don't restore on initial updateState() if we were SSR'd + restoreScrollPosition: init.hydrationData != null ? false : null, + preventScrollReset: false, + revalidation: "idle", + loaderData: (init.hydrationData && init.hydrationData.loaderData) || {}, + actionData: (init.hydrationData && init.hydrationData.actionData) || null, + errors: (init.hydrationData && init.hydrationData.errors) || initialErrors, + fetchers: new Map(), + blockers: new Map(), + }; + + // -- Stateful internal variables to manage navigations -- + // Current navigation in progress (to be committed in completeNavigation) + let pendingAction: HistoryAction = HistoryAction.Pop; + + // Should the current navigation prevent the scroll reset if scroll cannot + // be restored? + let pendingPreventScrollReset = false; + + // AbortController for the active navigation + let pendingNavigationController: AbortController | null; + + // Should the current navigation enable document.startViewTransition? + let pendingViewTransitionEnabled = false; + + // Store applied view transitions so we can apply them on POP + let appliedViewTransitions: Map> = new Map< + string, + Set + >(); + + // Cleanup function for persisting applied transitions to sessionStorage + let removePageHideEventListener: (() => void) | null = null; + + // We use this to avoid touching history in completeNavigation if a + // revalidation is entirely uninterrupted + let isUninterruptedRevalidation = false; + + // Use this internal flag to force revalidation of all loaders: + // - submissions (completed or interrupted) + // - useRevalidator() + // - X-Remix-Revalidate (from redirect) + let isRevalidationRequired = false; + + // Use this internal array to capture routes that require revalidation due + // to a cancelled deferred on action submission + let cancelledDeferredRoutes: string[] = []; + + // Use this internal array to capture fetcher loads that were cancelled by an + // action navigation and require revalidation + let cancelledFetcherLoads: string[] = []; + + // AbortControllers for any in-flight fetchers + let fetchControllers = new Map(); + + // Track loads based on the order in which they started + let incrementingLoadId = 0; + + // Track the outstanding pending navigation data load to be compared against + // the globally incrementing load when a fetcher load lands after a completed + // navigation + let pendingNavigationLoadId = -1; + + // Fetchers that triggered data reloads as a result of their actions + let fetchReloadIds = new Map(); + + // Fetchers that triggered redirect navigations + let fetchRedirectIds = new Set(); + + // Most recent href/match for fetcher.load calls for fetchers + let fetchLoadMatches = new Map(); + + // Ref-count mounted fetchers so we know when it's ok to clean them up + let activeFetchers = new Map(); + + // Fetchers that have requested a delete when using v7_fetcherPersist, + // they'll be officially removed after they return to idle + let deletedFetchers = new Set(); + + // Store DeferredData instances for active route matches. When a + // route loader returns defer() we stick one in here. Then, when a nested + // promise resolves we update loaderData. If a new navigation starts we + // cancel active deferreds for eliminated routes. + let activeDeferreds = new Map(); + + // Store blocker functions in a separate Map outside of router state since + // we don't need to update UI state if they change + let blockerFunctions = new Map(); + + // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so + // that we only kick them off once for a given combo + let pendingPatchRoutes = new Map< + string, + ReturnType + >(); + + // Flag to ignore the next history update, so we can revert the URL change on + // a POP navigation that was blocked by the user without touching router state + let ignoreNextHistoryUpdate = false; + + // Initialize the router, all side effects should be kicked off from here. + // Implemented as a Fluent API for ease of: + // let router = createRouter(init).initialize(); + function initialize() { + // If history informs us of a POP navigation, start the navigation but do not update + // state. We'll update our own state once the navigation completes + unlistenHistory = init.history.listen( + ({ action: historyAction, location, delta }) => { + // Ignore this event if it was just us resetting the URL from a + // blocked POP navigation + if (ignoreNextHistoryUpdate) { + ignoreNextHistoryUpdate = false; + return; + } + + warning( + blockerFunctions.size === 0 || delta != null, + "You are trying to use a blocker on a POP navigation to a location " + + "that was not created by @remix-run/router. This will fail silently in " + + "production. This can happen if you are navigating outside the router " + + "via `window.history.pushState`/`window.location.hash` instead of using " + + "router navigation APIs. This can also happen if you are using " + + "createHashRouter and the user manually changes the URL." + ); + + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction, + }); + + if (blockerKey && delta != null) { + // Restore the URL to match the current UI, but don't update router state + ignoreNextHistoryUpdate = true; + init.history.go(delta * -1); + + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location, + proceed() { + updateBlocker(blockerKey!, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location, + }); + // Re-do the same POP navigation we just blocked + init.history.go(delta); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey!, IDLE_BLOCKER); + updateState({ blockers }); + }, + }); + return; + } + + return startNavigation(historyAction, location); + } + ); + + if (isBrowser) { + // FIXME: This feels gross. How can we cleanup the lines between + // scrollRestoration/appliedTransitions persistance? + restoreAppliedTransitions(routerWindow, appliedViewTransitions); + let _saveAppliedTransitions = () => + persistAppliedTransitions(routerWindow, appliedViewTransitions); + routerWindow.addEventListener("pagehide", _saveAppliedTransitions); + removePageHideEventListener = () => + routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); + } + + // Kick off initial data load if needed. Use Pop to avoid modifying history + // Note we don't do any handling of lazy here. For SPA's it'll get handled + // in the normal navigation flow. For SSR it's expected that lazy modules are + // resolved prior to router creation since we can't go into a fallbackElement + // UI for SSR'd apps + if (!state.initialized) { + startNavigation(HistoryAction.Pop, state.location, { + initialHydration: true, + }); + } + + return router; + } + + // Clean up a router and it's side effects + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + if (removePageHideEventListener) { + removePageHideEventListener(); + } + subscribers.clear(); + pendingNavigationController && pendingNavigationController.abort(); + state.fetchers.forEach((_, key) => deleteFetcher(key)); + state.blockers.forEach((_, key) => deleteBlocker(key)); + } + + // Subscribe to state updates for the router + function subscribe(fn: RouterSubscriber) { + subscribers.add(fn); + return () => subscribers.delete(fn); + } + + // Update our state and notify the calling context of the change + function updateState( + newState: Partial, + opts: { + flushSync?: boolean; + viewTransitionOpts?: ViewTransitionOpts; + } = {} + ): void { + state = { + ...state, + ...newState, + }; + + // Prep fetcher cleanup so we can tell the UI which fetcher data entries + // can be removed + let completedFetchers: string[] = []; + let deletedFetchersKeys: string[] = []; + + if (future.v7_fetcherPersist) { + state.fetchers.forEach((fetcher, key) => { + if (fetcher.state === "idle") { + if (deletedFetchers.has(key)) { + // Unmounted from the UI and can be totally removed + deletedFetchersKeys.push(key); + } else { + // Returned to idle but still mounted in the UI, so semi-remains for + // revalidations and such + completedFetchers.push(key); + } + } + }); + } + + // Iterate over a local copy so that if flushSync is used and we end up + // removing and adding a new subscriber due to the useCallback dependencies, + // we don't get ourselves into a loop calling the new subscriber immediately + [...subscribers].forEach((subscriber) => + subscriber(state, { + deletedFetchers: deletedFetchersKeys, + unstable_viewTransitionOpts: opts.viewTransitionOpts, + unstable_flushSync: opts.flushSync === true, + }) + ); + + // Remove idle fetchers from state since we only care about in-flight fetchers. + if (future.v7_fetcherPersist) { + completedFetchers.forEach((key) => state.fetchers.delete(key)); + deletedFetchersKeys.forEach((key) => deleteFetcher(key)); + } + } + + // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION + // and setting state.[historyAction/location/matches] to the new route. + // - Location is a required param + // - Navigation will always be set to IDLE_NAVIGATION + // - Can pass any other state in newState + function completeNavigation( + location: Location, + newState: Partial>, + { flushSync }: { flushSync?: boolean } = {} + ): void { + // Deduce if we're in a loading/actionReload state: + // - We have committed actionData in the store + // - The current navigation was a mutation submission + // - We're past the submitting state and into the loading state + // - The location being loaded is not the result of a redirect + let isActionReload = + state.actionData != null && + state.navigation.formMethod != null && + isMutationMethod(state.navigation.formMethod) && + state.navigation.state === "loading" && + location.state?._isRedirect !== true; + + let actionData: RouteData | null; + if (newState.actionData) { + if (Object.keys(newState.actionData).length > 0) { + actionData = newState.actionData; + } else { + // Empty actionData -> clear prior actionData due to an action error + actionData = null; + } + } else if (isActionReload) { + // Keep the current data if we're wrapping up the action reload + actionData = state.actionData; + } else { + // Clear actionData on any other completed navigations + actionData = null; + } + + // Always preserve any existing loaderData from re-used routes + let loaderData = newState.loaderData + ? mergeLoaderData( + state.loaderData, + newState.loaderData, + newState.matches || [], + newState.errors + ) + : state.loaderData; + + // On a successful navigation we can assume we got through all blockers + // so we can start fresh + let blockers = state.blockers; + if (blockers.size > 0) { + blockers = new Map(blockers); + blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); + } + + // Always respect the user flag. Otherwise don't reset on mutation + // submission navigations unless they redirect + let preventScrollReset = + pendingPreventScrollReset === true || + (state.navigation.formMethod != null && + isMutationMethod(state.navigation.formMethod) && + location.state?._isRedirect !== true); + + // Commit any in-flight routes at the end of the HMR revalidation "navigation" + if (inFlightDataRoutes) { + dataRoutes = inFlightDataRoutes; + inFlightDataRoutes = undefined; + } + + if (isUninterruptedRevalidation) { + // If this was an uninterrupted revalidation then do not touch history + } else if (pendingAction === HistoryAction.Pop) { + // Do nothing for POP - URL has already been updated + } else if (pendingAction === HistoryAction.Push) { + init.history.push(location, location.state); + } else if (pendingAction === HistoryAction.Replace) { + init.history.replace(location, location.state); + } + + let viewTransitionOpts: ViewTransitionOpts | undefined; + + // On POP, enable transitions if they were enabled on the original navigation + if (pendingAction === HistoryAction.Pop) { + // Forward takes precedence so they behave like the original navigation + let priorPaths = appliedViewTransitions.get(state.location.pathname); + if (priorPaths && priorPaths.has(location.pathname)) { + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location, + }; + } else if (appliedViewTransitions.has(location.pathname)) { + // If we don't have a previous forward nav, assume we're popping back to + // the new location and enable if that location previously enabled + viewTransitionOpts = { + currentLocation: location, + nextLocation: state.location, + }; + } + } else if (pendingViewTransitionEnabled) { + // Store the applied transition on PUSH/REPLACE + let toPaths = appliedViewTransitions.get(state.location.pathname); + if (toPaths) { + toPaths.add(location.pathname); + } else { + toPaths = new Set([location.pathname]); + appliedViewTransitions.set(state.location.pathname, toPaths); + } + viewTransitionOpts = { + currentLocation: state.location, + nextLocation: location, + }; + } + + updateState( + { + ...newState, // matches, errors, fetchers go through as-is + actionData, + loaderData, + historyAction: pendingAction, + location, + initialized: true, + navigation: IDLE_NAVIGATION, + revalidation: "idle", + restoreScrollPosition: getSavedScrollPosition( + location, + newState.matches || state.matches + ), + preventScrollReset, + blockers, + }, + { + viewTransitionOpts, + flushSync: flushSync === true, + } + ); + + // Reset stateful navigation vars + pendingAction = HistoryAction.Pop; + pendingPreventScrollReset = false; + pendingViewTransitionEnabled = false; + isUninterruptedRevalidation = false; + isRevalidationRequired = false; + cancelledDeferredRoutes = []; + cancelledFetcherLoads = []; + } + + // Trigger a navigation event, which can either be a numerical POP or a PUSH + // replace with an optional submission + async function navigate( + to: number | To | null, + opts?: RouterNavigateOptions + ): Promise { + if (typeof to === "number") { + init.history.go(to); + return; + } + + let normalizedPath = normalizeTo( + state.location, + state.matches, + basename, + future.v7_prependBasename, + to, + future.v7_relativeSplatPath, + opts?.fromRouteId, + opts?.relative + ); + let { path, submission, error } = normalizeNavigateOptions( + future.v7_normalizeFormMethod, + false, + normalizedPath, + opts + ); + + let currentLocation = state.location; + let nextLocation = createLocation(state.location, path, opts && opts.state); + + // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded + // URL from window.location, so we need to encode it here so the behavior + // remains the same as POP and non-data-router usages. new URL() does all + // the same encoding we'd get from a history.pushState/window.location read + // without having to touch history + nextLocation = { + ...nextLocation, + ...init.history.encodeLocation(nextLocation), + }; + + let userReplace = opts && opts.replace != null ? opts.replace : undefined; + + let historyAction = HistoryAction.Push; + + if (userReplace === true) { + historyAction = HistoryAction.Replace; + } else if (userReplace === false) { + // no-op + } else if ( + submission != null && + isMutationMethod(submission.formMethod) && + submission.formAction === state.location.pathname + state.location.search + ) { + // By default on submissions to the current location we REPLACE so that + // users don't have to double-click the back button to get to the prior + // location. If the user redirects to a different location from the + // action/loader this will be ignored and the redirect will be a PUSH + historyAction = HistoryAction.Replace; + } + + let preventScrollReset = + opts && "preventScrollReset" in opts + ? opts.preventScrollReset === true + : undefined; + + let flushSync = (opts && opts.unstable_flushSync) === true; + + let blockerKey = shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction, + }); + + if (blockerKey) { + // Put the blocker into a blocked state + updateBlocker(blockerKey, { + state: "blocked", + location: nextLocation, + proceed() { + updateBlocker(blockerKey!, { + state: "proceeding", + proceed: undefined, + reset: undefined, + location: nextLocation, + }); + // Send the same navigation through + navigate(to, opts); + }, + reset() { + let blockers = new Map(state.blockers); + blockers.set(blockerKey!, IDLE_BLOCKER); + updateState({ blockers }); + }, + }); + return; + } + + return await startNavigation(historyAction, nextLocation, { + submission, + // Send through the formData serialization error if we have one so we can + // render at the right error boundary after we match routes + pendingError: error, + preventScrollReset, + replace: opts && opts.replace, + enableViewTransition: opts && opts.unstable_viewTransition, + flushSync, + }); + } + + // Revalidate all current loaders. If a navigation is in progress or if this + // is interrupted by a navigation, allow this to "succeed" by calling all + // loaders during the next loader round + function revalidate() { + interruptActiveLoads(); + updateState({ revalidation: "loading" }); + + // If we're currently submitting an action, we don't need to start a new + // navigation, we'll just let the follow up loader execution call all loaders + if (state.navigation.state === "submitting") { + return; + } + + // If we're currently in an idle state, start a new navigation for the current + // action/location and mark it as uninterrupted, which will skip the history + // update in completeNavigation + if (state.navigation.state === "idle") { + startNavigation(state.historyAction, state.location, { + startUninterruptedRevalidation: true, + }); + return; + } + + // Otherwise, if we're currently in a loading state, just start a new + // navigation to the navigation.location but do not trigger an uninterrupted + // revalidation so that history correctly updates once the navigation completes + startNavigation( + pendingAction || state.historyAction, + state.navigation.location, + { overrideNavigation: state.navigation } + ); + } + + // Start a navigation to the given action/location. Can optionally provide a + // overrideNavigation which will override the normalLoad in the case of a redirect + // navigation + async function startNavigation( + historyAction: HistoryAction, + location: Location, + opts?: { + initialHydration?: boolean; + submission?: Submission; + fetcherSubmission?: Submission; + overrideNavigation?: Navigation; + pendingError?: ErrorResponseImpl; + startUninterruptedRevalidation?: boolean; + preventScrollReset?: boolean; + replace?: boolean; + enableViewTransition?: boolean; + flushSync?: boolean; + } + ): Promise { + // Abort any in-progress navigations and start a new one. Unset any ongoing + // uninterrupted revalidations unless told otherwise, since we want this + // new navigation to update history normally + pendingNavigationController && pendingNavigationController.abort(); + pendingNavigationController = null; + pendingAction = historyAction; + isUninterruptedRevalidation = + (opts && opts.startUninterruptedRevalidation) === true; + + // Save the current scroll position every time we start a new navigation, + // and track whether we should reset scroll on completion + saveScrollPosition(state.location, state.matches); + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + + pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; + + let routesToUse = inFlightDataRoutes || dataRoutes; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(routesToUse, location, basename); + let flushSync = (opts && opts.flushSync) === true; + + let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + + // Short circuit with a 404 on the root error boundary if we match nothing + if (!matches) { + let { error, notFoundMatches, route } = handleNavigational404( + location.pathname + ); + completeNavigation( + location, + { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error, + }, + }, + { flushSync } + ); + return; + } + + // Short circuit if it's only a hash change and not a revalidation or + // mutation submission. + // + // Ignore on initial page loads because since the initial load will always + // be "same hash". For example, on /page#hash and submit a + // which will default to a navigation to /page + if ( + state.initialized && + !isRevalidationRequired && + isHashChangeOnly(state.location, location) && + !(opts && opts.submission && isMutationMethod(opts.submission.formMethod)) + ) { + completeNavigation(location, { matches }, { flushSync }); + return; + } + + // Create a controller/Request for this navigation + pendingNavigationController = new AbortController(); + let request = createClientSideRequest( + init.history, + location, + pendingNavigationController.signal, + opts && opts.submission + ); + let pendingActionResult: PendingActionResult | undefined; + + if (opts && opts.pendingError) { + // If we have a pendingError, it means the user attempted a GET submission + // with binary FormData so assign here and skip to handleLoaders. That + // way we handle calling loaders above the boundary etc. It's not really + // different from an actionError in that sense. + pendingActionResult = [ + findNearestBoundary(matches).route.id, + { type: ResultType.error, error: opts.pendingError }, + ]; + } else if ( + opts && + opts.submission && + isMutationMethod(opts.submission.formMethod) + ) { + // Call action if we received an action submission + let actionResult = await handleAction( + request, + location, + opts.submission, + matches, + fogOfWar.active, + { replace: opts.replace, flushSync } + ); + + if (actionResult.shortCircuited) { + return; + } + + // If we received a 404 from handleAction, it's because we couldn't lazily + // discover the destination route so we don't want to call loaders + if (actionResult.pendingActionResult) { + let [routeId, result] = actionResult.pendingActionResult; + if ( + isErrorResult(result) && + isRouteErrorResponse(result.error) && + result.error.status === 404 + ) { + pendingNavigationController = null; + + completeNavigation(location, { + matches: actionResult.matches, + loaderData: {}, + errors: { + [routeId]: result.error, + }, + }); + return; + } + } + + matches = actionResult.matches || matches; + pendingActionResult = actionResult.pendingActionResult; + loadingNavigation = getLoadingNavigation(location, opts.submission); + flushSync = false; + // No need to do fog of war matching again on loader execution + fogOfWar.active = false; + + // Create a GET request for the loaders + request = createClientSideRequest( + init.history, + request.url, + request.signal + ); + } + + // Call loaders + let { + shortCircuited, + matches: updatedMatches, + loaderData, + errors, + } = await handleLoaders( + request, + location, + matches, + fogOfWar.active, + loadingNavigation, + opts && opts.submission, + opts && opts.fetcherSubmission, + opts && opts.replace, + opts && opts.initialHydration === true, + flushSync, + pendingActionResult + ); + + if (shortCircuited) { + return; + } + + // Clean up now that the action/loaders have completed. Don't clean up if + // we short circuited because pendingNavigationController will have already + // been assigned to a new controller for the next navigation + pendingNavigationController = null; + + completeNavigation(location, { + matches: updatedMatches || matches, + ...getActionDataForCommit(pendingActionResult), + loaderData, + errors, + }); + } + + // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + async function handleAction( + request: Request, + location: Location, + submission: Submission, + matches: AgnosticDataRouteMatch[], + isFogOfWar: boolean, + opts: { replace?: boolean; flushSync?: boolean } = {} + ): Promise { + interruptActiveLoads(); + + // Put us in a submitting state + let navigation = getSubmittingNavigation(location, submission); + updateState({ navigation }, { flushSync: opts.flushSync === true }); + + if (isFogOfWar) { + let discoverResult = await discoverRoutes( + matches, + location.pathname, + request.signal + ); + if (discoverResult.type === "aborted") { + return { shortCircuited: true }; + } else if (discoverResult.type === "error") { + let { boundaryId, error } = handleDiscoverRouteError( + location.pathname, + discoverResult + ); + return { + matches: discoverResult.partialMatches, + pendingActionResult: [ + boundaryId, + { + type: ResultType.error, + error, + }, + ], + }; + } else if (!discoverResult.matches) { + let { notFoundMatches, error, route } = handleNavigational404( + location.pathname + ); + return { + matches: notFoundMatches, + pendingActionResult: [ + route.id, + { + type: ResultType.error, + error, + }, + ], + }; + } else { + matches = discoverResult.matches; + } + } + + // Call our action and get the result + let result: DataResult; + let actionMatch = getTargetMatch(matches, location); + + if (!actionMatch.route.action && !actionMatch.route.lazy) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id, + }), + }; + } else { + let results = await callDataStrategy( + "action", + request, + [actionMatch], + matches + ); + result = results[0]; + + if (request.signal.aborted) { + return { shortCircuited: true }; + } + } + + if (isRedirectResult(result)) { + let replace: boolean; + if (opts && opts.replace != null) { + replace = opts.replace; + } else { + // If the user didn't explicity indicate replace behavior, replace if + // we redirected to the exact same location we're currently at to avoid + // double back-buttons + let location = normalizeRedirectLocation( + result.response.headers.get("Location")!, + new URL(request.url), + basename + ); + replace = location === state.location.pathname + state.location.search; + } + await startRedirectNavigation(request, result, { + submission, + replace, + }); + return { shortCircuited: true }; + } + + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { type: "defer-action" }); + } + + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); + + // By default, all submissions to the current location are REPLACE + // navigations, but if the action threw an error that'll be rendered in + // an errorElement, we fall back to PUSH so that the user can use the + // back button to get back to the pre-submission form location to try + // again + if ((opts && opts.replace) !== true) { + pendingAction = HistoryAction.Push; + } + + return { + matches, + pendingActionResult: [boundaryMatch.route.id, result], + }; + } + + return { + matches, + pendingActionResult: [actionMatch.route.id, result], + }; + } + + // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + async function handleLoaders( + request: Request, + location: Location, + matches: AgnosticDataRouteMatch[], + isFogOfWar: boolean, + overrideNavigation?: Navigation, + submission?: Submission, + fetcherSubmission?: Submission, + replace?: boolean, + initialHydration?: boolean, + flushSync?: boolean, + pendingActionResult?: PendingActionResult + ): Promise { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = + overrideNavigation || getLoadingNavigation(location, submission); + + // If this was a redirect from an action we don't have a "submission" but + // we have it on the loading navigation so use that if available + let activeSubmission = + submission || + fetcherSubmission || + getSubmissionFromNavigation(loadingNavigation); + + // If this is an uninterrupted revalidation, we remain in our current idle + // state. If not, we need to switch to our loading state and load data, + // preserving any new action data or existing action data (in the case of + // a revalidation interrupting an actionReload) + // If we have partialHydration enabled, then don't update the state for the + // initial data load since it's not a "navigation" + let shouldUpdateNavigationState = + !isUninterruptedRevalidation && + (!future.v7_partialHydration || !initialHydration); + + // When fog of war is enabled, we enter our `loading` state earlier so we + // can discover new routes during the `loading` state. We skip this if + // we've already run actions since we would have done our matching already. + // If the children() function threw then, we want to proceed with the + // partial matches it discovered. + if (isFogOfWar) { + if (shouldUpdateNavigationState) { + let actionData = getUpdatedActionData(pendingActionResult); + updateState( + { + navigation: loadingNavigation, + ...(actionData !== undefined ? { actionData } : {}), + }, + { + flushSync, + } + ); + } + + let discoverResult = await discoverRoutes( + matches, + location.pathname, + request.signal + ); + + if (discoverResult.type === "aborted") { + return { shortCircuited: true }; + } else if (discoverResult.type === "error") { + let { boundaryId, error } = handleDiscoverRouteError( + location.pathname, + discoverResult + ); + return { + matches: discoverResult.partialMatches, + loaderData: {}, + errors: { + [boundaryId]: error, + }, + }; + } else if (!discoverResult.matches) { + let { error, notFoundMatches, route } = handleNavigational404( + location.pathname + ); + return { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error, + }, + }; + } else { + matches = discoverResult.matches; + } + } + + let routesToUse = inFlightDataRoutes || dataRoutes; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad( + init.history, + state, + matches, + activeSubmission, + location, + future.v7_partialHydration && initialHydration === true, + future.v7_skipActionErrorRevalidation, + isRevalidationRequired, + cancelledDeferredRoutes, + cancelledFetcherLoads, + deletedFetchers, + fetchLoadMatches, + fetchRedirectIds, + routesToUse, + basename, + pendingActionResult + ); + + // Cancel pending deferreds for no-longer-matched routes or routes we're + // about to reload. Note that if this is an action reload we would have + // already cancelled all pending deferreds so this would be a no-op + cancelActiveDeferreds( + (routeId) => + !(matches && matches.some((m) => m.route.id === routeId)) || + (matchesToLoad && matchesToLoad.some((m) => m.route.id === routeId)) + ); + + pendingNavigationLoadId = ++incrementingLoadId; + + // Short circuit if we have no loaders to run + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + let updatedFetchers = markFetchRedirectsDone(); + completeNavigation( + location, + { + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: + pendingActionResult && isErrorResult(pendingActionResult[1]) + ? { [pendingActionResult[0]]: pendingActionResult[1].error } + : null, + ...getActionDataForCommit(pendingActionResult), + ...(updatedFetchers ? { fetchers: new Map(state.fetchers) } : {}), + }, + { flushSync } + ); + return { shortCircuited: true }; + } + + if (shouldUpdateNavigationState) { + let updates: Partial = {}; + if (!isFogOfWar) { + // Only update navigation/actionNData if we didn't already do it above + updates.navigation = loadingNavigation; + let actionData = getUpdatedActionData(pendingActionResult); + if (actionData !== undefined) { + updates.actionData = actionData; + } + } + if (revalidatingFetchers.length > 0) { + updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); + } + updateState(updates, { flushSync }); + } + + revalidatingFetchers.forEach((rf) => { + if (fetchControllers.has(rf.key)) { + abortFetcher(rf.key); + } + if (rf.controller) { + // Fetchers use an independent AbortController so that aborting a fetcher + // (via deleteFetcher) does not abort the triggering navigation that + // triggered the revalidation + fetchControllers.set(rf.key, rf.controller); + } + }); + + // Proxy navigation abort through to revalidation fetchers + let abortPendingFetchRevalidations = () => + revalidatingFetchers.forEach((f) => abortFetcher(f.key)); + if (pendingNavigationController) { + pendingNavigationController.signal.addEventListener( + "abort", + abortPendingFetchRevalidations + ); + } + + let { loaderResults, fetcherResults } = + await callLoadersAndMaybeResolveData( + state.matches, + matches, + matchesToLoad, + revalidatingFetchers, + request + ); + + if (request.signal.aborted) { + return { shortCircuited: true }; + } + + // Clean up _after_ loaders have completed. Don't clean up if we short + // circuited because fetchControllers would have been aborted and + // reassigned to new controllers for the next navigation + if (pendingNavigationController) { + pendingNavigationController.signal.removeEventListener( + "abort", + abortPendingFetchRevalidations + ); + } + revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key)); + + // If any loaders returned a redirect Response, start a new REPLACE navigation + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = + revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + await startRedirectNavigation(request, redirect.result, { + replace, + }); + return { shortCircuited: true }; + } + + // Process and commit output from loaders + let { loaderData, errors } = processLoaderData( + state, + matches, + matchesToLoad, + loaderResults, + pendingActionResult, + revalidatingFetchers, + fetcherResults, + activeDeferreds + ); + + // Wire up subscribers to update loaderData as promises settle + activeDeferreds.forEach((deferredData, routeId) => { + deferredData.subscribe((aborted) => { + // Note: No need to updateState here since the TrackedPromise on + // loaderData is stable across resolve/reject + // Remove this instance if we were aborted or if promises have settled + if (aborted || deferredData.done) { + activeDeferreds.delete(routeId); + } + }); + }); + + // During partial hydration, preserve SSR errors for routes that don't re-run + if (future.v7_partialHydration && initialHydration && state.errors) { + Object.entries(state.errors) + .filter(([id]) => !matchesToLoad.some((m) => m.route.id === id)) + .forEach(([routeId, error]) => { + errors = Object.assign(errors || {}, { [routeId]: error }); + }); + } + + let updatedFetchers = markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + let shouldUpdateFetchers = + updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; + + return { + matches, + loaderData, + errors, + ...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}), + }; + } + + function getUpdatedActionData( + pendingActionResult: PendingActionResult | undefined + ): Record | null | undefined { + if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { + // This is cast to `any` currently because `RouteData`uses any and it + // would be a breaking change to use any. + // TODO: v7 - change `RouteData` to use `unknown` instead of `any` + return { + [pendingActionResult[0]]: pendingActionResult[1].data as any, + }; + } else if (state.actionData) { + if (Object.keys(state.actionData).length === 0) { + return null; + } else { + return state.actionData; + } + } + } + + function getUpdatedRevalidatingFetchers( + revalidatingFetchers: RevalidatingFetcher[] + ) { + revalidatingFetchers.forEach((rf) => { + let fetcher = state.fetchers.get(rf.key); + let revalidatingFetcher = getLoadingFetcher( + undefined, + fetcher ? fetcher.data : undefined + ); + state.fetchers.set(rf.key, revalidatingFetcher); + }); + return new Map(state.fetchers); + } + + // Trigger a fetcher load/submit for the given fetcher key + function fetch( + key: string, + routeId: string, + href: string | null, + opts?: RouterFetchOptions + ) { + if (isServer) { + throw new Error( + "router.fetch() was called during the server render, but it shouldn't be. " + + "You are likely calling a useFetcher() method in the body of your component. " + + "Try moving it to a useEffect or a callback." + ); + } + + if (fetchControllers.has(key)) abortFetcher(key); + let flushSync = (opts && opts.unstable_flushSync) === true; + + let routesToUse = inFlightDataRoutes || dataRoutes; + let normalizedPath = normalizeTo( + state.location, + state.matches, + basename, + future.v7_prependBasename, + href, + future.v7_relativeSplatPath, + routeId, + opts?.relative + ); + let matches = matchRoutes(routesToUse, normalizedPath, basename); + + let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); + if (fogOfWar.active && fogOfWar.matches) { + matches = fogOfWar.matches; + } + + if (!matches) { + setFetcherError( + key, + routeId, + getInternalRouterError(404, { pathname: normalizedPath }), + { flushSync } + ); + return; + } + + let { path, submission, error } = normalizeNavigateOptions( + future.v7_normalizeFormMethod, + true, + normalizedPath, + opts + ); + + if (error) { + setFetcherError(key, routeId, error, { flushSync }); + return; + } + + let match = getTargetMatch(matches, path); + + pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; + + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction( + key, + routeId, + path, + match, + matches, + fogOfWar.active, + flushSync, + submission + ); + return; + } + + // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + fetchLoadMatches.set(key, { routeId, path }); + handleFetcherLoader( + key, + routeId, + path, + match, + matches, + fogOfWar.active, + flushSync, + submission + ); + } + + // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + async function handleFetcherAction( + key: string, + routeId: string, + path: string, + match: AgnosticDataRouteMatch, + requestMatches: AgnosticDataRouteMatch[], + isFogOfWar: boolean, + flushSync: boolean, + submission: Submission + ) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + + function detectAndHandle405Error(m: AgnosticDataRouteMatch) { + if (!m.route.action && !m.route.lazy) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId, + }); + setFetcherError(key, routeId, error, { flushSync }); + return true; + } + return false; + } + + if (!isFogOfWar && detectAndHandle405Error(match)) { + return; + } + + // Put this fetcher into it's submitting state + let existingFetcher = state.fetchers.get(key); + updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { + flushSync, + }); + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest( + init.history, + path, + abortController.signal, + submission + ); + + if (isFogOfWar) { + let discoverResult = await discoverRoutes( + requestMatches, + path, + fetchRequest.signal + ); + + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { error } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { flushSync }); + return; + } else if (!discoverResult.matches) { + setFetcherError( + key, + routeId, + getInternalRouterError(404, { pathname: path }), + { flushSync } + ); + return; + } else { + requestMatches = discoverResult.matches; + match = getTargetMatch(requestMatches, path); + + if (detectAndHandle405Error(match)) { + return; + } + } + } + + // Call the action for the fetcher + fetchControllers.set(key, abortController); + + let originatingLoadId = incrementingLoadId; + let actionResults = await callDataStrategy( + "action", + fetchRequest, + [match], + requestMatches + ); + let actionResult = actionResults[0]; + + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + return; + } + + // When using v7_fetcherPersist, we don't want errors bubbling up to the UI + // or redirects processed for unmounted fetchers so we just revert them to + // idle + if (future.v7_fetcherPersist && deletedFetchers.has(key)) { + if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + // Let SuccessResult's fall through for revalidation + } else { + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our action started, so that + // should take precedence over this redirect navigation. We already + // set isRevalidationRequired so all loaders for the new route should + // fire unless opted out via shouldRevalidate + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + updateFetcherState(key, getLoadingFetcher(submission)); + return startRedirectNavigation(fetchRequest, actionResult, { + fetcherSubmission: submission, + }); + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(actionResult)) { + setFetcherError(key, routeId, actionResult.error); + return; + } + } + + if (isDeferredResult(actionResult)) { + throw getInternalRouterError(400, { type: "defer-action" }); + } + + // Start the data load for current matches, or the next location if we're + // in the middle of a navigation + let nextLocation = state.navigation.location || state.location; + let revalidationRequest = createClientSideRequest( + init.history, + nextLocation, + abortController.signal + ); + let routesToUse = inFlightDataRoutes || dataRoutes; + let matches = + state.navigation.state !== "idle" + ? matchRoutes(routesToUse, state.navigation.location, basename) + : state.matches; + + invariant(matches, "Didn't find any matches after fetcher action"); + + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + + let loadFetcher = getLoadingFetcher(submission, actionResult.data); + state.fetchers.set(key, loadFetcher); + + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad( + init.history, + state, + matches, + submission, + nextLocation, + false, + future.v7_skipActionErrorRevalidation, + isRevalidationRequired, + cancelledDeferredRoutes, + cancelledFetcherLoads, + deletedFetchers, + fetchLoadMatches, + fetchRedirectIds, + routesToUse, + basename, + [match.route.id, actionResult] + ); + + // Put all revalidating fetchers into the loading state, except for the + // current fetcher which we want to keep in it's current loading state which + // contains it's action submission info + action data + revalidatingFetchers + .filter((rf) => rf.key !== key) + .forEach((rf) => { + let staleKey = rf.key; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = getLoadingFetcher( + undefined, + existingFetcher ? existingFetcher.data : undefined + ); + state.fetchers.set(staleKey, revalidatingFetcher); + if (fetchControllers.has(staleKey)) { + abortFetcher(staleKey); + } + if (rf.controller) { + fetchControllers.set(staleKey, rf.controller); + } + }); + + updateState({ fetchers: new Map(state.fetchers) }); + + let abortPendingFetchRevalidations = () => + revalidatingFetchers.forEach((rf) => abortFetcher(rf.key)); + + abortController.signal.addEventListener( + "abort", + abortPendingFetchRevalidations + ); + + let { loaderResults, fetcherResults } = + await callLoadersAndMaybeResolveData( + state.matches, + matches, + matchesToLoad, + revalidatingFetchers, + revalidationRequest + ); + + if (abortController.signal.aborted) { + return; + } + + abortController.signal.removeEventListener( + "abort", + abortPendingFetchRevalidations + ); + + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key)); + + let redirect = findRedirect([...loaderResults, ...fetcherResults]); + if (redirect) { + if (redirect.idx >= matchesToLoad.length) { + // If this redirect came from a fetcher make sure we mark it in + // fetchRedirectIds so it doesn't get revalidated on the next set of + // loader executions + let fetcherKey = + revalidatingFetchers[redirect.idx - matchesToLoad.length].key; + fetchRedirectIds.add(fetcherKey); + } + return startRedirectNavigation(revalidationRequest, redirect.result); + } + + // Process and commit output from loaders + let { loaderData, errors } = processLoaderData( + state, + state.matches, + matchesToLoad, + loaderResults, + undefined, + revalidatingFetchers, + fetcherResults, + activeDeferreds + ); + + // Since we let revalidations complete even if the submitting fetcher was + // deleted, only put it back to idle if it hasn't been deleted + if (state.fetchers.has(key)) { + let doneFetcher = getDoneFetcher(actionResult.data); + state.fetchers.set(key, doneFetcher); + } + + abortStaleFetchLoads(loadId); + + // If we are currently in a navigation loading state and this fetcher is + // more recent than the navigation, we want the newer data so abort the + // navigation and complete it with the fetcher data + if ( + state.navigation.state === "loading" && + loadId > pendingNavigationLoadId + ) { + invariant(pendingAction, "Expected pending action"); + pendingNavigationController && pendingNavigationController.abort(); + + completeNavigation(state.navigation.location, { + matches, + loaderData, + errors, + fetchers: new Map(state.fetchers), + }); + } else { + // otherwise just update with the fetcher data, preserving any existing + // loaderData for loaders that did not need to reload. We have to + // manually merge here since we aren't going through completeNavigation + updateState({ + errors, + loaderData: mergeLoaderData( + state.loaderData, + loaderData, + matches, + errors + ), + fetchers: new Map(state.fetchers), + }); + isRevalidationRequired = false; + } + } + + // Call the matched loader for fetcher.load(), handling redirects, errors, etc. + async function handleFetcherLoader( + key: string, + routeId: string, + path: string, + match: AgnosticDataRouteMatch, + matches: AgnosticDataRouteMatch[], + isFogOfWar: boolean, + flushSync: boolean, + submission?: Submission + ) { + let existingFetcher = state.fetchers.get(key); + updateFetcherState( + key, + getLoadingFetcher( + submission, + existingFetcher ? existingFetcher.data : undefined + ), + { flushSync } + ); + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest( + init.history, + path, + abortController.signal + ); + + if (isFogOfWar) { + let discoverResult = await discoverRoutes( + matches, + path, + fetchRequest.signal + ); + + if (discoverResult.type === "aborted") { + return; + } else if (discoverResult.type === "error") { + let { error } = handleDiscoverRouteError(path, discoverResult); + setFetcherError(key, routeId, error, { flushSync }); + return; + } else if (!discoverResult.matches) { + setFetcherError( + key, + routeId, + getInternalRouterError(404, { pathname: path }), + { flushSync } + ); + return; + } else { + matches = discoverResult.matches; + match = getTargetMatch(matches, path); + } + } + + // Call the loader for this fetcher route match + fetchControllers.set(key, abortController); + + let originatingLoadId = incrementingLoadId; + let results = await callDataStrategy( + "loader", + fetchRequest, + [match], + matches + ); + let result = results[0]; + + // Deferred isn't supported for fetcher loads, await everything and treat it + // as a normal load. resolveDeferredData will return undefined if this + // fetcher gets aborted, so we just leave result untouched and short circuit + // below if that happens + if (isDeferredResult(result)) { + result = + (await resolveDeferredData(result, fetchRequest.signal, true)) || + result; + } + + // We can delete this so long as we weren't aborted by our our own fetcher + // re-load which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + + if (fetchRequest.signal.aborted) { + return; + } + + // We don't want errors bubbling up or redirects followed for unmounted + // fetchers, so short circuit here if it was removed from the UI + if (deletedFetchers.has(key)) { + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } + + // If the loader threw a redirect Response, start a new REPLACE navigation + if (isRedirectResult(result)) { + if (pendingNavigationLoadId > originatingLoadId) { + // A new navigation was kicked off after our loader started, so that + // should take precedence over this redirect navigation + updateFetcherState(key, getDoneFetcher(undefined)); + return; + } else { + fetchRedirectIds.add(key); + await startRedirectNavigation(fetchRequest, result); + return; + } + } + + // Process any non-redirect errors thrown + if (isErrorResult(result)) { + setFetcherError(key, routeId, result.error); + return; + } + + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); + + // Put the fetcher back into an idle state + updateFetcherState(key, getDoneFetcher(result.data)); + } + + /** + * Utility function to handle redirects returned from an action or loader. + * Normally, a redirect "replaces" the navigation that triggered it. So, for + * example: + * + * - user is on /a + * - user clicks a link to /b + * - loader for /b redirects to /c + * + * In a non-JS app the browser would track the in-flight navigation to /b and + * then replace it with /c when it encountered the redirect response. In + * the end it would only ever update the URL bar with /c. + * + * In client-side routing using pushState/replaceState, we aim to emulate + * this behavior and we also do not update history until the end of the + * navigation (including processed redirects). This means that we never + * actually touch history until we've processed redirects, so we just use + * the history action from the original navigation (PUSH or REPLACE). + */ + async function startRedirectNavigation( + request: Request, + redirect: RedirectResult, + { + submission, + fetcherSubmission, + replace, + }: { + submission?: Submission; + fetcherSubmission?: Submission; + replace?: boolean; + } = {} + ) { + if (redirect.response.headers.has("X-Remix-Revalidate")) { + isRevalidationRequired = true; + } + + let location = redirect.response.headers.get("Location"); + invariant(location, "Expected a Location header on the redirect Response"); + location = normalizeRedirectLocation( + location, + new URL(request.url), + basename + ); + let redirectLocation = createLocation(state.location, location, { + _isRedirect: true, + }); + + if (isBrowser) { + let isDocumentReload = false; + + if (redirect.response.headers.has("X-Remix-Reload-Document")) { + // Hard reload if the response contained X-Remix-Reload-Document + isDocumentReload = true; + } else if (ABSOLUTE_URL_REGEX.test(location)) { + const url = init.history.createURL(location); + isDocumentReload = + // Hard reload if it's an absolute URL to a new origin + url.origin !== routerWindow.location.origin || + // Hard reload if it's an absolute URL that does not match our basename + stripBasename(url.pathname, basename) == null; + } + + if (isDocumentReload) { + if (replace) { + routerWindow.location.replace(location); + } else { + routerWindow.location.assign(location); + } + return; + } + } + + // There's no need to abort on redirects, since we don't detect the + // redirect until the action/loaders have settled + pendingNavigationController = null; + + let redirectHistoryAction = + replace === true ? HistoryAction.Replace : HistoryAction.Push; + + // Use the incoming submission if provided, fallback on the active one in + // state.navigation + let { formMethod, formAction, formEncType } = state.navigation; + if ( + !submission && + !fetcherSubmission && + formMethod && + formAction && + formEncType + ) { + submission = getSubmissionFromNavigation(state.navigation); + } + + // If this was a 307/308 submission we want to preserve the HTTP method and + // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the + // redirected location + let activeSubmission = submission || fetcherSubmission; + if ( + redirectPreserveMethodStatusCodes.has(redirect.response.status) && + activeSubmission && + isMutationMethod(activeSubmission.formMethod) + ) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: { + ...activeSubmission, + formAction: location, + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset, + }); + } else { + // If we have a navigation submission, we will preserve it through the + // redirect navigation + let overrideNavigation = getLoadingNavigation( + redirectLocation, + submission + ); + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation, + // Send fetcher submissions through for shouldRevalidate + fetcherSubmission, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset, + }); + } + } + + // Utility wrapper for calling dataStrategy client-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy( + type: "loader" | "action", + request: Request, + matchesToLoad: AgnosticDataRouteMatch[], + matches: AgnosticDataRouteMatch[] + ): Promise { + try { + let results = await callDataStrategyImpl( + dataStrategyImpl, + type, + request, + matchesToLoad, + matches, + manifest, + mapRouteProperties + ); + + return await Promise.all( + results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result as Response; + return { + type: ResultType.redirect, + response: normalizeRelativeRoutingRedirectResponse( + response, + request, + matchesToLoad[i].route.id, + matches, + basename, + future.v7_relativeSplatPath + ), + }; + } + + return convertHandlerResultToDataResult(result); + }) + ); + } catch (e) { + // If the outer dataStrategy method throws, just return the error for all + // matches - and it'll naturally bubble to the root + return matchesToLoad.map(() => ({ + type: ResultType.error, + error: e, + })); + } + } + + async function callLoadersAndMaybeResolveData( + currentMatches: AgnosticDataRouteMatch[], + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + fetchersToLoad: RevalidatingFetcher[], + request: Request + ) { + let [loaderResults, ...fetcherResults] = await Promise.all([ + matchesToLoad.length + ? callDataStrategy("loader", request, matchesToLoad, matches) + : [], + ...fetchersToLoad.map((f) => { + if (f.matches && f.match && f.controller) { + let fetcherRequest = createClientSideRequest( + init.history, + f.path, + f.controller.signal + ); + return callDataStrategy( + "loader", + fetcherRequest, + [f.match], + f.matches + ).then((r) => r[0]); + } else { + return Promise.resolve({ + type: ResultType.error, + error: getInternalRouterError(404, { + pathname: f.path, + }), + }); + } + }), + ]); + + await Promise.all([ + resolveDeferredResults( + currentMatches, + matchesToLoad, + loaderResults, + loaderResults.map(() => request.signal), + false, + state.loaderData + ), + resolveDeferredResults( + currentMatches, + fetchersToLoad.map((f) => f.match), + fetcherResults, + fetchersToLoad.map((f) => (f.controller ? f.controller.signal : null)), + true + ), + ]); + + return { + loaderResults, + fetcherResults, + }; + } + + function interruptActiveLoads() { + // Every interruption triggers a revalidation + isRevalidationRequired = true; + + // Cancel pending route-level deferreds and mark cancelled routes for + // revalidation + cancelledDeferredRoutes.push(...cancelActiveDeferreds()); + + // Abort in-flight fetcher loads + fetchLoadMatches.forEach((_, key) => { + if (fetchControllers.has(key)) { + cancelledFetcherLoads.push(key); + abortFetcher(key); + } + }); + } + + function updateFetcherState( + key: string, + fetcher: Fetcher, + opts: { flushSync?: boolean } = {} + ) { + state.fetchers.set(key, fetcher); + updateState( + { fetchers: new Map(state.fetchers) }, + { flushSync: (opts && opts.flushSync) === true } + ); + } + + function setFetcherError( + key: string, + routeId: string, + error: any, + opts: { flushSync?: boolean } = {} + ) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState( + { + errors: { + [boundaryMatch.route.id]: error, + }, + fetchers: new Map(state.fetchers), + }, + { flushSync: (opts && opts.flushSync) === true } + ); + } + + function getFetcher(key: string): Fetcher { + if (future.v7_fetcherPersist) { + activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); + // If this fetcher was previously marked for deletion, unmark it since we + // have a new instance + if (deletedFetchers.has(key)) { + deletedFetchers.delete(key); + } + } + return state.fetchers.get(key) || IDLE_FETCHER; + } + + function deleteFetcher(key: string): void { + let fetcher = state.fetchers.get(key); + // Don't abort the controller if this is a deletion of a fetcher.submit() + // in it's loading phase since - we don't want to abort the corresponding + // revalidation and want them to complete and land + if ( + fetchControllers.has(key) && + !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key)) + ) { + abortFetcher(key); + } + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + deletedFetchers.delete(key); + state.fetchers.delete(key); + } + + function deleteFetcherAndUpdateState(key: string): void { + if (future.v7_fetcherPersist) { + let count = (activeFetchers.get(key) || 0) - 1; + if (count <= 0) { + activeFetchers.delete(key); + deletedFetchers.add(key); + } else { + activeFetchers.set(key, count); + } + } else { + deleteFetcher(key); + } + updateState({ fetchers: new Map(state.fetchers) }); + } + + function abortFetcher(key: string) { + let controller = fetchControllers.get(key); + invariant(controller, `Expected fetch controller: ${key}`); + controller.abort(); + fetchControllers.delete(key); + } + + function markFetchersDone(keys: string[]) { + for (let key of keys) { + let fetcher = getFetcher(key); + let doneFetcher = getDoneFetcher(fetcher.data); + state.fetchers.set(key, doneFetcher); + } + } + + function markFetchRedirectsDone(): boolean { + let doneKeys = []; + let updatedFetchers = false; + for (let key of fetchRedirectIds) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, `Expected fetcher: ${key}`); + if (fetcher.state === "loading") { + fetchRedirectIds.delete(key); + doneKeys.push(key); + updatedFetchers = true; + } + } + markFetchersDone(doneKeys); + return updatedFetchers; + } + + function abortStaleFetchLoads(landedId: number): boolean { + let yeetedKeys = []; + for (let [key, id] of fetchReloadIds) { + if (id < landedId) { + let fetcher = state.fetchers.get(key); + invariant(fetcher, `Expected fetcher: ${key}`); + if (fetcher.state === "loading") { + abortFetcher(key); + fetchReloadIds.delete(key); + yeetedKeys.push(key); + } + } + } + markFetchersDone(yeetedKeys); + return yeetedKeys.length > 0; + } + + function getBlocker(key: string, fn: BlockerFunction) { + let blocker: Blocker = state.blockers.get(key) || IDLE_BLOCKER; + + if (blockerFunctions.get(key) !== fn) { + blockerFunctions.set(key, fn); + } + + return blocker; + } + + function deleteBlocker(key: string) { + state.blockers.delete(key); + blockerFunctions.delete(key); + } + + // Utility function to update blockers, ensuring valid state transitions + function updateBlocker(key: string, newBlocker: Blocker) { + let blocker = state.blockers.get(key) || IDLE_BLOCKER; + + // Poor mans state machine :) + // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM + invariant( + (blocker.state === "unblocked" && newBlocker.state === "blocked") || + (blocker.state === "blocked" && newBlocker.state === "blocked") || + (blocker.state === "blocked" && newBlocker.state === "proceeding") || + (blocker.state === "blocked" && newBlocker.state === "unblocked") || + (blocker.state === "proceeding" && newBlocker.state === "unblocked"), + `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}` + ); + + let blockers = new Map(state.blockers); + blockers.set(key, newBlocker); + updateState({ blockers }); + } + + function shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction, + }: { + currentLocation: Location; + nextLocation: Location; + historyAction: HistoryAction; + }): string | undefined { + if (blockerFunctions.size === 0) { + return; + } + + // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + if (blockerFunctions.size > 1) { + warning(false, "A router only supports one blocker at a time"); + } + + let entries = Array.from(blockerFunctions.entries()); + let [blockerKey, blockerFunction] = entries[entries.length - 1]; + let blocker = state.blockers.get(blockerKey); + + if (blocker && blocker.state === "proceeding") { + // If the blocker is currently proceeding, we don't need to re-check + // it and can let this navigation continue + return; + } + + // At this point, we know we're unblocked/blocked so we need to check the + // user-provided blocker function + if (blockerFunction({ currentLocation, nextLocation, historyAction })) { + return blockerKey; + } + } + + function handleNavigational404(pathname: string) { + let error = getInternalRouterError(404, { pathname }); + let routesToUse = inFlightDataRoutes || dataRoutes; + let { matches, route } = getShortCircuitMatches(routesToUse); + + // Cancel all pending deferred on 404s since we don't keep any routes + cancelActiveDeferreds(); + + return { notFoundMatches: matches, route, error }; + } + + function handleDiscoverRouteError( + pathname: string, + discoverResult: DiscoverRoutesErrorResult + ) { + return { + boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id, + error: getInternalRouterError(400, { + type: "route-discovery", + pathname, + message: + discoverResult.error != null && "message" in discoverResult.error + ? discoverResult.error + : String(discoverResult.error), + }), + }; + } + + function cancelActiveDeferreds( + predicate?: (routeId: string) => boolean + ): string[] { + let cancelledRouteIds: string[] = []; + activeDeferreds.forEach((dfd, routeId) => { + if (!predicate || predicate(routeId)) { + // Cancel the deferred - but do not remove from activeDeferreds here - + // we rely on the subscribers to do that so our tests can assert proper + // cleanup via _internalActiveDeferreds + dfd.cancel(); + cancelledRouteIds.push(routeId); + activeDeferreds.delete(routeId); + } + }); + return cancelledRouteIds; + } + + // Opt in to capturing and reporting scroll positions during navigations, + // used by the component + function enableScrollRestoration( + positions: Record, + getPosition: GetScrollPositionFunction, + getKey?: GetScrollRestorationKeyFunction + ) { + savedScrollPositions = positions; + getScrollPosition = getPosition; + getScrollRestorationKey = getKey || null; + + // Perform initial hydration scroll restoration, since we miss the boat on + // the initial updateState() because we've not yet rendered + // and therefore have no savedScrollPositions available + if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { + initialScrollRestored = true; + let y = getSavedScrollPosition(state.location, state.matches); + if (y != null) { + updateState({ restoreScrollPosition: y }); + } + } + + return () => { + savedScrollPositions = null; + getScrollPosition = null; + getScrollRestorationKey = null; + }; + } + + function getScrollKey(location: Location, matches: AgnosticDataRouteMatch[]) { + if (getScrollRestorationKey) { + let key = getScrollRestorationKey( + location, + matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData)) + ); + return key || location.key; + } + return location.key; + } + + function saveScrollPosition( + location: Location, + matches: AgnosticDataRouteMatch[] + ): void { + if (savedScrollPositions && getScrollPosition) { + let key = getScrollKey(location, matches); + savedScrollPositions[key] = getScrollPosition(); + } + } + + function getSavedScrollPosition( + location: Location, + matches: AgnosticDataRouteMatch[] + ): number | null { + if (savedScrollPositions) { + let key = getScrollKey(location, matches); + let y = savedScrollPositions[key]; + if (typeof y === "number") { + return y; + } + } + return null; + } + + function checkFogOfWar( + matches: AgnosticDataRouteMatch[] | null, + routesToUse: AgnosticDataRouteObject[], + pathname: string + ): { active: boolean; matches: AgnosticDataRouteMatch[] | null } { + if (patchRoutesOnMissImpl) { + if (!matches) { + let fogMatches = matchRoutesImpl( + routesToUse, + pathname, + basename, + true + ); + + return { active: true, matches: fogMatches || [] }; + } else { + let leafRoute = matches[matches.length - 1].route; + if ( + leafRoute.path && + (leafRoute.path === "*" || leafRoute.path.endsWith("/*")) + ) { + // If we matched a splat, it might only be because we haven't yet fetched + // the children that would match with a higher score, so let's fetch + // around and find out + let partialMatches = matchRoutesImpl( + routesToUse, + pathname, + basename, + true + ); + return { active: true, matches: partialMatches }; + } + } + } + + return { active: false, matches: null }; + } + + type DiscoverRoutesSuccessResult = { + type: "success"; + matches: AgnosticDataRouteMatch[] | null; + }; + type DiscoverRoutesErrorResult = { + type: "error"; + error: any; + partialMatches: AgnosticDataRouteMatch[]; + }; + type DiscoverRoutesAbortedResult = { type: "aborted" }; + type DiscoverRoutesResult = + | DiscoverRoutesSuccessResult + | DiscoverRoutesErrorResult + | DiscoverRoutesAbortedResult; + + async function discoverRoutes( + matches: AgnosticDataRouteMatch[], + pathname: string, + signal: AbortSignal + ): Promise { + let partialMatches: AgnosticDataRouteMatch[] | null = matches; + let route = + partialMatches.length > 0 + ? partialMatches[partialMatches.length - 1].route + : null; + while (true) { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + try { + await loadLazyRouteChildren( + patchRoutesOnMissImpl!, + pathname, + partialMatches, + routesToUse, + manifest, + mapRouteProperties, + pendingPatchRoutes, + signal + ); + } catch (e) { + return { type: "error", error: e, partialMatches }; + } finally { + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity so when we `updateState` at the end of + // this navigation/fetch `router.routes` will be a new identity and + // trigger a re-run of memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + } + } + + if (signal.aborted) { + return { type: "aborted" }; + } + + let newMatches = matchRoutes(routesToUse, pathname, basename); + let matchedSplat = false; + if (newMatches) { + let leafRoute = newMatches[newMatches.length - 1].route; + + if (leafRoute.index) { + // If we found an index route, we can stop + return { type: "success", matches: newMatches }; + } + + if (leafRoute.path && leafRoute.path.length > 0) { + if (leafRoute.path === "*") { + // If we found a splat route, we can't be sure there's not a + // higher-scoring route down some partial matches trail so we need + // to check that out + matchedSplat = true; + } else { + // If we found a non-splat route, we can stop + return { type: "success", matches: newMatches }; + } + } + } + + let newPartialMatches = matchRoutesImpl( + routesToUse, + pathname, + basename, + true + ); + + // If we are no longer partially matching anything, this was either a + // legit splat match above, or it's a 404. Also avoid loops if the + // second pass results in the same partial matches + if ( + !newPartialMatches || + partialMatches.map((m) => m.route.id).join("-") === + newPartialMatches.map((m) => m.route.id).join("-") + ) { + return { type: "success", matches: matchedSplat ? newMatches : null }; + } + + partialMatches = newPartialMatches; + route = partialMatches[partialMatches.length - 1].route; + if (route.path === "*") { + // The splat is still our most accurate partial, so run with it + return { type: "success", matches: partialMatches }; + } + } + } + + function _internalSetRoutes(newRoutes: AgnosticDataRouteObject[]) { + manifest = {}; + inFlightDataRoutes = convertRoutesToDataRoutes( + newRoutes, + mapRouteProperties, + undefined, + manifest + ); + } + + function patchRoutes( + routeId: string | null, + children: AgnosticRouteObject[] + ): void { + let isNonHMR = inFlightDataRoutes == null; + let routesToUse = inFlightDataRoutes || dataRoutes; + patchRoutesImpl( + routeId, + children, + routesToUse, + manifest, + mapRouteProperties + ); + + // If we are not in the middle of an HMR revalidation and we changed the + // routes, provide a new identity and trigger a reflow via `updateState` + // to re-run memoized `router.routes` dependencies. + // HMR will already update the identity and reflow when it lands + // `inFlightDataRoutes` in `completeNavigation` + if (isNonHMR) { + dataRoutes = [...dataRoutes]; + updateState({}); + } + } + + router = { + get basename() { + return basename; + }, + get future() { + return future; + }, + get state() { + return state; + }, + get routes() { + return dataRoutes; + }, + get window() { + return routerWindow; + }, + initialize, + subscribe, + enableScrollRestoration, + navigate, + fetch, + revalidate, + // Passthrough to history-aware createHref used by useHref so we get proper + // hash-aware URLs in DOM paths + createHref: (to: To) => init.history.createHref(to), + encodeLocation: (to: To) => init.history.encodeLocation(to), + getFetcher, + deleteFetcher: deleteFetcherAndUpdateState, + dispose, + getBlocker, + deleteBlocker, + patchRoutes, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds, + // TODO: Remove setRoutes, it's temporary to avoid dealing with + // updating the tree while validating the update algorithm. + _internalSetRoutes, + }; + + return router; +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createStaticHandler +//////////////////////////////////////////////////////////////////////////////// + +export const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred"); + +/** + * Future flags to toggle new feature behavior + */ +export interface StaticHandlerFutureConfig { + v7_relativeSplatPath: boolean; + v7_throwAbortReason: boolean; +} + +export interface CreateStaticHandlerOptions { + basename?: string; + /** + * @deprecated Use `mapRouteProperties` instead + */ + detectErrorBoundary?: DetectErrorBoundaryFunction; + mapRouteProperties?: MapRoutePropertiesFunction; + future?: Partial; +} + +export function createStaticHandler( + routes: AgnosticRouteObject[], + opts?: CreateStaticHandlerOptions +): StaticHandler { + invariant( + routes.length > 0, + "You must provide a non-empty routes array to createStaticHandler" + ); + + let manifest: RouteManifest = {}; + let basename = (opts ? opts.basename : null) || "/"; + let mapRouteProperties: MapRoutePropertiesFunction; + if (opts?.mapRouteProperties) { + mapRouteProperties = opts.mapRouteProperties; + } else if (opts?.detectErrorBoundary) { + // If they are still using the deprecated version, wrap it with the new API + let detectErrorBoundary = opts.detectErrorBoundary; + mapRouteProperties = (route) => ({ + hasErrorBoundary: detectErrorBoundary(route), + }); + } else { + mapRouteProperties = defaultMapRouteProperties; + } + // Config driven behavior flags + let future: StaticHandlerFutureConfig = { + v7_relativeSplatPath: false, + v7_throwAbortReason: false, + ...(opts ? opts.future : null), + }; + + let dataRoutes = convertRoutesToDataRoutes( + routes, + mapRouteProperties, + undefined, + manifest + ); + + /** + * The query() method is intended for document requests, in which we want to + * call an optional action and potentially multiple loaders for all nested + * routes. It returns a StaticHandlerContext object, which is very similar + * to the router state (location, loaderData, actionData, errors, etc.) and + * also adds SSR-specific information such as the statusCode and headers + * from action/loaders Responses. + * + * It _should_ never throw and should report all errors through the + * returned context.errors object, properly associating errors to their error + * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be + * used to emulate React error boundaries during SSr by performing a second + * pass only down to the boundaryId. + * + * The one exception where we do not return a StaticHandlerContext is when a + * redirect response is returned or thrown from any action/loader. We + * propagate that out and return the raw Response so the HTTP server can + * return it directly. + * + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent + * the bubbling of errors which allows single-fetch-type implementations + * where the client will handle the bubbling and we may need to return data + * for the handling route + */ + async function query( + request: Request, + { + requestContext, + skipLoaderErrorBubbling, + unstable_dataStrategy, + }: { + requestContext?: unknown; + skipLoaderErrorBubbling?: boolean; + unstable_dataStrategy?: DataStrategyFunction; + } = {} + ): Promise { + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD") { + let error = getInternalRouterError(405, { method }); + let { matches: methodNotAllowedMatches, route } = + getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: methodNotAllowedMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error, + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null, + }; + } else if (!matches) { + let error = getInternalRouterError(404, { pathname: location.pathname }); + let { matches: notFoundMatches, route } = + getShortCircuitMatches(dataRoutes); + return { + basename, + location, + matches: notFoundMatches, + loaderData: {}, + actionData: null, + errors: { + [route.id]: error, + }, + statusCode: error.status, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null, + }; + } + + let result = await queryImpl( + request, + location, + matches, + requestContext, + unstable_dataStrategy || null, + skipLoaderErrorBubbling === true, + null + ); + if (isResponse(result)) { + return result; + } + + // When returning StaticHandlerContext, we patch back in the location here + // since we need it for React Context. But this helps keep our submit and + // loadRouteData operating on a Request instead of a Location + return { location, basename, ...result }; + } + + /** + * The queryRoute() method is intended for targeted route requests, either + * for fetch ?_data requests or resource route requests. In this case, we + * are only ever calling a single action or loader, and we are returning the + * returned value directly. In most cases, this will be a Response returned + * from the action/loader, but it may be a primitive or other value as well - + * and in such cases the calling context should handle that accordingly. + * + * We do respect the throw/return differentiation, so if an action/loader + * throws, then this method will throw the value. This is important so we + * can do proper boundary identification in Remix where a thrown Response + * must go to the Catch Boundary but a returned Response is happy-path. + * + * One thing to note is that any Router-initiated Errors that make sense + * to associate with a status code will be thrown as an ErrorResponse + * instance which include the raw Error, such that the calling context can + * serialize the error as they see fit while including the proper response + * code. Examples here are 404 and 405 errors that occur prior to reaching + * any user-defined loaders. + * + * - `opts.routeId` allows you to specify the specific route handler to call. + * If not provided the handler will determine the proper route by matching + * against `request.url` + * - `opts.requestContext` is an optional server context that will be passed + * to actions/loaders in the `context` parameter + */ + async function queryRoute( + request: Request, + { + routeId, + requestContext, + unstable_dataStrategy, + }: { + requestContext?: unknown; + routeId?: string; + unstable_dataStrategy?: DataStrategyFunction; + } = {} + ): Promise { + let url = new URL(request.url); + let method = request.method; + let location = createLocation("", createPath(url), null, "default"); + let matches = matchRoutes(dataRoutes, location, basename); + + // SSR supports HEAD requests while SPA doesn't + if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { + throw getInternalRouterError(405, { method }); + } else if (!matches) { + throw getInternalRouterError(404, { pathname: location.pathname }); + } + + let match = routeId + ? matches.find((m) => m.route.id === routeId) + : getTargetMatch(matches, location); + + if (routeId && !match) { + throw getInternalRouterError(403, { + pathname: location.pathname, + routeId, + }); + } else if (!match) { + // This should never hit I don't think? + throw getInternalRouterError(404, { pathname: location.pathname }); + } + + let result = await queryImpl( + request, + location, + matches, + requestContext, + unstable_dataStrategy || null, + false, + match + ); + + if (isResponse(result)) { + return result; + } + + let error = result.errors ? Object.values(result.errors)[0] : undefined; + if (error !== undefined) { + // If we got back result.errors, that means the loader/action threw + // _something_ that wasn't a Response, but it's not guaranteed/required + // to be an `instanceof Error` either, so we have to use throw here to + // preserve the "error" state outside of queryImpl. + throw error; + } + + // Pick off the right state value to return + if (result.actionData) { + return Object.values(result.actionData)[0]; + } + + if (result.loaderData) { + let data = Object.values(result.loaderData)[0]; + if (result.activeDeferreds?.[match.route.id]) { + data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id]; + } + return data; + } + + return undefined; + } + + async function queryImpl( + request: Request, + location: Location, + matches: AgnosticDataRouteMatch[], + requestContext: unknown, + unstable_dataStrategy: DataStrategyFunction | null, + skipLoaderErrorBubbling: boolean, + routeMatch: AgnosticDataRouteMatch | null + ): Promise | Response> { + invariant( + request.signal, + "query()/queryRoute() requests must contain an AbortController signal" + ); + + try { + if (isMutationMethod(request.method.toLowerCase())) { + let result = await submit( + request, + matches, + routeMatch || getTargetMatch(matches, location), + requestContext, + unstable_dataStrategy, + skipLoaderErrorBubbling, + routeMatch != null + ); + return result; + } + + let result = await loadRouteData( + request, + matches, + requestContext, + unstable_dataStrategy, + skipLoaderErrorBubbling, + routeMatch + ); + return isResponse(result) + ? result + : { + ...result, + actionData: null, + actionHeaders: {}, + }; + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction for a + // `queryRoute` call, we throw the `HandlerResult` to bail out early + // and then return or throw the raw Response here accordingly + if (isHandlerResult(e) && isResponse(e.result)) { + if (e.type === ResultType.error) { + throw e.result; + } + return e.result; + } + // Redirects are always returned since they don't propagate to catch + // boundaries + if (isRedirectResponse(e)) { + return e; + } + throw e; + } + } + + async function submit( + request: Request, + matches: AgnosticDataRouteMatch[], + actionMatch: AgnosticDataRouteMatch, + requestContext: unknown, + unstable_dataStrategy: DataStrategyFunction | null, + skipLoaderErrorBubbling: boolean, + isRouteRequest: boolean + ): Promise | Response> { + let result: DataResult; + + if (!actionMatch.route.action && !actionMatch.route.lazy) { + let error = getInternalRouterError(405, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: actionMatch.route.id, + }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error, + }; + } else { + let results = await callDataStrategy( + "action", + request, + [actionMatch], + matches, + isRouteRequest, + requestContext, + unstable_dataStrategy + ); + result = results[0]; + + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + } + + if (isRedirectResult(result)) { + // Uhhhh - this should never happen, we should always throw these from + // callLoaderOrAction, but the type narrowing here keeps TS happy and we + // can get back on the "throw all redirect responses" train here should + // this ever happen :/ + throw new Response(null, { + status: result.response.status, + headers: { + Location: result.response.headers.get("Location")!, + }, + }); + } + + if (isDeferredResult(result)) { + let error = getInternalRouterError(400, { type: "defer-action" }); + if (isRouteRequest) { + throw error; + } + result = { + type: ResultType.error, + error, + }; + } + + if (isRouteRequest) { + // Note: This should only be non-Response values if we get here, since + // isRouteRequest should throw any Response received in callLoaderOrAction + if (isErrorResult(result)) { + throw result.error; + } + + return { + matches: [actionMatch], + loaderData: {}, + actionData: { [actionMatch.route.id]: result.data }, + errors: null, + // Note: statusCode + headers are unused here since queryRoute will + // return the raw Response or value + statusCode: 200, + loaderHeaders: {}, + actionHeaders: {}, + activeDeferreds: null, + }; + } + + // Create a GET request for the loaders + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal, + }); + + if (isErrorResult(result)) { + // Store off the pending error - we use it to determine which loaders + // to call and will commit it when we complete the navigation + let boundaryMatch = skipLoaderErrorBubbling + ? actionMatch + : findNearestBoundary(matches, actionMatch.route.id); + + let context = await loadRouteData( + loaderRequest, + matches, + requestContext, + unstable_dataStrategy, + skipLoaderErrorBubbling, + null, + [boundaryMatch.route.id, result] + ); + + // action status codes take precedence over loader status codes + return { + ...context, + statusCode: isRouteErrorResponse(result.error) + ? result.error.status + : result.statusCode != null + ? result.statusCode + : 500, + actionData: null, + actionHeaders: { + ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}), + }, + }; + } + + let context = await loadRouteData( + loaderRequest, + matches, + requestContext, + unstable_dataStrategy, + skipLoaderErrorBubbling, + null + ); + + return { + ...context, + actionData: { + [actionMatch.route.id]: result.data, + }, + // action status codes take precedence over loader status codes + ...(result.statusCode ? { statusCode: result.statusCode } : {}), + actionHeaders: result.headers + ? { [actionMatch.route.id]: result.headers } + : {}, + }; + } + + async function loadRouteData( + request: Request, + matches: AgnosticDataRouteMatch[], + requestContext: unknown, + unstable_dataStrategy: DataStrategyFunction | null, + skipLoaderErrorBubbling: boolean, + routeMatch: AgnosticDataRouteMatch | null, + pendingActionResult?: PendingActionResult + ): Promise< + | Omit< + StaticHandlerContext, + "location" | "basename" | "actionData" | "actionHeaders" + > + | Response + > { + let isRouteRequest = routeMatch != null; + + // Short circuit if we have no loaders to run (queryRoute()) + if ( + isRouteRequest && + !routeMatch?.route.loader && + !routeMatch?.route.lazy + ) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch?.route.id, + }); + } + + let requestMatches = routeMatch + ? [routeMatch] + : pendingActionResult && isErrorResult(pendingActionResult[1]) + ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) + : matches; + let matchesToLoad = requestMatches.filter( + (m) => m.route.loader || m.route.lazy + ); + + // Short circuit if we have no loaders to run (query()) + if (matchesToLoad.length === 0) { + return { + matches, + // Add a null for all matched routes for proper revalidation on the client + loaderData: matches.reduce( + (acc, m) => Object.assign(acc, { [m.route.id]: null }), + {} + ), + errors: + pendingActionResult && isErrorResult(pendingActionResult[1]) + ? { + [pendingActionResult[0]]: pendingActionResult[1].error, + } + : null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null, + }; + } + + let results = await callDataStrategy( + "loader", + request, + matchesToLoad, + matches, + isRouteRequest, + requestContext, + unstable_dataStrategy + ); + + if (request.signal.aborted) { + throwStaticHandlerAbortedError(request, isRouteRequest, future); + } + + // Process and commit output from loaders + let activeDeferreds = new Map(); + let context = processRouteLoaderData( + matches, + matchesToLoad, + results, + pendingActionResult, + activeDeferreds, + skipLoaderErrorBubbling + ); + + // Add a null for any non-loader matches for proper revalidation on the client + let executedLoaders = new Set( + matchesToLoad.map((match) => match.route.id) + ); + matches.forEach((match) => { + if (!executedLoaders.has(match.route.id)) { + context.loaderData[match.route.id] = null; + } + }); + + return { + ...context, + matches, + activeDeferreds: + activeDeferreds.size > 0 + ? Object.fromEntries(activeDeferreds.entries()) + : null, + }; + } + + // Utility wrapper for calling dataStrategy server-side without having to + // pass around the manifest, mapRouteProperties, etc. + async function callDataStrategy( + type: "loader" | "action", + request: Request, + matchesToLoad: AgnosticDataRouteMatch[], + matches: AgnosticDataRouteMatch[], + isRouteRequest: boolean, + requestContext: unknown, + unstable_dataStrategy: DataStrategyFunction | null + ): Promise { + let results = await callDataStrategyImpl( + unstable_dataStrategy || defaultDataStrategy, + type, + request, + matchesToLoad, + matches, + manifest, + mapRouteProperties, + requestContext + ); + + return await Promise.all( + results.map((result, i) => { + if (isRedirectHandlerResult(result)) { + let response = result.result as Response; + // Throw redirects and let the server handle them with an HTTP redirect + throw normalizeRelativeRoutingRedirectResponse( + response, + request, + matchesToLoad[i].route.id, + matches, + basename, + future.v7_relativeSplatPath + ); + } + if (isResponse(result.result) && isRouteRequest) { + // For SSR single-route requests, we want to hand Responses back + // directly without unwrapping + throw result; + } + + return convertHandlerResultToDataResult(result); + }) + ); + } + + return { + dataRoutes, + query, + queryRoute, + }; +} + +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region Helpers +//////////////////////////////////////////////////////////////////////////////// + +/** + * Given an existing StaticHandlerContext and an error thrown at render time, + * provide an updated StaticHandlerContext suitable for a second SSR render + */ +export function getStaticContextFromError( + routes: AgnosticDataRouteObject[], + context: StaticHandlerContext, + error: any +) { + let newContext: StaticHandlerContext = { + ...context, + statusCode: isRouteErrorResponse(error) ? error.status : 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error, + }, + }; + return newContext; +} + +function throwStaticHandlerAbortedError( + request: Request, + isRouteRequest: boolean, + future: StaticHandlerFutureConfig +) { + if (future.v7_throwAbortReason && request.signal.reason !== undefined) { + throw request.signal.reason; + } + + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(`${method}() call aborted: ${request.method} ${request.url}`); +} + +function isSubmissionNavigation( + opts: BaseNavigateOrFetchOptions +): opts is SubmissionNavigateOptions { + return ( + opts != null && + (("formData" in opts && opts.formData != null) || + ("body" in opts && opts.body !== undefined)) + ); +} + +function normalizeTo( + location: Path, + matches: AgnosticDataRouteMatch[], + basename: string, + prependBasename: boolean, + to: To | null, + v7_relativeSplatPath: boolean, + fromRouteId?: string, + relative?: RelativeRoutingType +) { + let contextualMatches: AgnosticDataRouteMatch[]; + let activeRouteMatch: AgnosticDataRouteMatch | undefined; + if (fromRouteId) { + // Grab matches up to the calling route so our route-relative logic is + // relative to the correct source route + contextualMatches = []; + for (let match of matches) { + contextualMatches.push(match); + if (match.route.id === fromRouteId) { + activeRouteMatch = match; + break; + } + } + } else { + contextualMatches = matches; + activeRouteMatch = matches[matches.length - 1]; + } + + // Resolve the relative path + let path = resolveTo( + to ? to : ".", + getResolveToMatches(contextualMatches, v7_relativeSplatPath), + stripBasename(location.pathname, basename) || location.pathname, + relative === "path" + ); + + // When `to` is not specified we inherit search/hash from the current + // location, unlike when to="." and we just inherit the path. + // See https://github.com/remix-run/remix/issues/927 + if (to == null) { + path.search = location.search; + path.hash = location.hash; + } + + // Add an ?index param for matched index routes if we don't already have one + if ( + (to == null || to === "" || to === ".") && + activeRouteMatch && + activeRouteMatch.route.index && + !hasNakedIndexQuery(path.search) + ) { + path.search = path.search + ? path.search.replace(/^\?/, "?index&") + : "?index"; + } + + // If we're operating within a basename, prepend it to the pathname. If + // this is a root navigation, then just use the raw basename which allows + // the basename to have full control over the presence of a trailing slash + // on root actions + if (prependBasename && basename !== "/") { + path.pathname = + path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); + } + + return createPath(path); +} + +// Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params +function normalizeNavigateOptions( + normalizeFormMethod: boolean, + isFetcher: boolean, + path: string, + opts?: BaseNavigateOrFetchOptions +): { + path: string; + submission?: Submission; + error?: ErrorResponseImpl; +} { + // Return location verbatim on non-submission navigations + if (!opts || !isSubmissionNavigation(opts)) { + return { path }; + } + + if (opts.formMethod && !isValidMethod(opts.formMethod)) { + return { + path, + error: getInternalRouterError(405, { method: opts.formMethod }), + }; + } + + let getInvalidBodyError = () => ({ + path, + error: getInternalRouterError(400, { type: "invalid-body" }), + }); + + // Create a Submission on non-GET navigations + let rawFormMethod = opts.formMethod || "get"; + let formMethod = normalizeFormMethod + ? (rawFormMethod.toUpperCase() as V7_FormMethod) + : (rawFormMethod.toLowerCase() as FormMethod); + let formAction = stripHashFromPath(path); + + if (opts.body !== undefined) { + if (opts.formEncType === "text/plain") { + // text only support POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + + let text = + typeof opts.body === "string" + ? opts.body + : opts.body instanceof FormData || + opts.body instanceof URLSearchParams + ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data + Array.from(opts.body.entries()).reduce( + (acc, [name, value]) => `${acc}${name}=${value}\n`, + "" + ) + : String(opts.body); + + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json: undefined, + text, + }, + }; + } else if (opts.formEncType === "application/json") { + // json only supports POST/PUT/PATCH/DELETE submissions + if (!isMutationMethod(formMethod)) { + return getInvalidBodyError(); + } + + try { + let json = + typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; + + return { + path, + submission: { + formMethod, + formAction, + formEncType: opts.formEncType, + formData: undefined, + json, + text: undefined, + }, + }; + } catch (e) { + return getInvalidBodyError(); + } + } + } + + invariant( + typeof FormData === "function", + "FormData is not available in this environment" + ); + + let searchParams: URLSearchParams; + let formData: FormData; + + if (opts.formData) { + searchParams = convertFormDataToSearchParams(opts.formData); + formData = opts.formData; + } else if (opts.body instanceof FormData) { + searchParams = convertFormDataToSearchParams(opts.body); + formData = opts.body; + } else if (opts.body instanceof URLSearchParams) { + searchParams = opts.body; + formData = convertSearchParamsToFormData(searchParams); + } else if (opts.body == null) { + searchParams = new URLSearchParams(); + formData = new FormData(); + } else { + try { + searchParams = new URLSearchParams(opts.body); + formData = convertSearchParamsToFormData(searchParams); + } catch (e) { + return getInvalidBodyError(); + } + } + + let submission: Submission = { + formMethod, + formAction, + formEncType: + (opts && opts.formEncType) || "application/x-www-form-urlencoded", + formData, + json: undefined, + text: undefined, + }; + + if (isMutationMethod(submission.formMethod)) { + return { path, submission }; + } + + // Flatten submission onto URLSearchParams for GET submissions + let parsedPath = parsePath(path); + // On GET navigation submissions we can drop the ?index param from the + // resulting location since all loaders will run. But fetcher GET submissions + // only run a single loader so we need to preserve any incoming ?index params + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + parsedPath.search = `?${searchParams}`; + + return { path: createPath(parsedPath), submission }; +} + +// Filter out all routes below any caught error as they aren't going to +// render so we don't need to load them +function getLoaderMatchesUntilBoundary( + matches: AgnosticDataRouteMatch[], + boundaryId: string +) { + let boundaryMatches = matches; + if (boundaryId) { + let index = matches.findIndex((m) => m.route.id === boundaryId); + if (index >= 0) { + boundaryMatches = matches.slice(0, index); + } + } + return boundaryMatches; +} + +function getMatchesToLoad( + history: History, + state: RouterState, + matches: AgnosticDataRouteMatch[], + submission: Submission | undefined, + location: Location, + isInitialLoad: boolean, + skipActionErrorRevalidation: boolean, + isRevalidationRequired: boolean, + cancelledDeferredRoutes: string[], + cancelledFetcherLoads: string[], + deletedFetchers: Set, + fetchLoadMatches: Map, + fetchRedirectIds: Set, + routesToUse: AgnosticDataRouteObject[], + basename: string | undefined, + pendingActionResult?: PendingActionResult +): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] { + let actionResult = pendingActionResult + ? isErrorResult(pendingActionResult[1]) + ? pendingActionResult[1].error + : pendingActionResult[1].data + : undefined; + let currentUrl = history.createURL(state.location); + let nextUrl = history.createURL(location); + + // Pick navigation matches that are net-new or qualify for revalidation + let boundaryId = + pendingActionResult && isErrorResult(pendingActionResult[1]) + ? pendingActionResult[0] + : undefined; + let boundaryMatches = boundaryId + ? getLoaderMatchesUntilBoundary(matches, boundaryId) + : matches; + + // Don't revalidate loaders by default after action 4xx/5xx responses + // when the flag is enabled. They can still opt-into revalidation via + // `shouldRevalidate` via `actionResult` + let actionStatus = pendingActionResult + ? pendingActionResult[1].statusCode + : undefined; + let shouldSkipRevalidation = + skipActionErrorRevalidation && actionStatus && actionStatus >= 400; + + let navigationMatches = boundaryMatches.filter((match, index) => { + let { route } = match; + if (route.lazy) { + // We haven't loaded this route yet so we don't know if it's got a loader! + return true; + } + + if (route.loader == null) { + return false; + } + + if (isInitialLoad) { + if (typeof route.loader !== "function" || route.loader.hydrate) { + return true; + } + return ( + state.loaderData[route.id] === undefined && + // Don't re-run if the loader ran and threw an error + (!state.errors || state.errors[route.id] === undefined) + ); + } + + // Always call the loader on new route instances and pending defer cancellations + if ( + isNewLoader(state.loaderData, state.matches[index], match) || + cancelledDeferredRoutes.some((id) => id === match.route.id) + ) { + return true; + } + + // This is the default implementation for when we revalidate. If the route + // provides it's own implementation, then we give them full control but + // provide this value so they can leverage it if needed after they check + // their own specific use cases + let currentRouteMatch = state.matches[index]; + let nextRouteMatch = match; + + return shouldRevalidateLoader(match, { + currentUrl, + currentParams: currentRouteMatch.params, + nextUrl, + nextParams: nextRouteMatch.params, + ...submission, + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation + ? false + : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate + isRevalidationRequired || + currentUrl.pathname + currentUrl.search === + nextUrl.pathname + nextUrl.search || + // Search params affect all loaders + currentUrl.search !== nextUrl.search || + isNewRouteInstance(currentRouteMatch, nextRouteMatch), + }); + }); + + // Pick fetcher.loads that need to be revalidated + let revalidatingFetchers: RevalidatingFetcher[] = []; + fetchLoadMatches.forEach((f, key) => { + // Don't revalidate: + // - on initial load (shouldn't be any fetchers then anyway) + // - if fetcher won't be present in the subsequent render + // - no longer matches the URL (v7_fetcherPersist=false) + // - was unmounted but persisted due to v7_fetcherPersist=true + if ( + isInitialLoad || + !matches.some((m) => m.route.id === f.routeId) || + deletedFetchers.has(key) + ) { + return; + } + + let fetcherMatches = matchRoutes(routesToUse, f.path, basename); + + // If the fetcher path no longer matches, push it in with null matches so + // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is + // currently only a use-case for Remix HMR where the route tree can change + // at runtime and remove a route previously loaded via a fetcher + if (!fetcherMatches) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: null, + match: null, + controller: null, + }); + return; + } + + // Revalidating fetchers are decoupled from the route matches since they + // load from a static href. They revalidate based on explicit revalidation + // (submission, useRevalidator, or X-Remix-Revalidate) + let fetcher = state.fetchers.get(key); + let fetcherMatch = getTargetMatch(fetcherMatches, f.path); + + let shouldRevalidate = false; + if (fetchRedirectIds.has(key)) { + // Never trigger a revalidation of an actively redirecting fetcher + shouldRevalidate = false; + } else if (cancelledFetcherLoads.includes(key)) { + // Always revalidate if the fetcher was cancelled + shouldRevalidate = true; + } else if ( + fetcher && + fetcher.state !== "idle" && + fetcher.data === undefined + ) { + // If the fetcher hasn't ever completed loading yet, then this isn't a + // revalidation, it would just be a brand new load if an explicit + // revalidation is required + shouldRevalidate = isRevalidationRequired; + } else { + // Otherwise fall back on any user-defined shouldRevalidate, defaulting + // to explicit revalidations only + shouldRevalidate = shouldRevalidateLoader(fetcherMatch, { + currentUrl, + currentParams: state.matches[state.matches.length - 1].params, + nextUrl, + nextParams: matches[matches.length - 1].params, + ...submission, + actionResult, + actionStatus, + defaultShouldRevalidate: shouldSkipRevalidation + ? false + : isRevalidationRequired, + }); + } + + if (shouldRevalidate) { + revalidatingFetchers.push({ + key, + routeId: f.routeId, + path: f.path, + matches: fetcherMatches, + match: fetcherMatch, + controller: new AbortController(), + }); + } + }); + + return [navigationMatches, revalidatingFetchers]; +} + +function isNewLoader( + currentLoaderData: RouteData, + currentMatch: AgnosticDataRouteMatch, + match: AgnosticDataRouteMatch +) { + let isNew = + // [a] -> [a, b] + !currentMatch || + // [a, b] -> [a, c] + match.route.id !== currentMatch.route.id; + + // Handle the case that we don't have data for a re-used route, potentially + // from a prior error or from a cancelled pending deferred + let isMissingData = currentLoaderData[match.route.id] === undefined; + + // Always load if this is a net-new route or we don't yet have data + return isNew || isMissingData; +} + +function isNewRouteInstance( + currentMatch: AgnosticDataRouteMatch, + match: AgnosticDataRouteMatch +) { + let currentPath = currentMatch.route.path; + return ( + // param change for this match, /users/123 -> /users/456 + currentMatch.pathname !== match.pathname || + // splat param changed, which is not present in match.path + // e.g. /files/images/avatar.jpg -> files/finances.xls + (currentPath != null && + currentPath.endsWith("*") && + currentMatch.params["*"] !== match.params["*"]) + ); +} + +function shouldRevalidateLoader( + loaderMatch: AgnosticDataRouteMatch, + arg: ShouldRevalidateFunctionArgs +) { + if (loaderMatch.route.shouldRevalidate) { + let routeChoice = loaderMatch.route.shouldRevalidate(arg); + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + + return arg.defaultShouldRevalidate; +} + +/** + * Idempotent utility to execute patchRoutesOnMiss() to lazily load route + * definitions and update the routes/routeManifest + */ +async function loadLazyRouteChildren( + patchRoutesOnMissImpl: AgnosticPatchRoutesOnMissFunction, + path: string, + matches: AgnosticDataRouteMatch[], + routes: AgnosticDataRouteObject[], + manifest: RouteManifest, + mapRouteProperties: MapRoutePropertiesFunction, + pendingRouteChildren: Map>, + signal: AbortSignal +) { + let key = [path, ...matches.map((m) => m.route.id)].join("-"); + try { + let pending = pendingRouteChildren.get(key); + if (!pending) { + pending = patchRoutesOnMissImpl({ + path, + matches, + patch: (routeId, children) => { + if (!signal.aborted) { + patchRoutesImpl( + routeId, + children, + routes, + manifest, + mapRouteProperties + ); + } + }, + }); + pendingRouteChildren.set(key, pending); + } + + if (pending && isPromise(pending)) { + await pending; + } + } finally { + pendingRouteChildren.delete(key); + } +} + +function patchRoutesImpl( + routeId: string | null, + children: AgnosticRouteObject[], + routesToUse: AgnosticDataRouteObject[], + manifest: RouteManifest, + mapRouteProperties: MapRoutePropertiesFunction +) { + if (routeId) { + let route = manifest[routeId]; + invariant( + route, + `No route found to patch children into: routeId = ${routeId}` + ); + let dataChildren = convertRoutesToDataRoutes( + children, + mapRouteProperties, + [routeId, "patch", String(route.children?.length || "0")], + manifest + ); + if (route.children) { + route.children.push(...dataChildren); + } else { + route.children = dataChildren; + } + } else { + let dataChildren = convertRoutesToDataRoutes( + children, + mapRouteProperties, + ["patch", String(routesToUse.length || "0")], + manifest + ); + routesToUse.push(...dataChildren); + } +} + +/** + * Execute route.lazy() methods to lazily load route modules (loader, action, + * shouldRevalidate) and update the routeManifest in place which shares objects + * with dataRoutes so those get updated as well. + */ +async function loadLazyRouteModule( + route: AgnosticDataRouteObject, + mapRouteProperties: MapRoutePropertiesFunction, + manifest: RouteManifest +) { + if (!route.lazy) { + return; + } + + let lazyRoute = await route.lazy(); + + // If the lazy route function was executed and removed by another parallel + // call then we can return - first lazy() to finish wins because the return + // value of lazy is expected to be static + if (!route.lazy) { + return; + } + + let routeToUpdate = manifest[route.id]; + invariant(routeToUpdate, "No route found in manifest"); + + // Update the route in place. This should be safe because there's no way + // we could yet be sitting on this route as we can't get there without + // resolving lazy() first. + // + // This is different than the HMR "update" use-case where we may actively be + // on the route being updated. The main concern boils down to "does this + // mutation affect any ongoing navigations or any current state.matches + // values?". If not, it should be safe to update in place. + let routeUpdates: Record = {}; + for (let lazyRouteProperty in lazyRoute) { + let staticRouteValue = + routeToUpdate[lazyRouteProperty as keyof typeof routeToUpdate]; + + let isPropertyStaticallyDefined = + staticRouteValue !== undefined && + // This property isn't static since it should always be updated based + // on the route updates + lazyRouteProperty !== "hasErrorBoundary"; + + warning( + !isPropertyStaticallyDefined, + `Route "${routeToUpdate.id}" has a static property "${lazyRouteProperty}" ` + + `defined but its lazy function is also returning a value for this property. ` + + `The lazy route property "${lazyRouteProperty}" will be ignored.` + ); + + if ( + !isPropertyStaticallyDefined && + !immutableRouteKeys.has(lazyRouteProperty as ImmutableRouteKey) + ) { + routeUpdates[lazyRouteProperty] = + lazyRoute[lazyRouteProperty as keyof typeof lazyRoute]; + } + } + + // Mutate the route with the provided updates. Do this first so we pass + // the updated version to mapRouteProperties + Object.assign(routeToUpdate, routeUpdates); + + // Mutate the `hasErrorBoundary` property on the route based on the route + // updates and remove the `lazy` function so we don't resolve the lazy + // route again. + Object.assign(routeToUpdate, { + // To keep things framework agnostic, we use the provided + // `mapRouteProperties` (or wrapped `detectErrorBoundary`) function to + // set the framework-aware properties (`element`/`hasErrorBoundary`) since + // the logic will differ between frameworks. + ...mapRouteProperties(routeToUpdate), + lazy: undefined, + }); +} + +// Default implementation of `dataStrategy` which fetches all loaders in parallel +function defaultDataStrategy( + opts: DataStrategyFunctionArgs +): ReturnType { + return Promise.all(opts.matches.map((m) => m.resolve())); +} + +async function callDataStrategyImpl( + dataStrategyImpl: DataStrategyFunction, + type: "loader" | "action", + request: Request, + matchesToLoad: AgnosticDataRouteMatch[], + matches: AgnosticDataRouteMatch[], + manifest: RouteManifest, + mapRouteProperties: MapRoutePropertiesFunction, + requestContext?: unknown +): Promise { + let routeIdsToLoad = matchesToLoad.reduce( + (acc, m) => acc.add(m.route.id), + new Set() + ); + let loadedMatches = new Set(); + + // Send all matches here to allow for a middleware-type implementation. + // handler will be a no-op for unneeded routes and we filter those results + // back out below. + let results = await dataStrategyImpl({ + matches: matches.map((match) => { + let shouldLoad = routeIdsToLoad.has(match.route.id); + // `resolve` encapsulates the route.lazy, executing the + // loader/action, and mapping return values/thrown errors to a + // HandlerResult. Users can pass a callback to take fine-grained control + // over the execution of the loader/action + let resolve: DataStrategyMatch["resolve"] = (handlerOverride) => { + loadedMatches.add(match.route.id); + return shouldLoad + ? callLoaderOrAction( + type, + request, + match, + manifest, + mapRouteProperties, + handlerOverride, + requestContext + ) + : Promise.resolve({ type: ResultType.data, result: undefined }); + }; + + return { + ...match, + shouldLoad, + resolve, + }; + }), + request, + params: matches[0].params, + context: requestContext, + }); + + // Throw if any loadRoute implementations not called since they are what + // ensures a route is fully loaded + matches.forEach((m) => + invariant( + loadedMatches.has(m.route.id), + `\`match.resolve()\` was not called for route id "${m.route.id}". ` + + "You must call `match.resolve()` on every match passed to " + + "`dataStrategy` to ensure all routes are properly loaded." + ) + ); + + // Filter out any middleware-only matches for which we didn't need to run handlers + return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id)); +} + +// Default logic for calling a loader/action is the user has no specified a dataStrategy +async function callLoaderOrAction( + type: "loader" | "action", + request: Request, + match: AgnosticDataRouteMatch, + manifest: RouteManifest, + mapRouteProperties: MapRoutePropertiesFunction, + handlerOverride: Parameters[0], + staticContext?: unknown +): Promise { + let result: HandlerResult; + let onReject: (() => void) | undefined; + + let runHandler = ( + handler: AgnosticRouteObject["loader"] | AgnosticRouteObject["action"] + ): Promise => { + // Setup a promise we can race against so that abort signals short circuit + let reject: () => void; + // This will never resolve so safe to type it as Promise to + // satisfy the function return value + let abortPromise = new Promise((_, r) => (reject = r)); + onReject = () => reject(); + request.signal.addEventListener("abort", onReject); + + let actualHandler = (ctx?: unknown) => { + if (typeof handler !== "function") { + return Promise.reject( + new Error( + `You cannot call the handler for a route which defines a boolean ` + + `"${type}" [routeId: ${match.route.id}]` + ) + ); + } + return handler( + { + request, + params: match.params, + context: staticContext, + }, + ...(ctx !== undefined ? [ctx] : []) + ); + }; + + let handlerPromise: Promise; + if (handlerOverride) { + handlerPromise = handlerOverride((ctx: unknown) => actualHandler(ctx)); + } else { + handlerPromise = (async () => { + try { + let val = await actualHandler(); + return { type: "data", result: val }; + } catch (e) { + return { type: "error", result: e }; + } + })(); + } + + return Promise.race([handlerPromise, abortPromise]); + }; + + try { + let handler = match.route[type]; + + if (match.route.lazy) { + if (handler) { + // Run statically defined handler in parallel with lazy() + let handlerError; + let [value] = await Promise.all([ + // If the handler throws, don't let it immediately bubble out, + // since we need to let the lazy() execution finish so we know if this + // route has a boundary that can handle the error + runHandler(handler).catch((e) => { + handlerError = e; + }), + loadLazyRouteModule(match.route, mapRouteProperties, manifest), + ]); + if (handlerError !== undefined) { + throw handlerError; + } + result = value!; + } else { + // Load lazy route module, then run any returned handler + await loadLazyRouteModule(match.route, mapRouteProperties, manifest); + + handler = match.route[type]; + if (handler) { + // Handler still runs even if we got interrupted to maintain consistency + // with un-abortable behavior of handler execution on non-lazy or + // previously-lazy-loaded routes + result = await runHandler(handler); + } else if (type === "action") { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(405, { + method: request.method, + pathname, + routeId: match.route.id, + }); + } else { + // lazy() route has no loader to run. Short circuit here so we don't + // hit the invariant below that errors on returning undefined. + return { type: ResultType.data, result: undefined }; + } + } + } else if (!handler) { + let url = new URL(request.url); + let pathname = url.pathname + url.search; + throw getInternalRouterError(404, { + pathname, + }); + } else { + result = await runHandler(handler); + } + + invariant( + result.result !== undefined, + `You defined ${type === "action" ? "an action" : "a loader"} for route ` + + `"${match.route.id}" but didn't return anything from your \`${type}\` ` + + `function. Please return a value or \`null\`.` + ); + } catch (e) { + // We should already be catching and converting normal handler executions to + // HandlerResults and returning them, so anything that throws here is an + // unexpected error we still need to wrap + return { type: ResultType.error, result: e }; + } finally { + if (onReject) { + request.signal.removeEventListener("abort", onReject); + } + } + + return result; +} + +async function convertHandlerResultToDataResult( + handlerResult: HandlerResult +): Promise { + let { result, type, status } = handlerResult; + + if (isResponse(result)) { + let data: any; + + try { + let contentType = result.headers.get("Content-Type"); + // Check between word boundaries instead of startsWith() due to the last + // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type + if (contentType && /\bapplication\/json\b/.test(contentType)) { + if (result.body == null) { + data = null; + } else { + data = await result.json(); + } + } else { + data = await result.text(); + } + } catch (e) { + return { type: ResultType.error, error: e }; + } + + if (type === ResultType.error) { + return { + type: ResultType.error, + error: new ErrorResponseImpl(result.status, result.statusText, data), + statusCode: result.status, + headers: result.headers, + }; + } + + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers, + }; + } + + if (type === ResultType.error) { + return { + type: ResultType.error, + error: result, + statusCode: isRouteErrorResponse(result) ? result.status : status, + }; + } + + if (isDeferredData(result)) { + return { + type: ResultType.deferred, + deferredData: result, + statusCode: result.init?.status, + headers: result.init?.headers && new Headers(result.init.headers), + }; + } + + return { type: ResultType.data, data: result, statusCode: status }; +} + +// Support relative routing in internal redirects +function normalizeRelativeRoutingRedirectResponse( + response: Response, + request: Request, + routeId: string, + matches: AgnosticDataRouteMatch[], + basename: string, + v7_relativeSplatPath: boolean +) { + let location = response.headers.get("Location"); + invariant( + location, + "Redirects returned/thrown from loaders/actions must have a Location header" + ); + + if (!ABSOLUTE_URL_REGEX.test(location)) { + let trimmedMatches = matches.slice( + 0, + matches.findIndex((m) => m.route.id === routeId) + 1 + ); + location = normalizeTo( + new URL(request.url), + trimmedMatches, + basename, + true, + location, + v7_relativeSplatPath + ); + response.headers.set("Location", location); + } + + return response; +} + +function normalizeRedirectLocation( + location: string, + currentUrl: URL, + basename: string +): string { + if (ABSOLUTE_URL_REGEX.test(location)) { + // Strip off the protocol+origin for same-origin + same-basename absolute redirects + let normalizedLocation = location; + let url = normalizedLocation.startsWith("//") + ? new URL(currentUrl.protocol + normalizedLocation) + : new URL(normalizedLocation); + let isSameBasename = stripBasename(url.pathname, basename) != null; + if (url.origin === currentUrl.origin && isSameBasename) { + return url.pathname + url.search + url.hash; + } + } + return location; +} + +// Utility method for creating the Request instances for loaders/actions during +// client-side navigations and fetches. During SSR we will always have a +// Request instance from the static handler (query/queryRoute) +function createClientSideRequest( + history: History, + location: string | Location, + signal: AbortSignal, + submission?: Submission +): Request { + let url = history.createURL(stripHashFromPath(location)).toString(); + let init: RequestInit = { signal }; + + if (submission && isMutationMethod(submission.formMethod)) { + let { formMethod, formEncType } = submission; + // Didn't think we needed this but it turns out unlike other methods, patch + // won't be properly normalized to uppercase and results in a 405 error. + // See: https://fetch.spec.whatwg.org/#concept-method + init.method = formMethod.toUpperCase(); + + if (formEncType === "application/json") { + init.headers = new Headers({ "Content-Type": formEncType }); + init.body = JSON.stringify(submission.json); + } else if (formEncType === "text/plain") { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.text; + } else if ( + formEncType === "application/x-www-form-urlencoded" && + submission.formData + ) { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = convertFormDataToSearchParams(submission.formData); + } else { + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + init.body = submission.formData; + } + } + + return new Request(url, init); +} + +function convertFormDataToSearchParams(formData: FormData): URLSearchParams { + let searchParams = new URLSearchParams(); + + for (let [key, value] of formData.entries()) { + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs + searchParams.append(key, typeof value === "string" ? value : value.name); + } + + return searchParams; +} + +function convertSearchParamsToFormData( + searchParams: URLSearchParams +): FormData { + let formData = new FormData(); + for (let [key, value] of searchParams.entries()) { + formData.append(key, value); + } + return formData; +} + +function processRouteLoaderData( + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + results: DataResult[], + pendingActionResult: PendingActionResult | undefined, + activeDeferreds: Map, + skipLoaderErrorBubbling: boolean +): { + loaderData: RouterState["loaderData"]; + errors: RouterState["errors"] | null; + statusCode: number; + loaderHeaders: Record; +} { + // Fill in loaderData/errors from our loaders + let loaderData: RouterState["loaderData"] = {}; + let errors: RouterState["errors"] | null = null; + let statusCode: number | undefined; + let foundError = false; + let loaderHeaders: Record = {}; + let pendingError = + pendingActionResult && isErrorResult(pendingActionResult[1]) + ? pendingActionResult[1].error + : undefined; + + // Process loader results into state.loaderData/state.errors + results.forEach((result, index) => { + let id = matchesToLoad[index].route.id; + invariant( + !isRedirectResult(result), + "Cannot handle redirect results in processLoaderData" + ); + if (isErrorResult(result)) { + let error = result.error; + // If we have a pending action error, we report it at the highest-route + // that throws a loader error, and then clear it out to indicate that + // it was consumed + if (pendingError !== undefined) { + error = pendingError; + pendingError = undefined; + } + + errors = errors || {}; + + if (skipLoaderErrorBubbling) { + errors[id] = error; + } else { + // Look upwards from the matched route for the closest ancestor error + // boundary, defaulting to the root match. Prefer higher error values + // if lower errors bubble to the same boundary + let boundaryMatch = findNearestBoundary(matches, id); + if (errors[boundaryMatch.route.id] == null) { + errors[boundaryMatch.route.id] = error; + } + } + + // Clear our any prior loaderData for the throwing route + loaderData[id] = undefined; + + // Once we find our first (highest) error, we set the status code and + // prevent deeper status codes from overriding + if (!foundError) { + foundError = true; + statusCode = isRouteErrorResponse(result.error) + ? result.error.status + : 500; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + if (isDeferredResult(result)) { + activeDeferreds.set(id, result.deferredData); + loaderData[id] = result.deferredData.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if ( + result.statusCode != null && + result.statusCode !== 200 && + !foundError + ) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } else { + loaderData[id] = result.data; + // Error status codes always override success status codes, but if all + // loaders are successful we take the deepest status code. + if (result.statusCode && result.statusCode !== 200 && !foundError) { + statusCode = result.statusCode; + } + if (result.headers) { + loaderHeaders[id] = result.headers; + } + } + } + }); + + // If we didn't consume the pending action error (i.e., all loaders + // resolved), then consume it here. Also clear out any loaderData for the + // throwing route + if (pendingError !== undefined && pendingActionResult) { + errors = { [pendingActionResult[0]]: pendingError }; + loaderData[pendingActionResult[0]] = undefined; + } + + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders, + }; +} + +function processLoaderData( + state: RouterState, + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + results: DataResult[], + pendingActionResult: PendingActionResult | undefined, + revalidatingFetchers: RevalidatingFetcher[], + fetcherResults: DataResult[], + activeDeferreds: Map +): { + loaderData: RouterState["loaderData"]; + errors?: RouterState["errors"]; +} { + let { loaderData, errors } = processRouteLoaderData( + matches, + matchesToLoad, + results, + pendingActionResult, + activeDeferreds, + false // This method is only called client side so we always want to bubble + ); + + // Process results from our revalidating fetchers + for (let index = 0; index < revalidatingFetchers.length; index++) { + let { key, match, controller } = revalidatingFetchers[index]; + invariant( + fetcherResults !== undefined && fetcherResults[index] !== undefined, + "Did not find corresponding fetcher result" + ); + let result = fetcherResults[index]; + + // Process fetcher non-redirect errors + if (controller && controller.signal.aborted) { + // Nothing to do for aborted fetchers + continue; + } else if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, match?.route.id); + if (!(errors && errors[boundaryMatch.route.id])) { + errors = { + ...errors, + [boundaryMatch.route.id]: result.error, + }; + } + state.fetchers.delete(key); + } else if (isRedirectResult(result)) { + // Should never get here, redirects should get processed above, but we + // keep this to type narrow to a success result in the else + invariant(false, "Unhandled fetcher revalidation redirect"); + } else if (isDeferredResult(result)) { + // Should never get here, deferred data should be awaited for fetchers + // in resolveDeferredResults + invariant(false, "Unhandled fetcher deferred data"); + } else { + let doneFetcher = getDoneFetcher(result.data); + state.fetchers.set(key, doneFetcher); + } + } + + return { loaderData, errors }; +} + +function mergeLoaderData( + loaderData: RouteData, + newLoaderData: RouteData, + matches: AgnosticDataRouteMatch[], + errors: RouteData | null | undefined +): RouteData { + let mergedLoaderData = { ...newLoaderData }; + for (let match of matches) { + let id = match.route.id; + if (newLoaderData.hasOwnProperty(id)) { + if (newLoaderData[id] !== undefined) { + mergedLoaderData[id] = newLoaderData[id]; + } else { + // No-op - this is so we ignore existing data if we have a key in the + // incoming object with an undefined value, which is how we unset a prior + // loaderData if we encounter a loader error + } + } else if (loaderData[id] !== undefined && match.route.loader) { + // Preserve existing keys not included in newLoaderData and where a loader + // wasn't removed by HMR + mergedLoaderData[id] = loaderData[id]; + } + + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + return mergedLoaderData; +} + +function getActionDataForCommit( + pendingActionResult: PendingActionResult | undefined +) { + if (!pendingActionResult) { + return {}; + } + return isErrorResult(pendingActionResult[1]) + ? { + // Clear out prior actionData on errors + actionData: {}, + } + : { + actionData: { + [pendingActionResult[0]]: pendingActionResult[1].data, + }, + }; +} + +// Find the nearest error boundary, looking upwards from the leaf route (or the +// route specified by routeId) for the closest ancestor error boundary, +// defaulting to the root match +function findNearestBoundary( + matches: AgnosticDataRouteMatch[], + routeId?: string +): AgnosticDataRouteMatch { + let eligibleMatches = routeId + ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) + : [...matches]; + return ( + eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || + matches[0] + ); +} + +function getShortCircuitMatches(routes: AgnosticDataRouteObject[]): { + matches: AgnosticDataRouteMatch[]; + route: AgnosticDataRouteObject; +} { + // Prefer a root layout route if present, otherwise shim in a route object + let route = + routes.length === 1 + ? routes[0] + : routes.find((r) => r.index || !r.path || r.path === "/") || { + id: `__shim-error-route__`, + }; + + return { + matches: [ + { + params: {}, + pathname: "", + pathnameBase: "", + route, + }, + ], + route, + }; +} + +function getInternalRouterError( + status: number, + { + pathname, + routeId, + method, + type, + message, + }: { + pathname?: string; + routeId?: string; + method?: string; + type?: "defer-action" | "invalid-body" | "route-discovery"; + message?: string; + } = {} +) { + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + + if (status === 400) { + statusText = "Bad Request"; + if (type === "route-discovery") { + errorMessage = + `Unable to match URL "${pathname}" - the \`unstable_patchRoutesOnMiss()\` ` + + `function threw the following error:\n${message}`; + } else if (method && pathname && routeId) { + errorMessage = + `You made a ${method} request to "${pathname}" but ` + + `did not provide a \`loader\` for route "${routeId}", ` + + `so there is no way to handle the request.`; + } else if (type === "defer-action") { + errorMessage = "defer() is not supported in actions"; + } else if (type === "invalid-body") { + errorMessage = "Unable to encode submission body"; + } + } else if (status === 403) { + statusText = "Forbidden"; + errorMessage = `Route "${routeId}" does not match URL "${pathname}"`; + } else if (status === 404) { + statusText = "Not Found"; + errorMessage = `No route matches URL "${pathname}"`; + } else if (status === 405) { + statusText = "Method Not Allowed"; + if (method && pathname && routeId) { + errorMessage = + `You made a ${method.toUpperCase()} request to "${pathname}" but ` + + `did not provide an \`action\` for route "${routeId}", ` + + `so there is no way to handle the request.`; + } else if (method) { + errorMessage = `Invalid request method "${method.toUpperCase()}"`; + } + } + + return new ErrorResponseImpl( + status || 500, + statusText, + new Error(errorMessage), + true + ); +} + +// Find any returned redirect errors, starting from the lowest match +function findRedirect( + results: DataResult[] +): { result: RedirectResult; idx: number } | undefined { + for (let i = results.length - 1; i >= 0; i--) { + let result = results[i]; + if (isRedirectResult(result)) { + return { result, idx: i }; + } + } +} + +function stripHashFromPath(path: To) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath({ ...parsedPath, hash: "" }); +} + +function isHashChangeOnly(a: Location, b: Location): boolean { + if (a.pathname !== b.pathname || a.search !== b.search) { + return false; + } + + if (a.hash === "") { + // /page -> /page#hash + return b.hash !== ""; + } else if (a.hash === b.hash) { + // /page#hash -> /page#hash + return true; + } else if (b.hash !== "") { + // /page#hash -> /page#other + return true; + } + + // If the hash is removed the browser will re-perform a request to the server + // /page#hash -> /page + return false; +} + +function isPromise(val: unknown): val is Promise { + return typeof val === "object" && val != null && "then" in val; +} + +function isHandlerResult(result: unknown): result is HandlerResult { + return ( + result != null && + typeof result === "object" && + "type" in result && + "result" in result && + (result.type === ResultType.data || result.type === ResultType.error) + ); +} + +function isRedirectHandlerResult(result: HandlerResult) { + return ( + isResponse(result.result) && redirectStatusCodes.has(result.result.status) + ); +} + +function isDeferredResult(result: DataResult): result is DeferredResult { + return result.type === ResultType.deferred; +} + +function isErrorResult(result: DataResult): result is ErrorResult { + return result.type === ResultType.error; +} + +function isRedirectResult(result?: DataResult): result is RedirectResult { + return (result && result.type) === ResultType.redirect; +} + +export function isDeferredData(value: any): value is DeferredData { + let deferred: DeferredData = value; + return ( + deferred && + typeof deferred === "object" && + typeof deferred.data === "object" && + typeof deferred.subscribe === "function" && + typeof deferred.cancel === "function" && + typeof deferred.resolveData === "function" + ); +} + +function isResponse(value: any): value is Response { + return ( + value != null && + typeof value.status === "number" && + typeof value.statusText === "string" && + typeof value.headers === "object" && + typeof value.body !== "undefined" + ); +} + +function isRedirectResponse(result: any): result is Response { + if (!isResponse(result)) { + return false; + } + + let status = result.status; + let location = result.headers.get("Location"); + return status >= 300 && status <= 399 && location != null; +} + +function isValidMethod(method: string): method is FormMethod | V7_FormMethod { + return validRequestMethods.has(method.toLowerCase() as FormMethod); +} + +function isMutationMethod( + method: string +): method is MutationFormMethod | V7_MutationFormMethod { + return validMutationMethods.has(method.toLowerCase() as MutationFormMethod); +} + +async function resolveDeferredResults( + currentMatches: AgnosticDataRouteMatch[], + matchesToLoad: (AgnosticDataRouteMatch | null)[], + results: DataResult[], + signals: (AbortSignal | null)[], + isFetcher: boolean, + currentLoaderData?: RouteData +) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + // If we don't have a match, then we can have a deferred result to do + // anything with. This is for revalidating fetchers where the route was + // removed during HMR + if (!match) { + continue; + } + + let currentMatch = currentMatches.find( + (m) => m.route.id === match!.route.id + ); + let isRevalidatingLoader = + currentMatch != null && + !isNewRouteInstance(currentMatch, match) && + (currentLoaderData && currentLoaderData[match.route.id]) !== undefined; + + if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) { + // Note: we do not have to touch activeDeferreds here since we race them + // against the signal in resolveDeferredData and they'll get aborted + // there if needed + let signal = signals[index]; + invariant( + signal, + "Expected an AbortSignal for revalidating fetcher deferred result" + ); + await resolveDeferredData(result, signal, isFetcher).then((result) => { + if (result) { + results[index] = result || results[index]; + } + }); + } + } +} + +async function resolveDeferredData( + result: DeferredResult, + signal: AbortSignal, + unwrap = false +): Promise { + let aborted = await result.deferredData.resolveData(signal); + if (aborted) { + return; + } + + if (unwrap) { + try { + return { + type: ResultType.data, + data: result.deferredData.unwrappedData, + }; + } catch (e) { + // Handle any TrackedPromise._error values encountered while unwrapping + return { + type: ResultType.error, + error: e, + }; + } + } + + return { + type: ResultType.data, + data: result.deferredData.data, + }; +} + +function hasNakedIndexQuery(search: string): boolean { + return new URLSearchParams(search).getAll("index").some((v) => v === ""); +} + +function getTargetMatch( + matches: AgnosticDataRouteMatch[], + location: Location | string +) { + let search = + typeof location === "string" ? parsePath(location).search : location.search; + if ( + matches[matches.length - 1].route.index && + hasNakedIndexQuery(search || "") + ) { + // Return the leaf index route when index is present + return matches[matches.length - 1]; + } + // Otherwise grab the deepest "path contributing" match (ignoring index and + // pathless layout routes) + let pathMatches = getPathContributingMatches(matches); + return pathMatches[pathMatches.length - 1]; +} + +function getSubmissionFromNavigation( + navigation: Navigation +): Submission | undefined { + let { formMethod, formAction, formEncType, text, formData, json } = + navigation; + if (!formMethod || !formAction || !formEncType) { + return; + } + + if (text != null) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json: undefined, + text, + }; + } else if (formData != null) { + return { + formMethod, + formAction, + formEncType, + formData, + json: undefined, + text: undefined, + }; + } else if (json !== undefined) { + return { + formMethod, + formAction, + formEncType, + formData: undefined, + json, + text: undefined, + }; + } +} + +function getLoadingNavigation( + location: Location, + submission?: Submission +): NavigationStates["Loading"] { + if (submission) { + let navigation: NavigationStates["Loading"] = { + state: "loading", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + }; + return navigation; + } else { + let navigation: NavigationStates["Loading"] = { + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + }; + return navigation; + } +} + +function getSubmittingNavigation( + location: Location, + submission: Submission +): NavigationStates["Submitting"] { + let navigation: NavigationStates["Submitting"] = { + state: "submitting", + location, + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + }; + return navigation; +} + +function getLoadingFetcher( + submission?: Submission, + data?: Fetcher["data"] +): FetcherStates["Loading"] { + if (submission) { + let fetcher: FetcherStates["Loading"] = { + state: "loading", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data, + }; + return fetcher; + } else { + let fetcher: FetcherStates["Loading"] = { + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data, + }; + return fetcher; + } +} + +function getSubmittingFetcher( + submission: Submission, + existingFetcher?: Fetcher +): FetcherStates["Submitting"] { + let fetcher: FetcherStates["Submitting"] = { + state: "submitting", + formMethod: submission.formMethod, + formAction: submission.formAction, + formEncType: submission.formEncType, + formData: submission.formData, + json: submission.json, + text: submission.text, + data: existingFetcher ? existingFetcher.data : undefined, + }; + return fetcher; +} + +function getDoneFetcher(data: Fetcher["data"]): FetcherStates["Idle"] { + let fetcher: FetcherStates["Idle"] = { + state: "idle", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + json: undefined, + text: undefined, + data, + }; + return fetcher; +} + +function restoreAppliedTransitions( + _window: Window, + transitions: Map> +) { + try { + let sessionPositions = _window.sessionStorage.getItem( + TRANSITIONS_STORAGE_KEY + ); + if (sessionPositions) { + let json = JSON.parse(sessionPositions); + for (let [k, v] of Object.entries(json || {})) { + if (v && Array.isArray(v)) { + transitions.set(k, new Set(v || [])); + } + } + } + } catch (e) { + // no-op, use default empty object + } +} + +function persistAppliedTransitions( + _window: Window, + transitions: Map> +) { + if (transitions.size > 0) { + let json: Record = {}; + for (let [k, v] of transitions) { + json[k] = [...v]; + } + try { + _window.sessionStorage.setItem( + TRANSITIONS_STORAGE_KEY, + JSON.stringify(json) + ); + } catch (error) { + warning( + false, + `Failed to save applied view transitions in sessionStorage (${error}).` + ); + } + } +} +//#endregion diff --git a/node_modules/@remix-run/router/utils.ts b/node_modules/@remix-run/router/utils.ts new file mode 100644 index 0000000000..14e9fb2973 --- /dev/null +++ b/node_modules/@remix-run/router/utils.ts @@ -0,0 +1,1673 @@ +import type { Location, Path, To } from "./history"; +import { invariant, parsePath, warning } from "./history"; + +/** + * Map of routeId -> data returned from a loader/action/error + */ +export interface RouteData { + [routeId: string]: any; +} + +export enum ResultType { + data = "data", + deferred = "deferred", + redirect = "redirect", + error = "error", +} + +/** + * Successful result from a loader or action + */ +export interface SuccessResult { + type: ResultType.data; + data: unknown; + statusCode?: number; + headers?: Headers; +} + +/** + * Successful defer() result from a loader or action + */ +export interface DeferredResult { + type: ResultType.deferred; + deferredData: DeferredData; + statusCode?: number; + headers?: Headers; +} + +/** + * Redirect result from a loader or action + */ +export interface RedirectResult { + type: ResultType.redirect; + // We keep the raw Response for redirects so we can return it verbatim + response: Response; +} + +/** + * Unsuccessful result from a loader or action + */ +export interface ErrorResult { + type: ResultType.error; + error: unknown; + statusCode?: number; + headers?: Headers; +} + +/** + * Result from a loader or action - potentially successful or unsuccessful + */ +export type DataResult = + | SuccessResult + | DeferredResult + | RedirectResult + | ErrorResult; + +/** + * Result from a loader or action called via dataStrategy + */ +export interface HandlerResult { + type: "data" | "error"; + result: unknown; // data, Error, Response, DeferredData + status?: number; +} + +type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete"; +type UpperCaseFormMethod = Uppercase; + +/** + * Users can specify either lowercase or uppercase form methods on ``, + * useSubmit(), ``, etc. + */ +export type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod; + +/** + * Active navigation/fetcher form methods are exposed in lowercase on the + * RouterState + */ +export type FormMethod = LowerCaseFormMethod; +export type MutationFormMethod = Exclude; + +/** + * In v7, active navigation/fetcher form methods are exposed in uppercase on the + * RouterState. This is to align with the normalization done via fetch(). + */ +export type V7_FormMethod = UpperCaseFormMethod; +export type V7_MutationFormMethod = Exclude; + +export type FormEncType = + | "application/x-www-form-urlencoded" + | "multipart/form-data" + | "application/json" + | "text/plain"; + +// Thanks https://github.com/sindresorhus/type-fest! +type JsonObject = { [Key in string]: JsonValue } & { + [Key in string]?: JsonValue | undefined; +}; +type JsonArray = JsonValue[] | readonly JsonValue[]; +type JsonPrimitive = string | number | boolean | null; +type JsonValue = JsonPrimitive | JsonObject | JsonArray; + +/** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ +export type Submission = + | { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + json: undefined; + text: undefined; + } + | { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: undefined; + json: JsonValue; + text: undefined; + } + | { + formMethod: FormMethod | V7_FormMethod; + formAction: string; + formEncType: FormEncType; + formData: undefined; + json: undefined; + text: string; + }; + +/** + * @private + * Arguments passed to route loader/action functions. Same for now but we keep + * this as a private implementation detail in case they diverge in the future. + */ +interface DataFunctionArgs { + request: Request; + params: Params; + context?: Context; +} + +// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers: +// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs +// Also, make them a type alias instead of an interface + +/** + * Arguments passed to loader functions + */ +export interface LoaderFunctionArgs + extends DataFunctionArgs {} + +/** + * Arguments passed to action functions + */ +export interface ActionFunctionArgs + extends DataFunctionArgs {} + +/** + * Loaders and actions can return anything except `undefined` (`null` is a + * valid return value if there is no data to return). Responses are preferred + * and will ease any future migration to Remix + */ +type DataFunctionValue = Response | NonNullable | null; + +type DataFunctionReturnValue = Promise | DataFunctionValue; + +/** + * Route loader function signature + */ +export type LoaderFunction = { + ( + args: LoaderFunctionArgs, + handlerCtx?: unknown + ): DataFunctionReturnValue; +} & { hydrate?: boolean }; + +/** + * Route action function signature + */ +export interface ActionFunction { + ( + args: ActionFunctionArgs, + handlerCtx?: unknown + ): DataFunctionReturnValue; +} + +/** + * Arguments passed to shouldRevalidate function + */ +export interface ShouldRevalidateFunctionArgs { + currentUrl: URL; + currentParams: AgnosticDataRouteMatch["params"]; + nextUrl: URL; + nextParams: AgnosticDataRouteMatch["params"]; + formMethod?: Submission["formMethod"]; + formAction?: Submission["formAction"]; + formEncType?: Submission["formEncType"]; + text?: Submission["text"]; + formData?: Submission["formData"]; + json?: Submission["json"]; + actionStatus?: number; + actionResult?: any; + defaultShouldRevalidate: boolean; +} + +/** + * Route shouldRevalidate function signature. This runs after any submission + * (navigation or fetcher), so we flatten the navigation/fetcher submission + * onto the arguments. It shouldn't matter whether it came from a navigation + * or a fetcher, what really matters is the URLs and the formData since loaders + * have to re-run based on the data models that were potentially mutated. + */ +export interface ShouldRevalidateFunction { + (args: ShouldRevalidateFunctionArgs): boolean; +} + +/** + * Function provided by the framework-aware layers to set `hasErrorBoundary` + * from the framework-aware `errorElement` prop + * + * @deprecated Use `mapRouteProperties` instead + */ +export interface DetectErrorBoundaryFunction { + (route: AgnosticRouteObject): boolean; +} + +export interface DataStrategyMatch + extends AgnosticRouteMatch { + shouldLoad: boolean; + resolve: ( + handlerOverride?: ( + handler: (ctx?: unknown) => DataFunctionReturnValue + ) => Promise + ) => Promise; +} + +export interface DataStrategyFunctionArgs + extends DataFunctionArgs { + matches: DataStrategyMatch[]; +} + +export interface DataStrategyFunction { + (args: DataStrategyFunctionArgs): Promise; +} + +export interface AgnosticPatchRoutesOnMissFunction< + M extends AgnosticRouteMatch = AgnosticRouteMatch +> { + (opts: { + path: string; + matches: M[]; + patch: (routeId: string | null, children: AgnosticRouteObject[]) => void; + }): void | Promise; +} + +/** + * Function provided by the framework-aware layers to set any framework-specific + * properties from framework-agnostic properties + */ +export interface MapRoutePropertiesFunction { + (route: AgnosticRouteObject): { + hasErrorBoundary: boolean; + } & Record; +} + +/** + * Keys we cannot change from within a lazy() function. We spread all other keys + * onto the route. Either they're meaningful to the router, or they'll get + * ignored. + */ +export type ImmutableRouteKey = + | "lazy" + | "caseSensitive" + | "path" + | "id" + | "index" + | "children"; + +export const immutableRouteKeys = new Set([ + "lazy", + "caseSensitive", + "path", + "id", + "index", + "children", +]); + +type RequireOne = Exclude< + { + [K in keyof T]: K extends Key ? Omit & Required> : never; + }[keyof T], + undefined +>; + +/** + * lazy() function to load a route definition, which can add non-matching + * related properties to a route + */ +export interface LazyRouteFunction { + (): Promise>>; +} + +/** + * Base RouteObject with common props shared by all types of routes + */ +type AgnosticBaseRouteObject = { + caseSensitive?: boolean; + path?: string; + id?: string; + loader?: LoaderFunction | boolean; + action?: ActionFunction | boolean; + hasErrorBoundary?: boolean; + shouldRevalidate?: ShouldRevalidateFunction; + handle?: any; + lazy?: LazyRouteFunction; +}; + +/** + * Index routes must not have children + */ +export type AgnosticIndexRouteObject = AgnosticBaseRouteObject & { + children?: undefined; + index: true; +}; + +/** + * Non-index routes may have children, but cannot have index + */ +export type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & { + children?: AgnosticRouteObject[]; + index?: false; +}; + +/** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ +export type AgnosticRouteObject = + | AgnosticIndexRouteObject + | AgnosticNonIndexRouteObject; + +export type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & { + id: string; +}; + +export type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & { + children?: AgnosticDataRouteObject[]; + id: string; +}; + +/** + * A data route object, which is just a RouteObject with a required unique ID + */ +export type AgnosticDataRouteObject = + | AgnosticDataIndexRouteObject + | AgnosticDataNonIndexRouteObject; + +export type RouteManifest = Record; + +// Recursive helper for finding path parameters in the absence of wildcards +type _PathParam = + // split path into individual path segments + Path extends `${infer L}/${infer R}` + ? _PathParam | _PathParam + : // find params after `:` + Path extends `:${infer Param}` + ? Param extends `${infer Optional}?` + ? Optional + : Param + : // otherwise, there aren't any params present + never; + +/** + * Examples: + * "/a/b/*" -> "*" + * ":a" -> "a" + * "/a/:b" -> "b" + * "/a/blahblahblah:b" -> "b" + * "/:a/:b" -> "a" | "b" + * "/:a/b/:c/*" -> "a" | "c" | "*" + */ +export type PathParam = + // check if path is just a wildcard + Path extends "*" | "/*" + ? "*" + : // look for wildcard at the end of the path + Path extends `${infer Rest}/*` + ? "*" | _PathParam + : // look for params in the absence of wildcards + _PathParam; + +// Attempt to parse the given string segment. If it fails, then just return the +// plain string type as a default fallback. Otherwise, return the union of the +// parsed string literals that were referenced as dynamic segments in the route. +export type ParamParseKey = + // if you could not find path params, fallback to `string` + [PathParam] extends [never] ? string : PathParam; + +/** + * The parameters that were parsed from the URL path. + */ +export type Params = { + readonly [key in Key]: string | undefined; +}; + +/** + * A RouteMatch contains info about how a route matched a URL. + */ +export interface AgnosticRouteMatch< + ParamKey extends string = string, + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +> { + /** + * The names and values of dynamic parameters in the URL. + */ + params: Params; + /** + * The portion of the URL pathname that was matched. + */ + pathname: string; + /** + * The portion of the URL pathname that was matched before child routes. + */ + pathnameBase: string; + /** + * The route object that was used to match. + */ + route: RouteObjectType; +} + +export interface AgnosticDataRouteMatch + extends AgnosticRouteMatch {} + +function isIndexRoute( + route: AgnosticRouteObject +): route is AgnosticIndexRouteObject { + return route.index === true; +} + +// Walk the route tree generating unique IDs where necessary, so we are working +// solely with AgnosticDataRouteObject's within the Router +export function convertRoutesToDataRoutes( + routes: AgnosticRouteObject[], + mapRouteProperties: MapRoutePropertiesFunction, + parentPath: string[] = [], + manifest: RouteManifest = {} +): AgnosticDataRouteObject[] { + return routes.map((route, index) => { + let treePath = [...parentPath, String(index)]; + let id = typeof route.id === "string" ? route.id : treePath.join("-"); + invariant( + route.index !== true || !route.children, + `Cannot specify children on an index route` + ); + invariant( + !manifest[id], + `Found a route id collision on id "${id}". Route ` + + "id's must be globally unique within Data Router usages" + ); + + if (isIndexRoute(route)) { + let indexRoute: AgnosticDataIndexRouteObject = { + ...route, + ...mapRouteProperties(route), + id, + }; + manifest[id] = indexRoute; + return indexRoute; + } else { + let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = { + ...route, + ...mapRouteProperties(route), + id, + children: undefined, + }; + manifest[id] = pathOrLayoutRoute; + + if (route.children) { + pathOrLayoutRoute.children = convertRoutesToDataRoutes( + route.children, + mapRouteProperties, + treePath, + manifest + ); + } + + return pathOrLayoutRoute; + } + }); +} + +/** + * Matches the given routes to a location and returns the match data. + * + * @see https://reactrouter.com/utils/match-routes + */ +export function matchRoutes< + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +>( + routes: RouteObjectType[], + locationArg: Partial | string, + basename = "/" +): AgnosticRouteMatch[] | null { + return matchRoutesImpl(routes, locationArg, basename, false); +} + +export function matchRoutesImpl< + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +>( + routes: RouteObjectType[], + locationArg: Partial | string, + basename: string, + allowPartial: boolean +): AgnosticRouteMatch[] | null { + let location = + typeof locationArg === "string" ? parsePath(locationArg) : locationArg; + + let pathname = stripBasename(location.pathname || "/", basename); + + if (pathname == null) { + return null; + } + + let branches = flattenRoutes(routes); + rankRouteBranches(branches); + + let matches = null; + for (let i = 0; matches == null && i < branches.length; ++i) { + // Incoming pathnames are generally encoded from either window.location + // or from router.navigate, but we want to match against the unencoded + // paths in the route definitions. Memory router locations won't be + // encoded here but there also shouldn't be anything to decode so this + // should be a safe operation. This avoids needing matchRoutes to be + // history-aware. + let decoded = decodePath(pathname); + matches = matchRouteBranch( + branches[i], + decoded, + allowPartial + ); + } + + return matches; +} + +export interface UIMatch { + id: string; + pathname: string; + params: AgnosticRouteMatch["params"]; + data: Data; + handle: Handle; +} + +export function convertRouteMatchToUiMatch( + match: AgnosticDataRouteMatch, + loaderData: RouteData +): UIMatch { + let { route, pathname, params } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle, + }; +} + +interface RouteMeta< + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +> { + relativePath: string; + caseSensitive: boolean; + childrenIndex: number; + route: RouteObjectType; +} + +interface RouteBranch< + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +> { + path: string; + score: number; + routesMeta: RouteMeta[]; +} + +function flattenRoutes< + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +>( + routes: RouteObjectType[], + branches: RouteBranch[] = [], + parentsMeta: RouteMeta[] = [], + parentPath = "" +): RouteBranch[] { + let flattenRoute = ( + route: RouteObjectType, + index: number, + relativePath?: string + ) => { + let meta: RouteMeta = { + relativePath: + relativePath === undefined ? route.path || "" : relativePath, + caseSensitive: route.caseSensitive === true, + childrenIndex: index, + route, + }; + + if (meta.relativePath.startsWith("/")) { + invariant( + meta.relativePath.startsWith(parentPath), + `Absolute route path "${meta.relativePath}" nested under path ` + + `"${parentPath}" is not valid. An absolute child route path ` + + `must start with the combined path of all its parent routes.` + ); + + meta.relativePath = meta.relativePath.slice(parentPath.length); + } + + let path = joinPaths([parentPath, meta.relativePath]); + let routesMeta = parentsMeta.concat(meta); + + // Add the children before adding this route to the array, so we traverse the + // route tree depth-first and child routes appear before their parents in + // the "flattened" version. + if (route.children && route.children.length > 0) { + invariant( + // Our types know better, but runtime JS may not! + // @ts-expect-error + route.index !== true, + `Index routes must not have child routes. Please remove ` + + `all child routes from route path "${path}".` + ); + flattenRoutes(route.children, branches, routesMeta, path); + } + + // Routes without a path shouldn't ever match by themselves unless they are + // index routes, so don't add them to the list of possible branches. + if (route.path == null && !route.index) { + return; + } + + branches.push({ + path, + score: computeScore(path, route.index), + routesMeta, + }); + }; + routes.forEach((route, index) => { + // coarse-grain check for optional params + if (route.path === "" || !route.path?.includes("?")) { + flattenRoute(route, index); + } else { + for (let exploded of explodeOptionalSegments(route.path)) { + flattenRoute(route, index, exploded); + } + } + }); + + return branches; +} + +/** + * Computes all combinations of optional path segments for a given path, + * excluding combinations that are ambiguous and of lower priority. + * + * For example, `/one/:two?/three/:four?/:five?` explodes to: + * - `/one/three` + * - `/one/:two/three` + * - `/one/three/:four` + * - `/one/three/:five` + * - `/one/:two/three/:four` + * - `/one/:two/three/:five` + * - `/one/three/:four/:five` + * - `/one/:two/three/:four/:five` + */ +function explodeOptionalSegments(path: string): string[] { + let segments = path.split("/"); + if (segments.length === 0) return []; + + let [first, ...rest] = segments; + + // Optional path segments are denoted by a trailing `?` + let isOptional = first.endsWith("?"); + // Compute the corresponding required segment: `foo?` -> `foo` + let required = first.replace(/\?$/, ""); + + if (rest.length === 0) { + // Intepret empty string as omitting an optional segment + // `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three` + return isOptional ? [required, ""] : [required]; + } + + let restExploded = explodeOptionalSegments(rest.join("/")); + + let result: string[] = []; + + // All child paths with the prefix. Do this for all children before the + // optional version for all children, so we get consistent ordering where the + // parent optional aspect is preferred as required. Otherwise, we can get + // child sections interspersed where deeper optional segments are higher than + // parent optional segments, where for example, /:two would explode _earlier_ + // then /:one. By always including the parent as required _for all children_ + // first, we avoid this issue + result.push( + ...restExploded.map((subpath) => + subpath === "" ? required : [required, subpath].join("/") + ) + ); + + // Then, if this is an optional value, add all child versions without + if (isOptional) { + result.push(...restExploded); + } + + // for absolute paths, ensure `/` instead of empty segment + return result.map((exploded) => + path.startsWith("/") && exploded === "" ? "/" : exploded + ); +} + +function rankRouteBranches(branches: RouteBranch[]): void { + branches.sort((a, b) => + a.score !== b.score + ? b.score - a.score // Higher score first + : compareIndexes( + a.routesMeta.map((meta) => meta.childrenIndex), + b.routesMeta.map((meta) => meta.childrenIndex) + ) + ); +} + +const paramRe = /^:[\w-]+$/; +const dynamicSegmentValue = 3; +const indexRouteValue = 2; +const emptySegmentValue = 1; +const staticSegmentValue = 10; +const splatPenalty = -2; +const isSplat = (s: string) => s === "*"; + +function computeScore(path: string, index: boolean | undefined): number { + let segments = path.split("/"); + let initialScore = segments.length; + if (segments.some(isSplat)) { + initialScore += splatPenalty; + } + + if (index) { + initialScore += indexRouteValue; + } + + return segments + .filter((s) => !isSplat(s)) + .reduce( + (score, segment) => + score + + (paramRe.test(segment) + ? dynamicSegmentValue + : segment === "" + ? emptySegmentValue + : staticSegmentValue), + initialScore + ); +} + +function compareIndexes(a: number[], b: number[]): number { + let siblings = + a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); + + return siblings + ? // If two routes are siblings, we should try to match the earlier sibling + // first. This allows people to have fine-grained control over the matching + // behavior by simply putting routes with identical paths in the order they + // want them tried. + a[a.length - 1] - b[b.length - 1] + : // Otherwise, it doesn't really make sense to rank non-siblings by index, + // so they sort equally. + 0; +} + +function matchRouteBranch< + ParamKey extends string = string, + RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject +>( + branch: RouteBranch, + pathname: string, + allowPartial = false +): AgnosticRouteMatch[] | null { + let { routesMeta } = branch; + + let matchedParams = {}; + let matchedPathname = "/"; + let matches: AgnosticRouteMatch[] = []; + for (let i = 0; i < routesMeta.length; ++i) { + let meta = routesMeta[i]; + let end = i === routesMeta.length - 1; + let remainingPathname = + matchedPathname === "/" + ? pathname + : pathname.slice(matchedPathname.length) || "/"; + let match = matchPath( + { path: meta.relativePath, caseSensitive: meta.caseSensitive, end }, + remainingPathname + ); + + let route = meta.route; + + if ( + !match && + end && + allowPartial && + !routesMeta[routesMeta.length - 1].route.index + ) { + match = matchPath( + { + path: meta.relativePath, + caseSensitive: meta.caseSensitive, + end: false, + }, + remainingPathname + ); + } + + if (!match) { + return null; + } + + Object.assign(matchedParams, match.params); + + matches.push({ + // TODO: Can this as be avoided? + params: matchedParams as Params, + pathname: joinPaths([matchedPathname, match.pathname]), + pathnameBase: normalizePathname( + joinPaths([matchedPathname, match.pathnameBase]) + ), + route, + }); + + if (match.pathnameBase !== "/") { + matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); + } + } + + return matches; +} + +/** + * Returns a path with params interpolated. + * + * @see https://reactrouter.com/utils/generate-path + */ +export function generatePath( + originalPath: Path, + params: { + [key in PathParam]: string | null; + } = {} as any +): string { + let path: string = originalPath; + if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { + warning( + false, + `Route path "${path}" will be treated as if it were ` + + `"${path.replace(/\*$/, "/*")}" because the \`*\` character must ` + + `always follow a \`/\` in the pattern. To get rid of this warning, ` + + `please change the route path to "${path.replace(/\*$/, "/*")}".` + ); + path = path.replace(/\*$/, "/*") as Path; + } + + // ensure `/` is added at the beginning if the path is absolute + const prefix = path.startsWith("/") ? "/" : ""; + + const stringify = (p: any) => + p == null ? "" : typeof p === "string" ? p : String(p); + + const segments = path + .split(/\/+/) + .map((segment, index, array) => { + const isLastSegment = index === array.length - 1; + + // only apply the splat if it's the last segment + if (isLastSegment && segment === "*") { + const star = "*" as PathParam; + // Apply the splat + return stringify(params[star]); + } + + const keyMatch = segment.match(/^:([\w-]+)(\??)$/); + if (keyMatch) { + const [, key, optional] = keyMatch; + let param = params[key as PathParam]; + invariant(optional === "?" || param != null, `Missing ":${key}" param`); + return stringify(param); + } + + // Remove any optional markers from optional static segments + return segment.replace(/\?$/g, ""); + }) + // Remove empty segments + .filter((segment) => !!segment); + + return prefix + segments.join("/"); +} + +/** + * A PathPattern is used to match on some portion of a URL pathname. + */ +export interface PathPattern { + /** + * A string to match against a URL pathname. May contain `:id`-style segments + * to indicate placeholders for dynamic parameters. May also end with `/*` to + * indicate matching the rest of the URL pathname. + */ + path: Path; + /** + * Should be `true` if the static portions of the `path` should be matched in + * the same case. + */ + caseSensitive?: boolean; + /** + * Should be `true` if this pattern should match the entire URL pathname. + */ + end?: boolean; +} + +/** + * A PathMatch contains info about how a PathPattern matched on a URL pathname. + */ +export interface PathMatch { + /** + * The names and values of dynamic parameters in the URL. + */ + params: Params; + /** + * The portion of the URL pathname that was matched. + */ + pathname: string; + /** + * The portion of the URL pathname that was matched before child routes. + */ + pathnameBase: string; + /** + * The pattern that was used to match. + */ + pattern: PathPattern; +} + +type Mutable = { + -readonly [P in keyof T]: T[P]; +}; + +/** + * Performs pattern matching on a URL pathname and returns information about + * the match. + * + * @see https://reactrouter.com/utils/match-path + */ +export function matchPath< + ParamKey extends ParamParseKey, + Path extends string +>( + pattern: PathPattern | Path, + pathname: string +): PathMatch | null { + if (typeof pattern === "string") { + pattern = { path: pattern, caseSensitive: false, end: true }; + } + + let [matcher, compiledParams] = compilePath( + pattern.path, + pattern.caseSensitive, + pattern.end + ); + + let match = pathname.match(matcher); + if (!match) return null; + + let matchedPathname = match[0]; + let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); + let captureGroups = match.slice(1); + let params: Params = compiledParams.reduce>( + (memo, { paramName, isOptional }, index) => { + // We need to compute the pathnameBase here using the raw splat value + // instead of using params["*"] later because it will be decoded then + if (paramName === "*") { + let splatValue = captureGroups[index] || ""; + pathnameBase = matchedPathname + .slice(0, matchedPathname.length - splatValue.length) + .replace(/(.)\/+$/, "$1"); + } + + const value = captureGroups[index]; + if (isOptional && !value) { + memo[paramName] = undefined; + } else { + memo[paramName] = (value || "").replace(/%2F/g, "/"); + } + return memo; + }, + {} + ); + + return { + params, + pathname: matchedPathname, + pathnameBase, + pattern, + }; +} + +type CompiledPathParam = { paramName: string; isOptional?: boolean }; + +function compilePath( + path: string, + caseSensitive = false, + end = true +): [RegExp, CompiledPathParam[]] { + warning( + path === "*" || !path.endsWith("*") || path.endsWith("/*"), + `Route path "${path}" will be treated as if it were ` + + `"${path.replace(/\*$/, "/*")}" because the \`*\` character must ` + + `always follow a \`/\` in the pattern. To get rid of this warning, ` + + `please change the route path to "${path.replace(/\*$/, "/*")}".` + ); + + let params: CompiledPathParam[] = []; + let regexpSource = + "^" + + path + .replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below + .replace(/^\/*/, "/") // Make sure it has a leading / + .replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars + .replace( + /\/:([\w-]+)(\?)?/g, + (_: string, paramName: string, isOptional) => { + params.push({ paramName, isOptional: isOptional != null }); + return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)"; + } + ); + + if (path.endsWith("*")) { + params.push({ paramName: "*" }); + regexpSource += + path === "*" || path === "/*" + ? "(.*)$" // Already matched the initial /, just match the rest + : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"] + } else if (end) { + // When matching to the end, ignore trailing slashes + regexpSource += "\\/*$"; + } else if (path !== "" && path !== "/") { + // If our path is non-empty and contains anything beyond an initial slash, + // then we have _some_ form of path in our regex, so we should expect to + // match only if we find the end of this path segment. Look for an optional + // non-captured trailing slash (to match a portion of the URL) or the end + // of the path (if we've matched to the end). We used to do this with a + // word boundary but that gives false positives on routes like + // /user-preferences since `-` counts as a word boundary. + regexpSource += "(?:(?=\\/|$))"; + } else { + // Nothing to match for "" or "/" + } + + let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i"); + + return [matcher, params]; +} + +export function decodePath(value: string) { + try { + return value + .split("/") + .map((v) => decodeURIComponent(v).replace(/\//g, "%2F")) + .join("/"); + } catch (error) { + warning( + false, + `The URL path "${value}" could not be decoded because it is is a ` + + `malformed URL segment. This is probably due to a bad percent ` + + `encoding (${error}).` + ); + + return value; + } +} + +/** + * @private + */ +export function stripBasename( + pathname: string, + basename: string +): string | null { + if (basename === "/") return pathname; + + if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { + return null; + } + + // We want to leave trailing slash behavior in the user's control, so if they + // specify a basename with a trailing slash, we should support it + let startIndex = basename.endsWith("/") + ? basename.length - 1 + : basename.length; + let nextChar = pathname.charAt(startIndex); + if (nextChar && nextChar !== "/") { + // pathname does not start with basename/ + return null; + } + + return pathname.slice(startIndex) || "/"; +} + +/** + * Returns a resolved path object relative to the given pathname. + * + * @see https://reactrouter.com/utils/resolve-path + */ +export function resolvePath(to: To, fromPathname = "/"): Path { + let { + pathname: toPathname, + search = "", + hash = "", + } = typeof to === "string" ? parsePath(to) : to; + + let pathname = toPathname + ? toPathname.startsWith("/") + ? toPathname + : resolvePathname(toPathname, fromPathname) + : fromPathname; + + return { + pathname, + search: normalizeSearch(search), + hash: normalizeHash(hash), + }; +} + +function resolvePathname(relativePath: string, fromPathname: string): string { + let segments = fromPathname.replace(/\/+$/, "").split("/"); + let relativeSegments = relativePath.split("/"); + + relativeSegments.forEach((segment) => { + if (segment === "..") { + // Keep the root "" segment so the pathname starts at / + if (segments.length > 1) segments.pop(); + } else if (segment !== ".") { + segments.push(segment); + } + }); + + return segments.length > 1 ? segments.join("/") : "/"; +} + +function getInvalidPathError( + char: string, + field: string, + dest: string, + path: Partial +) { + return ( + `Cannot include a '${char}' character in a manually specified ` + + `\`to.${field}\` field [${JSON.stringify( + path + )}]. Please separate it out to the ` + + `\`to.${dest}\` field. Alternatively you may provide the full path as ` + + `a string in and the router will parse it for you.` + ); +} + +/** + * @private + * + * When processing relative navigation we want to ignore ancestor routes that + * do not contribute to the path, such that index/pathless layout routes don't + * interfere. + * + * For example, when moving a route element into an index route and/or a + * pathless layout route, relative link behavior contained within should stay + * the same. Both of the following examples should link back to the root: + * + * + * + * + * + * + * + * }> // <-- Does not contribute + * // <-- Does not contribute + * + * + */ +export function getPathContributingMatches< + T extends AgnosticRouteMatch = AgnosticRouteMatch +>(matches: T[]) { + return matches.filter( + (match, index) => + index === 0 || (match.route.path && match.route.path.length > 0) + ); +} + +// Return the array of pathnames for the current route matches - used to +// generate the routePathnames input for resolveTo() +export function getResolveToMatches< + T extends AgnosticRouteMatch = AgnosticRouteMatch +>(matches: T[], v7_relativeSplatPath: boolean) { + let pathMatches = getPathContributingMatches(matches); + + // When v7_relativeSplatPath is enabled, use the full pathname for the leaf + // match so we include splat values for "." links. See: + // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329 + if (v7_relativeSplatPath) { + return pathMatches.map((match, idx) => + idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase + ); + } + + return pathMatches.map((match) => match.pathnameBase); +} + +/** + * @private + */ +export function resolveTo( + toArg: To, + routePathnames: string[], + locationPathname: string, + isPathRelative = false +): Path { + let to: Partial; + if (typeof toArg === "string") { + to = parsePath(toArg); + } else { + to = { ...toArg }; + + invariant( + !to.pathname || !to.pathname.includes("?"), + getInvalidPathError("?", "pathname", "search", to) + ); + invariant( + !to.pathname || !to.pathname.includes("#"), + getInvalidPathError("#", "pathname", "hash", to) + ); + invariant( + !to.search || !to.search.includes("#"), + getInvalidPathError("#", "search", "hash", to) + ); + } + + let isEmptyPath = toArg === "" || to.pathname === ""; + let toPathname = isEmptyPath ? "/" : to.pathname; + + let from: string; + + // Routing is relative to the current pathname if explicitly requested. + // + // If a pathname is explicitly provided in `to`, it should be relative to the + // route context. This is explained in `Note on `` values` in our + // migration guide from v5 as a means of disambiguation between `to` values + // that begin with `/` and those that do not. However, this is problematic for + // `to` values that do not provide a pathname. `to` can simply be a search or + // hash string, in which case we should assume that the navigation is relative + // to the current location's pathname and *not* the route pathname. + if (toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + // With relative="route" (the default), each leading .. segment means + // "go up one route" instead of "go up one URL segment". This is a key + // difference from how works and a major reason we call this a + // "to" value instead of a "href". + if (!isPathRelative && toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); + + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + + to.pathname = toSegments.join("/"); + } + + from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; + } + + let path = resolvePath(to, from); + + // Ensure the pathname has a trailing slash if the original "to" had one + let hasExplicitTrailingSlash = + toPathname && toPathname !== "/" && toPathname.endsWith("/"); + // Or if this was a link to the current path which has a trailing slash + let hasCurrentTrailingSlash = + (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); + if ( + !path.pathname.endsWith("/") && + (hasExplicitTrailingSlash || hasCurrentTrailingSlash) + ) { + path.pathname += "/"; + } + + return path; +} + +/** + * @private + */ +export function getToPathname(to: To): string | undefined { + // Empty strings should be treated the same as / paths + return to === "" || (to as Path).pathname === "" + ? "/" + : typeof to === "string" + ? parsePath(to).pathname + : to.pathname; +} + +/** + * @private + */ +export const joinPaths = (paths: string[]): string => + paths.join("/").replace(/\/\/+/g, "/"); + +/** + * @private + */ +export const normalizePathname = (pathname: string): string => + pathname.replace(/\/+$/, "").replace(/^\/*/, "/"); + +/** + * @private + */ +export const normalizeSearch = (search: string): string => + !search || search === "?" + ? "" + : search.startsWith("?") + ? search + : "?" + search; + +/** + * @private + */ +export const normalizeHash = (hash: string): string => + !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; + +export type JsonFunction = ( + data: Data, + init?: number | ResponseInit +) => Response; + +/** + * This is a shortcut for creating `application/json` responses. Converts `data` + * to JSON and sets the `Content-Type` header. + */ +export const json: JsonFunction = (data, init = {}) => { + let responseInit = typeof init === "number" ? { status: init } : init; + + let headers = new Headers(responseInit.headers); + if (!headers.has("Content-Type")) { + headers.set("Content-Type", "application/json; charset=utf-8"); + } + + return new Response(JSON.stringify(data), { + ...responseInit, + headers, + }); +}; + +export interface TrackedPromise extends Promise { + _tracked?: boolean; + _data?: any; + _error?: any; +} + +export class AbortedDeferredError extends Error {} + +export class DeferredData { + private pendingKeysSet: Set = new Set(); + private controller: AbortController; + private abortPromise: Promise; + private unlistenAbortSignal: () => void; + private subscribers: Set<(aborted: boolean, settledKey?: string) => void> = + new Set(); + data: Record; + init?: ResponseInit; + deferredKeys: string[] = []; + + constructor(data: Record, responseInit?: ResponseInit) { + invariant( + data && typeof data === "object" && !Array.isArray(data), + "defer() only accepts plain objects" + ); + + // Set up an AbortController + Promise we can race against to exit early + // cancellation + let reject: (e: AbortedDeferredError) => void; + this.abortPromise = new Promise((_, r) => (reject = r)); + this.controller = new AbortController(); + let onAbort = () => + reject(new AbortedDeferredError("Deferred data aborted")); + this.unlistenAbortSignal = () => + this.controller.signal.removeEventListener("abort", onAbort); + this.controller.signal.addEventListener("abort", onAbort); + + this.data = Object.entries(data).reduce( + (acc, [key, value]) => + Object.assign(acc, { + [key]: this.trackPromise(key, value), + }), + {} + ); + + if (this.done) { + // All incoming values were resolved + this.unlistenAbortSignal(); + } + + this.init = responseInit; + } + + private trackPromise( + key: string, + value: Promise | unknown + ): TrackedPromise | unknown { + if (!(value instanceof Promise)) { + return value; + } + + this.deferredKeys.push(key); + this.pendingKeysSet.add(key); + + // We store a little wrapper promise that will be extended with + // _data/_error props upon resolve/reject + let promise: TrackedPromise = Promise.race([value, this.abortPromise]).then( + (data) => this.onSettle(promise, key, undefined, data as unknown), + (error) => this.onSettle(promise, key, error as unknown) + ); + + // Register rejection listeners to avoid uncaught promise rejections on + // errors or aborted deferred values + promise.catch(() => {}); + + Object.defineProperty(promise, "_tracked", { get: () => true }); + return promise; + } + + private onSettle( + promise: TrackedPromise, + key: string, + error: unknown, + data?: unknown + ): unknown { + if ( + this.controller.signal.aborted && + error instanceof AbortedDeferredError + ) { + this.unlistenAbortSignal(); + Object.defineProperty(promise, "_error", { get: () => error }); + return Promise.reject(error); + } + + this.pendingKeysSet.delete(key); + + if (this.done) { + // Nothing left to abort! + this.unlistenAbortSignal(); + } + + // If the promise was resolved/rejected with undefined, we'll throw an error as you + // should always resolve with a value or null + if (error === undefined && data === undefined) { + let undefinedError = new Error( + `Deferred data for key "${key}" resolved/rejected with \`undefined\`, ` + + `you must resolve/reject with a value or \`null\`.` + ); + Object.defineProperty(promise, "_error", { get: () => undefinedError }); + this.emit(false, key); + return Promise.reject(undefinedError); + } + + if (data === undefined) { + Object.defineProperty(promise, "_error", { get: () => error }); + this.emit(false, key); + return Promise.reject(error); + } + + Object.defineProperty(promise, "_data", { get: () => data }); + this.emit(false, key); + return data; + } + + private emit(aborted: boolean, settledKey?: string) { + this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey)); + } + + subscribe(fn: (aborted: boolean, settledKey?: string) => void) { + this.subscribers.add(fn); + return () => this.subscribers.delete(fn); + } + + cancel() { + this.controller.abort(); + this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k)); + this.emit(true); + } + + async resolveData(signal: AbortSignal) { + let aborted = false; + if (!this.done) { + let onAbort = () => this.cancel(); + signal.addEventListener("abort", onAbort); + aborted = await new Promise((resolve) => { + this.subscribe((aborted) => { + signal.removeEventListener("abort", onAbort); + if (aborted || this.done) { + resolve(aborted); + } + }); + }); + } + return aborted; + } + + get done() { + return this.pendingKeysSet.size === 0; + } + + get unwrappedData() { + invariant( + this.data !== null && this.done, + "Can only unwrap data on initialized and settled deferreds" + ); + + return Object.entries(this.data).reduce( + (acc, [key, value]) => + Object.assign(acc, { + [key]: unwrapTrackedPromise(value), + }), + {} + ); + } + + get pendingKeys() { + return Array.from(this.pendingKeysSet); + } +} + +function isTrackedPromise(value: any): value is TrackedPromise { + return ( + value instanceof Promise && (value as TrackedPromise)._tracked === true + ); +} + +function unwrapTrackedPromise(value: any) { + if (!isTrackedPromise(value)) { + return value; + } + + if (value._error) { + throw value._error; + } + return value._data; +} + +export type DeferFunction = ( + data: Record, + init?: number | ResponseInit +) => DeferredData; + +export const defer: DeferFunction = (data, init = {}) => { + let responseInit = typeof init === "number" ? { status: init } : init; + + return new DeferredData(data, responseInit); +}; + +export type RedirectFunction = ( + url: string, + init?: number | ResponseInit +) => Response; + +/** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +export const redirect: RedirectFunction = (url, init = 302) => { + let responseInit = init; + if (typeof responseInit === "number") { + responseInit = { status: responseInit }; + } else if (typeof responseInit.status === "undefined") { + responseInit.status = 302; + } + + let headers = new Headers(responseInit.headers); + headers.set("Location", url); + + return new Response(null, { + ...responseInit, + headers, + }); +}; + +/** + * A redirect response that will force a document reload to the new location. + * Sets the status code and the `Location` header. + * Defaults to "302 Found". + */ +export const redirectDocument: RedirectFunction = (url, init) => { + let response = redirect(url, init); + response.headers.set("X-Remix-Reload-Document", "true"); + return response; +}; + +export type ErrorResponse = { + status: number; + statusText: string; + data: any; +}; + +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + * + * We don't export the class for public use since it's an implementation + * detail, but we export the interface above so folks can build their own + * abstractions around instances via isRouteErrorResponse() + */ +export class ErrorResponseImpl implements ErrorResponse { + status: number; + statusText: string; + data: any; + private error?: Error; + private internal: boolean; + + constructor( + status: number, + statusText: string | undefined, + data: any, + internal = false + ) { + this.status = status; + this.statusText = statusText || ""; + this.internal = internal; + if (data instanceof Error) { + this.data = data.toString(); + this.error = data; + } else { + this.data = data; + } + } +} + +/** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response thrown from an action/loader + */ +export function isRouteErrorResponse(error: any): error is ErrorResponse { + return ( + error != null && + typeof error.status === "number" && + typeof error.statusText === "string" && + typeof error.internal === "boolean" && + "data" in error + ); +} diff --git a/node_modules/classnames/HISTORY.md b/node_modules/classnames/HISTORY.md new file mode 100644 index 0000000000..7a7cef26b2 --- /dev/null +++ b/node_modules/classnames/HISTORY.md @@ -0,0 +1,120 @@ +# Changelog + +## v2.5.1 / 2023-12-29 + +- Remove `workspaces` field from package ([#350](https://github.com/JedWatson/classnames/pull/350)) + +## v2.5.0 / 2023-12-27 + +- Restore ability to pass a TypeScript `interface` ([#341](https://github.com/JedWatson/classnames/pull/341)) +- Add `exports` field to package ([#342](https://github.com/JedWatson/classnames/pull/342)) + +## v2.4.0 / 2023-12-26 + +- Use string concatenation to increase performance thanks [Jon Koops](https://github.com/jonkoops) ([#336](https://github.com/JedWatson/classnames/pull/336)) + +## v2.3.3 / 2023-12-21 + +- Fix default export, thanks [Remco Haszing](https://github.com/remcohaszing) ([#301](https://github.com/JedWatson/classnames/pull/301)) +- Fix types for read-only arrays, thanks [Ben Thompson](https://github.com/BenGearset) ([#307](https://github.com/JedWatson/classnames/pull/307)) +- Replace README examples with functional-style components, thanks [JoeDGit](https://github.com/JoeDGit) ([#303](https://github.com/JedWatson/classnames/pull/303)) + +## v2.3.2 / 2022-09-13 + +- Fix TypeScript types when using require, thanks [Mark Dalgleish](https://github.com/markdalgleish) ([#276](https://github.com/JedWatson/classnames/pull/276)) +- Fix toString as `[Object object]` in a vm, thanks [Remco Haszing](https://github.com/remcohaszing) ([#281](https://github.com/JedWatson/classnames/pull/281)) + +## v2.3.1 / 2021-04-03 + +- Fix bind/dedupe TypeScript types exports +- Fix mapping Value types, thanks [Remco Haszing](https://github.com/remcohaszing) +- Removed non-existent named exports from types, thanks [Remco Haszing](https://github.com/remcohaszing) + +## v2.3.0 / 2021-04-01 + +- Added TypeScript types +- Added consistent support for custom `.toString()` methods on arguments, thanks [Stanislav Titenko](https://github.com/resetko) + +## v2.2.6 / 2018-06-08 + +- Fixed compatibility issue with usage in an es module environment + +## v2.2.5 / 2016-05-02 + +- Improved performance of `dedupe` variant even further, thanks [Andres Suarez](https://github.com/zertosh) + +## v2.2.4 / 2016-04-25 + +- Improved performance of `dedupe` variant by about 2x, thanks [Bartosz Gościński](https://github.com/bgoscinski) + +## v2.2.3 / 2016-01-05 + +- Updated `bind` variant to use `[].join(' ')` as per the main script in 2.2.2 + +## v2.2.2 / 2016-01-04 + +- Switched from string concatenation to `[].join(' ')` for a slight performance gain in the main function. + +## v2.2.1 / 2015-11-26 + +- Add deps parameter to the AMD module, fixes an issue using the Dojo loader, thanks [Chris Jordan](https://github.com/flipperkid) + +## v2.2.0 / 2015-10-18 + +- added a new `bind` variant for use with [css-modules](https://github.com/css-modules/css-modules) and similar abstractions, thanks to [Kirill Yakovenko](https://github.com/blia) + +## v2.1.5 / 2015-09-30 + +- reverted a new usage of `Object.keys` in `dedupe.js` that slipped through in the last release + +## v2.1.4 / 2015-09-30 + +- new case added to benchmarks +- safer `hasOwnProperty` check +- AMD module is now named, so you can do the following: + +``` +define(["classnames"], function (classNames) { + var style = classNames("foo", "bar"); + // ... +}); +``` + +## v2.1.3 / 2015-07-02 + +- updated UMD wrapper to support AMD and CommonJS on the same pacge + +## v2.1.2 / 2015-05-28 + +- added a proper UMD wrapper + +## v2.1.1 / 2015-05-06 + +- minor performance improvement thanks to type caching +- improved benchmarking and results output + +## v2.1.0 / 2015-05-05 + +- added alternate `dedupe` version of classNames, which is slower (10x) but ensures that if a class is added then overridden by a falsy value in a subsequent argument, it is excluded from the result. + +## v2.0.0 / 2015-05-03 + +- performance improvement; switched to `Array.isArray` for type detection, which is much faster in modern browsers. A polyfill is now required for IE8 support, see the Readme for details. + +## v1.2.2 / 2015-04-28 + +- license comment updates to simiplify certain build scenarios + +## v1.2.1 / 2015-04-22 + +- added safe exporting for requireJS usage +- clarified Bower usage and instructions + +## v1.2.0 / 2015-03-17 + +- added comprehensive support for array arguments, including nested arrays +- simplified code slightly + +## Previous + +Please see the git history for the details of previous versions. diff --git a/node_modules/classnames/LICENSE b/node_modules/classnames/LICENSE new file mode 100644 index 0000000000..4117bfae03 --- /dev/null +++ b/node_modules/classnames/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Jed Watson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/classnames/README.md b/node_modules/classnames/README.md new file mode 100644 index 0000000000..0d67b8a576 --- /dev/null +++ b/node_modules/classnames/README.md @@ -0,0 +1,219 @@ +# Classnames + +> A simple JavaScript utility for conditionally joining classNames together. + +

+ + + + + + + + + + +

+ +Install from the [npm registry](https://www.npmjs.com/) with your package manager: +```bash +npm install classnames +``` + +Use with [Node.js](https://nodejs.org/en/), [Browserify](https://browserify.org/), or [webpack](https://webpack.github.io/): + +```js +const classNames = require('classnames'); +classNames('foo', 'bar'); // => 'foo bar' +``` + +Alternatively, you can simply include `index.js` on your page with a standalone `