From be07d90207f1c77f972a723c911c5dee04946b22 Mon Sep 17 00:00:00 2001 From: Naian Date: Fri, 20 Jan 2023 23:49:41 -0300 Subject: [PATCH] feat:adiciona router-dom --- desafio5/src/components/Body/Body.tsx | 27 +- .../src/components/Body/Tabs/TabLayout.tsx | 24 +- desafio5/src/index.tsx | 15 +- node_modules/.yarn-integrity | 18 + node_modules/@remix-run/router/CHANGELOG.md | 156 + node_modules/@remix-run/router/LICENSE.md | 22 + node_modules/@remix-run/router/README.md | 107 + .../@remix-run/router/dist/history.d.ts | 249 + .../@remix-run/router/dist/index.d.ts | 7 + .../@remix-run/router/dist/router.cjs.js | 4067 ++++++++++++++++ .../@remix-run/router/dist/router.cjs.js.map | 1 + .../@remix-run/router/dist/router.d.ts | 426 ++ node_modules/@remix-run/router/dist/router.js | 3987 ++++++++++++++++ .../@remix-run/router/dist/router.js.map | 1 + .../@remix-run/router/dist/router.umd.js | 4073 +++++++++++++++++ .../@remix-run/router/dist/router.umd.js.map | 1 + .../@remix-run/router/dist/router.umd.min.js | 12 + .../router/dist/router.umd.min.js.map | 1 + .../@remix-run/router/dist/utils.d.ts | 389 ++ node_modules/@remix-run/router/history.ts | 737 +++ node_modules/@remix-run/router/index.ts | 84 + node_modules/@remix-run/router/package.json | 33 + node_modules/@remix-run/router/router.ts | 3692 +++++++++++++++ node_modules/@remix-run/router/utils.ts | 1402 ++++++ node_modules/react-router-dom/CHANGELOG.md | 142 + node_modules/react-router-dom/LICENSE.md | 22 + node_modules/react-router-dom/README.md | 5 + node_modules/react-router-dom/dist/dom.d.ts | 80 + node_modules/react-router-dom/dist/index.d.ts | 248 + node_modules/react-router-dom/dist/index.js | 987 ++++ .../react-router-dom/dist/index.js.map | 1 + node_modules/react-router-dom/dist/main.js | 19 + .../dist/react-router-dom.development.js | 934 ++++ .../dist/react-router-dom.development.js.map | 1 + .../dist/react-router-dom.production.min.js | 12 + .../react-router-dom.production.min.js.map | 1 + .../react-router-dom/dist/server.d.ts | 25 + node_modules/react-router-dom/dist/server.js | 293 ++ node_modules/react-router-dom/dist/server.mjs | 266 ++ .../dist/umd/react-router-dom.development.js | 1235 +++++ .../umd/react-router-dom.development.js.map | 1 + .../umd/react-router-dom.production.min.js | 12 + .../react-router-dom.production.min.js.map | 1 + node_modules/react-router-dom/package.json | 49 + node_modules/react-router-dom/server.d.ts | 25 + node_modules/react-router-dom/server.js | 293 ++ node_modules/react-router-dom/server.mjs | 266 ++ node_modules/react-router/CHANGELOG.md | 162 + node_modules/react-router/LICENSE.md | 22 + node_modules/react-router/README.md | 16 + node_modules/react-router/dist/index.d.ts | 21 + node_modules/react-router/dist/index.js | 1392 ++++++ node_modules/react-router/dist/index.js.map | 1 + .../react-router/dist/lib/components.d.ts | 146 + .../react-router/dist/lib/context.d.ts | 88 + node_modules/react-router/dist/lib/hooks.d.ts | 179 + .../use-sync-external-store-shim/index.d.ts | 7 + .../useSyncExternalStoreShimClient.d.ts | 7 + .../useSyncExternalStoreShimServer.d.ts | 9 + node_modules/react-router/dist/main.js | 19 + .../dist/react-router.development.js | 1349 ++++++ .../dist/react-router.development.js.map | 1 + .../dist/react-router.production.min.js | 12 + .../dist/react-router.production.min.js.map | 1 + .../dist/umd/react-router.development.js | 1504 ++++++ .../dist/umd/react-router.development.js.map | 1 + .../dist/umd/react-router.production.min.js | 12 + .../umd/react-router.production.min.js.map | 1 + node_modules/react-router/package.json | 43 + package.json | 5 + yarn.lock | 23 + 71 files changed, 29447 insertions(+), 23 deletions(-) create mode 100644 node_modules/.yarn-integrity create mode 100644 node_modules/@remix-run/router/CHANGELOG.md create mode 100644 node_modules/@remix-run/router/LICENSE.md create mode 100644 node_modules/@remix-run/router/README.md create mode 100644 node_modules/@remix-run/router/dist/history.d.ts create mode 100644 node_modules/@remix-run/router/dist/index.d.ts create mode 100644 node_modules/@remix-run/router/dist/router.cjs.js create mode 100644 node_modules/@remix-run/router/dist/router.cjs.js.map create mode 100644 node_modules/@remix-run/router/dist/router.d.ts create mode 100644 node_modules/@remix-run/router/dist/router.js create mode 100644 node_modules/@remix-run/router/dist/router.js.map create mode 100644 node_modules/@remix-run/router/dist/router.umd.js create mode 100644 node_modules/@remix-run/router/dist/router.umd.js.map create mode 100644 node_modules/@remix-run/router/dist/router.umd.min.js create mode 100644 node_modules/@remix-run/router/dist/router.umd.min.js.map create mode 100644 node_modules/@remix-run/router/dist/utils.d.ts create mode 100644 node_modules/@remix-run/router/history.ts create mode 100644 node_modules/@remix-run/router/index.ts create mode 100644 node_modules/@remix-run/router/package.json create mode 100644 node_modules/@remix-run/router/router.ts create mode 100644 node_modules/@remix-run/router/utils.ts create mode 100644 node_modules/react-router-dom/CHANGELOG.md create mode 100644 node_modules/react-router-dom/LICENSE.md create mode 100644 node_modules/react-router-dom/README.md create mode 100644 node_modules/react-router-dom/dist/dom.d.ts create mode 100644 node_modules/react-router-dom/dist/index.d.ts create mode 100644 node_modules/react-router-dom/dist/index.js create mode 100644 node_modules/react-router-dom/dist/index.js.map create mode 100644 node_modules/react-router-dom/dist/main.js create mode 100644 node_modules/react-router-dom/dist/react-router-dom.development.js create mode 100644 node_modules/react-router-dom/dist/react-router-dom.development.js.map create mode 100644 node_modules/react-router-dom/dist/react-router-dom.production.min.js create mode 100644 node_modules/react-router-dom/dist/react-router-dom.production.min.js.map create mode 100644 node_modules/react-router-dom/dist/server.d.ts create mode 100644 node_modules/react-router-dom/dist/server.js create mode 100644 node_modules/react-router-dom/dist/server.mjs create mode 100644 node_modules/react-router-dom/dist/umd/react-router-dom.development.js create mode 100644 node_modules/react-router-dom/dist/umd/react-router-dom.development.js.map create mode 100644 node_modules/react-router-dom/dist/umd/react-router-dom.production.min.js create mode 100644 node_modules/react-router-dom/dist/umd/react-router-dom.production.min.js.map create mode 100644 node_modules/react-router-dom/package.json create mode 100644 node_modules/react-router-dom/server.d.ts create mode 100644 node_modules/react-router-dom/server.js create mode 100644 node_modules/react-router-dom/server.mjs create mode 100644 node_modules/react-router/CHANGELOG.md create mode 100644 node_modules/react-router/LICENSE.md create mode 100644 node_modules/react-router/README.md create mode 100644 node_modules/react-router/dist/index.d.ts create mode 100644 node_modules/react-router/dist/index.js create mode 100644 node_modules/react-router/dist/index.js.map create mode 100644 node_modules/react-router/dist/lib/components.d.ts create mode 100644 node_modules/react-router/dist/lib/context.d.ts create mode 100644 node_modules/react-router/dist/lib/hooks.d.ts create mode 100644 node_modules/react-router/dist/lib/use-sync-external-store-shim/index.d.ts create mode 100644 node_modules/react-router/dist/lib/use-sync-external-store-shim/useSyncExternalStoreShimClient.d.ts create mode 100644 node_modules/react-router/dist/lib/use-sync-external-store-shim/useSyncExternalStoreShimServer.d.ts create mode 100644 node_modules/react-router/dist/main.js create mode 100644 node_modules/react-router/dist/react-router.development.js create mode 100644 node_modules/react-router/dist/react-router.development.js.map create mode 100644 node_modules/react-router/dist/react-router.production.min.js create mode 100644 node_modules/react-router/dist/react-router.production.min.js.map create mode 100644 node_modules/react-router/dist/umd/react-router.development.js create mode 100644 node_modules/react-router/dist/umd/react-router.development.js.map create mode 100644 node_modules/react-router/dist/umd/react-router.production.min.js create mode 100644 node_modules/react-router/dist/umd/react-router.production.min.js.map create mode 100644 node_modules/react-router/package.json create mode 100644 package.json create mode 100644 yarn.lock diff --git a/desafio5/src/components/Body/Body.tsx b/desafio5/src/components/Body/Body.tsx index ab0eff0..4cf3a66 100644 --- a/desafio5/src/components/Body/Body.tsx +++ b/desafio5/src/components/Body/Body.tsx @@ -9,32 +9,33 @@ import TrocaEDevolucao from "./Tabs/TrocaEDevolucao"; import SegurancaEPrivacidade from "./Tabs/SegurancaEPrivacidade"; import Contato from "./Tabs/Contato"; import style from "./body.module.scss"; +import { Route, Routes } from "react-router"; const Body = () => { const TabsItems = [ { title: "Sobre", - component: , + path: "sobre", }, { title: "Forma de Pagamento", - component: , + path: "formadepagamento", }, { title: "Entrega", - component: , + path: "entrega", }, { title: "Troca e Devolução", - component: , + path: "trocaedevolucao", }, { title: "Segurança e Privacidade", - component: , + path: "segurancaeprivacidade", }, { title: "Contato", - component: , + path: "contato", }, ]; @@ -48,6 +49,20 @@ const Body = () => {

INSTITUCIONAL

+ +
+ + } /> + } /> + } /> + } /> + } + /> + } /> + +
); diff --git a/desafio5/src/components/Body/Tabs/TabLayout.tsx b/desafio5/src/components/Body/Tabs/TabLayout.tsx index ff16c6c..e9f551a 100644 --- a/desafio5/src/components/Body/Tabs/TabLayout.tsx +++ b/desafio5/src/components/Body/Tabs/TabLayout.tsx @@ -1,9 +1,10 @@ import React, { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; import style from "../body.module.scss"; interface MenuValue { title: string; - component: JSX.Element; + path: string; } export interface TabLayoutProps { @@ -23,19 +24,20 @@ const TabLayout: React.FC = ({ tabs }) => {
    {tabs.map((tab, index) => { return ( -
  • { - handleClick(tab); - }} - className={ - tabs.indexOf(selectedTab!) === index ? style["active"] : "" - }> - {tab.title} -
  • + +
  • { + handleClick(tab); + }} + className={ + tabs.indexOf(selectedTab!) === index ? style["active"] : "" + }> + {tab.title} +
  • + ); })}
-
{selectedTab?.component}
); }; diff --git a/desafio5/src/index.tsx b/desafio5/src/index.tsx index 0d2b7de..81dd693 100644 --- a/desafio5/src/index.tsx +++ b/desafio5/src/index.tsx @@ -1,14 +1,17 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { Home } from './pages/Home'; -import './style/index.css'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import { Home } from "./pages/Home"; +import "./style/index.css"; +import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement + document.getElementById("root") as HTMLElement ); root.render( - + + + ); diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity new file mode 100644 index 0000000..8d26f56 --- /dev/null +++ b/node_modules/.yarn-integrity @@ -0,0 +1,18 @@ +{ + "systemParams": "win32-x64-108", + "modulesFolders": [ + "node_modules" + ], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [ + "react-router-dom@^6.7.0" + ], + "lockfileEntries": { + "@remix-run/router@1.3.0": "https://registry.yarnpkg.com/@remix-run/router/-/router-1.3.0.tgz#b6ee542c7f087b73b3d8215b9bf799f648be71cb", + "react-router-dom@^6.7.0": "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.7.0.tgz#0249f4ca4eb704562b8b0ff29caeb928c3a6ed38", + "react-router@6.7.0": "https://registry.yarnpkg.com/react-router/-/react-router-6.7.0.tgz#db262684c13b5c2970694084ae9e8531718a0681" + }, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/node_modules/@remix-run/router/CHANGELOG.md b/node_modules/@remix-run/router/CHANGELOG.md new file mode 100644 index 0000000..dcd242a --- /dev/null +++ b/node_modules/@remix-run/router/CHANGELOG.md @@ -0,0 +1,156 @@ +# `@remix-run/router` + +## 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][rr-docs], especially the [feature overview][rr-feature-overview] and the [tutorial][rr-tutorial]. + +For an overview of the features provided by `@remix-run/router`, please check out the [`README`][remix-router-readme]. + +[rr-docs]: https://reactrouter.com +[rr-feature-overview]: https://reactrouter.com/start/overview +[rr-tutorial]: https://reactrouter.com/start/tutorial +[remix-router-readme]: https://github.com/remix-run/react-router/blob/main/packages/router/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 0000000..47c96cb --- /dev/null +++ b/node_modules/@remix-run/router/LICENSE.md @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) React Training 2015-2019 +Copyright (c) Remix Software 2020-2022 + +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 0000000..e0589a0 --- /dev/null +++ b/node_modules/@remix-run/router/README.md @@ -0,0 +1,107 @@ +# 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` or `react-router` packages, but you should have everything you need in either `react-router-dom` or `react-router-native`. Both of those packages re-export everything from `@remix-run/router` and `react-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({ + // Routes array + routes: , + // History instance + history, +}).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, +}); +``` + +### 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. + +[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 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 0000000..b38e3bc --- /dev/null +++ b/node_modules/@remix-run/router/dist/history.d.ts @@ -0,0 +1,249 @@ +/** + * 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: any; + /** + * 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; +} +/** + * 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`. May be either a URL or the pieces of a + * URL path. + */ +export declare 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 declare type InitialEntry = string | Partial; +export declare 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 declare 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 declare 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; +/** + * 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 declare 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 0000000..9bfcc37 --- /dev/null +++ b/node_modules/@remix-run/router/dist/index.d.ts @@ -0,0 +1,7 @@ +export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils"; +export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils"; +export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history"; +export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, invariant, parsePath, } from "./history"; +export * from "./router"; +/** @internal */ +export { DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, } from "./utils"; 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 0000000..7373cb5 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.cjs.js @@ -0,0 +1,4067 @@ +/** + * @remix-run/router v1.3.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. + */ +exports.Action = void 0; +/** + * The pathname, search, and hash values of a URL. + */ + +(function (Action) { + Action["Pop"] = "POP"; + Action["Push"] = "PUSH"; + Action["Replace"] = "REPLACE"; +})(exports.Action || (exports.Action = {})); + +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. + */ + +/** + * 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 = exports.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$1(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 = exports.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 = exports.Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 0 + }); + } + }, + + go(delta) { + action = exports.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)); + 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$1(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$1(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 = exports.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() { + let nextAction = exports.Action.Pop; + let nextIndex = getIndex(); + + if (nextIndex != null) { + let delta = nextIndex - index; + action = nextAction; + index = nextIndex; + + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } else { + warning$1(false, // TODO: Write up a doc that explains our blocking strategy in detail + // and link to it here so people can understand better what is going on + // and how to avoid it. + "You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation."); + } + } + + function push(to, state) { + action = exports.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) { + // 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 = exports.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); + 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; +/** + * Successful result from a loader or action + */ + +(function (ResultType) { + ResultType["data"] = "data"; + ResultType["deferred"] = "deferred"; + ResultType["redirect"] = "redirect"; + ResultType["error"] = "error"; +})(ResultType || (ResultType = {})); + +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, parentPath, allIds) { + if (parentPath === void 0) { + parentPath = []; + } + + if (allIds === void 0) { + allIds = new Set(); + } + + return routes.map((route, index) => { + let treePath = [...parentPath, 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(!allIds.has(id), "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + allIds.add(id); + + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, { + id + }); + + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, { + id, + children: route.children ? convertRoutesToDataRoutes(route.children, treePath, allIds) : undefined + }); + + 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 = "/"; + } + + 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) { + matches = matchRouteBranch(branches[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. + safelyDecodeURI(pathname)); + } + + return matches; +} + +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 explodes _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) { + 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); + if (!match) return null; + Object.assign(matchedParams, match.params); + let route = meta.route; + 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(/\*$/, "/*"); + } + + return path.replace(/^:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return param; + }).replace(/\/:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : "/" + param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return "/" + param; + }) // Remove any optional markers from optional static segments + .replace(/\?/g, "").replace(/(\/?)\*/, (_, prefix, __, str) => { + const star = "*"; + + if (params[star] == null) { + // If no splat was provided, trim the trailing slash _unless_ it's + // the entire path + return str === "/*" ? "/" : ""; + } // Apply the splat + + + return "" + prefix + params[star]; + }); +} +/** + * A PathPattern is used to match on some portion of 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, paramNames] = 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 = paramNames.reduce((memo, paramName, 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"); + } + + memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName); + 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 paramNames = []; + 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) => { + paramNames.push(paramName); + return "/([^\\/]+)"; + }); + + if (path.endsWith("*")) { + paramNames.push("*"); + 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, paramNames]; +} + +function safelyDecodeURI(value) { + try { + return decodeURI(value); + } 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; + } +} + +function safelyDecodeURIComponent(value, paramName) { + try { + return decodeURIComponent(value); + } catch (error) { + warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" 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) || "/"; +} +/** + * @private + */ + +function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + + try { + // Welcome to debugging @remix-run/router! + // + // 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) {} + } +} +/** + * 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); +} +/** + * @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 (isPathRelative || toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + if (toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); // 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". + + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + + to.pathname = toSegments.join("/"); + } // If there are more ".." segments than parent routes, resolve relative to + // the root / URL. + + + 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, _ref) => { + let [key, value] = _ref; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + 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, null, 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 (error) { + 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, _ref2) => { + let [key, value] = _ref2; + 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 + })); +}; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + */ + +class ErrorResponse { + 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 throw from an action/loader + */ + +function isRouteErrorResponse(e) { + return e instanceof ErrorResponse; +} + +//#region Types and Constants +//////////////////////////////////////////////////////////////////////////////// + +/** + * A Router instance manages all navigation and data loading/mutations + */ + +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 +}; +const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined +}; +const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined +}; +const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; +const isServer = !isBrowser; //#endregion +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a router and listen to history POP navigations + */ + +function createRouter(init) { + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let dataRoutes = convertRoutesToDataRoutes(init.routes); // 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, init.basename); + let initialErrors = null; + + if (initialMatches == null) { + // 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 + }; + } + + let initialized = !initialMatches.some(m => m.route.loader) || 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 = exports.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; // 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) + // - useRevalidate() + // - 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 from their actions + + let fetchRedirectIds = new Set(); // Most recent href/match for fetcher.load calls for fetchers + + let fetchLoadMatches = new Map(); // 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(); // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + + let activeBlocker = null; // 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(); // 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; + } + + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + + if (blockerKey) { + // 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(router.state.blockers) + }); + } + + }); + return; + } + + return startNavigation(historyAction, location); + }); // Kick off initial data load if needed. Use Pop to avoid modifying history + + if (!state.initialized) { + startNavigation(exports.Action.Pop, state.location); + } + + return router; + } // Clean up a router and it's side effects + + + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + + 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) { + state = _extends({}, state, newState); + subscribers.forEach(subscriber => subscriber(state)); + } // 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) { + var _location$state, _location$state2; + + // 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 + + for (let [key] of blockerFunctions) { + deleteBlocker(key); + } // 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; + 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: new Map(state.blockers) + })); + + if (isUninterruptedRevalidation) ; else if (pendingAction === exports.Action.Pop) ; else if (pendingAction === exports.Action.Push) { + init.history.push(location, location.state); + } else if (pendingAction === exports.Action.Replace) { + init.history.replace(location, location.state); + } // Reset stateful navigation vars + + + pendingAction = exports.Action.Pop; + pendingPreventScrollReset = 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 { + path, + submission, + error + } = normalizeNavigateOptions(to, 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 = exports.Action.Push; + + if (userReplace === true) { + historyAction = exports.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 = exports.Action.Replace; + } + + let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined; + 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(state.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 + }); + } // 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; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(dataRoutes, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing + + if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); // Cancel all pending deferred on 404s since we don't keep any routes + + cancelActiveDeferreds(); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }); + return; + } // Short circuit if it's only a hash change + + + if (isHashChangeOnly(state.location, location)) { + completeNavigation(location, { + matches + }); + return; + } // Create a controller/Request for this navigation + + + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionData; + let pendingError; + + 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. + pendingError = { + [findNearestBoundary(matches).route.id]: opts.pendingError + }; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionOutput = await handleAction(request, location, opts.submission, matches, { + replace: opts.replace + }); + + if (actionOutput.shortCircuited) { + return; + } + + pendingActionData = actionOutput.pendingActionData; + pendingError = actionOutput.pendingActionError; + + let navigation = _extends({ + state: "loading", + location + }, opts.submission); + + loadingNavigation = navigation; // Create a GET request for the loaders + + request = new Request(request.url, { + signal: request.signal + }); + } // Call loaders + + + let { + shortCircuited, + loaderData, + errors + } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.replace, pendingActionData, pendingError); + + 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 + }, pendingActionData ? { + actionData: pendingActionData + } : {}, { + loaderData, + errors + })); + } // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + + + async function handleAction(request, location, submission, matches, opts) { + interruptActiveLoads(); // Put us in a submitting state + + let navigation = _extends({ + state: "submitting", + location + }, submission); + + updateState({ + navigation + }); // Call our action and get the result + + let result; + let actionMatch = getTargetMatch(matches, location); + + if (!actionMatch.route.action) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + result = await callLoaderOrAction("action", request, actionMatch, matches, router.basename); + + 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 + replace = result.location === state.location.pathname + state.location.search; + } + + await startRedirectNavigation(state, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + + 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 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 = exports.Action.Push; + } + + return { + // Send back an empty object we can use to clear out any prior actionData + pendingActionData: {}, + pendingActionError: { + [boundaryMatch.route.id]: result.error + } + }; + } + + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + + return { + pendingActionData: { + [actionMatch.route.id]: result.data + } + }; + } // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + + + async function handleLoaders(request, location, matches, overrideNavigation, submission, replace, pendingActionData, pendingError) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation; + + if (!loadingNavigation) { + let navigation = _extends({ + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission); + + loadingNavigation = navigation; + } // 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 ? submission : loadingNavigation.formMethod && loadingNavigation.formAction && loadingNavigation.formData && loadingNavigation.formEncType ? { + formMethod: loadingNavigation.formMethod, + formAction: loadingNavigation.formAction, + formData: loadingNavigation.formData, + formEncType: loadingNavigation.formEncType + } : undefined; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // 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)); // Short circuit if we have no loaders to run + + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingError || null + }, pendingActionData ? { + actionData: pendingActionData + } : {})); + return { + shortCircuited: true + }; + } // 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 (!isUninterruptedRevalidation) { + revalidatingFetchers.forEach(_ref2 => { + let [key] = _ref2; + let fetcher = state.fetchers.get(key); + let revalidatingFetcher = { + state: "loading", + data: fetcher && fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, revalidatingFetcher); + }); + let actionData = pendingActionData || state.actionData; + updateState(_extends({ + navigation: loadingNavigation + }, actionData ? Object.keys(actionData).length === 0 ? { + actionData: null + } : { + actionData + } : {}, revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {})); + } + + pendingNavigationLoadId = ++incrementingLoadId; + revalidatingFetchers.forEach(_ref3 => { + let [key] = _ref3; + return fetchControllers.set(key, pendingNavigationController); + }); + let { + results, + 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 + + + revalidatingFetchers.forEach(_ref4 => { + let [key] = _ref4; + return fetchControllers.delete(key); + }); // If any loaders returned a redirect Response, start a new REPLACE navigation + + let redirect = findRedirect(results); + + if (redirect) { + await startRedirectNavigation(state, redirect, { + replace + }); + return { + shortCircuited: true + }; + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingError, 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); + } + }); + }); + markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + return _extends({ + loaderData, + errors + }, didAbortFetchLoads || revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {}); + } + + function getFetcher(key) { + return state.fetchers.get(key) || IDLE_FETCHER; + } // 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 matches = matchRoutes(dataRoutes, href, init.basename); + + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: href + })); + return; + } + + let { + path, + submission + } = normalizeNavigateOptions(href, opts, true); + let match = getTargetMatch(matches, path); + + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, submission); + return; + } // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + + + fetchLoadMatches.set(key, [path, match, matches]); + handleFetcherLoader(key, routeId, path, match, matches, submission); + } // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + + + async function handleFetcherAction(key, routeId, path, match, requestMatches, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + + if (!match.route.action) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error); + return; + } // Put this fetcher into it's submitting state + + + let existingFetcher = state.fetchers.get(key); + + let fetcher = _extends({ + state: "submitting" + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the action for the fetcher + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + fetchControllers.set(key, abortController); + let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename); + + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by ou our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + + return; + } + + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + fetchRedirectIds.add(key); + + let loadingFetcher = _extends({ + state: "loading" + }, submission, { + data: undefined, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + return startRedirectNavigation(state, actionResult, { + isFetchActionRedirect: true + }); + } // 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 matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + + let loadFetcher = _extends({ + state: "loading", + data: actionResult.data + }, submission, { + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, { + [match.route.id]: actionResult.data + }, undefined, // No need to send through errors since we short circuit above + fetchLoadMatches); // 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(_ref5 => { + let [staleKey] = _ref5; + return staleKey !== key; + }).forEach(_ref6 => { + let [staleKey] = _ref6; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = { + state: "loading", + data: existingFetcher && existingFetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(staleKey, revalidatingFetcher); + fetchControllers.set(staleKey, abortController); + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let { + results, + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + + if (abortController.signal.aborted) { + return; + } + + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(_ref7 => { + let [staleKey] = _ref7; + return fetchControllers.delete(staleKey); + }); + let redirect = findRedirect(results); + + if (redirect) { + return startRedirectNavigation(state, redirect); + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + let doneFetcher = { + state: "idle", + data: actionResult.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + let didAbortFetchLoads = 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(_extends({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors) + }, didAbortFetchLoads ? { + 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, submission) { + let existingFetcher = state.fetchers.get(key); // Put this fetcher into it's loading state + + let loadingFetcher = _extends({ + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the loader for this fetcher route match + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + fetchControllers.set(key, abortController); + let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // 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 ou 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; + } // If the loader threw a redirect Response, start a new REPLACE navigation + + + if (isRedirectResult(result)) { + await startRedirectNavigation(state, result); + return; + } // Process any non-redirect errors thrown + + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + state.fetchers.delete(key); // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch - + // do we need to behave any differently with our non-redirect errors? + // What if it was a non-redirect Response? + + updateState({ + fetchers: new Map(state.fetchers), + errors: { + [boundaryMatch.route.id]: result.error + } + }); + return; + } + + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); // Put the fetcher back into an idle state + + let doneFetcher = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + } + /** + * 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(state, redirect, _temp) { + var _window; + + let { + submission, + replace, + isFetchActionRedirect + } = _temp === void 0 ? {} : _temp; + + if (redirect.revalidate) { + isRevalidationRequired = true; + } + + let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2 + _extends({ + _isRedirect: true + }, isFetchActionRedirect ? { + _isFetchActionRedirect: true + } : {})); + invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin + + if (isBrowser && typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") { + let newOrigin = init.history.createURL(redirect.location).origin; + + if (window.location.origin !== newOrigin) { + if (replace) { + window.location.replace(redirect.location); + } else { + window.location.assign(redirect.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 ? exports.Action.Replace : exports.Action.Push; // Use the incoming submission if provided, fallback on the active one in + // state.navigation + + let { + formMethod, + formAction, + formEncType, + formData + } = state.navigation; + + if (!submission && formMethod && formAction && formData && formEncType) { + submission = { + formMethod, + formAction, + formEncType, + formData + }; + } // 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 + + + if (redirectPreserveMethodStatusCodes.has(redirect.status) && submission && isMutationMethod(submission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, submission, { + formAction: redirect.location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // Otherwise, we kick off a new loading navigation, preserving the + // submission info for the duration of this navigation + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation: { + state: "loading", + location: redirectLocation, + formMethod: submission ? submission.formMethod : undefined, + formAction: submission ? submission.formAction : undefined, + formEncType: submission ? submission.formEncType : undefined, + formData: submission ? submission.formData : undefined + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + // Call all navigation loaders and revalidating fetcher loaders in parallel, + // then slice off the results into separate arrays so we can handle them + // accordingly + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => { + let [, href, match, fetchMatches] = _ref8; + return callLoaderOrAction("loader", createClientSideRequest(init.history, href, request.signal), match, fetchMatches, router.basename); + })]); + let loaderResults = results.slice(0, matchesToLoad.length); + let fetcherResults = results.slice(matchesToLoad.length); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(_ref9 => { + let [,, match] = _ref9; + return match; + }), fetcherResults, request.signal, true)]); + return { + results, + 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 setFetcherError(key, routeId, error) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }); + } + + function deleteFetcher(key) { + if (fetchControllers.has(key)) abortFetcher(key); + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + state.fetchers.delete(key); + } + + 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 = { + state: "idle", + data: fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + } + } + + function markFetchRedirectsDone() { + let doneKeys = []; + + 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); + } + } + + markFetchersDone(doneKeys); + } + + 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); + + if (activeBlocker == null) { + // This is now the active blocker + activeBlocker = key; + } else if (key !== activeBlocker) { + warning(false, "A router only supports one blocker at a time"); + } + } + + return blocker; + } + + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + + if (activeBlocker === key) { + activeBlocker = null; + } + } // 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); + state.blockers.set(key, newBlocker); + updateState({ + blockers: new Map(state.blockers) + }); + } + + function shouldBlockNavigation(_ref10) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref10; + + if (activeBlocker == null) { + return; + } // We only allow a single blocker at the moment. This will need to be + // updated if we enhance to support multiple blockers in the future + + + let blockerFunction = blockerFunctions.get(activeBlocker); + invariant(blockerFunction, "Could not find a function for the active blocker"); + let blocker = state.blockers.get(activeBlocker); + + 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 activeBlocker; + } + } + + 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 || (location => location.key); // 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 saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + savedScrollPositions[key] = getScrollPosition(); + } + } + + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + let y = savedScrollPositions[key]; + + if (typeof y === "number") { + return y; + } + } + + return null; + } + + router = { + get basename() { + return init.basename; + }, + + get state() { + return state; + }, + + get routes() { + return dataRoutes; + }, + + 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, + dispose, + getBlocker, + deleteBlocker, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds + }; + 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 dataRoutes = convertRoutesToDataRoutes(routes); + let basename = (opts ? opts.basename : null) || "/"; + /** + * 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. + */ + + async function query(request, _temp2) { + let { + requestContext + } = _temp2 === void 0 ? {} : _temp2; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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); + + 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. + */ + + + async function queryRoute(request, _temp3) { + let { + routeId, + requestContext + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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, 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, 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, routeMatch != null); + return result; + } + + let result = await loadRouteData(request, matches, requestContext, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction, we throw + // it to bail out and then return or throw here based on whether the user + // returned or threw + if (isQueryRouteResponse(e)) { + if (e.type === ResultType.error && !isRedirectResponse(e.response)) { + throw e.response; + } + + return e.response; + } // 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, isRouteRequest) { + let result; + + if (!actionMatch.route.action) { + 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 { + result = await callLoaderOrAction("action", request, actionMatch, matches, basename, true, isRouteRequest, requestContext); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } + } + + 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.status, + headers: { + Location: result.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 + }; + } + + 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); + let context = await loadRouteData(request, matches, requestContext, undefined, { + [boundaryMatch.route.id]: result.error + }); // action status codes take precedence over loader status codes + + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } // Create a GET request for the loaders + + + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + let context = await loadRouteData(loaderRequest, matches, requestContext); + return _extends({}, context, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionData: { + [actionMatch.route.id]: result.data + }, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + + async function loadRouteData(request, matches, requestContext, routeMatch, pendingActionError) { + let isRouteRequest = routeMatch != null; // Short circuit if we have no loaders to run (queryRoute()) + + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + + let requestMatches = routeMatch ? [routeMatch] : getLoaderMatchesUntilBoundary(matches, Object.keys(pendingActionError || {})[0]); + let matchesToLoad = requestMatches.filter(m => m.route.loader); // 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: pendingActionError || null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, basename, true, isRouteRequest, requestContext))]); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } // Process and commit output from loaders + + + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError, activeDeferreds); // 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 + }); + } + + 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: 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + + return newContext; +} + +function isSubmissionNavigation(opts) { + return opts != null && "formData" in opts; +} // Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params + + +function normalizeNavigateOptions(to, opts, isFetcher) { + if (isFetcher === void 0) { + isFetcher = false; + } + + let path = typeof to === "string" ? to : createPath(to); // 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 + }) + }; + } // Create a Submission on non-GET navigations + + + let submission; + + if (opts.formData) { + submission = { + formMethod: opts.formMethod || "get", + formAction: stripHashFromPath(path), + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData: opts.formData + }; + + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + } // Flatten submission onto URLSearchParams for GET submissions + + + let parsedPath = parsePath(path); + + try { + let searchParams = convertFormDataToSearchParams(opts.formData); // Since fetcher GET submissions only run a single loader (as opposed to + // navigation GET submissions which run all loaders), we need to preserve + // any incoming ?index params + + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + + parsedPath.search = "?" + searchParams; + } catch (e) { + return { + path, + error: getInternalRouterError(400) + }; + } + + 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, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) { + let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation + + let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined; + let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId); + let navigationMatches = boundaryMatches.filter((match, index) => match.route.loader != null && (isNewLoader(state.loaderData, state.matches[index], match) || // If this route had a pending deferred cancelled it must be revalidated + cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated + + let revalidatingFetchers = []; + fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => { + let [href, match, fetchMatches] = _ref11; + + // This fetcher was cancelled from a prior action submission - force reload + if (cancelledFetcherLoads.includes(key)) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } else if (isRevalidationRequired) { + let shouldRevalidate = shouldRevalidateLoader(history, href, match, submission, href, match, isRevalidationRequired, actionResult); + + if (shouldRevalidate) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } + } + }); + 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 && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); +} + +function shouldRevalidateLoader(history, currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) { + let currentUrl = history.createURL(currentLocation); + let currentParams = currentMatch.params; + let nextUrl = history.createURL(location); + let nextParams = match.params; // This is the default implementation as to 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 + // Note that fetchers always provide the same current/next locations so the + // URL-based checks here don't apply to fetcher shouldRevalidate calls + + let defaultShouldRevalidate = isNewRouteInstance(currentMatch, match) || // Clicked the same link, resubmitted a GET form + currentUrl.toString() === nextUrl.toString() || // Search params affect all loaders + currentUrl.search !== nextUrl.search || // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate + isRevalidationRequired; + + if (match.route.shouldRevalidate) { + let routeChoice = match.route.shouldRevalidate(_extends({ + currentUrl, + currentParams, + nextUrl, + nextParams + }, submission, { + actionResult, + defaultShouldRevalidate + })); + + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + + return defaultShouldRevalidate; +} + +async function callLoaderOrAction(type, request, match, matches, basename, isStaticRequest, isRouteRequest, requestContext) { + if (basename === void 0) { + basename = "/"; + } + + if (isStaticRequest === void 0) { + isStaticRequest = false; + } + + if (isRouteRequest === void 0) { + isRouteRequest = false; + } + + let resultType; + let result; // Setup a promise we can race against so that abort signals short circuit + + let reject; + let abortPromise = new Promise((_, r) => reject = r); + + let onReject = () => reject(); + + request.signal.addEventListener("abort", onReject); + + try { + let handler = match.route[type]; + invariant(handler, "Could not find the " + type + " to run on the \"" + match.route.id + "\" route"); + result = await Promise.race([handler({ + request, + params: match.params, + context: requestContext + }), abortPromise]); + invariant(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) { + resultType = ResultType.error; + result = e; + } finally { + request.signal.removeEventListener("abort", onReject); + } + + if (isResponse(result)) { + let status = result.status; // Process redirects + + if (redirectStatusCodes.has(status)) { + let location = result.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location); // Support relative routing in internal redirects + + if (!isAbsolute) { + let activeMatches = matches.slice(0, matches.indexOf(match) + 1); + let routePathnames = getPathContributingMatches(activeMatches).map(match => match.pathnameBase); + let resolvedLocation = resolveTo(location, routePathnames, new URL(request.url).pathname); + invariant(createPath(resolvedLocation), "Unable to resolve redirect location: " + location); // Prepend the basename to the redirect location if we have one + + if (basename) { + let path = resolvedLocation.pathname; + resolvedLocation.pathname = path === "/" ? basename : joinPaths([basename, path]); + } + + location = createPath(resolvedLocation); + } else if (!isStaticRequest) { + // Strip off the protocol+origin for same-origin absolute redirects. + // If this is a static reques, we can let it go back to the browser + // as-is + let currentUrl = new URL(request.url); + let url = location.startsWith("//") ? new URL(currentUrl.protocol + location) : new URL(location); + + if (url.origin === currentUrl.origin) { + location = url.pathname + url.search + url.hash; + } + } // Don't process redirects in the router during static requests requests. + // Instead, throw the Response and let the server handle it with an HTTP + // redirect. We also update the Location header in place in this flow so + // basename and relative routing is taken into account + + + if (isStaticRequest) { + result.headers.set("Location", location); + throw result; + } + + return { + type: ResultType.redirect, + status, + location, + revalidate: result.headers.get("X-Remix-Revalidate") !== null + }; + } // For SSR single-route requests, we want to hand Responses back directly + // without unwrapping. We do this with the QueryRouteResponse wrapper + // interface so we can know whether it was returned or thrown + + + if (isRouteRequest) { + // eslint-disable-next-line no-throw-literal + throw { + type: resultType || ResultType.data, + response: result + }; + } + + let data; + 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)) { + data = await result.json(); + } else { + data = await result.text(); + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: new ErrorResponse(status, result.statusText, data), + headers: result.headers + }; + } + + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: result + }; + } + + if (result instanceof DeferredData) { + return { + type: ResultType.deferred, + deferredData: result + }; + } + + return { + type: ResultType.data, + data: result + }; +} // 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, + formData + } = submission; + init.method = formMethod.toUpperCase(); + init.body = formEncType === "application/x-www-form-urlencoded" ? convertFormDataToSearchParams(formData) : formData; + } // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + + + return new Request(url, init); +} + +function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + + for (let [key, value] of formData.entries()) { + invariant(typeof value === "string", 'File inputs are not supported with encType "application/x-www-form-urlencoded", ' + 'please use "multipart/form-data" instead.'); + searchParams.append(key, value); + } + + return searchParams; +} + +function processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; // 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)) { + // Look upwards from the matched route for the closest ancestor + // error boundary, defaulting to the root match + let boundaryMatch = findNearestBoundary(matches, id); + 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) { + error = Object.values(pendingError)[0]; + pendingError = undefined; + } + + errors = errors || {}; // Prefer higher error values if lower errors bubble to the same boundary + + 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; + } 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 != null && 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) { + errors = pendingError; + loaderData[Object.keys(pendingError)[0]] = undefined; + } + + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; +} + +function processLoaderData(state, matches, matchesToLoad, results, pendingError, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds); // Process results from our revalidating fetchers + + for (let index = 0; index < revalidatingFetchers.length; index++) { + let [key,, match] = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; // Process fetcher non-redirect errors + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, 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 = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + 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) { + mergedLoaderData[id] = loaderData[id]; + } + + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + + return mergedLoaderData; +} // 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.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; +} + +function getInternalRouterError(status, _temp4) { + let { + pathname, + routeId, + method, + type + } = _temp4 === void 0 ? {} : _temp4; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + + if (status === 400) { + statusText = "Bad Request"; + + 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 { + errorMessage = "Cannot submit binary form data using GET"; + } + } 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 ErrorResponse(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; + } + } +} + +function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); +} + +function isHashChangeOnly(a, b) { + return a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash; +} + +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 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 isQueryRouteResponse(obj) { + return obj && isResponse(obj.response) && (obj.type === ResultType.data || ResultType.error); +} + +function isValidMethod(method) { + return validRequestMethods.has(method); +} + +function isMutationMethod(method) { + return validMutationMethods.has(method); +} + +async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + 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 + 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 === ""); +} // Note: This should match the format exported by useMatches, so if you change +// this please also change that :) Eventually we'll DRY this up + + +function createUseMatchesMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; +} + +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]; +} //#endregion + +exports.AbortedDeferredError = AbortedDeferredError; +exports.ErrorResponse = ErrorResponse; +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_convertRoutesToDataRoutes = convertRoutesToDataRoutes; +exports.UNSAFE_getPathContributingMatches = getPathContributingMatches; +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.invariant = invariant; +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.resolvePath = resolvePath; +exports.resolveTo = resolveTo; +exports.stripBasename = stripBasename; +exports.warning = warning; +//# 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 0000000..e111850 --- /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/**\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: any;\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;\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`. May be either a URL or the pieces of a\n * 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 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\nfunction 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 let nextAction = Action.Pop;\n let nextIndex = getIndex();\n\n if (nextIndex != null) {\n let delta = nextIndex - index;\n action = nextAction;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n } else {\n warning(\n false,\n // TODO: Write up a doc that explains our blocking strategy in detail\n // and link to it here so people can understand better what is going on\n // and how to avoid it.\n `You are trying to block a POP navigation to a location that was not ` +\n `created by @remix-run/router. The block will fail silently in ` +\n `production, but in general you should do all navigation with the ` +\n `router (instead of using window.history.pushState directly) ` +\n `to avoid this situation.`\n );\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 // 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 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 } 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: any;\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 status: number;\n location: string;\n revalidate: boolean;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: any;\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\nexport type MutationFormMethod = \"post\" | \"put\" | \"patch\" | \"delete\";\nexport type FormMethod = \"get\" | MutationFormMethod;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\";\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport interface Submission {\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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?: any;\n}\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Route loader function signature\n */\nexport interface LoaderFunction {\n (args: LoaderFunctionArgs): Promise | Response | Promise | any;\n}\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (args: ActionFunctionArgs): Promise | Response | Promise | any;\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: {\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 formData?: Submission[\"formData\"];\n actionResult?: DataResult;\n defaultShouldRevalidate: boolean;\n }): boolean;\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;\n action?: ActionFunction;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\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\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 */\ntype 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 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 parentPath: number[] = [],\n allIds: Set = new Set()\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, 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 !allIds.has(id),\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n allIds.add(id);\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = { ...route, id };\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n id,\n children: route.children\n ? convertRoutesToDataRoutes(route.children, treePath, allIds)\n : undefined,\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 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 matches = matchRouteBranch(\n branches[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 safelyDecodeURI(pathname)\n );\n }\n\n return matches;\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\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 explodes _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): 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 if (!match) return null;\n\n Object.assign(matchedParams, match.params);\n\n let route = meta.route;\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 = 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 return (\n path\n .replace(\n /^:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : param;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return param;\n }\n )\n .replace(\n /\\/:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : `/${param}`;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return `/${param}`;\n }\n )\n // Remove any optional markers from optional static segments\n .replace(/\\?/g, \"\")\n .replace(/(\\/?)\\*/, (_, prefix, __, str) => {\n const star = \"*\" as PathParam;\n\n if (params[star] == null) {\n // If no splat was provided, trim the trailing slash _unless_ it's\n // the entire path\n return str === \"/*\" ? \"/\" : \"\";\n }\n\n // Apply the splat\n return `${prefix}${params[star]}`;\n })\n );\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, paramNames] = 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 = paramNames.reduce>(\n (memo, paramName, 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 memo[paramName] = safelyDecodeURIComponent(\n captureGroups[index] || \"\",\n paramName\n );\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, string[]] {\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 paramNames: string[] = [];\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(/\\/:(\\w+)/g, (_: string, paramName: string) => {\n paramNames.push(paramName);\n return \"/([^\\\\/]+)\";\n });\n\n if (path.endsWith(\"*\")) {\n paramNames.push(\"*\");\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, paramNames];\n}\n\nfunction safelyDecodeURI(value: string) {\n try {\n return decodeURI(value);\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\nfunction safelyDecodeURIComponent(value: string, paramName: string) {\n try {\n return decodeURIComponent(value);\n } catch (error) {\n warning(\n false,\n `The value for the URL param \"${paramName}\" will not be decoded because` +\n ` the string \"${value}\" is a malformed URL segment. This is probably` +\n ` due to a bad percent 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 * @private\n */\nexport function warning(cond: any, message: string): void {\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 @remix-run/router!\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\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/**\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 (isPathRelative || toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n if (toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n // Each leading .. segment means \"go up one route\" instead of \"go up one\n // URL segment\". This is a key difference from how works and a\n // major reason we call this a \"to\" value instead of a \"href\".\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n // If there are more \"..\" segments than parent routes, resolve relative to\n // the root / URL.\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 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, null, 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 (error) {\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 * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n */\nexport class ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n error?: Error;\n 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 throw from an action/loader\n */\nexport function isRouteErrorResponse(e: any): e is ErrorResponse {\n return e instanceof ErrorResponse;\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n} from \"./history\";\nimport type {\n DataResult,\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DeferredResult,\n ErrorResult,\n FormEncType,\n FormMethod,\n RedirectResult,\n RouteData,\n AgnosticRouteObject,\n Submission,\n SuccessResult,\n AgnosticRouteMatch,\n MutationFormMethod,\n} from \"./utils\";\nimport {\n DeferredData,\n ErrorResponse,\n ResultType,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n resolveTo,\n warning,\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 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 * 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, 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,\n opts?: RouterNavigateOptions\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 * 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 * Initialization options for createRouter\n */\nexport interface RouterInit {\n basename?: string;\n routes: AgnosticRouteObject[];\n history: History;\n hydrationData?: HydrationState;\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?: { requestContext?: unknown }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: { routeId?: string; requestContext?: unknown }\n ): Promise;\n}\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (state: RouterState): void;\n}\n\ninterface UseMatchesMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: unknown;\n handle: unknown;\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: UseMatchesMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\n/**\n * Options for a navigate() call for a Link navigation\n */\ntype LinkNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n};\n\n/**\n * Options for a navigate() call for a Form navigation\n */\ntype SubmissionNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n formMethod?: FormMethod;\n formEncType?: FormEncType;\n formData: FormData;\n};\n\n/**\n * Options to pass to navigate() for either a Link or Form navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions =\n | Omit\n | Omit;\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 };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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 formData: undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Loading: {\n state: \"loading\";\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\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\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Error thrown from the current action, keyed by the route containing the\n * error boundary to render the error. To be committed to the state after\n * loaders have completed\n */\n pendingActionError?: RouteData;\n /**\n * Data returned from the current action, keyed by the route owning the action.\n * To be committed to the state after loaders have completed\n */\n pendingActionData?: RouteData;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\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 * Tuple of [key, href, DataRouteMatch, DataRouteMatch[]] for a revalidating\n * fetcher.load()\n */\ntype RevalidatingFetcher = [\n string,\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Tuple of [href, DataRouteMatch, DataRouteMatch[]] for an active\n * fetcher.load()\n */\ntype FetchLoadMatch = [\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Wrapper object to allow us to throw any response out from callLoaderOrAction\n * for queryRouter while preserving whether or not it was thrown or returned\n * from the loader/action\n */\ninterface QueryRouteResponse {\n type: ResultType.data | ResultType.error;\n response: Response;\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};\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};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n typeof window.document !== \"undefined\" &&\n typeof window.document.createElement !== \"undefined\";\nconst isServer = !isBrowser;\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 invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(init.routes);\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(\n dataRoutes,\n init.history.location,\n init.basename\n );\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null) {\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 let initialized =\n !initialMatches.some((m) => m.route.loader) || init.hydrationData != null;\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 // 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 // - useRevalidate()\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 from their actions\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\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 // 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 let activeBlocker: string | null = null;\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 // 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 let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n if (blockerKey) {\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(router.state.blockers) });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location);\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 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(newState: Partial): void {\n state = {\n ...state,\n ...newState,\n };\n subscribers.forEach((subscriber) => subscriber(state));\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 ): 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 for (let [key] of blockerFunctions) {\n deleteBlocker(key);\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 updateState({\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: new Map(state.blockers),\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 // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = 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,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(to, opts);\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 blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(state.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 });\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 submission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponse;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: 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 let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(dataRoutes, location, init.basename);\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n });\n return;\n }\n\n // Short circuit if it's only a hash change\n if (isHashChangeOnly(state.location, location)) {\n completeNavigation(location, { matches });\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 pendingActionData: RouteData | undefined;\n let pendingError: RouteData | 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 pendingError = {\n [findNearestBoundary(matches).route.id]: 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 actionOutput = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n { replace: opts.replace }\n );\n\n if (actionOutput.shortCircuited) {\n return;\n }\n\n pendingActionData = actionOutput.pendingActionData;\n pendingError = actionOutput.pendingActionError;\n\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n ...opts.submission,\n };\n loadingNavigation = navigation;\n\n // Create a GET request for the loaders\n request = new Request(request.url, { signal: request.signal });\n }\n\n // Call loaders\n let { shortCircuited, loaderData, errors } = await handleLoaders(\n request,\n location,\n matches,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.replace,\n pendingActionData,\n pendingError\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,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\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 opts?: { replace?: boolean }\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n ...submission,\n };\n updateState({ navigation });\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) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n router.basename\n );\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 replace =\n result.location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(state, result, { submission, replace });\n return { shortCircuited: true };\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 are REPLACE navigations, but if the\n // action threw an error that'll be rendered in an errorElement, we fall\n // back to PUSH so that the user can use the back button to get back to\n // the pre-submission form location to try again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n // Send back an empty object we can use to clear out any prior actionData\n pendingActionData: {},\n pendingActionError: { [boundaryMatch.route.id]: result.error },\n };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n return {\n pendingActionData: { [actionMatch.route.id]: result.data },\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 overrideNavigation?: Navigation,\n submission?: Submission,\n replace?: boolean,\n pendingActionData?: RouteData,\n pendingError?: RouteData\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation;\n if (!loadingNavigation) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n };\n loadingNavigation = navigation;\n }\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 = submission\n ? submission\n : loadingNavigation.formMethod &&\n loadingNavigation.formAction &&\n loadingNavigation.formData &&\n loadingNavigation.formEncType\n ? {\n formMethod: loadingNavigation.formMethod,\n formAction: loadingNavigation.formAction,\n formData: loadingNavigation.formData,\n formEncType: loadingNavigation.formEncType,\n }\n : undefined;\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n pendingActionData,\n pendingError,\n fetchLoadMatches\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 // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n completeNavigation(location, {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingError || null,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\n });\n return { shortCircuited: true };\n }\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 (!isUninterruptedRevalidation) {\n revalidatingFetchers.forEach(([key]) => {\n let fetcher = state.fetchers.get(key);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: fetcher && fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, revalidatingFetcher);\n });\n let actionData = pendingActionData || state.actionData;\n updateState({\n navigation: loadingNavigation,\n ...(actionData\n ? Object.keys(actionData).length === 0\n ? { actionData: null }\n : { actionData }\n : {}),\n ...(revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n });\n }\n\n pendingNavigationLoadId = ++incrementingLoadId;\n revalidatingFetchers.forEach(([key]) =>\n fetchControllers.set(key, pendingNavigationController!)\n );\n\n let { results, 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 revalidatingFetchers.forEach(([key]) => fetchControllers.delete(key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(results);\n if (redirect) {\n await startRedirectNavigation(state, redirect, { replace });\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 pendingError,\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 markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n\n return {\n loaderData,\n errors,\n ...(didAbortFetchLoads || revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n };\n }\n\n function getFetcher(key: string): Fetcher {\n return state.fetchers.get(key) || IDLE_FETCHER;\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,\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\n let matches = matchRoutes(dataRoutes, href, init.basename);\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: href })\n );\n return;\n }\n\n let { path, submission } = normalizeNavigateOptions(href, opts, true);\n let match = getTargetMatch(matches, path);\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, submission);\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, [path, match, matches]);\n handleFetcherLoader(key, routeId, path, match, matches, submission);\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 submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n if (!match.route.action) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error);\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, fetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the action for the fetcher\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n fetchControllers.set(key, abortController);\n\n let actionResult = await callLoaderOrAction(\n \"action\",\n fetchRequest,\n match,\n requestMatches,\n router.basename\n );\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by ou 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 if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n fetchRedirectIds.add(key);\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n ...submission,\n data: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n return startRedirectNavigation(state, actionResult, {\n isFetchActionRedirect: true,\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 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\n nextLocation,\n abortController.signal\n );\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(dataRoutes, state.navigation.location, init.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: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: actionResult.data,\n ...submission,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n { [match.route.id]: actionResult.data },\n undefined, // No need to send through errors since we short circuit above\n fetchLoadMatches\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(([staleKey]) => staleKey !== key)\n .forEach(([staleKey]) => {\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: existingFetcher && existingFetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(staleKey, revalidatingFetcher);\n fetchControllers.set(staleKey, abortController);\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let { results, 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 fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach(([staleKey]) =>\n fetchControllers.delete(staleKey)\n );\n\n let redirect = findRedirect(results);\n if (redirect) {\n return startRedirectNavigation(state, redirect);\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 let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: actionResult.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n\n let didAbortFetchLoads = 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 ...(didAbortFetchLoads ? { 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 submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n // Put this fetcher into it's loading state\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the loader for this fetcher route match\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n fetchControllers.set(key, abortController);\n let result: DataResult = await callLoaderOrAction(\n \"loader\",\n fetchRequest,\n match,\n matches,\n router.basename\n );\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 ou 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 // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n await startRedirectNavigation(state, result);\n return;\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n state.fetchers.delete(key);\n // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -\n // do we need to behave any differently with our non-redirect errors?\n // What if it was a non-redirect Response?\n updateState({\n fetchers: new Map(state.fetchers),\n errors: {\n [boundaryMatch.route.id]: result.error,\n },\n });\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\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 state: RouterState,\n redirect: RedirectResult,\n {\n submission,\n replace,\n isFetchActionRedirect,\n }: {\n submission?: Submission;\n replace?: boolean;\n isFetchActionRedirect?: boolean;\n } = {}\n ) {\n if (redirect.revalidate) {\n isRevalidationRequired = true;\n }\n\n let redirectLocation = createLocation(\n state.location,\n redirect.location,\n // TODO: This can be removed once we get rid of useTransition in Remix v2\n {\n _isRedirect: true,\n ...(isFetchActionRedirect ? { _isFetchActionRedirect: true } : {}),\n }\n );\n invariant(\n redirectLocation,\n \"Expected a location on the redirect navigation\"\n );\n\n // Check if this an external redirect that goes to a new origin\n if (isBrowser && typeof window?.location !== \"undefined\") {\n let newOrigin = init.history.createURL(redirect.location).origin;\n if (window.location.origin !== newOrigin) {\n if (replace) {\n window.location.replace(redirect.location);\n } else {\n window.location.assign(redirect.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, formData } = state.navigation;\n if (!submission && formMethod && formAction && formData && formEncType) {\n submission = {\n formMethod,\n formAction,\n formEncType,\n formData,\n };\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 if (\n redirectPreserveMethodStatusCodes.has(redirect.status) &&\n submission &&\n isMutationMethod(submission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...submission,\n formAction: redirect.location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // Otherwise, we kick off a new loading navigation, preserving the\n // submission info for the duration of this navigation\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation: {\n state: \"loading\",\n location: redirectLocation,\n formMethod: submission ? submission.formMethod : undefined,\n formAction: submission ? submission.formAction : undefined,\n formEncType: submission ? submission.formEncType : undefined,\n formData: submission ? submission.formData : undefined,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\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 // Call all navigation loaders and revalidating fetcher loaders in parallel,\n // then slice off the results into separate arrays so we can handle them\n // accordingly\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\"loader\", request, match, matches, router.basename)\n ),\n ...fetchersToLoad.map(([, href, match, fetchMatches]) =>\n callLoaderOrAction(\n \"loader\",\n createClientSideRequest(init.history, href, request.signal),\n match,\n fetchMatches,\n router.basename\n )\n ),\n ]);\n let loaderResults = results.slice(0, matchesToLoad.length);\n let fetcherResults = results.slice(matchesToLoad.length);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n request.signal,\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map(([, , match]) => match),\n fetcherResults,\n request.signal,\n true\n ),\n ]);\n\n return { results, loaderResults, fetcherResults };\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 setFetcherError(key: string, routeId: string, error: any) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n });\n }\n\n function deleteFetcher(key: string): void {\n if (fetchControllers.has(key)) abortFetcher(key);\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n state.fetchers.delete(key);\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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): void {\n let doneKeys = [];\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 }\n }\n markFetchersDone(doneKeys);\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 if (activeBlocker == null) {\n // This is now the active blocker\n activeBlocker = key;\n } else if (key !== activeBlocker) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n if (activeBlocker === key) {\n activeBlocker = null;\n }\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 state.blockers.set(key, newBlocker);\n updateState({ blockers: new Map(state.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 (activeBlocker == null) {\n return;\n }\n\n // We only allow a single blocker at the moment. This will need to be\n // updated if we enhance to support multiple blockers in the future\n let blockerFunction = blockerFunctions.get(activeBlocker);\n invariant(\n blockerFunction,\n \"Could not find a function for the active blocker\"\n );\n let blocker = state.blockers.get(activeBlocker);\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 activeBlocker;\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 || ((location) => location.key);\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 saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n router = {\n get basename() {\n return init.basename;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\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,\n dispose,\n getBlocker,\n deleteBlocker,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: {\n basename?: string;\n }\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(routes);\n let basename = (opts ? opts.basename : null) || \"/\";\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 async function query(\n request: Request,\n { requestContext }: { requestContext?: unknown } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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(request, location, matches, requestContext);\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 async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n }: { requestContext?: unknown; routeId?: string } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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 match\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 routeMatch?: AgnosticDataRouteMatch\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 routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\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, we throw\n // it to bail out and then return or throw here based on whether the user\n // returned or threw\n if (isQueryRouteResponse(e)) {\n if (e.type === ResultType.error && !isRedirectResponse(e.response)) {\n throw e.response;\n }\n return e.response;\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 isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n );\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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.status,\n headers: {\n Location: result.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 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 let context = await loadRouteData(\n request,\n matches,\n requestContext,\n undefined,\n {\n [boundaryMatch.route.id]: result.error,\n }\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 : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\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 let context = await loadRouteData(loaderRequest, matches, requestContext);\n\n return {\n ...context,\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n routeMatch?: AgnosticDataRouteMatch,\n pendingActionError?: RouteData\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 (isRouteRequest && !routeMatch?.route.loader) {\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 : getLoaderMatchesUntilBoundary(\n matches,\n Object.keys(pendingActionError || {})[0]\n );\n let matchesToLoad = requestMatches.filter((m) => m.route.loader);\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: pendingActionError || null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\n \"loader\",\n request,\n match,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n )\n ),\n ]);\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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 pendingActionError,\n activeDeferreds\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 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: 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction isSubmissionNavigation(\n opts: RouterNavigateOptions\n): opts is SubmissionNavigateOptions {\n return opts != null && \"formData\" in opts;\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 to: To,\n opts?: RouterNavigateOptions,\n isFetcher = false\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponse;\n} {\n let path = typeof to === \"string\" ? to : createPath(to);\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 // Create a Submission on non-GET navigations\n let submission: Submission | undefined;\n if (opts.formData) {\n submission = {\n formMethod: opts.formMethod || \"get\",\n formAction: stripHashFromPath(path),\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData: opts.formData,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n try {\n let searchParams = convertFormDataToSearchParams(opts.formData);\n // Since fetcher GET submissions only run a single loader (as opposed to\n // navigation GET submissions which run all loaders), we need to preserve\n // any incoming ?index params\n if (\n isFetcher &&\n parsedPath.search &&\n hasNakedIndexQuery(parsedPath.search)\n ) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n } catch (e) {\n return {\n path,\n error: getInternalRouterError(400),\n };\n }\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 isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n pendingActionData?: RouteData,\n pendingError?: RouteData,\n fetchLoadMatches?: Map\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingError\n ? Object.values(pendingError)[0]\n : pendingActionData\n ? Object.values(pendingActionData)[0]\n : undefined;\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;\n let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);\n let navigationMatches = boundaryMatches.filter(\n (match, index) =>\n match.route.loader != null &&\n (isNewLoader(state.loaderData, state.matches[index], match) ||\n // If this route had a pending deferred cancelled it must be revalidated\n cancelledDeferredRoutes.some((id) => id === match.route.id) ||\n shouldRevalidateLoader(\n history,\n state.location,\n state.matches[index],\n submission,\n location,\n match,\n isRevalidationRequired,\n actionResult\n ))\n );\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches &&\n fetchLoadMatches.forEach(([href, match, fetchMatches], key) => {\n // This fetcher was cancelled from a prior action submission - force reload\n if (cancelledFetcherLoads.includes(key)) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\n } else if (isRevalidationRequired) {\n let shouldRevalidate = shouldRevalidateLoader(\n history,\n href,\n match,\n submission,\n href,\n match,\n isRevalidationRequired,\n actionResult\n );\n if (shouldRevalidate) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\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 &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n history: History,\n currentLocation: string | Location,\n currentMatch: AgnosticDataRouteMatch,\n submission: Submission | undefined,\n location: string | Location,\n match: AgnosticDataRouteMatch,\n isRevalidationRequired: boolean,\n actionResult: DataResult | undefined\n) {\n let currentUrl = history.createURL(currentLocation);\n let currentParams = currentMatch.params;\n let nextUrl = history.createURL(location);\n let nextParams = match.params;\n\n // This is the default implementation as to 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 // Note that fetchers always provide the same current/next locations so the\n // URL-based checks here don't apply to fetcher shouldRevalidate calls\n let defaultShouldRevalidate =\n isNewRouteInstance(currentMatch, match) ||\n // Clicked the same link, resubmitted a GET form\n currentUrl.toString() === nextUrl.toString() ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate\n isRevalidationRequired;\n\n if (match.route.shouldRevalidate) {\n let routeChoice = match.route.shouldRevalidate({\n currentUrl,\n currentParams,\n nextUrl,\n nextParams,\n ...submission,\n actionResult,\n defaultShouldRevalidate,\n });\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return defaultShouldRevalidate;\n}\n\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n basename = \"/\",\n isStaticRequest: boolean = false,\n isRouteRequest: boolean = false,\n requestContext?: unknown\n): Promise {\n let resultType;\n let result;\n\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n let abortPromise = new Promise((_, r) => (reject = r));\n let onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n try {\n let handler = match.route[type];\n invariant(\n handler,\n `Could not find the ${type} to run on the \"${match.route.id}\" route`\n );\n\n result = await Promise.race([\n handler({ request, params: match.params, context: requestContext }),\n abortPromise,\n ]);\n\n invariant(\n 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 resultType = ResultType.error;\n result = e;\n } finally {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n\n if (isResponse(result)) {\n let status = result.status;\n\n // Process redirects\n if (redirectStatusCodes.has(status)) {\n let location = result.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(location);\n\n // Support relative routing in internal redirects\n if (!isAbsolute) {\n let activeMatches = matches.slice(0, matches.indexOf(match) + 1);\n let routePathnames = getPathContributingMatches(activeMatches).map(\n (match) => match.pathnameBase\n );\n let resolvedLocation = resolveTo(\n location,\n routePathnames,\n new URL(request.url).pathname\n );\n invariant(\n createPath(resolvedLocation),\n `Unable to resolve redirect location: ${location}`\n );\n\n // Prepend the basename to the redirect location if we have one\n if (basename) {\n let path = resolvedLocation.pathname;\n resolvedLocation.pathname =\n path === \"/\" ? basename : joinPaths([basename, path]);\n }\n\n location = createPath(resolvedLocation);\n } else if (!isStaticRequest) {\n // Strip off the protocol+origin for same-origin absolute redirects.\n // If this is a static reques, we can let it go back to the browser\n // as-is\n let currentUrl = new URL(request.url);\n let url = location.startsWith(\"//\")\n ? new URL(currentUrl.protocol + location)\n : new URL(location);\n if (url.origin === currentUrl.origin) {\n location = url.pathname + url.search + url.hash;\n }\n }\n\n // Don't process redirects in the router during static requests requests.\n // Instead, throw the Response and let the server handle it with an HTTP\n // redirect. We also update the Location header in place in this flow so\n // basename and relative routing is taken into account\n if (isStaticRequest) {\n result.headers.set(\"Location\", location);\n throw result;\n }\n\n return {\n type: ResultType.redirect,\n status,\n location,\n revalidate: result.headers.get(\"X-Remix-Revalidate\") !== null,\n };\n }\n\n // For SSR single-route requests, we want to hand Responses back directly\n // without unwrapping. We do this with the QueryRouteResponse wrapper\n // interface so we can know whether it was returned or thrown\n if (isRouteRequest) {\n // eslint-disable-next-line no-throw-literal\n throw {\n type: resultType || ResultType.data,\n response: result,\n };\n }\n\n let data: any;\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 data = await result.json();\n } else {\n data = await result.text();\n }\n\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: new ErrorResponse(status, result.statusText, data),\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 (resultType === ResultType.error) {\n return { type: resultType, error: result };\n }\n\n if (result instanceof DeferredData) {\n return { type: ResultType.deferred, deferredData: result };\n }\n\n return { type: ResultType.data, data: result };\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, formData } = submission;\n init.method = formMethod.toUpperCase();\n init.body =\n formEncType === \"application/x-www-form-urlencoded\"\n ? convertFormDataToSearchParams(formData)\n : formData;\n }\n\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\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 invariant(\n typeof value === \"string\",\n 'File inputs are not supported with encType \"application/x-www-form-urlencoded\", ' +\n 'please use \"multipart/form-data\" instead.'\n );\n searchParams.append(key, value);\n }\n\n return searchParams;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingError: RouteData | undefined,\n activeDeferreds: Map\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\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 // Look upwards from the matched route for the closest ancestor\n // error boundary, defaulting to the root match\n let boundaryMatch = findNearestBoundary(matches, id);\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) {\n error = Object.values(pendingError)[0];\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n // Prefer higher error values if lower errors bubble to the same boundary\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\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 } else {\n loaderData[id] = result.data;\n }\n\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 }\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) {\n errors = pendingError;\n loaderData[Object.keys(pendingError)[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 pendingError: RouteData | 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 pendingError,\n activeDeferreds\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let [key, , match] = 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 (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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\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) {\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\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 = 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 }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\";\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 (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 {\n errorMessage = \"Cannot submit binary form data using GET\";\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 ErrorResponse(\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(results: DataResult[]): RedirectResult | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return result;\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 return (\n a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash\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\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 isQueryRouteResponse(obj: any): obj is QueryRouteResponse {\n return (\n obj &&\n isResponse(obj.response) &&\n (obj.type === ResultType.data || ResultType.error)\n );\n}\n\nfunction isValidMethod(method: string): method is FormMethod {\n return validRequestMethods.has(method as FormMethod);\n}\n\nfunction isMutationMethod(method?: string): method is MutationFormMethod {\n return validMutationMethods.has(method as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n signal: AbortSignal,\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 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 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\n// Note: This should match the format exported by useMatches, so if you change\n// this please also change that :) Eventually we'll DRY this up\nfunction createUseMatchesMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UseMatchesMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id] as unknown,\n handle: route.handle as unknown,\n };\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//#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","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","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","nextAction","historyState","pushState","error","assign","origin","addEventListener","removeEventListener","ResultType","isIndexRoute","route","convertRoutesToDataRoutes","routes","parentPath","allIds","Set","treePath","id","join","children","has","add","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","matchRouteBranch","safelyDecodeURI","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","startsWith","joinPaths","routesMeta","concat","score","computeScore","forEach","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","match","matchPath","Object","params","pathnameBase","normalizePathname","generatePath","originalPath","_","optional","param","prefix","__","str","star","pattern","matcher","paramNames","compilePath","captureGroups","memo","paramName","splatValue","safelyDecodeURIComponent","regexpSource","RegExp","decodeURI","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","data","init","responseInit","status","headers","Headers","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","trackPromise","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","done","emit","settledKey","subscriber","subscribe","cancel","abort","v","k","resolveData","resolve","size","unwrappedData","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","ErrorResponse","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","isBrowser","createElement","isServer","createRouter","dataRoutes","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","initialized","m","loader","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","loaderData","actionData","errors","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeDeferreds","activeBlocker","blockerFunctions","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","deleteBlocker","updateState","startNavigation","dispose","clear","deleteFetcher","newState","completeNavigation","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","getSavedScrollPosition","navigate","opts","submission","normalizeNavigateOptions","userReplace","pendingError","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","loadingNavigation","notFoundMatches","cancelActiveDeferreds","isHashChangeOnly","request","createClientSideRequest","pendingActionData","findNearestBoundary","actionOutput","handleAction","shortCircuited","pendingActionError","Request","handleLoaders","actionMatch","getTargetMatch","type","method","routeId","callLoaderOrAction","isRedirectResult","startRedirectNavigation","isErrorResult","boundaryMatch","isDeferredResult","activeSubmission","matchesToLoad","revalidatingFetchers","getMatchesToLoad","fetcher","revalidatingFetcher","results","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","processLoaderData","deferredData","markFetchRedirectsDone","didAbortFetchLoads","abortStaleFetchLoads","getFetcher","fetch","abortFetcher","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","existingFetcher","abortController","fetchRequest","actionResult","loadingFetcher","isFetchActionRedirect","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","redirectLocation","_isFetchActionRedirect","newOrigin","redirectHistoryAction","currentMatches","fetchersToLoad","all","fetchMatches","resolveDeferredResults","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","userMatches","createUseMatchesMatch","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","query","requestContext","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","find","values","routeMatch","submit","loadRouteData","isQueryRouteResponse","isRedirectResponse","response","isRouteRequest","Location","context","loaderRequest","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","isSubmissionNavigation","isFetcher","stripHashFromPath","searchParams","convertFormDataToSearchParams","hasNakedIndexQuery","append","boundaryId","boundaryMatches","findIndex","navigationMatches","isNewLoader","shouldRevalidateLoader","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","isNewRouteInstance","currentPath","currentUrl","currentParams","nextUrl","nextParams","defaultShouldRevalidate","routeChoice","isStaticRequest","resultType","onReject","handler","isAbsolute","activeMatches","resolvedLocation","protocol","contentType","text","deferred","toUpperCase","body","URLSearchParams","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","hasErrorBoundary","errorMessage","obj","isRevalidatingLoader","unwrap","getAll","handle","pathMatches"],"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 0000000..6519370 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.d.ts @@ -0,0 +1,426 @@ +import type { History, Location, Path, To } from "./history"; +import { Action as HistoryAction } from "./history"; +import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, FormEncType, FormMethod, RouteData, AgnosticRouteObject, AgnosticRouteMatch } from "./utils"; +import { DeferredData } 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 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 + * + * 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, 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, opts?: RouterNavigateOptions): 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 + * + * 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 declare type HydrationState = Partial>; +/** + * Initialization options for createRouter + */ +export interface RouterInit { + basename?: string; + routes: AgnosticRouteObject[]; + history: History; + hydrationData?: HydrationState; +} +/** + * 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; + }): Promise; + queryRoute(request: Request, opts?: { + routeId?: string; + requestContext?: unknown; + }): Promise; +} +/** + * Subscriber function signature for changes to router state + */ +export interface RouterSubscriber { + (state: RouterState): void; +} +interface UseMatchesMatch { + id: string; + pathname: string; + params: AgnosticRouteMatch["params"]; + data: unknown; + handle: unknown; +} +/** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ +export interface GetScrollRestorationKeyFunction { + (location: Location, matches: UseMatchesMatch[]): string | null; +} +/** + * Function signature for determining the current scroll position + */ +export interface GetScrollPositionFunction { + (): number; +} +/** + * Options for a navigate() call for a Link navigation + */ +declare type LinkNavigateOptions = { + replace?: boolean; + state?: any; + preventScrollReset?: boolean; +}; +/** + * Options for a navigate() call for a Form navigation + */ +declare type SubmissionNavigateOptions = { + replace?: boolean; + state?: any; + preventScrollReset?: boolean; + formMethod?: FormMethod; + formEncType?: FormEncType; + formData: FormData; +}; +/** + * Options to pass to navigate() for either a Link or Form navigation + */ +export declare type RouterNavigateOptions = LinkNavigateOptions | SubmissionNavigateOptions; +/** + * Options to pass to fetch() + */ +export declare type RouterFetchOptions = Omit | Omit; +/** + * Potential states for state.navigation + */ +export declare type NavigationStates = { + Idle: { + state: "idle"; + location: undefined; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + formData: undefined; + }; + Loading: { + state: "loading"; + location: Location; + formMethod: FormMethod | undefined; + formAction: string | undefined; + formEncType: FormEncType | undefined; + formData: FormData | undefined; + }; + Submitting: { + state: "submitting"; + location: Location; + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + }; +}; +export declare type Navigation = NavigationStates[keyof NavigationStates]; +export declare type RevalidationState = "idle" | "loading"; +/** + * Potential states for fetchers + */ +declare type FetcherStates = { + Idle: { + state: "idle"; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + formData: undefined; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; + Loading: { + state: "loading"; + formMethod: FormMethod | undefined; + formAction: string | undefined; + formEncType: FormEncType | undefined; + formData: FormData | undefined; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; + Submitting: { + state: "submitting"; + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; +}; +export declare 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 declare type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding; +export declare 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; +export declare function createStaticHandler(routes: AgnosticRouteObject[], opts?: { + basename?: string; +}): 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 {}; 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 0000000..18509c0 --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.js @@ -0,0 +1,3987 @@ +/** + * @remix-run/router v1.3.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$1(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)); + 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$1(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$1(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() { + let nextAction = Action.Pop; + let nextIndex = getIndex(); + + if (nextIndex != null) { + let delta = nextIndex - index; + action = nextAction; + index = nextIndex; + + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } else { + warning$1(false, // TODO: Write up a doc that explains our blocking strategy in detail + // and link to it here so people can understand better what is going on + // and how to avoid it. + "You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation."); + } + } + + 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) { + // 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); + 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 = {})); + +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, parentPath, allIds) { + if (parentPath === void 0) { + parentPath = []; + } + + if (allIds === void 0) { + allIds = new Set(); + } + + return routes.map((route, index) => { + let treePath = [...parentPath, 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(!allIds.has(id), "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + allIds.add(id); + + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, { + id + }); + + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, { + id, + children: route.children ? convertRoutesToDataRoutes(route.children, treePath, allIds) : undefined + }); + + 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 = "/"; + } + + 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) { + matches = matchRouteBranch(branches[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. + safelyDecodeURI(pathname)); + } + + return matches; +} + +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 explodes _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) { + 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); + if (!match) return null; + Object.assign(matchedParams, match.params); + let route = meta.route; + 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(/\*$/, "/*"); + } + + return path.replace(/^:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return param; + }).replace(/\/:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : "/" + param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return "/" + param; + }) // Remove any optional markers from optional static segments + .replace(/\?/g, "").replace(/(\/?)\*/, (_, prefix, __, str) => { + const star = "*"; + + if (params[star] == null) { + // If no splat was provided, trim the trailing slash _unless_ it's + // the entire path + return str === "/*" ? "/" : ""; + } // Apply the splat + + + return "" + prefix + params[star]; + }); +} +/** + * 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, paramNames] = 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 = paramNames.reduce((memo, paramName, 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"); + } + + memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName); + 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 paramNames = []; + 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) => { + paramNames.push(paramName); + return "/([^\\/]+)"; + }); + + if (path.endsWith("*")) { + paramNames.push("*"); + 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, paramNames]; +} + +function safelyDecodeURI(value) { + try { + return decodeURI(value); + } 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; + } +} + +function safelyDecodeURIComponent(value, paramName) { + try { + return decodeURIComponent(value); + } catch (error) { + warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" 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) || "/"; +} +/** + * @private + */ + +function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + + try { + // Welcome to debugging @remix-run/router! + // + // 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) {} + } +} +/** + * 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); +} +/** + * @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 (isPathRelative || toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + if (toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); // 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". + + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + + to.pathname = toSegments.join("/"); + } // If there are more ".." segments than parent routes, resolve relative to + // the root / URL. + + + 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, _ref) => { + let [key, value] = _ref; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + 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, null, 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 (error) { + 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, _ref2) => { + let [key, value] = _ref2; + 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 + })); +}; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + */ + +class ErrorResponse { + 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 throw from an action/loader + */ + +function isRouteErrorResponse(e) { + return e instanceof ErrorResponse; +} + +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 +}; +const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined +}; +const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined +}; +const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; +const isServer = !isBrowser; //#endregion +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a router and listen to history POP navigations + */ + +function createRouter(init) { + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let dataRoutes = convertRoutesToDataRoutes(init.routes); // 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, init.basename); + let initialErrors = null; + + if (initialMatches == null) { + // 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 + }; + } + + let initialized = !initialMatches.some(m => m.route.loader) || 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; // 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) + // - useRevalidate() + // - 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 from their actions + + let fetchRedirectIds = new Set(); // Most recent href/match for fetcher.load calls for fetchers + + let fetchLoadMatches = new Map(); // 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(); // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + + let activeBlocker = null; // 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(); // 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; + } + + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + + if (blockerKey) { + // 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(router.state.blockers) + }); + } + + }); + return; + } + + return startNavigation(historyAction, location); + }); // Kick off initial data load if needed. Use Pop to avoid modifying history + + if (!state.initialized) { + startNavigation(Action.Pop, state.location); + } + + return router; + } // Clean up a router and it's side effects + + + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + + 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) { + state = _extends({}, state, newState); + subscribers.forEach(subscriber => subscriber(state)); + } // 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) { + var _location$state, _location$state2; + + // 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 + + for (let [key] of blockerFunctions) { + deleteBlocker(key); + } // 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; + updateState(_extends({}, newState, { + actionData, + loaderData, + historyAction: pendingAction, + location, + initialized: true, + navigation: IDLE_NAVIGATION, + revalidation: "idle", + restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches), + preventScrollReset, + blockers: new Map(state.blockers) + })); + + 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); + } // Reset stateful navigation vars + + + pendingAction = Action.Pop; + pendingPreventScrollReset = 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 { + path, + submission, + error + } = normalizeNavigateOptions(to, 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 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(state.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 + }); + } // 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; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(dataRoutes, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing + + if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); // Cancel all pending deferred on 404s since we don't keep any routes + + cancelActiveDeferreds(); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }); + return; + } // Short circuit if it's only a hash change + + + if (isHashChangeOnly(state.location, location)) { + completeNavigation(location, { + matches + }); + return; + } // Create a controller/Request for this navigation + + + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionData; + let pendingError; + + 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. + pendingError = { + [findNearestBoundary(matches).route.id]: opts.pendingError + }; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionOutput = await handleAction(request, location, opts.submission, matches, { + replace: opts.replace + }); + + if (actionOutput.shortCircuited) { + return; + } + + pendingActionData = actionOutput.pendingActionData; + pendingError = actionOutput.pendingActionError; + + let navigation = _extends({ + state: "loading", + location + }, opts.submission); + + loadingNavigation = navigation; // Create a GET request for the loaders + + request = new Request(request.url, { + signal: request.signal + }); + } // Call loaders + + + let { + shortCircuited, + loaderData, + errors + } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.replace, pendingActionData, pendingError); + + 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 + }, pendingActionData ? { + actionData: pendingActionData + } : {}, { + loaderData, + errors + })); + } // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + + + async function handleAction(request, location, submission, matches, opts) { + interruptActiveLoads(); // Put us in a submitting state + + let navigation = _extends({ + state: "submitting", + location + }, submission); + + updateState({ + navigation + }); // Call our action and get the result + + let result; + let actionMatch = getTargetMatch(matches, location); + + if (!actionMatch.route.action) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + result = await callLoaderOrAction("action", request, actionMatch, matches, router.basename); + + 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 + replace = result.location === state.location.pathname + state.location.search; + } + + await startRedirectNavigation(state, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + + 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 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 { + // Send back an empty object we can use to clear out any prior actionData + pendingActionData: {}, + pendingActionError: { + [boundaryMatch.route.id]: result.error + } + }; + } + + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + + return { + pendingActionData: { + [actionMatch.route.id]: result.data + } + }; + } // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + + + async function handleLoaders(request, location, matches, overrideNavigation, submission, replace, pendingActionData, pendingError) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation; + + if (!loadingNavigation) { + let navigation = _extends({ + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission); + + loadingNavigation = navigation; + } // 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 ? submission : loadingNavigation.formMethod && loadingNavigation.formAction && loadingNavigation.formData && loadingNavigation.formEncType ? { + formMethod: loadingNavigation.formMethod, + formAction: loadingNavigation.formAction, + formData: loadingNavigation.formData, + formEncType: loadingNavigation.formEncType + } : undefined; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // 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)); // Short circuit if we have no loaders to run + + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingError || null + }, pendingActionData ? { + actionData: pendingActionData + } : {})); + return { + shortCircuited: true + }; + } // 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 (!isUninterruptedRevalidation) { + revalidatingFetchers.forEach(_ref2 => { + let [key] = _ref2; + let fetcher = state.fetchers.get(key); + let revalidatingFetcher = { + state: "loading", + data: fetcher && fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, revalidatingFetcher); + }); + let actionData = pendingActionData || state.actionData; + updateState(_extends({ + navigation: loadingNavigation + }, actionData ? Object.keys(actionData).length === 0 ? { + actionData: null + } : { + actionData + } : {}, revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {})); + } + + pendingNavigationLoadId = ++incrementingLoadId; + revalidatingFetchers.forEach(_ref3 => { + let [key] = _ref3; + return fetchControllers.set(key, pendingNavigationController); + }); + let { + results, + 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 + + + revalidatingFetchers.forEach(_ref4 => { + let [key] = _ref4; + return fetchControllers.delete(key); + }); // If any loaders returned a redirect Response, start a new REPLACE navigation + + let redirect = findRedirect(results); + + if (redirect) { + await startRedirectNavigation(state, redirect, { + replace + }); + return { + shortCircuited: true + }; + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingError, 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); + } + }); + }); + markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + return _extends({ + loaderData, + errors + }, didAbortFetchLoads || revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {}); + } + + function getFetcher(key) { + return state.fetchers.get(key) || IDLE_FETCHER; + } // 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 matches = matchRoutes(dataRoutes, href, init.basename); + + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: href + })); + return; + } + + let { + path, + submission + } = normalizeNavigateOptions(href, opts, true); + let match = getTargetMatch(matches, path); + + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, submission); + return; + } // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + + + fetchLoadMatches.set(key, [path, match, matches]); + handleFetcherLoader(key, routeId, path, match, matches, submission); + } // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + + + async function handleFetcherAction(key, routeId, path, match, requestMatches, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + + if (!match.route.action) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error); + return; + } // Put this fetcher into it's submitting state + + + let existingFetcher = state.fetchers.get(key); + + let fetcher = _extends({ + state: "submitting" + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the action for the fetcher + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + fetchControllers.set(key, abortController); + let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename); + + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by ou our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + + return; + } + + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + fetchRedirectIds.add(key); + + let loadingFetcher = _extends({ + state: "loading" + }, submission, { + data: undefined, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + return startRedirectNavigation(state, actionResult, { + isFetchActionRedirect: true + }); + } // 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 matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + + let loadFetcher = _extends({ + state: "loading", + data: actionResult.data + }, submission, { + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, { + [match.route.id]: actionResult.data + }, undefined, // No need to send through errors since we short circuit above + fetchLoadMatches); // 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(_ref5 => { + let [staleKey] = _ref5; + return staleKey !== key; + }).forEach(_ref6 => { + let [staleKey] = _ref6; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = { + state: "loading", + data: existingFetcher && existingFetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(staleKey, revalidatingFetcher); + fetchControllers.set(staleKey, abortController); + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let { + results, + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + + if (abortController.signal.aborted) { + return; + } + + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(_ref7 => { + let [staleKey] = _ref7; + return fetchControllers.delete(staleKey); + }); + let redirect = findRedirect(results); + + if (redirect) { + return startRedirectNavigation(state, redirect); + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + let doneFetcher = { + state: "idle", + data: actionResult.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + let didAbortFetchLoads = 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(_extends({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors) + }, didAbortFetchLoads ? { + 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, submission) { + let existingFetcher = state.fetchers.get(key); // Put this fetcher into it's loading state + + let loadingFetcher = _extends({ + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the loader for this fetcher route match + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + fetchControllers.set(key, abortController); + let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // 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 ou 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; + } // If the loader threw a redirect Response, start a new REPLACE navigation + + + if (isRedirectResult(result)) { + await startRedirectNavigation(state, result); + return; + } // Process any non-redirect errors thrown + + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + state.fetchers.delete(key); // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch - + // do we need to behave any differently with our non-redirect errors? + // What if it was a non-redirect Response? + + updateState({ + fetchers: new Map(state.fetchers), + errors: { + [boundaryMatch.route.id]: result.error + } + }); + return; + } + + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); // Put the fetcher back into an idle state + + let doneFetcher = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + } + /** + * 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(state, redirect, _temp) { + var _window; + + let { + submission, + replace, + isFetchActionRedirect + } = _temp === void 0 ? {} : _temp; + + if (redirect.revalidate) { + isRevalidationRequired = true; + } + + let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2 + _extends({ + _isRedirect: true + }, isFetchActionRedirect ? { + _isFetchActionRedirect: true + } : {})); + invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin + + if (isBrowser && typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") { + let newOrigin = init.history.createURL(redirect.location).origin; + + if (window.location.origin !== newOrigin) { + if (replace) { + window.location.replace(redirect.location); + } else { + window.location.assign(redirect.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, + formData + } = state.navigation; + + if (!submission && formMethod && formAction && formData && formEncType) { + submission = { + formMethod, + formAction, + formEncType, + formData + }; + } // 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 + + + if (redirectPreserveMethodStatusCodes.has(redirect.status) && submission && isMutationMethod(submission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, submission, { + formAction: redirect.location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // Otherwise, we kick off a new loading navigation, preserving the + // submission info for the duration of this navigation + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation: { + state: "loading", + location: redirectLocation, + formMethod: submission ? submission.formMethod : undefined, + formAction: submission ? submission.formAction : undefined, + formEncType: submission ? submission.formEncType : undefined, + formData: submission ? submission.formData : undefined + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + // Call all navigation loaders and revalidating fetcher loaders in parallel, + // then slice off the results into separate arrays so we can handle them + // accordingly + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => { + let [, href, match, fetchMatches] = _ref8; + return callLoaderOrAction("loader", createClientSideRequest(init.history, href, request.signal), match, fetchMatches, router.basename); + })]); + let loaderResults = results.slice(0, matchesToLoad.length); + let fetcherResults = results.slice(matchesToLoad.length); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(_ref9 => { + let [,, match] = _ref9; + return match; + }), fetcherResults, request.signal, true)]); + return { + results, + 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 setFetcherError(key, routeId, error) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }); + } + + function deleteFetcher(key) { + if (fetchControllers.has(key)) abortFetcher(key); + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + state.fetchers.delete(key); + } + + 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 = { + state: "idle", + data: fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + } + } + + function markFetchRedirectsDone() { + let doneKeys = []; + + 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); + } + } + + markFetchersDone(doneKeys); + } + + 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); + + if (activeBlocker == null) { + // This is now the active blocker + activeBlocker = key; + } else if (key !== activeBlocker) { + warning(false, "A router only supports one blocker at a time"); + } + } + + return blocker; + } + + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + + if (activeBlocker === key) { + activeBlocker = null; + } + } // 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); + state.blockers.set(key, newBlocker); + updateState({ + blockers: new Map(state.blockers) + }); + } + + function shouldBlockNavigation(_ref10) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref10; + + if (activeBlocker == null) { + return; + } // We only allow a single blocker at the moment. This will need to be + // updated if we enhance to support multiple blockers in the future + + + let blockerFunction = blockerFunctions.get(activeBlocker); + invariant(blockerFunction, "Could not find a function for the active blocker"); + let blocker = state.blockers.get(activeBlocker); + + 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 activeBlocker; + } + } + + 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 || (location => location.key); // 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 saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + savedScrollPositions[key] = getScrollPosition(); + } + } + + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + let y = savedScrollPositions[key]; + + if (typeof y === "number") { + return y; + } + } + + return null; + } + + router = { + get basename() { + return init.basename; + }, + + get state() { + return state; + }, + + get routes() { + return dataRoutes; + }, + + 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, + dispose, + getBlocker, + deleteBlocker, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds + }; + 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 dataRoutes = convertRoutesToDataRoutes(routes); + let basename = (opts ? opts.basename : null) || "/"; + /** + * 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. + */ + + async function query(request, _temp2) { + let { + requestContext + } = _temp2 === void 0 ? {} : _temp2; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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); + + 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. + */ + + + async function queryRoute(request, _temp3) { + let { + routeId, + requestContext + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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, 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, 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, routeMatch != null); + return result; + } + + let result = await loadRouteData(request, matches, requestContext, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction, we throw + // it to bail out and then return or throw here based on whether the user + // returned or threw + if (isQueryRouteResponse(e)) { + if (e.type === ResultType.error && !isRedirectResponse(e.response)) { + throw e.response; + } + + return e.response; + } // 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, isRouteRequest) { + let result; + + if (!actionMatch.route.action) { + 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 { + result = await callLoaderOrAction("action", request, actionMatch, matches, basename, true, isRouteRequest, requestContext); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } + } + + 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.status, + headers: { + Location: result.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 + }; + } + + 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); + let context = await loadRouteData(request, matches, requestContext, undefined, { + [boundaryMatch.route.id]: result.error + }); // action status codes take precedence over loader status codes + + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } // Create a GET request for the loaders + + + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + let context = await loadRouteData(loaderRequest, matches, requestContext); + return _extends({}, context, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionData: { + [actionMatch.route.id]: result.data + }, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + + async function loadRouteData(request, matches, requestContext, routeMatch, pendingActionError) { + let isRouteRequest = routeMatch != null; // Short circuit if we have no loaders to run (queryRoute()) + + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + + let requestMatches = routeMatch ? [routeMatch] : getLoaderMatchesUntilBoundary(matches, Object.keys(pendingActionError || {})[0]); + let matchesToLoad = requestMatches.filter(m => m.route.loader); // 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: pendingActionError || null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, basename, true, isRouteRequest, requestContext))]); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } // Process and commit output from loaders + + + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError, activeDeferreds); // 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 + }); + } + + 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: 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + + return newContext; +} + +function isSubmissionNavigation(opts) { + return opts != null && "formData" in opts; +} // Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params + + +function normalizeNavigateOptions(to, opts, isFetcher) { + if (isFetcher === void 0) { + isFetcher = false; + } + + let path = typeof to === "string" ? to : createPath(to); // 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 + }) + }; + } // Create a Submission on non-GET navigations + + + let submission; + + if (opts.formData) { + submission = { + formMethod: opts.formMethod || "get", + formAction: stripHashFromPath(path), + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData: opts.formData + }; + + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + } // Flatten submission onto URLSearchParams for GET submissions + + + let parsedPath = parsePath(path); + + try { + let searchParams = convertFormDataToSearchParams(opts.formData); // Since fetcher GET submissions only run a single loader (as opposed to + // navigation GET submissions which run all loaders), we need to preserve + // any incoming ?index params + + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + + parsedPath.search = "?" + searchParams; + } catch (e) { + return { + path, + error: getInternalRouterError(400) + }; + } + + 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, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) { + let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation + + let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined; + let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId); + let navigationMatches = boundaryMatches.filter((match, index) => match.route.loader != null && (isNewLoader(state.loaderData, state.matches[index], match) || // If this route had a pending deferred cancelled it must be revalidated + cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated + + let revalidatingFetchers = []; + fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => { + let [href, match, fetchMatches] = _ref11; + + // This fetcher was cancelled from a prior action submission - force reload + if (cancelledFetcherLoads.includes(key)) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } else if (isRevalidationRequired) { + let shouldRevalidate = shouldRevalidateLoader(history, href, match, submission, href, match, isRevalidationRequired, actionResult); + + if (shouldRevalidate) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } + } + }); + 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 && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); +} + +function shouldRevalidateLoader(history, currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) { + let currentUrl = history.createURL(currentLocation); + let currentParams = currentMatch.params; + let nextUrl = history.createURL(location); + let nextParams = match.params; // This is the default implementation as to 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 + // Note that fetchers always provide the same current/next locations so the + // URL-based checks here don't apply to fetcher shouldRevalidate calls + + let defaultShouldRevalidate = isNewRouteInstance(currentMatch, match) || // Clicked the same link, resubmitted a GET form + currentUrl.toString() === nextUrl.toString() || // Search params affect all loaders + currentUrl.search !== nextUrl.search || // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate + isRevalidationRequired; + + if (match.route.shouldRevalidate) { + let routeChoice = match.route.shouldRevalidate(_extends({ + currentUrl, + currentParams, + nextUrl, + nextParams + }, submission, { + actionResult, + defaultShouldRevalidate + })); + + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + + return defaultShouldRevalidate; +} + +async function callLoaderOrAction(type, request, match, matches, basename, isStaticRequest, isRouteRequest, requestContext) { + if (basename === void 0) { + basename = "/"; + } + + if (isStaticRequest === void 0) { + isStaticRequest = false; + } + + if (isRouteRequest === void 0) { + isRouteRequest = false; + } + + let resultType; + let result; // Setup a promise we can race against so that abort signals short circuit + + let reject; + let abortPromise = new Promise((_, r) => reject = r); + + let onReject = () => reject(); + + request.signal.addEventListener("abort", onReject); + + try { + let handler = match.route[type]; + invariant(handler, "Could not find the " + type + " to run on the \"" + match.route.id + "\" route"); + result = await Promise.race([handler({ + request, + params: match.params, + context: requestContext + }), abortPromise]); + invariant(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) { + resultType = ResultType.error; + result = e; + } finally { + request.signal.removeEventListener("abort", onReject); + } + + if (isResponse(result)) { + let status = result.status; // Process redirects + + if (redirectStatusCodes.has(status)) { + let location = result.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location); // Support relative routing in internal redirects + + if (!isAbsolute) { + let activeMatches = matches.slice(0, matches.indexOf(match) + 1); + let routePathnames = getPathContributingMatches(activeMatches).map(match => match.pathnameBase); + let resolvedLocation = resolveTo(location, routePathnames, new URL(request.url).pathname); + invariant(createPath(resolvedLocation), "Unable to resolve redirect location: " + location); // Prepend the basename to the redirect location if we have one + + if (basename) { + let path = resolvedLocation.pathname; + resolvedLocation.pathname = path === "/" ? basename : joinPaths([basename, path]); + } + + location = createPath(resolvedLocation); + } else if (!isStaticRequest) { + // Strip off the protocol+origin for same-origin absolute redirects. + // If this is a static reques, we can let it go back to the browser + // as-is + let currentUrl = new URL(request.url); + let url = location.startsWith("//") ? new URL(currentUrl.protocol + location) : new URL(location); + + if (url.origin === currentUrl.origin) { + location = url.pathname + url.search + url.hash; + } + } // Don't process redirects in the router during static requests requests. + // Instead, throw the Response and let the server handle it with an HTTP + // redirect. We also update the Location header in place in this flow so + // basename and relative routing is taken into account + + + if (isStaticRequest) { + result.headers.set("Location", location); + throw result; + } + + return { + type: ResultType.redirect, + status, + location, + revalidate: result.headers.get("X-Remix-Revalidate") !== null + }; + } // For SSR single-route requests, we want to hand Responses back directly + // without unwrapping. We do this with the QueryRouteResponse wrapper + // interface so we can know whether it was returned or thrown + + + if (isRouteRequest) { + // eslint-disable-next-line no-throw-literal + throw { + type: resultType || ResultType.data, + response: result + }; + } + + let data; + 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)) { + data = await result.json(); + } else { + data = await result.text(); + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: new ErrorResponse(status, result.statusText, data), + headers: result.headers + }; + } + + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: result + }; + } + + if (result instanceof DeferredData) { + return { + type: ResultType.deferred, + deferredData: result + }; + } + + return { + type: ResultType.data, + data: result + }; +} // 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, + formData + } = submission; + init.method = formMethod.toUpperCase(); + init.body = formEncType === "application/x-www-form-urlencoded" ? convertFormDataToSearchParams(formData) : formData; + } // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + + + return new Request(url, init); +} + +function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + + for (let [key, value] of formData.entries()) { + invariant(typeof value === "string", 'File inputs are not supported with encType "application/x-www-form-urlencoded", ' + 'please use "multipart/form-data" instead.'); + searchParams.append(key, value); + } + + return searchParams; +} + +function processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; // 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)) { + // Look upwards from the matched route for the closest ancestor + // error boundary, defaulting to the root match + let boundaryMatch = findNearestBoundary(matches, id); + 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) { + error = Object.values(pendingError)[0]; + pendingError = undefined; + } + + errors = errors || {}; // Prefer higher error values if lower errors bubble to the same boundary + + 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; + } 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 != null && 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) { + errors = pendingError; + loaderData[Object.keys(pendingError)[0]] = undefined; + } + + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; +} + +function processLoaderData(state, matches, matchesToLoad, results, pendingError, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds); // Process results from our revalidating fetchers + + for (let index = 0; index < revalidatingFetchers.length; index++) { + let [key,, match] = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; // Process fetcher non-redirect errors + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, 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 = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + 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) { + mergedLoaderData[id] = loaderData[id]; + } + + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + + return mergedLoaderData; +} // 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.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; +} + +function getInternalRouterError(status, _temp4) { + let { + pathname, + routeId, + method, + type + } = _temp4 === void 0 ? {} : _temp4; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + + if (status === 400) { + statusText = "Bad Request"; + + 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 { + errorMessage = "Cannot submit binary form data using GET"; + } + } 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 ErrorResponse(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; + } + } +} + +function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); +} + +function isHashChangeOnly(a, b) { + return a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash; +} + +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 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 isQueryRouteResponse(obj) { + return obj && isResponse(obj.response) && (obj.type === ResultType.data || ResultType.error); +} + +function isValidMethod(method) { + return validRequestMethods.has(method); +} + +function isMutationMethod(method) { + return validMutationMethods.has(method); +} + +async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + 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 + 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 === ""); +} // Note: This should match the format exported by useMatches, so if you change +// this please also change that :) Eventually we'll DRY this up + + +function createUseMatchesMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; +} + +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]; +} //#endregion + +export { AbortedDeferredError, Action, ErrorResponse, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, resolvePath, resolveTo, stripBasename, warning }; +//# 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 0000000..c804c55 --- /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/**\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: any;\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;\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`. May be either a URL or the pieces of a\n * 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 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\nfunction 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 let nextAction = Action.Pop;\n let nextIndex = getIndex();\n\n if (nextIndex != null) {\n let delta = nextIndex - index;\n action = nextAction;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n } else {\n warning(\n false,\n // TODO: Write up a doc that explains our blocking strategy in detail\n // and link to it here so people can understand better what is going on\n // and how to avoid it.\n `You are trying to block a POP navigation to a location that was not ` +\n `created by @remix-run/router. The block will fail silently in ` +\n `production, but in general you should do all navigation with the ` +\n `router (instead of using window.history.pushState directly) ` +\n `to avoid this situation.`\n );\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 // 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 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 } 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: any;\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 status: number;\n location: string;\n revalidate: boolean;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: any;\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\nexport type MutationFormMethod = \"post\" | \"put\" | \"patch\" | \"delete\";\nexport type FormMethod = \"get\" | MutationFormMethod;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\";\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport interface Submission {\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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?: any;\n}\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Route loader function signature\n */\nexport interface LoaderFunction {\n (args: LoaderFunctionArgs): Promise | Response | Promise | any;\n}\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (args: ActionFunctionArgs): Promise | Response | Promise | any;\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: {\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 formData?: Submission[\"formData\"];\n actionResult?: DataResult;\n defaultShouldRevalidate: boolean;\n }): boolean;\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;\n action?: ActionFunction;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\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\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 */\ntype 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 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 parentPath: number[] = [],\n allIds: Set = new Set()\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, 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 !allIds.has(id),\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n allIds.add(id);\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = { ...route, id };\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n id,\n children: route.children\n ? convertRoutesToDataRoutes(route.children, treePath, allIds)\n : undefined,\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 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 matches = matchRouteBranch(\n branches[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 safelyDecodeURI(pathname)\n );\n }\n\n return matches;\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\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 explodes _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): 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 if (!match) return null;\n\n Object.assign(matchedParams, match.params);\n\n let route = meta.route;\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 = 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 return (\n path\n .replace(\n /^:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : param;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return param;\n }\n )\n .replace(\n /\\/:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : `/${param}`;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return `/${param}`;\n }\n )\n // Remove any optional markers from optional static segments\n .replace(/\\?/g, \"\")\n .replace(/(\\/?)\\*/, (_, prefix, __, str) => {\n const star = \"*\" as PathParam;\n\n if (params[star] == null) {\n // If no splat was provided, trim the trailing slash _unless_ it's\n // the entire path\n return str === \"/*\" ? \"/\" : \"\";\n }\n\n // Apply the splat\n return `${prefix}${params[star]}`;\n })\n );\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, paramNames] = 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 = paramNames.reduce>(\n (memo, paramName, 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 memo[paramName] = safelyDecodeURIComponent(\n captureGroups[index] || \"\",\n paramName\n );\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, string[]] {\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 paramNames: string[] = [];\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(/\\/:(\\w+)/g, (_: string, paramName: string) => {\n paramNames.push(paramName);\n return \"/([^\\\\/]+)\";\n });\n\n if (path.endsWith(\"*\")) {\n paramNames.push(\"*\");\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, paramNames];\n}\n\nfunction safelyDecodeURI(value: string) {\n try {\n return decodeURI(value);\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\nfunction safelyDecodeURIComponent(value: string, paramName: string) {\n try {\n return decodeURIComponent(value);\n } catch (error) {\n warning(\n false,\n `The value for the URL param \"${paramName}\" will not be decoded because` +\n ` the string \"${value}\" is a malformed URL segment. This is probably` +\n ` due to a bad percent 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 * @private\n */\nexport function warning(cond: any, message: string): void {\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 @remix-run/router!\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\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/**\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 (isPathRelative || toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n if (toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n // Each leading .. segment means \"go up one route\" instead of \"go up one\n // URL segment\". This is a key difference from how works and a\n // major reason we call this a \"to\" value instead of a \"href\".\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n // If there are more \"..\" segments than parent routes, resolve relative to\n // the root / URL.\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 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, null, 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 (error) {\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 * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n */\nexport class ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n error?: Error;\n 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 throw from an action/loader\n */\nexport function isRouteErrorResponse(e: any): e is ErrorResponse {\n return e instanceof ErrorResponse;\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n} from \"./history\";\nimport type {\n DataResult,\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DeferredResult,\n ErrorResult,\n FormEncType,\n FormMethod,\n RedirectResult,\n RouteData,\n AgnosticRouteObject,\n Submission,\n SuccessResult,\n AgnosticRouteMatch,\n MutationFormMethod,\n} from \"./utils\";\nimport {\n DeferredData,\n ErrorResponse,\n ResultType,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n resolveTo,\n warning,\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 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 * 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, 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,\n opts?: RouterNavigateOptions\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 * 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 * Initialization options for createRouter\n */\nexport interface RouterInit {\n basename?: string;\n routes: AgnosticRouteObject[];\n history: History;\n hydrationData?: HydrationState;\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?: { requestContext?: unknown }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: { routeId?: string; requestContext?: unknown }\n ): Promise;\n}\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (state: RouterState): void;\n}\n\ninterface UseMatchesMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: unknown;\n handle: unknown;\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: UseMatchesMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\n/**\n * Options for a navigate() call for a Link navigation\n */\ntype LinkNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n};\n\n/**\n * Options for a navigate() call for a Form navigation\n */\ntype SubmissionNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n formMethod?: FormMethod;\n formEncType?: FormEncType;\n formData: FormData;\n};\n\n/**\n * Options to pass to navigate() for either a Link or Form navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions =\n | Omit\n | Omit;\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 };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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 formData: undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Loading: {\n state: \"loading\";\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\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\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Error thrown from the current action, keyed by the route containing the\n * error boundary to render the error. To be committed to the state after\n * loaders have completed\n */\n pendingActionError?: RouteData;\n /**\n * Data returned from the current action, keyed by the route owning the action.\n * To be committed to the state after loaders have completed\n */\n pendingActionData?: RouteData;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\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 * Tuple of [key, href, DataRouteMatch, DataRouteMatch[]] for a revalidating\n * fetcher.load()\n */\ntype RevalidatingFetcher = [\n string,\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Tuple of [href, DataRouteMatch, DataRouteMatch[]] for an active\n * fetcher.load()\n */\ntype FetchLoadMatch = [\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Wrapper object to allow us to throw any response out from callLoaderOrAction\n * for queryRouter while preserving whether or not it was thrown or returned\n * from the loader/action\n */\ninterface QueryRouteResponse {\n type: ResultType.data | ResultType.error;\n response: Response;\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};\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};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n typeof window.document !== \"undefined\" &&\n typeof window.document.createElement !== \"undefined\";\nconst isServer = !isBrowser;\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 invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(init.routes);\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(\n dataRoutes,\n init.history.location,\n init.basename\n );\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null) {\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 let initialized =\n !initialMatches.some((m) => m.route.loader) || init.hydrationData != null;\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 // 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 // - useRevalidate()\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 from their actions\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\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 // 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 let activeBlocker: string | null = null;\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 // 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 let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n if (blockerKey) {\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(router.state.blockers) });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location);\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 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(newState: Partial): void {\n state = {\n ...state,\n ...newState,\n };\n subscribers.forEach((subscriber) => subscriber(state));\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 ): 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 for (let [key] of blockerFunctions) {\n deleteBlocker(key);\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 updateState({\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: new Map(state.blockers),\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 // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = 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,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(to, opts);\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 blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(state.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 });\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 submission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponse;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: 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 let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(dataRoutes, location, init.basename);\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n });\n return;\n }\n\n // Short circuit if it's only a hash change\n if (isHashChangeOnly(state.location, location)) {\n completeNavigation(location, { matches });\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 pendingActionData: RouteData | undefined;\n let pendingError: RouteData | 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 pendingError = {\n [findNearestBoundary(matches).route.id]: 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 actionOutput = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n { replace: opts.replace }\n );\n\n if (actionOutput.shortCircuited) {\n return;\n }\n\n pendingActionData = actionOutput.pendingActionData;\n pendingError = actionOutput.pendingActionError;\n\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n ...opts.submission,\n };\n loadingNavigation = navigation;\n\n // Create a GET request for the loaders\n request = new Request(request.url, { signal: request.signal });\n }\n\n // Call loaders\n let { shortCircuited, loaderData, errors } = await handleLoaders(\n request,\n location,\n matches,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.replace,\n pendingActionData,\n pendingError\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,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\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 opts?: { replace?: boolean }\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n ...submission,\n };\n updateState({ navigation });\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) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n router.basename\n );\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 replace =\n result.location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(state, result, { submission, replace });\n return { shortCircuited: true };\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 are REPLACE navigations, but if the\n // action threw an error that'll be rendered in an errorElement, we fall\n // back to PUSH so that the user can use the back button to get back to\n // the pre-submission form location to try again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n // Send back an empty object we can use to clear out any prior actionData\n pendingActionData: {},\n pendingActionError: { [boundaryMatch.route.id]: result.error },\n };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n return {\n pendingActionData: { [actionMatch.route.id]: result.data },\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 overrideNavigation?: Navigation,\n submission?: Submission,\n replace?: boolean,\n pendingActionData?: RouteData,\n pendingError?: RouteData\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation;\n if (!loadingNavigation) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n };\n loadingNavigation = navigation;\n }\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 = submission\n ? submission\n : loadingNavigation.formMethod &&\n loadingNavigation.formAction &&\n loadingNavigation.formData &&\n loadingNavigation.formEncType\n ? {\n formMethod: loadingNavigation.formMethod,\n formAction: loadingNavigation.formAction,\n formData: loadingNavigation.formData,\n formEncType: loadingNavigation.formEncType,\n }\n : undefined;\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n pendingActionData,\n pendingError,\n fetchLoadMatches\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 // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n completeNavigation(location, {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingError || null,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\n });\n return { shortCircuited: true };\n }\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 (!isUninterruptedRevalidation) {\n revalidatingFetchers.forEach(([key]) => {\n let fetcher = state.fetchers.get(key);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: fetcher && fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, revalidatingFetcher);\n });\n let actionData = pendingActionData || state.actionData;\n updateState({\n navigation: loadingNavigation,\n ...(actionData\n ? Object.keys(actionData).length === 0\n ? { actionData: null }\n : { actionData }\n : {}),\n ...(revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n });\n }\n\n pendingNavigationLoadId = ++incrementingLoadId;\n revalidatingFetchers.forEach(([key]) =>\n fetchControllers.set(key, pendingNavigationController!)\n );\n\n let { results, 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 revalidatingFetchers.forEach(([key]) => fetchControllers.delete(key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(results);\n if (redirect) {\n await startRedirectNavigation(state, redirect, { replace });\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 pendingError,\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 markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n\n return {\n loaderData,\n errors,\n ...(didAbortFetchLoads || revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n };\n }\n\n function getFetcher(key: string): Fetcher {\n return state.fetchers.get(key) || IDLE_FETCHER;\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,\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\n let matches = matchRoutes(dataRoutes, href, init.basename);\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: href })\n );\n return;\n }\n\n let { path, submission } = normalizeNavigateOptions(href, opts, true);\n let match = getTargetMatch(matches, path);\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, submission);\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, [path, match, matches]);\n handleFetcherLoader(key, routeId, path, match, matches, submission);\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 submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n if (!match.route.action) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error);\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, fetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the action for the fetcher\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n fetchControllers.set(key, abortController);\n\n let actionResult = await callLoaderOrAction(\n \"action\",\n fetchRequest,\n match,\n requestMatches,\n router.basename\n );\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by ou 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 if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n fetchRedirectIds.add(key);\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n ...submission,\n data: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n return startRedirectNavigation(state, actionResult, {\n isFetchActionRedirect: true,\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 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\n nextLocation,\n abortController.signal\n );\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(dataRoutes, state.navigation.location, init.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: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: actionResult.data,\n ...submission,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n { [match.route.id]: actionResult.data },\n undefined, // No need to send through errors since we short circuit above\n fetchLoadMatches\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(([staleKey]) => staleKey !== key)\n .forEach(([staleKey]) => {\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: existingFetcher && existingFetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(staleKey, revalidatingFetcher);\n fetchControllers.set(staleKey, abortController);\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let { results, 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 fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach(([staleKey]) =>\n fetchControllers.delete(staleKey)\n );\n\n let redirect = findRedirect(results);\n if (redirect) {\n return startRedirectNavigation(state, redirect);\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 let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: actionResult.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n\n let didAbortFetchLoads = 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 ...(didAbortFetchLoads ? { 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 submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n // Put this fetcher into it's loading state\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the loader for this fetcher route match\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n fetchControllers.set(key, abortController);\n let result: DataResult = await callLoaderOrAction(\n \"loader\",\n fetchRequest,\n match,\n matches,\n router.basename\n );\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 ou 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 // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n await startRedirectNavigation(state, result);\n return;\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n state.fetchers.delete(key);\n // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -\n // do we need to behave any differently with our non-redirect errors?\n // What if it was a non-redirect Response?\n updateState({\n fetchers: new Map(state.fetchers),\n errors: {\n [boundaryMatch.route.id]: result.error,\n },\n });\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\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 state: RouterState,\n redirect: RedirectResult,\n {\n submission,\n replace,\n isFetchActionRedirect,\n }: {\n submission?: Submission;\n replace?: boolean;\n isFetchActionRedirect?: boolean;\n } = {}\n ) {\n if (redirect.revalidate) {\n isRevalidationRequired = true;\n }\n\n let redirectLocation = createLocation(\n state.location,\n redirect.location,\n // TODO: This can be removed once we get rid of useTransition in Remix v2\n {\n _isRedirect: true,\n ...(isFetchActionRedirect ? { _isFetchActionRedirect: true } : {}),\n }\n );\n invariant(\n redirectLocation,\n \"Expected a location on the redirect navigation\"\n );\n\n // Check if this an external redirect that goes to a new origin\n if (isBrowser && typeof window?.location !== \"undefined\") {\n let newOrigin = init.history.createURL(redirect.location).origin;\n if (window.location.origin !== newOrigin) {\n if (replace) {\n window.location.replace(redirect.location);\n } else {\n window.location.assign(redirect.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, formData } = state.navigation;\n if (!submission && formMethod && formAction && formData && formEncType) {\n submission = {\n formMethod,\n formAction,\n formEncType,\n formData,\n };\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 if (\n redirectPreserveMethodStatusCodes.has(redirect.status) &&\n submission &&\n isMutationMethod(submission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...submission,\n formAction: redirect.location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // Otherwise, we kick off a new loading navigation, preserving the\n // submission info for the duration of this navigation\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation: {\n state: \"loading\",\n location: redirectLocation,\n formMethod: submission ? submission.formMethod : undefined,\n formAction: submission ? submission.formAction : undefined,\n formEncType: submission ? submission.formEncType : undefined,\n formData: submission ? submission.formData : undefined,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\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 // Call all navigation loaders and revalidating fetcher loaders in parallel,\n // then slice off the results into separate arrays so we can handle them\n // accordingly\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\"loader\", request, match, matches, router.basename)\n ),\n ...fetchersToLoad.map(([, href, match, fetchMatches]) =>\n callLoaderOrAction(\n \"loader\",\n createClientSideRequest(init.history, href, request.signal),\n match,\n fetchMatches,\n router.basename\n )\n ),\n ]);\n let loaderResults = results.slice(0, matchesToLoad.length);\n let fetcherResults = results.slice(matchesToLoad.length);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n request.signal,\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map(([, , match]) => match),\n fetcherResults,\n request.signal,\n true\n ),\n ]);\n\n return { results, loaderResults, fetcherResults };\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 setFetcherError(key: string, routeId: string, error: any) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n });\n }\n\n function deleteFetcher(key: string): void {\n if (fetchControllers.has(key)) abortFetcher(key);\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n state.fetchers.delete(key);\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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): void {\n let doneKeys = [];\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 }\n }\n markFetchersDone(doneKeys);\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 if (activeBlocker == null) {\n // This is now the active blocker\n activeBlocker = key;\n } else if (key !== activeBlocker) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n if (activeBlocker === key) {\n activeBlocker = null;\n }\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 state.blockers.set(key, newBlocker);\n updateState({ blockers: new Map(state.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 (activeBlocker == null) {\n return;\n }\n\n // We only allow a single blocker at the moment. This will need to be\n // updated if we enhance to support multiple blockers in the future\n let blockerFunction = blockerFunctions.get(activeBlocker);\n invariant(\n blockerFunction,\n \"Could not find a function for the active blocker\"\n );\n let blocker = state.blockers.get(activeBlocker);\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 activeBlocker;\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 || ((location) => location.key);\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 saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n router = {\n get basename() {\n return init.basename;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\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,\n dispose,\n getBlocker,\n deleteBlocker,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: {\n basename?: string;\n }\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(routes);\n let basename = (opts ? opts.basename : null) || \"/\";\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 async function query(\n request: Request,\n { requestContext }: { requestContext?: unknown } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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(request, location, matches, requestContext);\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 async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n }: { requestContext?: unknown; routeId?: string } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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 match\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 routeMatch?: AgnosticDataRouteMatch\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 routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\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, we throw\n // it to bail out and then return or throw here based on whether the user\n // returned or threw\n if (isQueryRouteResponse(e)) {\n if (e.type === ResultType.error && !isRedirectResponse(e.response)) {\n throw e.response;\n }\n return e.response;\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 isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n );\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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.status,\n headers: {\n Location: result.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 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 let context = await loadRouteData(\n request,\n matches,\n requestContext,\n undefined,\n {\n [boundaryMatch.route.id]: result.error,\n }\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 : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\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 let context = await loadRouteData(loaderRequest, matches, requestContext);\n\n return {\n ...context,\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n routeMatch?: AgnosticDataRouteMatch,\n pendingActionError?: RouteData\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 (isRouteRequest && !routeMatch?.route.loader) {\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 : getLoaderMatchesUntilBoundary(\n matches,\n Object.keys(pendingActionError || {})[0]\n );\n let matchesToLoad = requestMatches.filter((m) => m.route.loader);\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: pendingActionError || null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\n \"loader\",\n request,\n match,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n )\n ),\n ]);\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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 pendingActionError,\n activeDeferreds\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 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: 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction isSubmissionNavigation(\n opts: RouterNavigateOptions\n): opts is SubmissionNavigateOptions {\n return opts != null && \"formData\" in opts;\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 to: To,\n opts?: RouterNavigateOptions,\n isFetcher = false\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponse;\n} {\n let path = typeof to === \"string\" ? to : createPath(to);\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 // Create a Submission on non-GET navigations\n let submission: Submission | undefined;\n if (opts.formData) {\n submission = {\n formMethod: opts.formMethod || \"get\",\n formAction: stripHashFromPath(path),\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData: opts.formData,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n try {\n let searchParams = convertFormDataToSearchParams(opts.formData);\n // Since fetcher GET submissions only run a single loader (as opposed to\n // navigation GET submissions which run all loaders), we need to preserve\n // any incoming ?index params\n if (\n isFetcher &&\n parsedPath.search &&\n hasNakedIndexQuery(parsedPath.search)\n ) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n } catch (e) {\n return {\n path,\n error: getInternalRouterError(400),\n };\n }\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 isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n pendingActionData?: RouteData,\n pendingError?: RouteData,\n fetchLoadMatches?: Map\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingError\n ? Object.values(pendingError)[0]\n : pendingActionData\n ? Object.values(pendingActionData)[0]\n : undefined;\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;\n let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);\n let navigationMatches = boundaryMatches.filter(\n (match, index) =>\n match.route.loader != null &&\n (isNewLoader(state.loaderData, state.matches[index], match) ||\n // If this route had a pending deferred cancelled it must be revalidated\n cancelledDeferredRoutes.some((id) => id === match.route.id) ||\n shouldRevalidateLoader(\n history,\n state.location,\n state.matches[index],\n submission,\n location,\n match,\n isRevalidationRequired,\n actionResult\n ))\n );\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches &&\n fetchLoadMatches.forEach(([href, match, fetchMatches], key) => {\n // This fetcher was cancelled from a prior action submission - force reload\n if (cancelledFetcherLoads.includes(key)) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\n } else if (isRevalidationRequired) {\n let shouldRevalidate = shouldRevalidateLoader(\n history,\n href,\n match,\n submission,\n href,\n match,\n isRevalidationRequired,\n actionResult\n );\n if (shouldRevalidate) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\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 &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n history: History,\n currentLocation: string | Location,\n currentMatch: AgnosticDataRouteMatch,\n submission: Submission | undefined,\n location: string | Location,\n match: AgnosticDataRouteMatch,\n isRevalidationRequired: boolean,\n actionResult: DataResult | undefined\n) {\n let currentUrl = history.createURL(currentLocation);\n let currentParams = currentMatch.params;\n let nextUrl = history.createURL(location);\n let nextParams = match.params;\n\n // This is the default implementation as to 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 // Note that fetchers always provide the same current/next locations so the\n // URL-based checks here don't apply to fetcher shouldRevalidate calls\n let defaultShouldRevalidate =\n isNewRouteInstance(currentMatch, match) ||\n // Clicked the same link, resubmitted a GET form\n currentUrl.toString() === nextUrl.toString() ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate\n isRevalidationRequired;\n\n if (match.route.shouldRevalidate) {\n let routeChoice = match.route.shouldRevalidate({\n currentUrl,\n currentParams,\n nextUrl,\n nextParams,\n ...submission,\n actionResult,\n defaultShouldRevalidate,\n });\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return defaultShouldRevalidate;\n}\n\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n basename = \"/\",\n isStaticRequest: boolean = false,\n isRouteRequest: boolean = false,\n requestContext?: unknown\n): Promise {\n let resultType;\n let result;\n\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n let abortPromise = new Promise((_, r) => (reject = r));\n let onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n try {\n let handler = match.route[type];\n invariant(\n handler,\n `Could not find the ${type} to run on the \"${match.route.id}\" route`\n );\n\n result = await Promise.race([\n handler({ request, params: match.params, context: requestContext }),\n abortPromise,\n ]);\n\n invariant(\n 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 resultType = ResultType.error;\n result = e;\n } finally {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n\n if (isResponse(result)) {\n let status = result.status;\n\n // Process redirects\n if (redirectStatusCodes.has(status)) {\n let location = result.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(location);\n\n // Support relative routing in internal redirects\n if (!isAbsolute) {\n let activeMatches = matches.slice(0, matches.indexOf(match) + 1);\n let routePathnames = getPathContributingMatches(activeMatches).map(\n (match) => match.pathnameBase\n );\n let resolvedLocation = resolveTo(\n location,\n routePathnames,\n new URL(request.url).pathname\n );\n invariant(\n createPath(resolvedLocation),\n `Unable to resolve redirect location: ${location}`\n );\n\n // Prepend the basename to the redirect location if we have one\n if (basename) {\n let path = resolvedLocation.pathname;\n resolvedLocation.pathname =\n path === \"/\" ? basename : joinPaths([basename, path]);\n }\n\n location = createPath(resolvedLocation);\n } else if (!isStaticRequest) {\n // Strip off the protocol+origin for same-origin absolute redirects.\n // If this is a static reques, we can let it go back to the browser\n // as-is\n let currentUrl = new URL(request.url);\n let url = location.startsWith(\"//\")\n ? new URL(currentUrl.protocol + location)\n : new URL(location);\n if (url.origin === currentUrl.origin) {\n location = url.pathname + url.search + url.hash;\n }\n }\n\n // Don't process redirects in the router during static requests requests.\n // Instead, throw the Response and let the server handle it with an HTTP\n // redirect. We also update the Location header in place in this flow so\n // basename and relative routing is taken into account\n if (isStaticRequest) {\n result.headers.set(\"Location\", location);\n throw result;\n }\n\n return {\n type: ResultType.redirect,\n status,\n location,\n revalidate: result.headers.get(\"X-Remix-Revalidate\") !== null,\n };\n }\n\n // For SSR single-route requests, we want to hand Responses back directly\n // without unwrapping. We do this with the QueryRouteResponse wrapper\n // interface so we can know whether it was returned or thrown\n if (isRouteRequest) {\n // eslint-disable-next-line no-throw-literal\n throw {\n type: resultType || ResultType.data,\n response: result,\n };\n }\n\n let data: any;\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 data = await result.json();\n } else {\n data = await result.text();\n }\n\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: new ErrorResponse(status, result.statusText, data),\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 (resultType === ResultType.error) {\n return { type: resultType, error: result };\n }\n\n if (result instanceof DeferredData) {\n return { type: ResultType.deferred, deferredData: result };\n }\n\n return { type: ResultType.data, data: result };\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, formData } = submission;\n init.method = formMethod.toUpperCase();\n init.body =\n formEncType === \"application/x-www-form-urlencoded\"\n ? convertFormDataToSearchParams(formData)\n : formData;\n }\n\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\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 invariant(\n typeof value === \"string\",\n 'File inputs are not supported with encType \"application/x-www-form-urlencoded\", ' +\n 'please use \"multipart/form-data\" instead.'\n );\n searchParams.append(key, value);\n }\n\n return searchParams;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingError: RouteData | undefined,\n activeDeferreds: Map\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\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 // Look upwards from the matched route for the closest ancestor\n // error boundary, defaulting to the root match\n let boundaryMatch = findNearestBoundary(matches, id);\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) {\n error = Object.values(pendingError)[0];\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n // Prefer higher error values if lower errors bubble to the same boundary\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\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 } else {\n loaderData[id] = result.data;\n }\n\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 }\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) {\n errors = pendingError;\n loaderData[Object.keys(pendingError)[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 pendingError: RouteData | 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 pendingError,\n activeDeferreds\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let [key, , match] = 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 (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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\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) {\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\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 = 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 }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\";\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 (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 {\n errorMessage = \"Cannot submit binary form data using GET\";\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 ErrorResponse(\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(results: DataResult[]): RedirectResult | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return result;\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 return (\n a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash\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\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 isQueryRouteResponse(obj: any): obj is QueryRouteResponse {\n return (\n obj &&\n isResponse(obj.response) &&\n (obj.type === ResultType.data || ResultType.error)\n );\n}\n\nfunction isValidMethod(method: string): method is FormMethod {\n return validRequestMethods.has(method as FormMethod);\n}\n\nfunction isMutationMethod(method?: string): method is MutationFormMethod {\n return validMutationMethods.has(method as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n signal: AbortSignal,\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 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 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\n// Note: This should match the format exported by useMatches, so if you change\n// this please also change that :) Eventually we'll DRY this up\nfunction createUseMatchesMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UseMatchesMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id] as unknown,\n handle: route.handle as unknown,\n };\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//#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","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","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","nextAction","historyState","pushState","error","assign","origin","addEventListener","removeEventListener","ResultType","isIndexRoute","route","convertRoutesToDataRoutes","routes","parentPath","allIds","Set","treePath","id","join","children","has","add","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","matchRouteBranch","safelyDecodeURI","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","startsWith","joinPaths","routesMeta","concat","score","computeScore","forEach","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","match","matchPath","Object","params","pathnameBase","normalizePathname","generatePath","originalPath","_","optional","param","prefix","__","str","star","pattern","matcher","paramNames","compilePath","captureGroups","memo","paramName","splatValue","safelyDecodeURIComponent","regexpSource","RegExp","decodeURI","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","data","init","responseInit","status","headers","Headers","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","trackPromise","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","done","emit","settledKey","subscriber","subscribe","cancel","abort","v","k","resolveData","resolve","size","unwrappedData","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","ErrorResponse","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","isBrowser","createElement","isServer","createRouter","dataRoutes","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","initialized","m","loader","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","loaderData","actionData","errors","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeDeferreds","activeBlocker","blockerFunctions","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","deleteBlocker","updateState","startNavigation","dispose","clear","deleteFetcher","newState","completeNavigation","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","getSavedScrollPosition","navigate","opts","submission","normalizeNavigateOptions","userReplace","pendingError","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","loadingNavigation","notFoundMatches","cancelActiveDeferreds","isHashChangeOnly","request","createClientSideRequest","pendingActionData","findNearestBoundary","actionOutput","handleAction","shortCircuited","pendingActionError","Request","handleLoaders","actionMatch","getTargetMatch","type","method","routeId","callLoaderOrAction","isRedirectResult","startRedirectNavigation","isErrorResult","boundaryMatch","isDeferredResult","activeSubmission","matchesToLoad","revalidatingFetchers","getMatchesToLoad","fetcher","revalidatingFetcher","results","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","processLoaderData","deferredData","markFetchRedirectsDone","didAbortFetchLoads","abortStaleFetchLoads","getFetcher","fetch","abortFetcher","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","existingFetcher","abortController","fetchRequest","actionResult","loadingFetcher","isFetchActionRedirect","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","redirectLocation","_isFetchActionRedirect","newOrigin","redirectHistoryAction","currentMatches","fetchersToLoad","all","fetchMatches","resolveDeferredResults","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","userMatches","createUseMatchesMatch","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","query","requestContext","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","find","values","routeMatch","submit","loadRouteData","isQueryRouteResponse","isRedirectResponse","response","isRouteRequest","Location","context","loaderRequest","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","isSubmissionNavigation","isFetcher","stripHashFromPath","searchParams","convertFormDataToSearchParams","hasNakedIndexQuery","append","boundaryId","boundaryMatches","findIndex","navigationMatches","isNewLoader","shouldRevalidateLoader","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","isNewRouteInstance","currentPath","currentUrl","currentParams","nextUrl","nextParams","defaultShouldRevalidate","routeChoice","isStaticRequest","resultType","onReject","handler","isAbsolute","activeMatches","resolvedLocation","protocol","contentType","text","deferred","toUpperCase","body","URLSearchParams","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","hasErrorBoundary","errorMessage","obj","isRevalidatingLoader","unwrap","getAll","handle","pathMatches"],"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 0000000..cda147f --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.js @@ -0,0 +1,4073 @@ +/** + * @remix-run/router v1.3.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. + */ + exports.Action = void 0; + /** + * The pathname, search, and hash values of a URL. + */ + + (function (Action) { + Action["Pop"] = "POP"; + Action["Push"] = "PUSH"; + Action["Replace"] = "REPLACE"; + })(exports.Action || (exports.Action = {})); + + 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. + */ + + /** + * 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 = exports.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$1(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 = exports.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 = exports.Action.Replace; + let nextLocation = createMemoryLocation(to, state); + entries[index] = nextLocation; + + if (v5Compat && listener) { + listener({ + action, + location: nextLocation, + delta: 0 + }); + } + }, + + go(delta) { + action = exports.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)); + 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$1(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$1(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 = exports.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() { + let nextAction = exports.Action.Pop; + let nextIndex = getIndex(); + + if (nextIndex != null) { + let delta = nextIndex - index; + action = nextAction; + index = nextIndex; + + if (listener) { + listener({ + action, + location: history.location, + delta + }); + } + } else { + warning$1(false, // TODO: Write up a doc that explains our blocking strategy in detail + // and link to it here so people can understand better what is going on + // and how to avoid it. + "You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation."); + } + } + + function push(to, state) { + action = exports.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) { + // 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 = exports.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); + 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; + /** + * Successful result from a loader or action + */ + + (function (ResultType) { + ResultType["data"] = "data"; + ResultType["deferred"] = "deferred"; + ResultType["redirect"] = "redirect"; + ResultType["error"] = "error"; + })(ResultType || (ResultType = {})); + + 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, parentPath, allIds) { + if (parentPath === void 0) { + parentPath = []; + } + + if (allIds === void 0) { + allIds = new Set(); + } + + return routes.map((route, index) => { + let treePath = [...parentPath, 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(!allIds.has(id), "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages"); + allIds.add(id); + + if (isIndexRoute(route)) { + let indexRoute = _extends({}, route, { + id + }); + + return indexRoute; + } else { + let pathOrLayoutRoute = _extends({}, route, { + id, + children: route.children ? convertRoutesToDataRoutes(route.children, treePath, allIds) : undefined + }); + + 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 = "/"; + } + + 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) { + matches = matchRouteBranch(branches[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. + safelyDecodeURI(pathname)); + } + + return matches; + } + + 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 explodes _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) { + 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); + if (!match) return null; + Object.assign(matchedParams, match.params); + let route = meta.route; + 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(/\*$/, "/*"); + } + + return path.replace(/^:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return param; + }).replace(/\/:(\w+)(\??)/g, (_, key, optional) => { + let param = params[key]; + + if (optional === "?") { + return param == null ? "" : "/" + param; + } + + if (param == null) { + invariant(false, "Missing \":" + key + "\" param"); + } + + return "/" + param; + }) // Remove any optional markers from optional static segments + .replace(/\?/g, "").replace(/(\/?)\*/, (_, prefix, __, str) => { + const star = "*"; + + if (params[star] == null) { + // If no splat was provided, trim the trailing slash _unless_ it's + // the entire path + return str === "/*" ? "/" : ""; + } // Apply the splat + + + return "" + prefix + params[star]; + }); + } + /** + * A PathPattern is used to match on some portion of 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, paramNames] = 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 = paramNames.reduce((memo, paramName, 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"); + } + + memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName); + 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 paramNames = []; + 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) => { + paramNames.push(paramName); + return "/([^\\/]+)"; + }); + + if (path.endsWith("*")) { + paramNames.push("*"); + 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, paramNames]; + } + + function safelyDecodeURI(value) { + try { + return decodeURI(value); + } 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; + } + } + + function safelyDecodeURIComponent(value, paramName) { + try { + return decodeURIComponent(value); + } catch (error) { + warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" 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) || "/"; + } + /** + * @private + */ + + function warning(cond, message) { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + + try { + // Welcome to debugging @remix-run/router! + // + // 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) {} + } + } + /** + * 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); + } + /** + * @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 (isPathRelative || toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + if (toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); // 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". + + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + + to.pathname = toSegments.join("/"); + } // If there are more ".." segments than parent routes, resolve relative to + // the root / URL. + + + 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, _ref) => { + let [key, value] = _ref; + return Object.assign(acc, { + [key]: this.trackPromise(key, value) + }); + }, {}); + 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, null, 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 (error) { + 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, _ref2) => { + let [key, value] = _ref2; + 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 + })); + }; + /** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + */ + + class ErrorResponse { + 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 throw from an action/loader + */ + + function isRouteErrorResponse(e) { + return e instanceof ErrorResponse; + } + + //#region Types and Constants + //////////////////////////////////////////////////////////////////////////////// + + /** + * A Router instance manages all navigation and data loading/mutations + */ + + 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 + }; + const IDLE_FETCHER = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }; + const IDLE_BLOCKER = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined + }; + const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; + const isServer = !isBrowser; //#endregion + //////////////////////////////////////////////////////////////////////////////// + //#region createRouter + //////////////////////////////////////////////////////////////////////////////// + + /** + * Create a router and listen to history POP navigations + */ + + function createRouter(init) { + invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter"); + let dataRoutes = convertRoutesToDataRoutes(init.routes); // 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, init.basename); + let initialErrors = null; + + if (initialMatches == null) { + // 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 + }; + } + + let initialized = !initialMatches.some(m => m.route.loader) || 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 = exports.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; // 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) + // - useRevalidate() + // - 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 from their actions + + let fetchRedirectIds = new Set(); // Most recent href/match for fetcher.load calls for fetchers + + let fetchLoadMatches = new Map(); // 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(); // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + + let activeBlocker = null; // 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(); // 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; + } + + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction + }); + + if (blockerKey) { + // 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(router.state.blockers) + }); + } + + }); + return; + } + + return startNavigation(historyAction, location); + }); // Kick off initial data load if needed. Use Pop to avoid modifying history + + if (!state.initialized) { + startNavigation(exports.Action.Pop, state.location); + } + + return router; + } // Clean up a router and it's side effects + + + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + + 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) { + state = _extends({}, state, newState); + subscribers.forEach(subscriber => subscriber(state)); + } // 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) { + var _location$state, _location$state2; + + // 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 + + for (let [key] of blockerFunctions) { + deleteBlocker(key); + } // 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; + 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: new Map(state.blockers) + })); + + if (isUninterruptedRevalidation) ; else if (pendingAction === exports.Action.Pop) ; else if (pendingAction === exports.Action.Push) { + init.history.push(location, location.state); + } else if (pendingAction === exports.Action.Replace) { + init.history.replace(location, location.state); + } // Reset stateful navigation vars + + + pendingAction = exports.Action.Pop; + pendingPreventScrollReset = 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 { + path, + submission, + error + } = normalizeNavigateOptions(to, 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 = exports.Action.Push; + + if (userReplace === true) { + historyAction = exports.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 = exports.Action.Replace; + } + + let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined; + 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() { + deleteBlocker(blockerKey); + updateState({ + blockers: new Map(state.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 + }); + } // 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; + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(dataRoutes, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing + + if (!matches) { + let error = getInternalRouterError(404, { + pathname: location.pathname + }); + let { + matches: notFoundMatches, + route + } = getShortCircuitMatches(dataRoutes); // Cancel all pending deferred on 404s since we don't keep any routes + + cancelActiveDeferreds(); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error + } + }); + return; + } // Short circuit if it's only a hash change + + + if (isHashChangeOnly(state.location, location)) { + completeNavigation(location, { + matches + }); + return; + } // Create a controller/Request for this navigation + + + pendingNavigationController = new AbortController(); + let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission); + let pendingActionData; + let pendingError; + + 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. + pendingError = { + [findNearestBoundary(matches).route.id]: opts.pendingError + }; + } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { + // Call action if we received an action submission + let actionOutput = await handleAction(request, location, opts.submission, matches, { + replace: opts.replace + }); + + if (actionOutput.shortCircuited) { + return; + } + + pendingActionData = actionOutput.pendingActionData; + pendingError = actionOutput.pendingActionError; + + let navigation = _extends({ + state: "loading", + location + }, opts.submission); + + loadingNavigation = navigation; // Create a GET request for the loaders + + request = new Request(request.url, { + signal: request.signal + }); + } // Call loaders + + + let { + shortCircuited, + loaderData, + errors + } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.replace, pendingActionData, pendingError); + + 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 + }, pendingActionData ? { + actionData: pendingActionData + } : {}, { + loaderData, + errors + })); + } // Call the action matched by the leaf route for this navigation and handle + // redirects/errors + + + async function handleAction(request, location, submission, matches, opts) { + interruptActiveLoads(); // Put us in a submitting state + + let navigation = _extends({ + state: "submitting", + location + }, submission); + + updateState({ + navigation + }); // Call our action and get the result + + let result; + let actionMatch = getTargetMatch(matches, location); + + if (!actionMatch.route.action) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id + }) + }; + } else { + result = await callLoaderOrAction("action", request, actionMatch, matches, router.basename); + + 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 + replace = result.location === state.location.pathname + state.location.search; + } + + await startRedirectNavigation(state, result, { + submission, + replace + }); + return { + shortCircuited: true + }; + } + + 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 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 = exports.Action.Push; + } + + return { + // Send back an empty object we can use to clear out any prior actionData + pendingActionData: {}, + pendingActionError: { + [boundaryMatch.route.id]: result.error + } + }; + } + + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { + type: "defer-action" + }); + } + + return { + pendingActionData: { + [actionMatch.route.id]: result.data + } + }; + } // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + + + async function handleLoaders(request, location, matches, overrideNavigation, submission, replace, pendingActionData, pendingError) { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation; + + if (!loadingNavigation) { + let navigation = _extends({ + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission); + + loadingNavigation = navigation; + } // 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 ? submission : loadingNavigation.formMethod && loadingNavigation.formAction && loadingNavigation.formData && loadingNavigation.formEncType ? { + formMethod: loadingNavigation.formMethod, + formAction: loadingNavigation.formAction, + formData: loadingNavigation.formData, + formEncType: loadingNavigation.formEncType + } : undefined; + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // 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)); // Short circuit if we have no loaders to run + + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + completeNavigation(location, _extends({ + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingError || null + }, pendingActionData ? { + actionData: pendingActionData + } : {})); + return { + shortCircuited: true + }; + } // 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 (!isUninterruptedRevalidation) { + revalidatingFetchers.forEach(_ref2 => { + let [key] = _ref2; + let fetcher = state.fetchers.get(key); + let revalidatingFetcher = { + state: "loading", + data: fetcher && fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, revalidatingFetcher); + }); + let actionData = pendingActionData || state.actionData; + updateState(_extends({ + navigation: loadingNavigation + }, actionData ? Object.keys(actionData).length === 0 ? { + actionData: null + } : { + actionData + } : {}, revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {})); + } + + pendingNavigationLoadId = ++incrementingLoadId; + revalidatingFetchers.forEach(_ref3 => { + let [key] = _ref3; + return fetchControllers.set(key, pendingNavigationController); + }); + let { + results, + 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 + + + revalidatingFetchers.forEach(_ref4 => { + let [key] = _ref4; + return fetchControllers.delete(key); + }); // If any loaders returned a redirect Response, start a new REPLACE navigation + + let redirect = findRedirect(results); + + if (redirect) { + await startRedirectNavigation(state, redirect, { + replace + }); + return { + shortCircuited: true + }; + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingError, 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); + } + }); + }); + markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + return _extends({ + loaderData, + errors + }, didAbortFetchLoads || revalidatingFetchers.length > 0 ? { + fetchers: new Map(state.fetchers) + } : {}); + } + + function getFetcher(key) { + return state.fetchers.get(key) || IDLE_FETCHER; + } // 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 matches = matchRoutes(dataRoutes, href, init.basename); + + if (!matches) { + setFetcherError(key, routeId, getInternalRouterError(404, { + pathname: href + })); + return; + } + + let { + path, + submission + } = normalizeNavigateOptions(href, opts, true); + let match = getTargetMatch(matches, path); + + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, submission); + return; + } // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + + + fetchLoadMatches.set(key, [path, match, matches]); + handleFetcherLoader(key, routeId, path, match, matches, submission); + } // Call the action for the matched fetcher.submit(), and then handle redirects, + // errors, and revalidation + + + async function handleFetcherAction(key, routeId, path, match, requestMatches, submission) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + + if (!match.route.action) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId + }); + setFetcherError(key, routeId, error); + return; + } // Put this fetcher into it's submitting state + + + let existingFetcher = state.fetchers.get(key); + + let fetcher = _extends({ + state: "submitting" + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, fetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the action for the fetcher + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission); + fetchControllers.set(key, abortController); + let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename); + + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by ou our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + + return; + } + + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + fetchRedirectIds.add(key); + + let loadingFetcher = _extends({ + state: "loading" + }, submission, { + data: undefined, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + return startRedirectNavigation(state, actionResult, { + isFetchActionRedirect: true + }); + } // 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 matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches; + invariant(matches, "Didn't find any matches after fetcher action"); + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + + let loadFetcher = _extends({ + state: "loading", + data: actionResult.data + }, submission, { + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadFetcher); + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, { + [match.route.id]: actionResult.data + }, undefined, // No need to send through errors since we short circuit above + fetchLoadMatches); // 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(_ref5 => { + let [staleKey] = _ref5; + return staleKey !== key; + }).forEach(_ref6 => { + let [staleKey] = _ref6; + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher = { + state: "loading", + data: existingFetcher && existingFetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(staleKey, revalidatingFetcher); + fetchControllers.set(staleKey, abortController); + }); + updateState({ + fetchers: new Map(state.fetchers) + }); + let { + results, + loaderResults, + fetcherResults + } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest); + + if (abortController.signal.aborted) { + return; + } + + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(_ref7 => { + let [staleKey] = _ref7; + return fetchControllers.delete(staleKey); + }); + let redirect = findRedirect(results); + + if (redirect) { + return startRedirectNavigation(state, redirect); + } // Process and commit output from loaders + + + let { + loaderData, + errors + } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds); + let doneFetcher = { + state: "idle", + data: actionResult.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + let didAbortFetchLoads = 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(_extends({ + errors, + loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors) + }, didAbortFetchLoads ? { + 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, submission) { + let existingFetcher = state.fetchers.get(key); // Put this fetcher into it's loading state + + let loadingFetcher = _extends({ + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined + }, submission, { + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true + }); + + state.fetchers.set(key, loadingFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); // Call the loader for this fetcher route match + + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest(init.history, path, abortController.signal); + fetchControllers.set(key, abortController); + let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // 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 ou 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; + } // If the loader threw a redirect Response, start a new REPLACE navigation + + + if (isRedirectResult(result)) { + await startRedirectNavigation(state, result); + return; + } // Process any non-redirect errors thrown + + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + state.fetchers.delete(key); // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch - + // do we need to behave any differently with our non-redirect errors? + // What if it was a non-redirect Response? + + updateState({ + fetchers: new Map(state.fetchers), + errors: { + [boundaryMatch.route.id]: result.error + } + }); + return; + } + + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); // Put the fetcher back into an idle state + + let doneFetcher = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + updateState({ + fetchers: new Map(state.fetchers) + }); + } + /** + * 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(state, redirect, _temp) { + var _window; + + let { + submission, + replace, + isFetchActionRedirect + } = _temp === void 0 ? {} : _temp; + + if (redirect.revalidate) { + isRevalidationRequired = true; + } + + let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2 + _extends({ + _isRedirect: true + }, isFetchActionRedirect ? { + _isFetchActionRedirect: true + } : {})); + invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin + + if (isBrowser && typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") { + let newOrigin = init.history.createURL(redirect.location).origin; + + if (window.location.origin !== newOrigin) { + if (replace) { + window.location.replace(redirect.location); + } else { + window.location.assign(redirect.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 ? exports.Action.Replace : exports.Action.Push; // Use the incoming submission if provided, fallback on the active one in + // state.navigation + + let { + formMethod, + formAction, + formEncType, + formData + } = state.navigation; + + if (!submission && formMethod && formAction && formData && formEncType) { + submission = { + formMethod, + formAction, + formEncType, + formData + }; + } // 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 + + + if (redirectPreserveMethodStatusCodes.has(redirect.status) && submission && isMutationMethod(submission.formMethod)) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: _extends({}, submission, { + formAction: redirect.location + }), + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } else { + // Otherwise, we kick off a new loading navigation, preserving the + // submission info for the duration of this navigation + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation: { + state: "loading", + location: redirectLocation, + formMethod: submission ? submission.formMethod : undefined, + formAction: submission ? submission.formAction : undefined, + formEncType: submission ? submission.formEncType : undefined, + formData: submission ? submission.formData : undefined + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset + }); + } + } + + async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) { + // Call all navigation loaders and revalidating fetcher loaders in parallel, + // then slice off the results into separate arrays so we can handle them + // accordingly + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => { + let [, href, match, fetchMatches] = _ref8; + return callLoaderOrAction("loader", createClientSideRequest(init.history, href, request.signal), match, fetchMatches, router.basename); + })]); + let loaderResults = results.slice(0, matchesToLoad.length); + let fetcherResults = results.slice(matchesToLoad.length); + await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(_ref9 => { + let [,, match] = _ref9; + return match; + }), fetcherResults, request.signal, true)]); + return { + results, + 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 setFetcherError(key, routeId, error) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error + }, + fetchers: new Map(state.fetchers) + }); + } + + function deleteFetcher(key) { + if (fetchControllers.has(key)) abortFetcher(key); + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + state.fetchers.delete(key); + } + + 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 = { + state: "idle", + data: fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + state.fetchers.set(key, doneFetcher); + } + } + + function markFetchRedirectsDone() { + let doneKeys = []; + + 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); + } + } + + markFetchersDone(doneKeys); + } + + 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); + + if (activeBlocker == null) { + // This is now the active blocker + activeBlocker = key; + } else if (key !== activeBlocker) { + warning(false, "A router only supports one blocker at a time"); + } + } + + return blocker; + } + + function deleteBlocker(key) { + state.blockers.delete(key); + blockerFunctions.delete(key); + + if (activeBlocker === key) { + activeBlocker = null; + } + } // 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); + state.blockers.set(key, newBlocker); + updateState({ + blockers: new Map(state.blockers) + }); + } + + function shouldBlockNavigation(_ref10) { + let { + currentLocation, + nextLocation, + historyAction + } = _ref10; + + if (activeBlocker == null) { + return; + } // We only allow a single blocker at the moment. This will need to be + // updated if we enhance to support multiple blockers in the future + + + let blockerFunction = blockerFunctions.get(activeBlocker); + invariant(blockerFunction, "Could not find a function for the active blocker"); + let blocker = state.blockers.get(activeBlocker); + + 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 activeBlocker; + } + } + + 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 || (location => location.key); // 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 saveScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + savedScrollPositions[key] = getScrollPosition(); + } + } + + function getSavedScrollPosition(location, matches) { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map(m => createUseMatchesMatch(m, state.loaderData)); + let key = getScrollRestorationKey(location, userMatches) || location.key; + let y = savedScrollPositions[key]; + + if (typeof y === "number") { + return y; + } + } + + return null; + } + + router = { + get basename() { + return init.basename; + }, + + get state() { + return state; + }, + + get routes() { + return dataRoutes; + }, + + 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, + dispose, + getBlocker, + deleteBlocker, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds + }; + 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 dataRoutes = convertRoutesToDataRoutes(routes); + let basename = (opts ? opts.basename : null) || "/"; + /** + * 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. + */ + + async function query(request, _temp2) { + let { + requestContext + } = _temp2 === void 0 ? {} : _temp2; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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); + + 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. + */ + + + async function queryRoute(request, _temp3) { + let { + routeId, + requestContext + } = _temp3 === void 0 ? {} : _temp3; + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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, 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, 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, routeMatch != null); + return result; + } + + let result = await loadRouteData(request, matches, requestContext, routeMatch); + return isResponse(result) ? result : _extends({}, result, { + actionData: null, + actionHeaders: {} + }); + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction, we throw + // it to bail out and then return or throw here based on whether the user + // returned or threw + if (isQueryRouteResponse(e)) { + if (e.type === ResultType.error && !isRedirectResponse(e.response)) { + throw e.response; + } + + return e.response; + } // 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, isRouteRequest) { + let result; + + if (!actionMatch.route.action) { + 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 { + result = await callLoaderOrAction("action", request, actionMatch, matches, basename, true, isRouteRequest, requestContext); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } + } + + 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.status, + headers: { + Location: result.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 + }; + } + + 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); + let context = await loadRouteData(request, matches, requestContext, undefined, { + [boundaryMatch.route.id]: result.error + }); // action status codes take precedence over loader status codes + + return _extends({}, context, { + statusCode: isRouteErrorResponse(result.error) ? result.error.status : 500, + actionData: null, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } // Create a GET request for the loaders + + + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal + }); + let context = await loadRouteData(loaderRequest, matches, requestContext); + return _extends({}, context, result.statusCode ? { + statusCode: result.statusCode + } : {}, { + actionData: { + [actionMatch.route.id]: result.data + }, + actionHeaders: _extends({}, result.headers ? { + [actionMatch.route.id]: result.headers + } : {}) + }); + } + + async function loadRouteData(request, matches, requestContext, routeMatch, pendingActionError) { + let isRouteRequest = routeMatch != null; // Short circuit if we have no loaders to run (queryRoute()) + + if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader)) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch == null ? void 0 : routeMatch.route.id + }); + } + + let requestMatches = routeMatch ? [routeMatch] : getLoaderMatchesUntilBoundary(matches, Object.keys(pendingActionError || {})[0]); + let matchesToLoad = requestMatches.filter(m => m.route.loader); // 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: pendingActionError || null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null + }; + } + + let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, basename, true, isRouteRequest, requestContext))]); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(method + "() call aborted"); + } // Process and commit output from loaders + + + let activeDeferreds = new Map(); + let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError, activeDeferreds); // 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 + }); + } + + 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: 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error + } + }); + + return newContext; + } + + function isSubmissionNavigation(opts) { + return opts != null && "formData" in opts; + } // Normalize navigation options by converting formMethod=GET formData objects to + // URLSearchParams so they behave identically to links with query params + + + function normalizeNavigateOptions(to, opts, isFetcher) { + if (isFetcher === void 0) { + isFetcher = false; + } + + let path = typeof to === "string" ? to : createPath(to); // 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 + }) + }; + } // Create a Submission on non-GET navigations + + + let submission; + + if (opts.formData) { + submission = { + formMethod: opts.formMethod || "get", + formAction: stripHashFromPath(path), + formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", + formData: opts.formData + }; + + if (isMutationMethod(submission.formMethod)) { + return { + path, + submission + }; + } + } // Flatten submission onto URLSearchParams for GET submissions + + + let parsedPath = parsePath(path); + + try { + let searchParams = convertFormDataToSearchParams(opts.formData); // Since fetcher GET submissions only run a single loader (as opposed to + // navigation GET submissions which run all loaders), we need to preserve + // any incoming ?index params + + if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { + searchParams.append("index", ""); + } + + parsedPath.search = "?" + searchParams; + } catch (e) { + return { + path, + error: getInternalRouterError(400) + }; + } + + 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, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) { + let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation + + let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined; + let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId); + let navigationMatches = boundaryMatches.filter((match, index) => match.route.loader != null && (isNewLoader(state.loaderData, state.matches[index], match) || // If this route had a pending deferred cancelled it must be revalidated + cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated + + let revalidatingFetchers = []; + fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => { + let [href, match, fetchMatches] = _ref11; + + // This fetcher was cancelled from a prior action submission - force reload + if (cancelledFetcherLoads.includes(key)) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } else if (isRevalidationRequired) { + let shouldRevalidate = shouldRevalidateLoader(history, href, match, submission, href, match, isRevalidationRequired, actionResult); + + if (shouldRevalidate) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } + } + }); + 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 && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] + ); + } + + function shouldRevalidateLoader(history, currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) { + let currentUrl = history.createURL(currentLocation); + let currentParams = currentMatch.params; + let nextUrl = history.createURL(location); + let nextParams = match.params; // This is the default implementation as to 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 + // Note that fetchers always provide the same current/next locations so the + // URL-based checks here don't apply to fetcher shouldRevalidate calls + + let defaultShouldRevalidate = isNewRouteInstance(currentMatch, match) || // Clicked the same link, resubmitted a GET form + currentUrl.toString() === nextUrl.toString() || // Search params affect all loaders + currentUrl.search !== nextUrl.search || // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate + isRevalidationRequired; + + if (match.route.shouldRevalidate) { + let routeChoice = match.route.shouldRevalidate(_extends({ + currentUrl, + currentParams, + nextUrl, + nextParams + }, submission, { + actionResult, + defaultShouldRevalidate + })); + + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + + return defaultShouldRevalidate; + } + + async function callLoaderOrAction(type, request, match, matches, basename, isStaticRequest, isRouteRequest, requestContext) { + if (basename === void 0) { + basename = "/"; + } + + if (isStaticRequest === void 0) { + isStaticRequest = false; + } + + if (isRouteRequest === void 0) { + isRouteRequest = false; + } + + let resultType; + let result; // Setup a promise we can race against so that abort signals short circuit + + let reject; + let abortPromise = new Promise((_, r) => reject = r); + + let onReject = () => reject(); + + request.signal.addEventListener("abort", onReject); + + try { + let handler = match.route[type]; + invariant(handler, "Could not find the " + type + " to run on the \"" + match.route.id + "\" route"); + result = await Promise.race([handler({ + request, + params: match.params, + context: requestContext + }), abortPromise]); + invariant(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) { + resultType = ResultType.error; + result = e; + } finally { + request.signal.removeEventListener("abort", onReject); + } + + if (isResponse(result)) { + let status = result.status; // Process redirects + + if (redirectStatusCodes.has(status)) { + let location = result.headers.get("Location"); + invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); + let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location); // Support relative routing in internal redirects + + if (!isAbsolute) { + let activeMatches = matches.slice(0, matches.indexOf(match) + 1); + let routePathnames = getPathContributingMatches(activeMatches).map(match => match.pathnameBase); + let resolvedLocation = resolveTo(location, routePathnames, new URL(request.url).pathname); + invariant(createPath(resolvedLocation), "Unable to resolve redirect location: " + location); // Prepend the basename to the redirect location if we have one + + if (basename) { + let path = resolvedLocation.pathname; + resolvedLocation.pathname = path === "/" ? basename : joinPaths([basename, path]); + } + + location = createPath(resolvedLocation); + } else if (!isStaticRequest) { + // Strip off the protocol+origin for same-origin absolute redirects. + // If this is a static reques, we can let it go back to the browser + // as-is + let currentUrl = new URL(request.url); + let url = location.startsWith("//") ? new URL(currentUrl.protocol + location) : new URL(location); + + if (url.origin === currentUrl.origin) { + location = url.pathname + url.search + url.hash; + } + } // Don't process redirects in the router during static requests requests. + // Instead, throw the Response and let the server handle it with an HTTP + // redirect. We also update the Location header in place in this flow so + // basename and relative routing is taken into account + + + if (isStaticRequest) { + result.headers.set("Location", location); + throw result; + } + + return { + type: ResultType.redirect, + status, + location, + revalidate: result.headers.get("X-Remix-Revalidate") !== null + }; + } // For SSR single-route requests, we want to hand Responses back directly + // without unwrapping. We do this with the QueryRouteResponse wrapper + // interface so we can know whether it was returned or thrown + + + if (isRouteRequest) { + // eslint-disable-next-line no-throw-literal + throw { + type: resultType || ResultType.data, + response: result + }; + } + + let data; + 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)) { + data = await result.json(); + } else { + data = await result.text(); + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: new ErrorResponse(status, result.statusText, data), + headers: result.headers + }; + } + + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers + }; + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: result + }; + } + + if (result instanceof DeferredData) { + return { + type: ResultType.deferred, + deferredData: result + }; + } + + return { + type: ResultType.data, + data: result + }; + } // 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, + formData + } = submission; + init.method = formMethod.toUpperCase(); + init.body = formEncType === "application/x-www-form-urlencoded" ? convertFormDataToSearchParams(formData) : formData; + } // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + + + return new Request(url, init); + } + + function convertFormDataToSearchParams(formData) { + let searchParams = new URLSearchParams(); + + for (let [key, value] of formData.entries()) { + invariant(typeof value === "string", 'File inputs are not supported with encType "application/x-www-form-urlencoded", ' + 'please use "multipart/form-data" instead.'); + searchParams.append(key, value); + } + + return searchParams; + } + + function processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds) { + // Fill in loaderData/errors from our loaders + let loaderData = {}; + let errors = null; + let statusCode; + let foundError = false; + let loaderHeaders = {}; // 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)) { + // Look upwards from the matched route for the closest ancestor + // error boundary, defaulting to the root match + let boundaryMatch = findNearestBoundary(matches, id); + 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) { + error = Object.values(pendingError)[0]; + pendingError = undefined; + } + + errors = errors || {}; // Prefer higher error values if lower errors bubble to the same boundary + + 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; + } 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 != null && 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) { + errors = pendingError; + loaderData[Object.keys(pendingError)[0]] = undefined; + } + + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders + }; + } + + function processLoaderData(state, matches, matchesToLoad, results, pendingError, revalidatingFetchers, fetcherResults, activeDeferreds) { + let { + loaderData, + errors + } = processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds); // Process results from our revalidating fetchers + + for (let index = 0; index < revalidatingFetchers.length; index++) { + let [key,, match] = revalidatingFetchers[index]; + invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result"); + let result = fetcherResults[index]; // Process fetcher non-redirect errors + + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, 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 = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true + }; + 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) { + mergedLoaderData[id] = loaderData[id]; + } + + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + + return mergedLoaderData; + } // 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.find(r => r.index || !r.path || r.path === "/") || { + id: "__shim-error-route__" + }; + return { + matches: [{ + params: {}, + pathname: "", + pathnameBase: "", + route + }], + route + }; + } + + function getInternalRouterError(status, _temp4) { + let { + pathname, + routeId, + method, + type + } = _temp4 === void 0 ? {} : _temp4; + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + + if (status === 400) { + statusText = "Bad Request"; + + 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 { + errorMessage = "Cannot submit binary form data using GET"; + } + } 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 ErrorResponse(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; + } + } + } + + function stripHashFromPath(path) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath(_extends({}, parsedPath, { + hash: "" + })); + } + + function isHashChangeOnly(a, b) { + return a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash; + } + + 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 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 isQueryRouteResponse(obj) { + return obj && isResponse(obj.response) && (obj.type === ResultType.data || ResultType.error); + } + + function isValidMethod(method) { + return validRequestMethods.has(method); + } + + function isMutationMethod(method) { + return validMutationMethods.has(method); + } + + async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + 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 + 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 === ""); + } // Note: This should match the format exported by useMatches, so if you change + // this please also change that :) Eventually we'll DRY this up + + + function createUseMatchesMatch(match, loaderData) { + let { + route, + pathname, + params + } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id], + handle: route.handle + }; + } + + 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]; + } //#endregion + + exports.AbortedDeferredError = AbortedDeferredError; + exports.ErrorResponse = ErrorResponse; + 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_convertRoutesToDataRoutes = convertRoutesToDataRoutes; + exports.UNSAFE_getPathContributingMatches = getPathContributingMatches; + 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.invariant = invariant; + 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.resolvePath = resolvePath; + exports.resolveTo = resolveTo; + exports.stripBasename = stripBasename; + exports.warning = warning; + + 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 0000000..fce8a70 --- /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/**\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: any;\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;\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`. May be either a URL or the pieces of a\n * 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 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\nfunction 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 let nextAction = Action.Pop;\n let nextIndex = getIndex();\n\n if (nextIndex != null) {\n let delta = nextIndex - index;\n action = nextAction;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n } else {\n warning(\n false,\n // TODO: Write up a doc that explains our blocking strategy in detail\n // and link to it here so people can understand better what is going on\n // and how to avoid it.\n `You are trying to block a POP navigation to a location that was not ` +\n `created by @remix-run/router. The block will fail silently in ` +\n `production, but in general you should do all navigation with the ` +\n `router (instead of using window.history.pushState directly) ` +\n `to avoid this situation.`\n );\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 // 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 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 } 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: any;\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 status: number;\n location: string;\n revalidate: boolean;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: any;\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\nexport type MutationFormMethod = \"post\" | \"put\" | \"patch\" | \"delete\";\nexport type FormMethod = \"get\" | MutationFormMethod;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\";\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport interface Submission {\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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?: any;\n}\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Route loader function signature\n */\nexport interface LoaderFunction {\n (args: LoaderFunctionArgs): Promise | Response | Promise | any;\n}\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (args: ActionFunctionArgs): Promise | Response | Promise | any;\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: {\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 formData?: Submission[\"formData\"];\n actionResult?: DataResult;\n defaultShouldRevalidate: boolean;\n }): boolean;\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;\n action?: ActionFunction;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\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\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 */\ntype 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 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 parentPath: number[] = [],\n allIds: Set = new Set()\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, 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 !allIds.has(id),\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n allIds.add(id);\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = { ...route, id };\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n id,\n children: route.children\n ? convertRoutesToDataRoutes(route.children, treePath, allIds)\n : undefined,\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 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 matches = matchRouteBranch(\n branches[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 safelyDecodeURI(pathname)\n );\n }\n\n return matches;\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\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 explodes _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): 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 if (!match) return null;\n\n Object.assign(matchedParams, match.params);\n\n let route = meta.route;\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 = 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 return (\n path\n .replace(\n /^:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : param;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return param;\n }\n )\n .replace(\n /\\/:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : `/${param}`;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return `/${param}`;\n }\n )\n // Remove any optional markers from optional static segments\n .replace(/\\?/g, \"\")\n .replace(/(\\/?)\\*/, (_, prefix, __, str) => {\n const star = \"*\" as PathParam;\n\n if (params[star] == null) {\n // If no splat was provided, trim the trailing slash _unless_ it's\n // the entire path\n return str === \"/*\" ? \"/\" : \"\";\n }\n\n // Apply the splat\n return `${prefix}${params[star]}`;\n })\n );\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, paramNames] = 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 = paramNames.reduce>(\n (memo, paramName, 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 memo[paramName] = safelyDecodeURIComponent(\n captureGroups[index] || \"\",\n paramName\n );\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, string[]] {\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 paramNames: string[] = [];\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(/\\/:(\\w+)/g, (_: string, paramName: string) => {\n paramNames.push(paramName);\n return \"/([^\\\\/]+)\";\n });\n\n if (path.endsWith(\"*\")) {\n paramNames.push(\"*\");\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, paramNames];\n}\n\nfunction safelyDecodeURI(value: string) {\n try {\n return decodeURI(value);\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\nfunction safelyDecodeURIComponent(value: string, paramName: string) {\n try {\n return decodeURIComponent(value);\n } catch (error) {\n warning(\n false,\n `The value for the URL param \"${paramName}\" will not be decoded because` +\n ` the string \"${value}\" is a malformed URL segment. This is probably` +\n ` due to a bad percent 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 * @private\n */\nexport function warning(cond: any, message: string): void {\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 @remix-run/router!\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\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/**\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 (isPathRelative || toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n if (toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n // Each leading .. segment means \"go up one route\" instead of \"go up one\n // URL segment\". This is a key difference from how works and a\n // major reason we call this a \"to\" value instead of a \"href\".\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n // If there are more \"..\" segments than parent routes, resolve relative to\n // the root / URL.\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 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, null, 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 (error) {\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 * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n */\nexport class ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n error?: Error;\n 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 throw from an action/loader\n */\nexport function isRouteErrorResponse(e: any): e is ErrorResponse {\n return e instanceof ErrorResponse;\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n} from \"./history\";\nimport type {\n DataResult,\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DeferredResult,\n ErrorResult,\n FormEncType,\n FormMethod,\n RedirectResult,\n RouteData,\n AgnosticRouteObject,\n Submission,\n SuccessResult,\n AgnosticRouteMatch,\n MutationFormMethod,\n} from \"./utils\";\nimport {\n DeferredData,\n ErrorResponse,\n ResultType,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n resolveTo,\n warning,\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 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 * 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, 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,\n opts?: RouterNavigateOptions\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 * 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 * Initialization options for createRouter\n */\nexport interface RouterInit {\n basename?: string;\n routes: AgnosticRouteObject[];\n history: History;\n hydrationData?: HydrationState;\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?: { requestContext?: unknown }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: { routeId?: string; requestContext?: unknown }\n ): Promise;\n}\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (state: RouterState): void;\n}\n\ninterface UseMatchesMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: unknown;\n handle: unknown;\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: UseMatchesMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\n/**\n * Options for a navigate() call for a Link navigation\n */\ntype LinkNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n};\n\n/**\n * Options for a navigate() call for a Form navigation\n */\ntype SubmissionNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n formMethod?: FormMethod;\n formEncType?: FormEncType;\n formData: FormData;\n};\n\n/**\n * Options to pass to navigate() for either a Link or Form navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions =\n | Omit\n | Omit;\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 };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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 formData: undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Loading: {\n state: \"loading\";\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\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\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Error thrown from the current action, keyed by the route containing the\n * error boundary to render the error. To be committed to the state after\n * loaders have completed\n */\n pendingActionError?: RouteData;\n /**\n * Data returned from the current action, keyed by the route owning the action.\n * To be committed to the state after loaders have completed\n */\n pendingActionData?: RouteData;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\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 * Tuple of [key, href, DataRouteMatch, DataRouteMatch[]] for a revalidating\n * fetcher.load()\n */\ntype RevalidatingFetcher = [\n string,\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Tuple of [href, DataRouteMatch, DataRouteMatch[]] for an active\n * fetcher.load()\n */\ntype FetchLoadMatch = [\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Wrapper object to allow us to throw any response out from callLoaderOrAction\n * for queryRouter while preserving whether or not it was thrown or returned\n * from the loader/action\n */\ninterface QueryRouteResponse {\n type: ResultType.data | ResultType.error;\n response: Response;\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};\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};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n typeof window.document !== \"undefined\" &&\n typeof window.document.createElement !== \"undefined\";\nconst isServer = !isBrowser;\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 invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(init.routes);\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(\n dataRoutes,\n init.history.location,\n init.basename\n );\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null) {\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 let initialized =\n !initialMatches.some((m) => m.route.loader) || init.hydrationData != null;\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 // 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 // - useRevalidate()\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 from their actions\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\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 // 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 let activeBlocker: string | null = null;\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 // 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 let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n if (blockerKey) {\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(router.state.blockers) });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location);\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 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(newState: Partial): void {\n state = {\n ...state,\n ...newState,\n };\n subscribers.forEach((subscriber) => subscriber(state));\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 ): 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 for (let [key] of blockerFunctions) {\n deleteBlocker(key);\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 updateState({\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: new Map(state.blockers),\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 // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = 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,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(to, opts);\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 blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(state.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 });\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 submission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponse;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: 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 let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(dataRoutes, location, init.basename);\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n });\n return;\n }\n\n // Short circuit if it's only a hash change\n if (isHashChangeOnly(state.location, location)) {\n completeNavigation(location, { matches });\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 pendingActionData: RouteData | undefined;\n let pendingError: RouteData | 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 pendingError = {\n [findNearestBoundary(matches).route.id]: 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 actionOutput = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n { replace: opts.replace }\n );\n\n if (actionOutput.shortCircuited) {\n return;\n }\n\n pendingActionData = actionOutput.pendingActionData;\n pendingError = actionOutput.pendingActionError;\n\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n ...opts.submission,\n };\n loadingNavigation = navigation;\n\n // Create a GET request for the loaders\n request = new Request(request.url, { signal: request.signal });\n }\n\n // Call loaders\n let { shortCircuited, loaderData, errors } = await handleLoaders(\n request,\n location,\n matches,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.replace,\n pendingActionData,\n pendingError\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,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\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 opts?: { replace?: boolean }\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n ...submission,\n };\n updateState({ navigation });\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) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n router.basename\n );\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 replace =\n result.location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(state, result, { submission, replace });\n return { shortCircuited: true };\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 are REPLACE navigations, but if the\n // action threw an error that'll be rendered in an errorElement, we fall\n // back to PUSH so that the user can use the back button to get back to\n // the pre-submission form location to try again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n // Send back an empty object we can use to clear out any prior actionData\n pendingActionData: {},\n pendingActionError: { [boundaryMatch.route.id]: result.error },\n };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n return {\n pendingActionData: { [actionMatch.route.id]: result.data },\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 overrideNavigation?: Navigation,\n submission?: Submission,\n replace?: boolean,\n pendingActionData?: RouteData,\n pendingError?: RouteData\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation;\n if (!loadingNavigation) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n };\n loadingNavigation = navigation;\n }\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 = submission\n ? submission\n : loadingNavigation.formMethod &&\n loadingNavigation.formAction &&\n loadingNavigation.formData &&\n loadingNavigation.formEncType\n ? {\n formMethod: loadingNavigation.formMethod,\n formAction: loadingNavigation.formAction,\n formData: loadingNavigation.formData,\n formEncType: loadingNavigation.formEncType,\n }\n : undefined;\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n pendingActionData,\n pendingError,\n fetchLoadMatches\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 // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n completeNavigation(location, {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingError || null,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\n });\n return { shortCircuited: true };\n }\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 (!isUninterruptedRevalidation) {\n revalidatingFetchers.forEach(([key]) => {\n let fetcher = state.fetchers.get(key);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: fetcher && fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, revalidatingFetcher);\n });\n let actionData = pendingActionData || state.actionData;\n updateState({\n navigation: loadingNavigation,\n ...(actionData\n ? Object.keys(actionData).length === 0\n ? { actionData: null }\n : { actionData }\n : {}),\n ...(revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n });\n }\n\n pendingNavigationLoadId = ++incrementingLoadId;\n revalidatingFetchers.forEach(([key]) =>\n fetchControllers.set(key, pendingNavigationController!)\n );\n\n let { results, 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 revalidatingFetchers.forEach(([key]) => fetchControllers.delete(key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(results);\n if (redirect) {\n await startRedirectNavigation(state, redirect, { replace });\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 pendingError,\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 markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n\n return {\n loaderData,\n errors,\n ...(didAbortFetchLoads || revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n };\n }\n\n function getFetcher(key: string): Fetcher {\n return state.fetchers.get(key) || IDLE_FETCHER;\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,\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\n let matches = matchRoutes(dataRoutes, href, init.basename);\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: href })\n );\n return;\n }\n\n let { path, submission } = normalizeNavigateOptions(href, opts, true);\n let match = getTargetMatch(matches, path);\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, submission);\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, [path, match, matches]);\n handleFetcherLoader(key, routeId, path, match, matches, submission);\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 submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n if (!match.route.action) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error);\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, fetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the action for the fetcher\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n fetchControllers.set(key, abortController);\n\n let actionResult = await callLoaderOrAction(\n \"action\",\n fetchRequest,\n match,\n requestMatches,\n router.basename\n );\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by ou 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 if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n fetchRedirectIds.add(key);\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n ...submission,\n data: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n return startRedirectNavigation(state, actionResult, {\n isFetchActionRedirect: true,\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 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\n nextLocation,\n abortController.signal\n );\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(dataRoutes, state.navigation.location, init.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: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: actionResult.data,\n ...submission,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n { [match.route.id]: actionResult.data },\n undefined, // No need to send through errors since we short circuit above\n fetchLoadMatches\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(([staleKey]) => staleKey !== key)\n .forEach(([staleKey]) => {\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: existingFetcher && existingFetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(staleKey, revalidatingFetcher);\n fetchControllers.set(staleKey, abortController);\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let { results, 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 fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach(([staleKey]) =>\n fetchControllers.delete(staleKey)\n );\n\n let redirect = findRedirect(results);\n if (redirect) {\n return startRedirectNavigation(state, redirect);\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 let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: actionResult.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n\n let didAbortFetchLoads = 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 ...(didAbortFetchLoads ? { 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 submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n // Put this fetcher into it's loading state\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the loader for this fetcher route match\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n fetchControllers.set(key, abortController);\n let result: DataResult = await callLoaderOrAction(\n \"loader\",\n fetchRequest,\n match,\n matches,\n router.basename\n );\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 ou 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 // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n await startRedirectNavigation(state, result);\n return;\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n state.fetchers.delete(key);\n // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -\n // do we need to behave any differently with our non-redirect errors?\n // What if it was a non-redirect Response?\n updateState({\n fetchers: new Map(state.fetchers),\n errors: {\n [boundaryMatch.route.id]: result.error,\n },\n });\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\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 state: RouterState,\n redirect: RedirectResult,\n {\n submission,\n replace,\n isFetchActionRedirect,\n }: {\n submission?: Submission;\n replace?: boolean;\n isFetchActionRedirect?: boolean;\n } = {}\n ) {\n if (redirect.revalidate) {\n isRevalidationRequired = true;\n }\n\n let redirectLocation = createLocation(\n state.location,\n redirect.location,\n // TODO: This can be removed once we get rid of useTransition in Remix v2\n {\n _isRedirect: true,\n ...(isFetchActionRedirect ? { _isFetchActionRedirect: true } : {}),\n }\n );\n invariant(\n redirectLocation,\n \"Expected a location on the redirect navigation\"\n );\n\n // Check if this an external redirect that goes to a new origin\n if (isBrowser && typeof window?.location !== \"undefined\") {\n let newOrigin = init.history.createURL(redirect.location).origin;\n if (window.location.origin !== newOrigin) {\n if (replace) {\n window.location.replace(redirect.location);\n } else {\n window.location.assign(redirect.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, formData } = state.navigation;\n if (!submission && formMethod && formAction && formData && formEncType) {\n submission = {\n formMethod,\n formAction,\n formEncType,\n formData,\n };\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 if (\n redirectPreserveMethodStatusCodes.has(redirect.status) &&\n submission &&\n isMutationMethod(submission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...submission,\n formAction: redirect.location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // Otherwise, we kick off a new loading navigation, preserving the\n // submission info for the duration of this navigation\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation: {\n state: \"loading\",\n location: redirectLocation,\n formMethod: submission ? submission.formMethod : undefined,\n formAction: submission ? submission.formAction : undefined,\n formEncType: submission ? submission.formEncType : undefined,\n formData: submission ? submission.formData : undefined,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\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 // Call all navigation loaders and revalidating fetcher loaders in parallel,\n // then slice off the results into separate arrays so we can handle them\n // accordingly\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\"loader\", request, match, matches, router.basename)\n ),\n ...fetchersToLoad.map(([, href, match, fetchMatches]) =>\n callLoaderOrAction(\n \"loader\",\n createClientSideRequest(init.history, href, request.signal),\n match,\n fetchMatches,\n router.basename\n )\n ),\n ]);\n let loaderResults = results.slice(0, matchesToLoad.length);\n let fetcherResults = results.slice(matchesToLoad.length);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n request.signal,\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map(([, , match]) => match),\n fetcherResults,\n request.signal,\n true\n ),\n ]);\n\n return { results, loaderResults, fetcherResults };\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 setFetcherError(key: string, routeId: string, error: any) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n });\n }\n\n function deleteFetcher(key: string): void {\n if (fetchControllers.has(key)) abortFetcher(key);\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n state.fetchers.delete(key);\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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): void {\n let doneKeys = [];\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 }\n }\n markFetchersDone(doneKeys);\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 if (activeBlocker == null) {\n // This is now the active blocker\n activeBlocker = key;\n } else if (key !== activeBlocker) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n if (activeBlocker === key) {\n activeBlocker = null;\n }\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 state.blockers.set(key, newBlocker);\n updateState({ blockers: new Map(state.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 (activeBlocker == null) {\n return;\n }\n\n // We only allow a single blocker at the moment. This will need to be\n // updated if we enhance to support multiple blockers in the future\n let blockerFunction = blockerFunctions.get(activeBlocker);\n invariant(\n blockerFunction,\n \"Could not find a function for the active blocker\"\n );\n let blocker = state.blockers.get(activeBlocker);\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 activeBlocker;\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 || ((location) => location.key);\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 saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n router = {\n get basename() {\n return init.basename;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\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,\n dispose,\n getBlocker,\n deleteBlocker,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: {\n basename?: string;\n }\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(routes);\n let basename = (opts ? opts.basename : null) || \"/\";\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 async function query(\n request: Request,\n { requestContext }: { requestContext?: unknown } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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(request, location, matches, requestContext);\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 async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n }: { requestContext?: unknown; routeId?: string } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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 match\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 routeMatch?: AgnosticDataRouteMatch\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 routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\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, we throw\n // it to bail out and then return or throw here based on whether the user\n // returned or threw\n if (isQueryRouteResponse(e)) {\n if (e.type === ResultType.error && !isRedirectResponse(e.response)) {\n throw e.response;\n }\n return e.response;\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 isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n );\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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.status,\n headers: {\n Location: result.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 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 let context = await loadRouteData(\n request,\n matches,\n requestContext,\n undefined,\n {\n [boundaryMatch.route.id]: result.error,\n }\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 : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\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 let context = await loadRouteData(loaderRequest, matches, requestContext);\n\n return {\n ...context,\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n routeMatch?: AgnosticDataRouteMatch,\n pendingActionError?: RouteData\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 (isRouteRequest && !routeMatch?.route.loader) {\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 : getLoaderMatchesUntilBoundary(\n matches,\n Object.keys(pendingActionError || {})[0]\n );\n let matchesToLoad = requestMatches.filter((m) => m.route.loader);\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: pendingActionError || null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\n \"loader\",\n request,\n match,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n )\n ),\n ]);\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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 pendingActionError,\n activeDeferreds\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 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: 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction isSubmissionNavigation(\n opts: RouterNavigateOptions\n): opts is SubmissionNavigateOptions {\n return opts != null && \"formData\" in opts;\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 to: To,\n opts?: RouterNavigateOptions,\n isFetcher = false\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponse;\n} {\n let path = typeof to === \"string\" ? to : createPath(to);\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 // Create a Submission on non-GET navigations\n let submission: Submission | undefined;\n if (opts.formData) {\n submission = {\n formMethod: opts.formMethod || \"get\",\n formAction: stripHashFromPath(path),\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData: opts.formData,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n try {\n let searchParams = convertFormDataToSearchParams(opts.formData);\n // Since fetcher GET submissions only run a single loader (as opposed to\n // navigation GET submissions which run all loaders), we need to preserve\n // any incoming ?index params\n if (\n isFetcher &&\n parsedPath.search &&\n hasNakedIndexQuery(parsedPath.search)\n ) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n } catch (e) {\n return {\n path,\n error: getInternalRouterError(400),\n };\n }\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 isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n pendingActionData?: RouteData,\n pendingError?: RouteData,\n fetchLoadMatches?: Map\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingError\n ? Object.values(pendingError)[0]\n : pendingActionData\n ? Object.values(pendingActionData)[0]\n : undefined;\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;\n let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);\n let navigationMatches = boundaryMatches.filter(\n (match, index) =>\n match.route.loader != null &&\n (isNewLoader(state.loaderData, state.matches[index], match) ||\n // If this route had a pending deferred cancelled it must be revalidated\n cancelledDeferredRoutes.some((id) => id === match.route.id) ||\n shouldRevalidateLoader(\n history,\n state.location,\n state.matches[index],\n submission,\n location,\n match,\n isRevalidationRequired,\n actionResult\n ))\n );\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches &&\n fetchLoadMatches.forEach(([href, match, fetchMatches], key) => {\n // This fetcher was cancelled from a prior action submission - force reload\n if (cancelledFetcherLoads.includes(key)) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\n } else if (isRevalidationRequired) {\n let shouldRevalidate = shouldRevalidateLoader(\n history,\n href,\n match,\n submission,\n href,\n match,\n isRevalidationRequired,\n actionResult\n );\n if (shouldRevalidate) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\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 &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n history: History,\n currentLocation: string | Location,\n currentMatch: AgnosticDataRouteMatch,\n submission: Submission | undefined,\n location: string | Location,\n match: AgnosticDataRouteMatch,\n isRevalidationRequired: boolean,\n actionResult: DataResult | undefined\n) {\n let currentUrl = history.createURL(currentLocation);\n let currentParams = currentMatch.params;\n let nextUrl = history.createURL(location);\n let nextParams = match.params;\n\n // This is the default implementation as to 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 // Note that fetchers always provide the same current/next locations so the\n // URL-based checks here don't apply to fetcher shouldRevalidate calls\n let defaultShouldRevalidate =\n isNewRouteInstance(currentMatch, match) ||\n // Clicked the same link, resubmitted a GET form\n currentUrl.toString() === nextUrl.toString() ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate\n isRevalidationRequired;\n\n if (match.route.shouldRevalidate) {\n let routeChoice = match.route.shouldRevalidate({\n currentUrl,\n currentParams,\n nextUrl,\n nextParams,\n ...submission,\n actionResult,\n defaultShouldRevalidate,\n });\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return defaultShouldRevalidate;\n}\n\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n basename = \"/\",\n isStaticRequest: boolean = false,\n isRouteRequest: boolean = false,\n requestContext?: unknown\n): Promise {\n let resultType;\n let result;\n\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n let abortPromise = new Promise((_, r) => (reject = r));\n let onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n try {\n let handler = match.route[type];\n invariant(\n handler,\n `Could not find the ${type} to run on the \"${match.route.id}\" route`\n );\n\n result = await Promise.race([\n handler({ request, params: match.params, context: requestContext }),\n abortPromise,\n ]);\n\n invariant(\n 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 resultType = ResultType.error;\n result = e;\n } finally {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n\n if (isResponse(result)) {\n let status = result.status;\n\n // Process redirects\n if (redirectStatusCodes.has(status)) {\n let location = result.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(location);\n\n // Support relative routing in internal redirects\n if (!isAbsolute) {\n let activeMatches = matches.slice(0, matches.indexOf(match) + 1);\n let routePathnames = getPathContributingMatches(activeMatches).map(\n (match) => match.pathnameBase\n );\n let resolvedLocation = resolveTo(\n location,\n routePathnames,\n new URL(request.url).pathname\n );\n invariant(\n createPath(resolvedLocation),\n `Unable to resolve redirect location: ${location}`\n );\n\n // Prepend the basename to the redirect location if we have one\n if (basename) {\n let path = resolvedLocation.pathname;\n resolvedLocation.pathname =\n path === \"/\" ? basename : joinPaths([basename, path]);\n }\n\n location = createPath(resolvedLocation);\n } else if (!isStaticRequest) {\n // Strip off the protocol+origin for same-origin absolute redirects.\n // If this is a static reques, we can let it go back to the browser\n // as-is\n let currentUrl = new URL(request.url);\n let url = location.startsWith(\"//\")\n ? new URL(currentUrl.protocol + location)\n : new URL(location);\n if (url.origin === currentUrl.origin) {\n location = url.pathname + url.search + url.hash;\n }\n }\n\n // Don't process redirects in the router during static requests requests.\n // Instead, throw the Response and let the server handle it with an HTTP\n // redirect. We also update the Location header in place in this flow so\n // basename and relative routing is taken into account\n if (isStaticRequest) {\n result.headers.set(\"Location\", location);\n throw result;\n }\n\n return {\n type: ResultType.redirect,\n status,\n location,\n revalidate: result.headers.get(\"X-Remix-Revalidate\") !== null,\n };\n }\n\n // For SSR single-route requests, we want to hand Responses back directly\n // without unwrapping. We do this with the QueryRouteResponse wrapper\n // interface so we can know whether it was returned or thrown\n if (isRouteRequest) {\n // eslint-disable-next-line no-throw-literal\n throw {\n type: resultType || ResultType.data,\n response: result,\n };\n }\n\n let data: any;\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 data = await result.json();\n } else {\n data = await result.text();\n }\n\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: new ErrorResponse(status, result.statusText, data),\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 (resultType === ResultType.error) {\n return { type: resultType, error: result };\n }\n\n if (result instanceof DeferredData) {\n return { type: ResultType.deferred, deferredData: result };\n }\n\n return { type: ResultType.data, data: result };\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, formData } = submission;\n init.method = formMethod.toUpperCase();\n init.body =\n formEncType === \"application/x-www-form-urlencoded\"\n ? convertFormDataToSearchParams(formData)\n : formData;\n }\n\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\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 invariant(\n typeof value === \"string\",\n 'File inputs are not supported with encType \"application/x-www-form-urlencoded\", ' +\n 'please use \"multipart/form-data\" instead.'\n );\n searchParams.append(key, value);\n }\n\n return searchParams;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingError: RouteData | undefined,\n activeDeferreds: Map\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\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 // Look upwards from the matched route for the closest ancestor\n // error boundary, defaulting to the root match\n let boundaryMatch = findNearestBoundary(matches, id);\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) {\n error = Object.values(pendingError)[0];\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n // Prefer higher error values if lower errors bubble to the same boundary\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\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 } else {\n loaderData[id] = result.data;\n }\n\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 }\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) {\n errors = pendingError;\n loaderData[Object.keys(pendingError)[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 pendingError: RouteData | 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 pendingError,\n activeDeferreds\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let [key, , match] = 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 (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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\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) {\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\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 = 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 }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\";\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 (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 {\n errorMessage = \"Cannot submit binary form data using GET\";\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 ErrorResponse(\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(results: DataResult[]): RedirectResult | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return result;\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 return (\n a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash\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\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 isQueryRouteResponse(obj: any): obj is QueryRouteResponse {\n return (\n obj &&\n isResponse(obj.response) &&\n (obj.type === ResultType.data || ResultType.error)\n );\n}\n\nfunction isValidMethod(method: string): method is FormMethod {\n return validRequestMethods.has(method as FormMethod);\n}\n\nfunction isMutationMethod(method?: string): method is MutationFormMethod {\n return validMutationMethods.has(method as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n signal: AbortSignal,\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 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 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\n// Note: This should match the format exported by useMatches, so if you change\n// this please also change that :) Eventually we'll DRY this up\nfunction createUseMatchesMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UseMatchesMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id] as unknown,\n handle: route.handle as unknown,\n };\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//#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","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","parsedPath","searchIndex","getLocation","validateLocation","defaultView","getIndex","replaceState","handlePop","nextAction","historyState","pushState","error","assign","origin","addEventListener","removeEventListener","ResultType","isIndexRoute","route","convertRoutesToDataRoutes","routes","parentPath","allIds","Set","treePath","id","join","children","has","add","indexRoute","pathOrLayoutRoute","matchRoutes","locationArg","basename","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","matchRouteBranch","safelyDecodeURI","parentsMeta","flattenRoute","relativePath","meta","caseSensitive","childrenIndex","startsWith","joinPaths","routesMeta","concat","score","computeScore","forEach","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","match","matchPath","Object","params","pathnameBase","normalizePathname","generatePath","originalPath","_","optional","param","prefix","__","str","star","pattern","matcher","paramNames","compilePath","captureGroups","memo","paramName","splatValue","safelyDecodeURIComponent","regexpSource","RegExp","decodeURI","decodeURIComponent","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","resolvePathname","normalizeSearch","normalizeHash","relativeSegments","pop","getInvalidPathError","char","field","dest","getPathContributingMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","getToPathname","paths","json","data","init","responseInit","status","headers","Headers","set","Response","AbortedDeferredError","DeferredData","constructor","pendingKeysSet","subscribers","deferredKeys","Array","isArray","reject","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","acc","trackPromise","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","done","emit","settledKey","subscriber","subscribe","cancel","abort","v","k","resolveData","resolve","size","unwrappedData","unwrapTrackedPromise","pendingKeys","isTrackedPromise","_tracked","_error","_data","defer","redirect","ErrorResponse","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","isBrowser","createElement","isServer","createRouter","dataRoutes","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","getInternalRouterError","getShortCircuitMatches","initialized","m","loader","router","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","loaderData","actionData","errors","fetchers","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","pendingNavigationController","isUninterruptedRevalidation","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeDeferreds","activeBlocker","blockerFunctions","ignoreNextHistoryUpdate","initialize","blockerKey","shouldBlockNavigation","currentLocation","updateBlocker","deleteBlocker","updateState","startNavigation","dispose","clear","deleteFetcher","newState","completeNavigation","isActionReload","isMutationMethod","_isRedirect","keys","mergeLoaderData","getSavedScrollPosition","navigate","opts","submission","normalizeNavigateOptions","userReplace","pendingError","revalidate","interruptActiveLoads","startUninterruptedRevalidation","overrideNavigation","saveScrollPosition","loadingNavigation","notFoundMatches","cancelActiveDeferreds","isHashChangeOnly","request","createClientSideRequest","pendingActionData","findNearestBoundary","actionOutput","handleAction","shortCircuited","pendingActionError","Request","handleLoaders","actionMatch","getTargetMatch","type","method","routeId","callLoaderOrAction","isRedirectResult","startRedirectNavigation","isErrorResult","boundaryMatch","isDeferredResult","activeSubmission","matchesToLoad","revalidatingFetchers","getMatchesToLoad","fetcher","revalidatingFetcher","results","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","findRedirect","processLoaderData","deferredData","markFetchRedirectsDone","didAbortFetchLoads","abortStaleFetchLoads","getFetcher","fetch","abortFetcher","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","existingFetcher","abortController","fetchRequest","actionResult","loadingFetcher","isFetchActionRedirect","revalidationRequest","loadId","loadFetcher","staleKey","doneFetcher","resolveDeferredData","redirectLocation","_isFetchActionRedirect","newOrigin","redirectHistoryAction","currentMatches","fetchersToLoad","all","fetchMatches","resolveDeferredResults","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","blockerFunction","predicate","cancelledRouteIds","dfd","enableScrollRestoration","positions","getPosition","getKey","y","userMatches","createUseMatchesMatch","_internalFetchControllers","_internalActiveDeferreds","UNSAFE_DEFERRED_SYMBOL","Symbol","createStaticHandler","query","requestContext","isValidMethod","methodNotAllowedMatches","statusCode","loaderHeaders","actionHeaders","queryImpl","isResponse","queryRoute","find","values","routeMatch","submit","loadRouteData","isQueryRouteResponse","isRedirectResponse","response","isRouteRequest","Location","context","loaderRequest","getLoaderMatchesUntilBoundary","processRouteLoaderData","executedLoaders","fromEntries","getStaticContextFromError","newContext","_deepestRenderedBoundaryId","isSubmissionNavigation","isFetcher","stripHashFromPath","searchParams","convertFormDataToSearchParams","hasNakedIndexQuery","append","boundaryId","boundaryMatches","findIndex","navigationMatches","isNewLoader","shouldRevalidateLoader","shouldRevalidate","currentLoaderData","currentMatch","isNew","isMissingData","isNewRouteInstance","currentPath","currentUrl","currentParams","nextUrl","nextParams","defaultShouldRevalidate","routeChoice","isStaticRequest","resultType","onReject","handler","isAbsolute","activeMatches","resolvedLocation","protocol","contentType","text","deferred","toUpperCase","body","URLSearchParams","foundError","newLoaderData","mergedLoaderData","hasOwnProperty","eligibleMatches","reverse","hasErrorBoundary","errorMessage","obj","isRevalidatingLoader","unwrap","getAll","handle","pathMatches"],"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 0000000..f19147e --- /dev/null +++ b/node_modules/@remix-run/router/dist/router.umd.min.js @@ -0,0 +1,12 @@ +/** + * @remix-run/router v1.3.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 d(r,c,d,u){void 0===u&&(u={});let{window:h=document.defaultView,v5Compat:f=!1}=u,p=h.history,m=e.Action.Pop,g=null,v=y();function y(){return(p.state||{idx:null}).idx}function b(){let t=e.Action.Pop,r=y();if(null!=r){let e=r-v;m=t,v=r,g&&g({action:m,location:D.location,delta:e})}else n(!1,"You are trying to block a POP navigation to a location that was not created by @remix-run/router. The block will fail silently in production, but in general you should do all navigation with the router (instead of using window.history.pushState directly) to avoid this situation.")}function w(e){let t="null"!==h.location.origin?h.location.origin:h.location.href,r="string"==typeof e?e:l(e);return o(t,"No window.location.(origin|href) available to create URL for href: "+r),new URL(r,t)}null==v&&(v=0,p.replaceState(t({},p.state,{idx:v}),""));let D={get action(){return m},get location(){return r(h,p)},listen(e){if(g)throw new Error("A history only accepts one active listener");return h.addEventListener(a,b),g=e,()=>{h.removeEventListener(a,b),g=null}},createHref:e=>c(h,e),createURL:w,encodeLocation(e){let t=w(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(t,r){m=e.Action.Push;let a=s(D.location,t,r);d&&d(a,t),v=y()+1;let o=i(a,v),n=D.createHref(a);try{p.pushState(o,"",n)}catch(e){h.location.assign(n)}f&&g&&g({action:m,location:D.location,delta:1})},replace:function(t,r){m=e.Action.Replace;let a=s(D.location,t,r);d&&d(a,t),v=y();let o=i(a,v),n=D.createHref(a);p.replaceState(o,"",n),f&&g&&g({action:m,location:D.location,delta:0})},go:e=>p.go(e)};return D}let u;function h(e,r,a){return void 0===r&&(r=[]),void 0===a&&(a=new Set),e.map(((e,n)=>{let i=[...r,n],s="string"==typeof e.id?e.id:i.join("-");if(o(!0!==e.index||!e.children,"Cannot specify children on an index route"),o(!a.has(s),'Found a route id collision on id "'+s+"\". Route id's must be globally unique within Data Router usages"),a.add(s),function(e){return!0===e.index}(e)){return t({},e,{id:s})}return t({},e,{id:s,children:e.children?h(e.children,i,a):void 0})}))}function f(e,t,r){void 0===r&&(r="/");let a=A(("string"==typeof t?c(t):t).pathname||"/",r);if(null==a)return null;let o=p(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 n=null;for(let e=0;null==n&&e{let s={relativePath:void 0===i?e.path||"":i,caseSensitive:!0===e.caseSensitive,childrenIndex:n,route:e};s.relativePath.startsWith("/")&&(o(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=L([a,s.relativePath]),c=r.concat(s);e.children&&e.children.length>0&&(o(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+l+'".'),p(e.children,t,c,l)),(null!=e.path||e.index)&&t.push({path:l,score:y(l,e.index),routesMeta:c})};return e.forEach(((e,t)=>{var r;if(""!==e.path&&null!=(r=e.path)&&r.includes("?"))for(let r of m(e.path))n(e,t,r);else n(e,t)})),t}function m(e){let t=e.split("/");if(0===t.length)return[];let[r,...a]=t,o=r.endsWith("?"),n=r.replace(/\?$/,"");if(0===a.length)return o?[n,""]:[n];let i=m(a.join("/")),s=[];return s.push(...i.map((e=>""===e?n:[n,e].join("/")))),o&&s.push(...i),s.map((t=>e.startsWith("/")&&""===t?"/":t))}!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(u||(u={}));const g=/^:\w+$/,v=e=>"*"===e;function y(e,t){let r=e.split("/"),a=r.length;return r.some(v)&&(a+=-2),t&&(a+=2),r.filter((e=>!v(e))).reduce(((e,t)=>e+(g.test(t)?3:""===t?1:10)),a)}function b(e,t){let{routesMeta:r}=e,a={},o="/",n=[];for(let e=0;e(a.push(t),"/([^\\/]+)")));e.endsWith("*")?(a.push("*"),o+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?o+="\\/*$":""!==e&&"/"!==e&&(o+="(?:(?=\\/|$))");return[new RegExp(o,t?void 0:"i"),a]}(e.path,e.caseSensitive,e.end),o=t.match(r);if(!o)return null;let n=o[0],i=n.replace(/(.)\/+$/,"$1"),s=o.slice(1);return{params:a.reduce(((e,t,r)=>{if("*"===t){let e=s[r]||"";i=n.slice(0,n.length-e.length).replace(/(.)\/+$/,"$1")}return e[t]=function(e,t){try{return decodeURIComponent(e)}catch(r){return R(!1,'The value for the URL param "'+t+'" will not be decoded because the string "'+e+'" is a malformed URL segment. This is probably due to a bad percent encoding ('+r+")."),e}}(s[r]||"",t),e}),{}),pathname:n,pathnameBase:i,pattern:e}}function D(e){try{return decodeURI(e)}catch(t){return R(!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 A(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 R(e,t){if(!e){"undefined"!=typeof console&&console.warn(t);try{throw new Error(t)}catch(e){}}}function E(e,t){void 0===t&&(t="/");let{pathname:r,search:a="",hash:o=""}="string"==typeof e?c(e):e,n=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:n,search:k(a),hash:C(o)}}function P(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 M(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function S(e,r,a,n){let i;void 0===n&&(n=!1),"string"==typeof e?i=c(e):(i=t({},e),o(!i.pathname||!i.pathname.includes("?"),P("?","pathname","search",i)),o(!i.pathname||!i.pathname.includes("#"),P("#","pathname","hash",i)),o(!i.search||!i.search.includes("#"),P("#","search","hash",i)));let s,l=""===e||""===i.pathname,d=l?"/":i.pathname;if(n||null==d)s=a;else{let e=r.length-1;if(d.startsWith("..")){let t=d.split("/");for(;".."===t[0];)t.shift(),e-=1;i.pathname=t.join("/")}s=e>=0?r[e]:"/"}let u=E(i,s),h=d&&"/"!==d&&d.endsWith("/"),f=(l||"."===d)&&a.endsWith("/");return u.pathname.endsWith("/")||!h&&!f||(u.pathname+="/"),u}const L=e=>e.join("/").replace(/\/\/+/g,"/"),x=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),k=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",C=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";class U extends Error{}class j{constructor(e,t){let r;this.pendingKeysSet=new Set,this.subscribers=new Set,this.deferredKeys=[],o(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 U("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.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,null,t)),(t=>this.onSettle(r,e,t)));return r.catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),r}onSettle(e,t,r,a){return this.controller.signal.aborted&&r instanceof U?(this.unlistenAbortSignal(),Object.defineProperty(e,"_error",{get:()=>r}),Promise.reject(r)):(this.pendingKeysSet.delete(t),this.done&&this.unlistenAbortSignal(),r?(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 o(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]:T(a)})}),{})}get pendingKeys(){return Array.from(this.pendingKeysSet)}}function T(e){if(!function(e){return e instanceof Promise&&!0===e._tracked}(e))return e;if(e._error)throw e._error;return e._data}class O{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 _(e){return e instanceof O}const F=["post","put","patch","delete"],H=new Set(F),I=["get",...F],q=new Set(I),W=new Set([301,302,303,307,308]),$=new Set([307,308]),N={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},B={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},K={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},z="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,Y=!z;const J=Symbol("deferred");function G(e,t,r){void 0===r&&(r=!1);let a,o="string"==typeof e?e:l(e);if(!t||!function(e){return null!=e&&"formData"in e}(t))return{path:o};if(t.formMethod&&!ge(t.formMethod))return{path:o,error:le(405,{method:t.formMethod})};if(t.formData&&(a={formMethod:t.formMethod||"get",formAction:de(o),formEncType:t&&t.formEncType||"application/x-www-form-urlencoded",formData:t.formData},ve(a.formMethod)))return{path:o,submission:a};let n=c(o);try{let e=re(t.formData);r&&n.search&&we(n.search)&&e.append("index",""),n.search="?"+e}catch(e){return{path:o,error:le(400)}}return{path:l(n),submission:a}}function V(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 X(e,t,r,a,o,n,i,s,l,c,d){let u=c?Object.values(c)[0]:l?Object.values(l)[0]:void 0,h=V(r,c?Object.keys(c)[0]:void 0).filter(((r,s)=>null!=r.route.loader&&(function(e,t,r){let a=!t||r.route.id!==t.route.id,o=void 0===e[r.route.id];return a||o}(t.loaderData,t.matches[s],r)||i.some((e=>e===r.route.id))||Z(e,t.location,t.matches[s],a,o,r,n,u)))),f=[];return d&&d.forEach(((t,r)=>{let[o,i,l]=t;if(s.includes(r))f.push([r,o,i,l]);else if(n){Z(e,o,i,a,o,i,n,u)&&f.push([r,o,i,l])}})),[h,f]}function Q(e,t){let r=e.route.path;return e.pathname!==t.pathname||r&&r.endsWith("*")&&e.params["*"]!==t.params["*"]}function Z(e,r,a,o,n,i,s,l){let c=e.createURL(r),d=a.params,u=e.createURL(n),h=i.params,f=Q(a,i)||c.toString()===u.toString()||c.search!==u.search||s;if(i.route.shouldRevalidate){let e=i.route.shouldRevalidate(t({currentUrl:c,currentParams:d,nextUrl:u,nextParams:h},o,{actionResult:l,defaultShouldRevalidate:f}));if("boolean"==typeof e)return e}return f}async function ee(e,t,r,a,n,i,s,c){let d,h,f;void 0===n&&(n="/"),void 0===i&&(i=!1),void 0===s&&(s=!1);let p=new Promise(((e,t)=>f=t)),m=()=>f();t.signal.addEventListener("abort",m);try{let a=r.route[e];o(a,"Could not find the "+e+' to run on the "'+r.route.id+'" route'),h=await Promise.race([a({request:t,params:r.params,context:c}),p]),o(void 0!==h,"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){d=u.error,h=e}finally{t.signal.removeEventListener("abort",m)}if(pe(h)){let e,c=h.status;if(W.has(c)){let e=h.headers.get("Location");if(o(e,"Redirects returned/thrown from loaders/actions must have a Location header"),/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(e)){if(!i){let r=new URL(t.url),a=e.startsWith("//")?new URL(r.protocol+e):new URL(e);a.origin===r.origin&&(e=a.pathname+a.search+a.hash)}}else{let i=S(e,M(a.slice(0,a.indexOf(r)+1)).map((e=>e.pathnameBase)),new URL(t.url).pathname);if(o(l(i),"Unable to resolve redirect location: "+e),n){let e=i.pathname;i.pathname="/"===e?n:L([n,e])}e=l(i)}if(i)throw h.headers.set("Location",e),h;return{type:u.redirect,status:c,location:e,revalidate:null!==h.headers.get("X-Remix-Revalidate")}}if(s)throw{type:d||u.data,response:h};let f=h.headers.get("Content-Type");return e=f&&/\bapplication\/json\b/.test(f)?await h.json():await h.text(),d===u.error?{type:d,error:new O(c,h.statusText,e),headers:h.headers}:{type:u.data,data:e,statusCode:h.status,headers:h.headers}}return d===u.error?{type:d,error:h}:h instanceof j?{type:u.deferred,deferredData:h}:{type:u.data,data:h}}function te(e,t,r,a){let o=e.createURL(de(t)).toString(),n={signal:r};if(a&&ve(a.formMethod)){let{formMethod:e,formEncType:t,formData:r}=a;n.method=e.toUpperCase(),n.body="application/x-www-form-urlencoded"===t?re(r):r}return new Request(o,n)}function re(e){let t=new URLSearchParams;for(let[r,a]of e.entries())o("string"==typeof a,'File inputs are not supported with encType "application/x-www-form-urlencoded", please use "multipart/form-data" instead.'),t.append(r,a);return t}function ae(e,t,r,a,n){let i,s={},l=null,c=!1,d={};return r.forEach(((r,u)=>{let h=t[u].route.id;if(o(!fe(r),"Cannot handle redirect results in processLoaderData"),he(r)){let t=ie(e,h),o=r.error;a&&(o=Object.values(a)[0],a=void 0),l=l||{},null==l[t.route.id]&&(l[t.route.id]=o),s[h]=void 0,c||(c=!0,i=_(r.error)?r.error.status:500),r.headers&&(d[h]=r.headers)}else ue(r)?(n.set(h,r.deferredData),s[h]=r.deferredData.data):s[h]=r.data,null==r.statusCode||200===r.statusCode||c||(i=r.statusCode),r.headers&&(d[h]=r.headers)})),a&&(l=a,s[Object.keys(a)[0]]=void 0),{loaderData:s,errors:l,statusCode:i||200,loaderHeaders:d}}function oe(e,r,a,n,i,s,l,c){let{loaderData:d,errors:u}=ae(r,a,n,i,c);for(let r=0;re.route.id===t))+1):[...e]).reverse().find((e=>!0===e.route.hasErrorBoundary))||e[0]}function se(e){let t=e.find((e=>e.index||!e.path||"/"===e.path))||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function le(e,t){let{pathname:r,routeId:a,method:o,type:n}=void 0===t?{}:t,i="Unknown Server Error",s="Unknown @remix-run/router error";return 400===e?(i="Bad Request",s=o&&r&&a?"You made a "+o+' request to "'+r+'" but did not provide a `loader` for route "'+a+'", so there is no way to handle the request.':"defer-action"===n?"defer() is not supported in actions":"Cannot submit binary form data using GET"):403===e?(i="Forbidden",s='Route "'+a+'" does not match URL "'+r+'"'):404===e?(i="Not Found",s='No route matches URL "'+r+'"'):405===e&&(i="Method Not Allowed",o&&r&&a?s="You made a "+o.toUpperCase()+' request to "'+r+'" but did not provide an `action` for route "'+a+'", so there is no way to handle the request.':o&&(s='Invalid request method "'+o.toUpperCase()+'"')),new O(e||500,i,new Error(s),!0)}function ce(e){for(let t=e.length-1;t>=0;t--){let r=e[t];if(fe(r))return r}}function de(e){return l(t({},"string"==typeof e?c(e):e,{hash:""}))}function ue(e){return e.type===u.deferred}function he(e){return e.type===u.error}function fe(e){return(e&&e.type)===u.redirect}function pe(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"object"==typeof e.headers&&void 0!==e.body}function me(e){if(!pe(e))return!1;let t=e.status,r=e.headers.get("Location");return t>=300&&t<=399&&null!=r}function ge(e){return q.has(e)}function ve(e){return H.has(e)}async function ye(e,t,r,a,o,n){for(let i=0;ie.route.id===l.route.id)),d=null!=c&&!Q(c,l)&&void 0!==(n&&n[l.route.id]);ue(s)&&(o||d)&&await be(s,a,o).then((e=>{e&&(r[i]=e||r[i])}))}}async function be(e,t,r){if(void 0===r&&(r=!1),!await e.deferredData.resolveData(t)){if(r)try{return{type:u.data,data:e.deferredData.unwrappedData}}catch(e){return{type:u.error,error:e}}return{type:u.data,data:e.deferredData.data}}}function we(e){return new URLSearchParams(e).getAll("index").some((e=>""===e))}function De(e,t){let{route:r,pathname:a,params:o}=e;return{id:r.id,pathname:a,params:o,data:t[r.id],handle:r.handle}}function Ae(e,t){let r="string"==typeof t?c(t).search:t.search;if(e[e.length-1].route.index&&we(r||""))return e[e.length-1];let a=M(e);return a[a.length-1]}e.AbortedDeferredError=U,e.ErrorResponse=O,e.IDLE_BLOCKER=K,e.IDLE_FETCHER=B,e.IDLE_NAVIGATION=N,e.UNSAFE_DEFERRED_SYMBOL=J,e.UNSAFE_DeferredData=j,e.UNSAFE_convertRoutesToDataRoutes=h,e.UNSAFE_getPathContributingMatches=M,e.createBrowserHistory=function(e){return void 0===e&&(e={}),d((function(e,t){let{pathname:r,search:a,hash:o}=e.location;return s("",{pathname:r,search:a,hash:o},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={}),d((function(e,t){let{pathname:r="/",search:a="",hash:o=""}=c(e.location.hash.substr(1));return s("",{pathname:r,search:a,hash:o},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){n("/"===e.pathname.charAt(0),"relative pathnames are not supported in hash history.push("+JSON.stringify(t)+")")}),e)},e.createMemoryHistory=function(t){void 0===t&&(t={});let r,{initialEntries:a=["/"],initialIndex:o,v5Compat:i=!1}=t;r=a.map(((e,t)=>m(e,"string"==typeof e?null:e.state,0===t?"default":void 0)));let d=f(null==o?r.length-1:o),u=e.Action.Pop,h=null;function f(e){return Math.min(Math.max(e,0),r.length-1)}function p(){return r[d]}function m(e,t,a){void 0===t&&(t=null);let o=s(r?p().pathname:"/",e,t,a);return n("/"===o.pathname.charAt(0),"relative pathnames are not supported in memory history: "+JSON.stringify(e)),o}function g(e){return"string"==typeof e?e:l(e)}return{get index(){return d},get action(){return u},get location(){return p()},createHref:g,createURL:e=>new URL(g(e),"http://localhost"),encodeLocation(e){let t="string"==typeof e?c(e):e;return{pathname:t.pathname||"",search:t.search||"",hash:t.hash||""}},push(t,a){u=e.Action.Push;let o=m(t,a);d+=1,r.splice(d,r.length,o),i&&h&&h({action:u,location:o,delta:1})},replace(t,a){u=e.Action.Replace;let o=m(t,a);r[d]=o,i&&h&&h({action:u,location:o,delta:0})},go(t){u=e.Action.Pop;let a=f(d+t),o=r[a];d=a,h&&h({action:u,location:o,delta:t})},listen:e=>(h=e,()=>{h=null})}},e.createPath=l,e.createRouter=function(r){o(r.routes.length>0,"You must provide a non-empty routes array to createRouter");let a=h(r.routes),n=null,i=new Set,l=null,c=null,d=null,p=null!=r.hydrationData,m=f(a,r.history.location,r.basename),g=null;if(null==m){let e=le(404,{pathname:r.history.location.pathname}),{matches:t,route:o}=se(a);m=t,g={[o.id]:e}}let v,y,b=!m.some((e=>e.route.loader))||null!=r.hydrationData,w={historyAction:r.history.action,location:r.history.location,matches:m,initialized:b,navigation:N,restoreScrollPosition:null==r.hydrationData&&null,preventScrollReset:!1,revalidation:"idle",loaderData:r.hydrationData&&r.hydrationData.loaderData||{},actionData:r.hydrationData&&r.hydrationData.actionData||null,errors:r.hydrationData&&r.hydrationData.errors||g,fetchers:new Map,blockers:new Map},D=e.Action.Pop,A=!1,E=!1,P=!1,M=[],S=[],L=new Map,x=0,k=-1,C=new Map,U=new Set,j=new Map,T=new Map,O=null,_=new Map,F=!1;function H(e){w=t({},w,e),i.forEach((e=>e(w)))}function I(a,o){var n,i;let s,l=null!=w.actionData&&null!=w.navigation.formMethod&&ve(w.navigation.formMethod)&&"loading"===w.navigation.state&&!0!==(null==(n=a.state)?void 0:n._isRedirect);s=o.actionData?Object.keys(o.actionData).length>0?o.actionData:null:l?w.actionData:null;let c=o.loaderData?ne(w.loaderData,o.loaderData,o.matches||[],o.errors):w.loaderData;for(let[e]of _)me(e);let d=!0===A||null!=w.navigation.formMethod&&ve(w.navigation.formMethod)&&!0!==(null==(i=a.state)?void 0:i._isRedirect);H(t({},o,{actionData:s,loaderData:c,historyAction:D,location:a,initialized:!0,navigation:N,revalidation:"idle",restoreScrollPosition:Ee(a,o.matches||w.matches),preventScrollReset:d,blockers:new Map(w.blockers)})),E||D===e.Action.Pop||(D===e.Action.Push?r.history.push(a,a.state):D===e.Action.Replace&&r.history.replace(a,a.state)),D=e.Action.Pop,A=!1,E=!1,P=!1,M=[],S=[]}async function q(n,i,s){y&&y.abort(),y=null,D=n,E=!0===(s&&s.startUninterruptedRevalidation),function(e,t){if(l&&c&&d){let r=t.map((e=>De(e,w.loaderData))),a=c(e,r)||e.key;l[a]=d()}}(w.location,w.matches),A=!0===(s&&s.preventScrollReset);let h=s&&s.overrideNavigation,p=f(a,i,r.basename);if(!p){let e=le(404,{pathname:i.pathname}),{matches:t,route:r}=se(a);return Re(),void I(i,{matches:t,loaderData:{},errors:{[r.id]:e}})}if(m=w.location,g=i,m.pathname===g.pathname&&m.search===g.search&&m.hash!==g.hash)return void I(i,{matches:p});var m,g;y=new AbortController;let b,R,C=te(r.history,i,y.signal,s&&s.submission);if(s&&s.pendingError)R={[ie(p).route.id]:s.pendingError};else if(s&&s.submission&&ve(s.submission.formMethod)){let r=await async function(r,a,o,n,i){let s;Q(),H({navigation:t({state:"submitting",location:a},o)});let l=Ae(n,a);if(l.route.action){if(s=await ee("action",r,l,n,v.basename),r.signal.aborted)return{shortCircuited:!0}}else s={type:u.error,error:le(405,{method:r.method,pathname:a.pathname,routeId:l.route.id})};if(fe(s)){let e;return e=i&&null!=i.replace?i.replace:s.location===w.location.pathname+w.location.search,await J(w,s,{submission:o,replace:e}),{shortCircuited:!0}}if(he(s)){let t=ie(n,l.route.id);return!0!==(i&&i.replace)&&(D=e.Action.Push),{pendingActionData:{},pendingActionError:{[t.route.id]:s.error}}}if(ue(s))throw le(400,{type:"defer-action"});return{pendingActionData:{[l.route.id]:s.data}}}(C,i,s.submission,p,{replace:s.replace});if(r.shortCircuited)return;b=r.pendingActionData,R=r.pendingActionError,h=t({state:"loading",location:i},s.submission),C=new Request(C.url,{signal:C.signal})}let{shortCircuited:O,loaderData:_,errors:F}=await async function(e,a,n,i,s,l,c,d){let u=i;if(!u){u=t({state:"loading",location:a,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},s)}let h=s||(u.formMethod&&u.formAction&&u.formData&&u.formEncType?{formMethod:u.formMethod,formAction:u.formAction,formData:u.formData,formEncType:u.formEncType}:void 0),[f,p]=X(r.history,w,n,h,a,P,M,S,c,d,j);if(Re((e=>!(n&&n.some((t=>t.route.id===e)))||f&&f.some((t=>t.route.id===e)))),0===f.length&&0===p.length)return I(a,t({matches:n,loaderData:{},errors:d||null},c?{actionData:c}:{})),{shortCircuited:!0};if(!E){p.forEach((e=>{let[t]=e,r=w.fetchers.get(t),a={state:"loading",data:r&&r.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};w.fetchers.set(t,a)}));let e=c||w.actionData;H(t({navigation:u},e?0===Object.keys(e).length?{actionData:null}:{actionData:e}:{},p.length>0?{fetchers:new Map(w.fetchers)}:{}))}k=++x,p.forEach((e=>{let[t]=e;return L.set(t,y)}));let{results:m,loaderResults:g,fetcherResults:v}=await V(w.matches,n,f,p,e);if(e.signal.aborted)return{shortCircuited:!0};p.forEach((e=>{let[t]=e;return L.delete(t)}));let b=ce(m);if(b)return await J(w,b,{replace:l}),{shortCircuited:!0};let{loaderData:D,errors:A}=oe(w,n,f,g,d,p,v,T);T.forEach(((e,t)=>{e.subscribe((r=>{(r||e.done)&&T.delete(t)}))})),function(){let e=[];for(let t of U){let r=w.fetchers.get(t);o(r,"Expected fetcher: "+t),"loading"===r.state&&(U.delete(t),e.push(t))}de(e)}();let R=pe(k);return t({loaderData:D,errors:A},R||p.length>0?{fetchers:new Map(w.fetchers)}:{})}(C,i,p,h,s&&s.submission,s&&s.replace,b,R);O||(y=null,I(i,t({matches:p},b?{actionData:b}:{},{loaderData:_,errors:F})))}function W(e){return w.fetchers.get(e)||B}async function J(a,n,i){var l;let{submission:c,replace:d,isFetchActionRedirect:u}=void 0===i?{}:i;n.revalidate&&(P=!0);let h=s(a.location,n.location,t({_isRedirect:!0},u?{_isFetchActionRedirect:!0}:{}));if(o(h,"Expected a location on the redirect navigation"),z&&void 0!==(null==(l=window)?void 0:l.location)){let e=r.history.createURL(n.location).origin;if(window.location.origin!==e)return void(d?window.location.replace(n.location):window.location.assign(n.location))}y=null;let f=!0===d?e.Action.Replace:e.Action.Push,{formMethod:p,formAction:m,formEncType:g,formData:v}=a.navigation;!c&&p&&m&&v&&g&&(c={formMethod:p,formAction:m,formEncType:g,formData:v}),$.has(n.status)&&c&&ve(c.formMethod)?await q(f,h,{submission:t({},c,{formAction:n.location}),preventScrollReset:A}):await q(f,h,{overrideNavigation:{state:"loading",location:h,formMethod:c?c.formMethod:void 0,formAction:c?c.formAction:void 0,formEncType:c?c.formEncType:void 0,formData:c?c.formData:void 0},preventScrollReset:A})}async function V(e,t,a,o,n){let i=await Promise.all([...a.map((e=>ee("loader",n,e,t,v.basename))),...o.map((e=>{let[,t,a,o]=e;return ee("loader",te(r.history,t,n.signal),a,o,v.basename)}))]),s=i.slice(0,a.length),l=i.slice(a.length);return await Promise.all([ye(e,a,s,n.signal,!1,w.loaderData),ye(e,o.map((e=>{let[,,t]=e;return t})),l,n.signal,!0)]),{results:i,loaderResults:s,fetcherResults:l}}function Q(){P=!0,M.push(...Re()),j.forEach(((e,t)=>{L.has(t)&&(S.push(t),ae(t))}))}function Z(e,t,r){let a=ie(w.matches,t);re(e),H({errors:{[a.route.id]:r},fetchers:new Map(w.fetchers)})}function re(e){L.has(e)&&ae(e),j.delete(e),C.delete(e),U.delete(e),w.fetchers.delete(e)}function ae(e){let t=L.get(e);o(t,"Expected fetch controller: "+e),t.abort(),L.delete(e)}function de(e){for(let t of e){let e={state:"idle",data:W(t).data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};w.fetchers.set(t,e)}}function pe(e){let t=[];for(let[r,a]of C)if(a0}function me(e){w.blockers.delete(e),_.delete(e),O===e&&(O=null)}function ge(e,t){let r=w.blockers.get(e)||K;o("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),w.blockers.set(e,t),H({blockers:new Map(w.blockers)})}function we(e){let{currentLocation:t,nextLocation:r,historyAction:a}=e;if(null==O)return;let n=_.get(O);o(n,"Could not find a function for the active blocker");let i=w.blockers.get(O);return i&&"proceeding"===i.state?void 0:n({currentLocation:t,nextLocation:r,historyAction:a})?O:void 0}function Re(e){let t=[];return T.forEach(((r,a)=>{e&&!e(a)||(r.cancel(),t.push(a),T.delete(a))})),t}function Ee(e,t){if(l&&c&&d){let r=t.map((e=>De(e,w.loaderData))),a=c(e,r)||e.key,o=l[a];if("number"==typeof o)return o}return null}return v={get basename(){return r.basename},get state(){return w},get routes(){return a},initialize:function(){return n=r.history.listen((e=>{let{action:t,location:a,delta:o}=e;if(F)return void(F=!1);let n=we({currentLocation:w.location,nextLocation:a,historyAction:t});return n?(F=!0,r.history.go(-1*o),void ge(n,{state:"blocked",location:a,proceed(){ge(n,{state:"proceeding",proceed:void 0,reset:void 0,location:a}),r.history.go(o)},reset(){me(n),H({blockers:new Map(v.state.blockers)})}})):q(t,a)})),w.initialized||q(e.Action.Pop,w.location),v},subscribe:function(e){return i.add(e),()=>i.delete(e)},enableScrollRestoration:function(e,t,r){if(l=e,d=t,c=r||(e=>e.key),!p&&w.navigation===N){p=!0;let e=Ee(w.location,w.matches);null!=e&&H({restoreScrollPosition:e})}return()=>{l=null,d=null,c=null}},navigate:async function a(o,n){if("number"==typeof o)return void r.history.go(o);let{path:i,submission:l,error:c}=G(o,n),d=w.location,u=s(w.location,i,n&&n.state);u=t({},u,r.history.encodeLocation(u));let h=n&&null!=n.replace?n.replace:void 0,f=e.Action.Push;!0===h?f=e.Action.Replace:!1===h||null!=l&&ve(l.formMethod)&&l.formAction===w.location.pathname+w.location.search&&(f=e.Action.Replace);let p=n&&"preventScrollReset"in n?!0===n.preventScrollReset:void 0,m=we({currentLocation:d,nextLocation:u,historyAction:f});if(!m)return await q(f,u,{submission:l,pendingError:c,preventScrollReset:p,replace:n&&n.replace});ge(m,{state:"blocked",location:u,proceed(){ge(m,{state:"proceeding",proceed:void 0,reset:void 0,location:u}),a(o,n)},reset(){me(m),H({blockers:new Map(w.blockers)})}})},fetch:function(e,n,i,s){if(Y)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.");L.has(e)&&ae(e);let l=f(a,i,r.basename);if(!l)return void Z(e,n,le(404,{pathname:i}));let{path:c,submission:d}=G(i,s,!0),u=Ae(l,c);d&&ve(d.formMethod)?async function(e,n,i,s,l,c){if(Q(),j.delete(e),!s.route.action){let t=le(405,{method:c.formMethod,pathname:i,routeId:n});return void Z(e,n,t)}let d=w.fetchers.get(e),u=t({state:"submitting"},c,{data:d&&d.data," _hasFetcherDoneAnything ":!0});w.fetchers.set(e,u),H({fetchers:new Map(w.fetchers)});let h=new AbortController,p=te(r.history,i,h.signal,c);L.set(e,h);let m=await ee("action",p,s,l,v.basename);if(p.signal.aborted)return void(L.get(e)===h&&L.delete(e));if(fe(m)){L.delete(e),U.add(e);let r=t({state:"loading"},c,{data:void 0," _hasFetcherDoneAnything ":!0});return w.fetchers.set(e,r),H({fetchers:new Map(w.fetchers)}),J(w,m,{isFetchActionRedirect:!0})}if(he(m))return void Z(e,n,m.error);if(ue(m))throw le(400,{type:"defer-action"});let g=w.navigation.location||w.location,b=te(r.history,g,h.signal),A="idle"!==w.navigation.state?f(a,w.navigation.location,r.basename):w.matches;o(A,"Didn't find any matches after fetcher action");let R=++x;C.set(e,R);let E=t({state:"loading",data:m.data},c,{" _hasFetcherDoneAnything ":!0});w.fetchers.set(e,E);let[O,_]=X(r.history,w,A,c,g,P,M,S,{[s.route.id]:m.data},void 0,j);_.filter((t=>{let[r]=t;return r!==e})).forEach((e=>{let[t]=e,r=w.fetchers.get(t),a={state:"loading",data:r&&r.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};w.fetchers.set(t,a),L.set(t,h)})),H({fetchers:new Map(w.fetchers)});let{results:F,loaderResults:q,fetcherResults:W}=await V(w.matches,A,O,_,b);if(h.signal.aborted)return;C.delete(e),L.delete(e),_.forEach((e=>{let[t]=e;return L.delete(t)}));let $=ce(F);if($)return J(w,$);let{loaderData:N,errors:B}=oe(w,w.matches,O,q,void 0,_,W,T),K={state:"idle",data:m.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};w.fetchers.set(e,K);let z=pe(R);"loading"===w.navigation.state&&R>k?(o(D,"Expected pending action"),y&&y.abort(),I(w.navigation.location,{matches:A,loaderData:N,errors:B,fetchers:new Map(w.fetchers)})):(H(t({errors:B,loaderData:ne(w.loaderData,N,A,B)},z?{fetchers:new Map(w.fetchers)}:{})),P=!1)}(e,n,c,u,l,d):(j.set(e,[c,u,l]),async function(e,a,n,i,s,l){let c=w.fetchers.get(e),d=t({state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},l,{data:c&&c.data," _hasFetcherDoneAnything ":!0});w.fetchers.set(e,d),H({fetchers:new Map(w.fetchers)});let u=new AbortController,h=te(r.history,n,u.signal);L.set(e,u);let f=await ee("loader",h,i,s,v.basename);ue(f)&&(f=await be(f,h.signal,!0)||f);L.get(e)===u&&L.delete(e);if(h.signal.aborted)return;if(fe(f))return void await J(w,f);if(he(f)){let t=ie(w.matches,a);return w.fetchers.delete(e),void H({fetchers:new Map(w.fetchers),errors:{[t.route.id]:f.error}})}o(!ue(f),"Unhandled fetcher deferred data");let p={state:"idle",data:f.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};w.fetchers.set(e,p),H({fetchers:new Map(w.fetchers)})}(e,n,c,u,l,d))},revalidate:function(){Q(),H({revalidation:"loading"}),"submitting"!==w.navigation.state&&("idle"!==w.navigation.state?q(D||w.historyAction,w.navigation.location,{overrideNavigation:w.navigation}):q(w.historyAction,w.location,{startUninterruptedRevalidation:!0}))},createHref:e=>r.history.createHref(e),encodeLocation:e=>r.history.encodeLocation(e),getFetcher:W,deleteFetcher:re,dispose:function(){n&&n(),i.clear(),y&&y.abort(),w.fetchers.forEach(((e,t)=>re(t))),w.blockers.forEach(((e,t)=>me(t)))},getBlocker:function(e,t){let r=w.blockers.get(e)||K;return _.get(e)!==t&&(_.set(e,t),null==O?O=e:e!==O&&R(!1,"A router only supports one blocker at a time")),r},deleteBlocker:me,_internalFetchControllers:L,_internalActiveDeferreds:T},v},e.createStaticHandler=function(e,r){o(e.length>0,"You must provide a non-empty routes array to createStaticHandler");let a=h(e),n=(r?r.basename:null)||"/";async function i(e,r,a,i,s){o(e.signal,"query()/queryRoute() requests must contain an AbortController signal");try{if(ve(e.method.toLowerCase())){let o=await async function(e,r,a,o,i){let s;if(a.route.action){if(s=await ee("action",e,a,r,n,!0,i,o),e.signal.aborted){throw new Error((i?"queryRoute":"query")+"() call aborted")}}else{let t=le(405,{method:e.method,pathname:new URL(e.url).pathname,routeId:a.route.id});if(i)throw t;s={type:u.error,error:t}}if(fe(s))throw new Response(null,{status:s.status,headers:{Location:s.location}});if(ue(s)){let e=le(400,{type:"defer-action"});if(i)throw e;s={type:u.error,error:e}}if(i){if(he(s))throw s.error;return{matches:[a],loaderData:{},actionData:{[a.route.id]:s.data},errors:null,statusCode:200,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(he(s)){let n=ie(r,a.route.id);return t({},await c(e,r,o,void 0,{[n.route.id]:s.error}),{statusCode:_(s.error)?s.error.status:500,actionData:null,actionHeaders:t({},s.headers?{[a.route.id]:s.headers}:{})})}let l=new Request(e.url,{headers:e.headers,redirect:e.redirect,signal:e.signal});return t({},await c(l,r,o),s.statusCode?{statusCode:s.statusCode}:{},{actionData:{[a.route.id]:s.data},actionHeaders:t({},s.headers?{[a.route.id]:s.headers}:{})})}(e,a,s||Ae(a,r),i,null!=s);return o}let o=await c(e,a,i,s);return pe(o)?o:t({},o,{actionData:null,actionHeaders:{}})}catch(e){if((l=e)&&pe(l.response)&&(l.type===u.data||u.error)){if(e.type===u.error&&!me(e.response))throw e.response;return e.response}if(me(e))return e;throw e}var l}async function c(e,r,a,o,i){let s=null!=o;if(s&&(null==o||!o.route.loader))throw le(400,{method:e.method,pathname:new URL(e.url).pathname,routeId:null==o?void 0:o.route.id});let l=(o?[o]:V(r,Object.keys(i||{})[0])).filter((e=>e.route.loader));if(0===l.length)return{matches:r,loaderData:r.reduce(((e,t)=>Object.assign(e,{[t.route.id]:null})),{}),errors:i||null,statusCode:200,loaderHeaders:{},activeDeferreds:null};let c=await Promise.all([...l.map((t=>ee("loader",e,t,r,n,!0,s,a)))]);if(e.signal.aborted){throw new Error((s?"queryRoute":"query")+"() call aborted")}let d=new Map,u=ae(r,l,c,i,d),h=new Set(l.map((e=>e.route.id)));return r.forEach((e=>{h.has(e.route.id)||(u.loaderData[e.route.id]=null)})),t({},u,{matches:r,activeDeferreds:d.size>0?Object.fromEntries(d.entries()):null})}return{dataRoutes:a,query:async function(e,r){let{requestContext:o}=void 0===r?{}:r,c=new URL(e.url),d=e.method.toLowerCase(),u=s("",l(c),null,"default"),h=f(a,u,n);if(!ge(d)&&"head"!==d){let e=le(405,{method:d}),{matches:t,route:r}=se(a);return{basename:n,location:u,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(!h){let e=le(404,{pathname:u.pathname}),{matches:t,route:r}=se(a);return{basename:n,location:u,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}let p=await i(e,u,h,o);return pe(p)?p:t({location:u,basename:n},p)},queryRoute:async function(e,t){let{routeId:r,requestContext:o}=void 0===t?{}:t,c=new URL(e.url),d=e.method.toLowerCase(),u=s("",l(c),null,"default"),h=f(a,u,n);if(!ge(d)&&"head"!==d&&"options"!==d)throw le(405,{method:d});if(!h)throw le(404,{pathname:u.pathname});let p=r?h.find((e=>e.route.id===r)):Ae(h,u);if(r&&!p)throw le(403,{pathname:u.pathname,routeId:r});if(!p)throw le(404,{pathname:u.pathname});let m=await i(e,u,h,o,p);if(pe(m))return m;let g=m.errors?Object.values(m.errors)[0]:void 0;if(void 0!==g)throw g;if(m.actionData)return Object.values(m.actionData)[0];if(m.loaderData){var v;let e=Object.values(m.loaderData)[0];return null!=(v=m.activeDeferreds)&&v[p.route.id]&&(e[J]=m.activeDeferreds[p.route.id]),e}}}},e.defer=function(e,t){return void 0===t&&(t={}),new j(e,"number"==typeof t?{status:t}:t)},e.generatePath=function(e,t){void 0===t&&(t={});let r=e;return r.endsWith("*")&&"*"!==r&&!r.endsWith("/*")&&(R(!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(/\*$/,"/*")),r.replace(/^:(\w+)(\??)/g,((e,r,a)=>{let n=t[r];return"?"===a?null==n?"":n:(null==n&&o(!1,'Missing ":'+r+'" param'),n)})).replace(/\/:(\w+)(\??)/g,((e,r,a)=>{let n=t[r];return"?"===a?null==n?"":"/"+n:(null==n&&o(!1,'Missing ":'+r+'" param'),"/"+n)})).replace(/\?/g,"").replace(/(\/?)\*/,((e,r,a,o)=>null==t["*"]?"/*"===o?"/":"":""+r+t["*"]))},e.getStaticContextFromError=function(e,r,a){return t({},r,{statusCode:500,errors:{[r._deepestRenderedBoundaryId||e[0].id]:a}})},e.getToPathname=function(e){return""===e||""===e.pathname?"/":"string"==typeof e?c(e).pathname:e.pathname},e.invariant=o,e.isRouteErrorResponse=_,e.joinPaths=L,e.json=function(e,r){void 0===r&&(r={});let a="number"==typeof r?{status:r}:r,o=new Headers(a.headers);return o.has("Content-Type")||o.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),t({},a,{headers:o}))},e.matchPath=w,e.matchRoutes=f,e.normalizePathname=x,e.parsePath=c,e.redirect=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 o=new Headers(a.headers);return o.set("Location",e),new Response(null,t({},a,{headers:o}))},e.resolvePath=E,e.resolveTo=S,e.stripBasename=A,e.warning=R,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 0000000..1d92af8 --- /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/**\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: any;\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;\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`. May be either a URL or the pieces of a\n * 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 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\nfunction 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 let nextAction = Action.Pop;\n let nextIndex = getIndex();\n\n if (nextIndex != null) {\n let delta = nextIndex - index;\n action = nextAction;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n } else {\n warning(\n false,\n // TODO: Write up a doc that explains our blocking strategy in detail\n // and link to it here so people can understand better what is going on\n // and how to avoid it.\n `You are trying to block a POP navigation to a location that was not ` +\n `created by @remix-run/router. The block will fail silently in ` +\n `production, but in general you should do all navigation with the ` +\n `router (instead of using window.history.pushState directly) ` +\n `to avoid this situation.`\n );\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 // 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 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 } 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: any;\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 status: number;\n location: string;\n revalidate: boolean;\n}\n\n/**\n * Unsuccessful result from a loader or action\n */\nexport interface ErrorResult {\n type: ResultType.error;\n error: any;\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\nexport type MutationFormMethod = \"post\" | \"put\" | \"patch\" | \"delete\";\nexport type FormMethod = \"get\" | MutationFormMethod;\n\nexport type FormEncType =\n | \"application/x-www-form-urlencoded\"\n | \"multipart/form-data\";\n\n/**\n * @private\n * Internal interface to pass around for action submissions, not intended for\n * external consumption\n */\nexport interface Submission {\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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?: any;\n}\n\n/**\n * Arguments passed to loader functions\n */\nexport interface LoaderFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Arguments passed to action functions\n */\nexport interface ActionFunctionArgs extends DataFunctionArgs {}\n\n/**\n * Route loader function signature\n */\nexport interface LoaderFunction {\n (args: LoaderFunctionArgs): Promise | Response | Promise | any;\n}\n\n/**\n * Route action function signature\n */\nexport interface ActionFunction {\n (args: ActionFunctionArgs): Promise | Response | Promise | any;\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: {\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 formData?: Submission[\"formData\"];\n actionResult?: DataResult;\n defaultShouldRevalidate: boolean;\n }): boolean;\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;\n action?: ActionFunction;\n hasErrorBoundary?: boolean;\n shouldRevalidate?: ShouldRevalidateFunction;\n handle?: any;\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\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 */\ntype 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 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 parentPath: number[] = [],\n allIds: Set = new Set()\n): AgnosticDataRouteObject[] {\n return routes.map((route, index) => {\n let treePath = [...parentPath, 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 !allIds.has(id),\n `Found a route id collision on id \"${id}\". Route ` +\n \"id's must be globally unique within Data Router usages\"\n );\n allIds.add(id);\n\n if (isIndexRoute(route)) {\n let indexRoute: AgnosticDataIndexRouteObject = { ...route, id };\n return indexRoute;\n } else {\n let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = {\n ...route,\n id,\n children: route.children\n ? convertRoutesToDataRoutes(route.children, treePath, allIds)\n : undefined,\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 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 matches = matchRouteBranch(\n branches[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 safelyDecodeURI(pathname)\n );\n }\n\n return matches;\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\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 explodes _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): 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 if (!match) return null;\n\n Object.assign(matchedParams, match.params);\n\n let route = meta.route;\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 = 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 return (\n path\n .replace(\n /^:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : param;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return param;\n }\n )\n .replace(\n /\\/:(\\w+)(\\??)/g,\n (_, key: PathParam, optional: string | undefined) => {\n let param = params[key];\n if (optional === \"?\") {\n return param == null ? \"\" : `/${param}`;\n }\n if (param == null) {\n invariant(false, `Missing \":${key}\" param`);\n }\n return `/${param}`;\n }\n )\n // Remove any optional markers from optional static segments\n .replace(/\\?/g, \"\")\n .replace(/(\\/?)\\*/, (_, prefix, __, str) => {\n const star = \"*\" as PathParam;\n\n if (params[star] == null) {\n // If no splat was provided, trim the trailing slash _unless_ it's\n // the entire path\n return str === \"/*\" ? \"/\" : \"\";\n }\n\n // Apply the splat\n return `${prefix}${params[star]}`;\n })\n );\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, paramNames] = 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 = paramNames.reduce>(\n (memo, paramName, 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 memo[paramName] = safelyDecodeURIComponent(\n captureGroups[index] || \"\",\n paramName\n );\n return memo;\n },\n {}\n );\n\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern,\n };\n}\n\nfunction compilePath(\n path: string,\n caseSensitive = false,\n end = true\n): [RegExp, string[]] {\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 paramNames: string[] = [];\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(/\\/:(\\w+)/g, (_: string, paramName: string) => {\n paramNames.push(paramName);\n return \"/([^\\\\/]+)\";\n });\n\n if (path.endsWith(\"*\")) {\n paramNames.push(\"*\");\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, paramNames];\n}\n\nfunction safelyDecodeURI(value: string) {\n try {\n return decodeURI(value);\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\nfunction safelyDecodeURIComponent(value: string, paramName: string) {\n try {\n return decodeURIComponent(value);\n } catch (error) {\n warning(\n false,\n `The value for the URL param \"${paramName}\" will not be decoded because` +\n ` the string \"${value}\" is a malformed URL segment. This is probably` +\n ` due to a bad percent 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 * @private\n */\nexport function warning(cond: any, message: string): void {\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 @remix-run/router!\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\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/**\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 (isPathRelative || toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n\n if (toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n\n // Each leading .. segment means \"go up one route\" instead of \"go up one\n // URL segment\". This is a key difference from how works and a\n // major reason we call this a \"to\" value instead of a \"href\".\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n\n to.pathname = toSegments.join(\"/\");\n }\n\n // If there are more \"..\" segments than parent routes, resolve relative to\n // the root / URL.\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 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, null, 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 (error) {\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 * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n */\nexport class ErrorResponse {\n status: number;\n statusText: string;\n data: any;\n error?: Error;\n 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 throw from an action/loader\n */\nexport function isRouteErrorResponse(e: any): e is ErrorResponse {\n return e instanceof ErrorResponse;\n}\n","import type { History, Location, Path, To } from \"./history\";\nimport {\n Action as HistoryAction,\n createLocation,\n createPath,\n invariant,\n parsePath,\n} from \"./history\";\nimport type {\n DataResult,\n AgnosticDataRouteMatch,\n AgnosticDataRouteObject,\n DeferredResult,\n ErrorResult,\n FormEncType,\n FormMethod,\n RedirectResult,\n RouteData,\n AgnosticRouteObject,\n Submission,\n SuccessResult,\n AgnosticRouteMatch,\n MutationFormMethod,\n} from \"./utils\";\nimport {\n DeferredData,\n ErrorResponse,\n ResultType,\n convertRoutesToDataRoutes,\n getPathContributingMatches,\n isRouteErrorResponse,\n joinPaths,\n matchRoutes,\n resolveTo,\n warning,\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 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 * 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, 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,\n opts?: RouterNavigateOptions\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 * 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 * Initialization options for createRouter\n */\nexport interface RouterInit {\n basename?: string;\n routes: AgnosticRouteObject[];\n history: History;\n hydrationData?: HydrationState;\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?: { requestContext?: unknown }\n ): Promise;\n queryRoute(\n request: Request,\n opts?: { routeId?: string; requestContext?: unknown }\n ): Promise;\n}\n\n/**\n * Subscriber function signature for changes to router state\n */\nexport interface RouterSubscriber {\n (state: RouterState): void;\n}\n\ninterface UseMatchesMatch {\n id: string;\n pathname: string;\n params: AgnosticRouteMatch[\"params\"];\n data: unknown;\n handle: unknown;\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: UseMatchesMatch[]): string | null;\n}\n\n/**\n * Function signature for determining the current scroll position\n */\nexport interface GetScrollPositionFunction {\n (): number;\n}\n\n/**\n * Options for a navigate() call for a Link navigation\n */\ntype LinkNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n};\n\n/**\n * Options for a navigate() call for a Form navigation\n */\ntype SubmissionNavigateOptions = {\n replace?: boolean;\n state?: any;\n preventScrollReset?: boolean;\n formMethod?: FormMethod;\n formEncType?: FormEncType;\n formData: FormData;\n};\n\n/**\n * Options to pass to navigate() for either a Link or Form navigation\n */\nexport type RouterNavigateOptions =\n | LinkNavigateOptions\n | SubmissionNavigateOptions;\n\n/**\n * Options to pass to fetch()\n */\nexport type RouterFetchOptions =\n | Omit\n | Omit;\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 };\n Loading: {\n state: \"loading\";\n location: Location;\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n };\n Submitting: {\n state: \"submitting\";\n location: Location;\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\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 formData: undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Loading: {\n state: \"loading\";\n formMethod: FormMethod | undefined;\n formAction: string | undefined;\n formEncType: FormEncType | undefined;\n formData: FormData | undefined;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\n };\n Submitting: {\n state: \"submitting\";\n formMethod: FormMethod;\n formAction: string;\n formEncType: FormEncType;\n formData: FormData;\n data: TData | undefined;\n \" _hasFetcherDoneAnything \"?: boolean;\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\ninterface HandleActionResult extends ShortCircuitable {\n /**\n * Error thrown from the current action, keyed by the route containing the\n * error boundary to render the error. To be committed to the state after\n * loaders have completed\n */\n pendingActionError?: RouteData;\n /**\n * Data returned from the current action, keyed by the route owning the action.\n * To be committed to the state after loaders have completed\n */\n pendingActionData?: RouteData;\n}\n\ninterface HandleLoadersResult extends ShortCircuitable {\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 * Tuple of [key, href, DataRouteMatch, DataRouteMatch[]] for a revalidating\n * fetcher.load()\n */\ntype RevalidatingFetcher = [\n string,\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Tuple of [href, DataRouteMatch, DataRouteMatch[]] for an active\n * fetcher.load()\n */\ntype FetchLoadMatch = [\n string,\n AgnosticDataRouteMatch,\n AgnosticDataRouteMatch[]\n];\n\n/**\n * Wrapper object to allow us to throw any response out from callLoaderOrAction\n * for queryRouter while preserving whether or not it was thrown or returned\n * from the loader/action\n */\ninterface QueryRouteResponse {\n type: ResultType.data | ResultType.error;\n response: Response;\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};\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};\n\nexport const IDLE_BLOCKER: BlockerUnblocked = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined,\n};\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n typeof window.document !== \"undefined\" &&\n typeof window.document.createElement !== \"undefined\";\nconst isServer = !isBrowser;\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 invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(init.routes);\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(\n dataRoutes,\n init.history.location,\n init.basename\n );\n let initialErrors: RouteData | null = null;\n\n if (initialMatches == null) {\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 let initialized =\n !initialMatches.some((m) => m.route.loader) || init.hydrationData != null;\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 // 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 // - useRevalidate()\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 from their actions\n let fetchRedirectIds = new Set();\n\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\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 // 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 let activeBlocker: string | null = null;\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 // 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 let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction,\n });\n if (blockerKey) {\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(router.state.blockers) });\n },\n });\n return;\n }\n\n return startNavigation(historyAction, location);\n }\n );\n\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n if (!state.initialized) {\n startNavigation(HistoryAction.Pop, state.location);\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 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(newState: Partial): void {\n state = {\n ...state,\n ...newState,\n };\n subscribers.forEach((subscriber) => subscriber(state));\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 ): 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 for (let [key] of blockerFunctions) {\n deleteBlocker(key);\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 updateState({\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: new Map(state.blockers),\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 // Reset stateful navigation vars\n pendingAction = HistoryAction.Pop;\n pendingPreventScrollReset = 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,\n opts?: RouterNavigateOptions\n ): Promise {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n\n let { path, submission, error } = normalizeNavigateOptions(to, opts);\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 blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction,\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 deleteBlocker(blockerKey!);\n updateState({ blockers: new Map(state.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 });\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 submission?: Submission;\n overrideNavigation?: Navigation;\n pendingError?: ErrorResponse;\n startUninterruptedRevalidation?: boolean;\n preventScrollReset?: boolean;\n replace?: 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 let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(dataRoutes, location, init.basename);\n\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } =\n getShortCircuitMatches(dataRoutes);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error,\n },\n });\n return;\n }\n\n // Short circuit if it's only a hash change\n if (isHashChangeOnly(state.location, location)) {\n completeNavigation(location, { matches });\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 pendingActionData: RouteData | undefined;\n let pendingError: RouteData | 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 pendingError = {\n [findNearestBoundary(matches).route.id]: 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 actionOutput = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n { replace: opts.replace }\n );\n\n if (actionOutput.shortCircuited) {\n return;\n }\n\n pendingActionData = actionOutput.pendingActionData;\n pendingError = actionOutput.pendingActionError;\n\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n ...opts.submission,\n };\n loadingNavigation = navigation;\n\n // Create a GET request for the loaders\n request = new Request(request.url, { signal: request.signal });\n }\n\n // Call loaders\n let { shortCircuited, loaderData, errors } = await handleLoaders(\n request,\n location,\n matches,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.replace,\n pendingActionData,\n pendingError\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,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\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 opts?: { replace?: boolean }\n ): Promise {\n interruptActiveLoads();\n\n // Put us in a submitting state\n let navigation: NavigationStates[\"Submitting\"] = {\n state: \"submitting\",\n location,\n ...submission,\n };\n updateState({ navigation });\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) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n router.basename\n );\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 replace =\n result.location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(state, result, { submission, replace });\n return { shortCircuited: true };\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 are REPLACE navigations, but if the\n // action threw an error that'll be rendered in an errorElement, we fall\n // back to PUSH so that the user can use the back button to get back to\n // the pre-submission form location to try again\n if ((opts && opts.replace) !== true) {\n pendingAction = HistoryAction.Push;\n }\n\n return {\n // Send back an empty object we can use to clear out any prior actionData\n pendingActionData: {},\n pendingActionError: { [boundaryMatch.route.id]: result.error },\n };\n }\n\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, { type: \"defer-action\" });\n }\n\n return {\n pendingActionData: { [actionMatch.route.id]: result.data },\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 overrideNavigation?: Navigation,\n submission?: Submission,\n replace?: boolean,\n pendingActionData?: RouteData,\n pendingError?: RouteData\n ): Promise {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation;\n if (!loadingNavigation) {\n let navigation: NavigationStates[\"Loading\"] = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n };\n loadingNavigation = navigation;\n }\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 = submission\n ? submission\n : loadingNavigation.formMethod &&\n loadingNavigation.formAction &&\n loadingNavigation.formData &&\n loadingNavigation.formEncType\n ? {\n formMethod: loadingNavigation.formMethod,\n formAction: loadingNavigation.formAction,\n formData: loadingNavigation.formData,\n formEncType: loadingNavigation.formEncType,\n }\n : undefined;\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n pendingActionData,\n pendingError,\n fetchLoadMatches\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 // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n completeNavigation(location, {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingError || null,\n ...(pendingActionData ? { actionData: pendingActionData } : {}),\n });\n return { shortCircuited: true };\n }\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 (!isUninterruptedRevalidation) {\n revalidatingFetchers.forEach(([key]) => {\n let fetcher = state.fetchers.get(key);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: fetcher && fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, revalidatingFetcher);\n });\n let actionData = pendingActionData || state.actionData;\n updateState({\n navigation: loadingNavigation,\n ...(actionData\n ? Object.keys(actionData).length === 0\n ? { actionData: null }\n : { actionData }\n : {}),\n ...(revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n });\n }\n\n pendingNavigationLoadId = ++incrementingLoadId;\n revalidatingFetchers.forEach(([key]) =>\n fetchControllers.set(key, pendingNavigationController!)\n );\n\n let { results, 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 revalidatingFetchers.forEach(([key]) => fetchControllers.delete(key));\n\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(results);\n if (redirect) {\n await startRedirectNavigation(state, redirect, { replace });\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 pendingError,\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 markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n\n return {\n loaderData,\n errors,\n ...(didAbortFetchLoads || revalidatingFetchers.length > 0\n ? { fetchers: new Map(state.fetchers) }\n : {}),\n };\n }\n\n function getFetcher(key: string): Fetcher {\n return state.fetchers.get(key) || IDLE_FETCHER;\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,\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\n let matches = matchRoutes(dataRoutes, href, init.basename);\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: href })\n );\n return;\n }\n\n let { path, submission } = normalizeNavigateOptions(href, opts, true);\n let match = getTargetMatch(matches, path);\n\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, submission);\n return;\n }\n\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, [path, match, matches]);\n handleFetcherLoader(key, routeId, path, match, matches, submission);\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 submission: Submission\n ) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n\n if (!match.route.action) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId,\n });\n setFetcherError(key, routeId, error);\n return;\n }\n\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n let fetcher: FetcherStates[\"Submitting\"] = {\n state: \"submitting\",\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, fetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the action for the fetcher\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n fetchControllers.set(key, abortController);\n\n let actionResult = await callLoaderOrAction(\n \"action\",\n fetchRequest,\n match,\n requestMatches,\n router.basename\n );\n\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by ou 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 if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n fetchRedirectIds.add(key);\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n ...submission,\n data: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n return startRedirectNavigation(state, actionResult, {\n isFetchActionRedirect: true,\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 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\n nextLocation,\n abortController.signal\n );\n let matches =\n state.navigation.state !== \"idle\"\n ? matchRoutes(dataRoutes, state.navigation.location, init.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: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: actionResult.data,\n ...submission,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadFetcher);\n\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n isRevalidationRequired,\n cancelledDeferredRoutes,\n cancelledFetcherLoads,\n { [match.route.id]: actionResult.data },\n undefined, // No need to send through errors since we short circuit above\n fetchLoadMatches\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(([staleKey]) => staleKey !== key)\n .forEach(([staleKey]) => {\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n data: existingFetcher && existingFetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(staleKey, revalidatingFetcher);\n fetchControllers.set(staleKey, abortController);\n });\n\n updateState({ fetchers: new Map(state.fetchers) });\n\n let { results, 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 fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach(([staleKey]) =>\n fetchControllers.delete(staleKey)\n );\n\n let redirect = findRedirect(results);\n if (redirect) {\n return startRedirectNavigation(state, redirect);\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 let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: actionResult.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n\n let didAbortFetchLoads = 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 ...(didAbortFetchLoads ? { 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 submission?: Submission\n ) {\n let existingFetcher = state.fetchers.get(key);\n // Put this fetcher into it's loading state\n let loadingFetcher: FetcherStates[\"Loading\"] = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n ...submission,\n data: existingFetcher && existingFetcher.data,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, loadingFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\n\n // Call the loader for this fetcher route match\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n fetchControllers.set(key, abortController);\n let result: DataResult = await callLoaderOrAction(\n \"loader\",\n fetchRequest,\n match,\n matches,\n router.basename\n );\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 ou 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 // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n await startRedirectNavigation(state, result);\n return;\n }\n\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n state.fetchers.delete(key);\n // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -\n // do we need to behave any differently with our non-redirect errors?\n // What if it was a non-redirect Response?\n updateState({\n fetchers: new Map(state.fetchers),\n errors: {\n [boundaryMatch.route.id]: result.error,\n },\n });\n return;\n }\n\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n\n // Put the fetcher back into an idle state\n let doneFetcher: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n updateState({ fetchers: new Map(state.fetchers) });\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 state: RouterState,\n redirect: RedirectResult,\n {\n submission,\n replace,\n isFetchActionRedirect,\n }: {\n submission?: Submission;\n replace?: boolean;\n isFetchActionRedirect?: boolean;\n } = {}\n ) {\n if (redirect.revalidate) {\n isRevalidationRequired = true;\n }\n\n let redirectLocation = createLocation(\n state.location,\n redirect.location,\n // TODO: This can be removed once we get rid of useTransition in Remix v2\n {\n _isRedirect: true,\n ...(isFetchActionRedirect ? { _isFetchActionRedirect: true } : {}),\n }\n );\n invariant(\n redirectLocation,\n \"Expected a location on the redirect navigation\"\n );\n\n // Check if this an external redirect that goes to a new origin\n if (isBrowser && typeof window?.location !== \"undefined\") {\n let newOrigin = init.history.createURL(redirect.location).origin;\n if (window.location.origin !== newOrigin) {\n if (replace) {\n window.location.replace(redirect.location);\n } else {\n window.location.assign(redirect.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, formData } = state.navigation;\n if (!submission && formMethod && formAction && formData && formEncType) {\n submission = {\n formMethod,\n formAction,\n formEncType,\n formData,\n };\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 if (\n redirectPreserveMethodStatusCodes.has(redirect.status) &&\n submission &&\n isMutationMethod(submission.formMethod)\n ) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: {\n ...submission,\n formAction: redirect.location,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\n });\n } else {\n // Otherwise, we kick off a new loading navigation, preserving the\n // submission info for the duration of this navigation\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation: {\n state: \"loading\",\n location: redirectLocation,\n formMethod: submission ? submission.formMethod : undefined,\n formAction: submission ? submission.formAction : undefined,\n formEncType: submission ? submission.formEncType : undefined,\n formData: submission ? submission.formData : undefined,\n },\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset,\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 // Call all navigation loaders and revalidating fetcher loaders in parallel,\n // then slice off the results into separate arrays so we can handle them\n // accordingly\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\"loader\", request, match, matches, router.basename)\n ),\n ...fetchersToLoad.map(([, href, match, fetchMatches]) =>\n callLoaderOrAction(\n \"loader\",\n createClientSideRequest(init.history, href, request.signal),\n match,\n fetchMatches,\n router.basename\n )\n ),\n ]);\n let loaderResults = results.slice(0, matchesToLoad.length);\n let fetcherResults = results.slice(matchesToLoad.length);\n\n await Promise.all([\n resolveDeferredResults(\n currentMatches,\n matchesToLoad,\n loaderResults,\n request.signal,\n false,\n state.loaderData\n ),\n resolveDeferredResults(\n currentMatches,\n fetchersToLoad.map(([, , match]) => match),\n fetcherResults,\n request.signal,\n true\n ),\n ]);\n\n return { results, loaderResults, fetcherResults };\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 setFetcherError(key: string, routeId: string, error: any) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error,\n },\n fetchers: new Map(state.fetchers),\n });\n }\n\n function deleteFetcher(key: string): void {\n if (fetchControllers.has(key)) abortFetcher(key);\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n state.fetchers.delete(key);\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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: fetcher.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\n state.fetchers.set(key, doneFetcher);\n }\n }\n\n function markFetchRedirectsDone(): void {\n let doneKeys = [];\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 }\n }\n markFetchersDone(doneKeys);\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 if (activeBlocker == null) {\n // This is now the active blocker\n activeBlocker = key;\n } else if (key !== activeBlocker) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n }\n\n return blocker;\n }\n\n function deleteBlocker(key: string) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n if (activeBlocker === key) {\n activeBlocker = null;\n }\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 state.blockers.set(key, newBlocker);\n updateState({ blockers: new Map(state.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 (activeBlocker == null) {\n return;\n }\n\n // We only allow a single blocker at the moment. This will need to be\n // updated if we enhance to support multiple blockers in the future\n let blockerFunction = blockerFunctions.get(activeBlocker);\n invariant(\n blockerFunction,\n \"Could not find a function for the active blocker\"\n );\n let blocker = state.blockers.get(activeBlocker);\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 activeBlocker;\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 || ((location) => location.key);\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 saveScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): void {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n\n function getSavedScrollPosition(\n location: Location,\n matches: AgnosticDataRouteMatch[]\n ): number | null {\n if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) {\n let userMatches = matches.map((m) =>\n createUseMatchesMatch(m, state.loaderData)\n );\n let key = getScrollRestorationKey(location, userMatches) || location.key;\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n\n router = {\n get basename() {\n return init.basename;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\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,\n dispose,\n getBlocker,\n deleteBlocker,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n };\n\n return router;\n}\n//#endregion\n\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\n\nexport const UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\n\nexport function createStaticHandler(\n routes: AgnosticRouteObject[],\n opts?: {\n basename?: string;\n }\n): StaticHandler {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n\n let dataRoutes = convertRoutesToDataRoutes(routes);\n let basename = (opts ? opts.basename : null) || \"/\";\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 async function query(\n request: Request,\n { requestContext }: { requestContext?: unknown } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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(request, location, matches, requestContext);\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 async function queryRoute(\n request: Request,\n {\n routeId,\n requestContext,\n }: { requestContext?: unknown; routeId?: string } = {}\n ): Promise {\n let url = new URL(request.url);\n let method = request.method.toLowerCase();\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 match\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 routeMatch?: AgnosticDataRouteMatch\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 routeMatch != null\n );\n return result;\n }\n\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\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, we throw\n // it to bail out and then return or throw here based on whether the user\n // returned or threw\n if (isQueryRouteResponse(e)) {\n if (e.type === ResultType.error && !isRedirectResponse(e.response)) {\n throw e.response;\n }\n return e.response;\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 isRouteRequest: boolean\n ): Promise | Response> {\n let result: DataResult;\n\n if (!actionMatch.route.action) {\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 result = await callLoaderOrAction(\n \"action\",\n request,\n actionMatch,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n );\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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.status,\n headers: {\n Location: result.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 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 let context = await loadRouteData(\n request,\n matches,\n requestContext,\n undefined,\n {\n [boundaryMatch.route.id]: result.error,\n }\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 : 500,\n actionData: null,\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\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 let context = await loadRouteData(loaderRequest, matches, requestContext);\n\n return {\n ...context,\n // action status codes take precedence over loader status codes\n ...(result.statusCode ? { statusCode: result.statusCode } : {}),\n actionData: {\n [actionMatch.route.id]: result.data,\n },\n actionHeaders: {\n ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}),\n },\n };\n }\n\n async function loadRouteData(\n request: Request,\n matches: AgnosticDataRouteMatch[],\n requestContext: unknown,\n routeMatch?: AgnosticDataRouteMatch,\n pendingActionError?: RouteData\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 (isRouteRequest && !routeMatch?.route.loader) {\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 : getLoaderMatchesUntilBoundary(\n matches,\n Object.keys(pendingActionError || {})[0]\n );\n let matchesToLoad = requestMatches.filter((m) => m.route.loader);\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: pendingActionError || null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null,\n };\n }\n\n let results = await Promise.all([\n ...matchesToLoad.map((match) =>\n callLoaderOrAction(\n \"loader\",\n request,\n match,\n matches,\n basename,\n true,\n isRouteRequest,\n requestContext\n )\n ),\n ]);\n\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(`${method}() call aborted`);\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 pendingActionError,\n activeDeferreds\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 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: 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error,\n },\n };\n return newContext;\n}\n\nfunction isSubmissionNavigation(\n opts: RouterNavigateOptions\n): opts is SubmissionNavigateOptions {\n return opts != null && \"formData\" in opts;\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 to: To,\n opts?: RouterNavigateOptions,\n isFetcher = false\n): {\n path: string;\n submission?: Submission;\n error?: ErrorResponse;\n} {\n let path = typeof to === \"string\" ? to : createPath(to);\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 // Create a Submission on non-GET navigations\n let submission: Submission | undefined;\n if (opts.formData) {\n submission = {\n formMethod: opts.formMethod || \"get\",\n formAction: stripHashFromPath(path),\n formEncType:\n (opts && opts.formEncType) || \"application/x-www-form-urlencoded\",\n formData: opts.formData,\n };\n\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n }\n\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n try {\n let searchParams = convertFormDataToSearchParams(opts.formData);\n // Since fetcher GET submissions only run a single loader (as opposed to\n // navigation GET submissions which run all loaders), we need to preserve\n // any incoming ?index params\n if (\n isFetcher &&\n parsedPath.search &&\n hasNakedIndexQuery(parsedPath.search)\n ) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n } catch (e) {\n return {\n path,\n error: getInternalRouterError(400),\n };\n }\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 isRevalidationRequired: boolean,\n cancelledDeferredRoutes: string[],\n cancelledFetcherLoads: string[],\n pendingActionData?: RouteData,\n pendingError?: RouteData,\n fetchLoadMatches?: Map\n): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] {\n let actionResult = pendingError\n ? Object.values(pendingError)[0]\n : pendingActionData\n ? Object.values(pendingActionData)[0]\n : undefined;\n\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;\n let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);\n let navigationMatches = boundaryMatches.filter(\n (match, index) =>\n match.route.loader != null &&\n (isNewLoader(state.loaderData, state.matches[index], match) ||\n // If this route had a pending deferred cancelled it must be revalidated\n cancelledDeferredRoutes.some((id) => id === match.route.id) ||\n shouldRevalidateLoader(\n history,\n state.location,\n state.matches[index],\n submission,\n location,\n match,\n isRevalidationRequired,\n actionResult\n ))\n );\n\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers: RevalidatingFetcher[] = [];\n fetchLoadMatches &&\n fetchLoadMatches.forEach(([href, match, fetchMatches], key) => {\n // This fetcher was cancelled from a prior action submission - force reload\n if (cancelledFetcherLoads.includes(key)) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\n } else if (isRevalidationRequired) {\n let shouldRevalidate = shouldRevalidateLoader(\n history,\n href,\n match,\n submission,\n href,\n match,\n isRevalidationRequired,\n actionResult\n );\n if (shouldRevalidate) {\n revalidatingFetchers.push([key, href, match, fetchMatches]);\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 &&\n currentPath.endsWith(\"*\") &&\n currentMatch.params[\"*\"] !== match.params[\"*\"])\n );\n}\n\nfunction shouldRevalidateLoader(\n history: History,\n currentLocation: string | Location,\n currentMatch: AgnosticDataRouteMatch,\n submission: Submission | undefined,\n location: string | Location,\n match: AgnosticDataRouteMatch,\n isRevalidationRequired: boolean,\n actionResult: DataResult | undefined\n) {\n let currentUrl = history.createURL(currentLocation);\n let currentParams = currentMatch.params;\n let nextUrl = history.createURL(location);\n let nextParams = match.params;\n\n // This is the default implementation as to 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 // Note that fetchers always provide the same current/next locations so the\n // URL-based checks here don't apply to fetcher shouldRevalidate calls\n let defaultShouldRevalidate =\n isNewRouteInstance(currentMatch, match) ||\n // Clicked the same link, resubmitted a GET form\n currentUrl.toString() === nextUrl.toString() ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search ||\n // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate\n isRevalidationRequired;\n\n if (match.route.shouldRevalidate) {\n let routeChoice = match.route.shouldRevalidate({\n currentUrl,\n currentParams,\n nextUrl,\n nextParams,\n ...submission,\n actionResult,\n defaultShouldRevalidate,\n });\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n\n return defaultShouldRevalidate;\n}\n\nasync function callLoaderOrAction(\n type: \"loader\" | \"action\",\n request: Request,\n match: AgnosticDataRouteMatch,\n matches: AgnosticDataRouteMatch[],\n basename = \"/\",\n isStaticRequest: boolean = false,\n isRouteRequest: boolean = false,\n requestContext?: unknown\n): Promise {\n let resultType;\n let result;\n\n // Setup a promise we can race against so that abort signals short circuit\n let reject: () => void;\n let abortPromise = new Promise((_, r) => (reject = r));\n let onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n\n try {\n let handler = match.route[type];\n invariant(\n handler,\n `Could not find the ${type} to run on the \"${match.route.id}\" route`\n );\n\n result = await Promise.race([\n handler({ request, params: match.params, context: requestContext }),\n abortPromise,\n ]);\n\n invariant(\n 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 resultType = ResultType.error;\n result = e;\n } finally {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n\n if (isResponse(result)) {\n let status = result.status;\n\n // Process redirects\n if (redirectStatusCodes.has(status)) {\n let location = result.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n\n let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(location);\n\n // Support relative routing in internal redirects\n if (!isAbsolute) {\n let activeMatches = matches.slice(0, matches.indexOf(match) + 1);\n let routePathnames = getPathContributingMatches(activeMatches).map(\n (match) => match.pathnameBase\n );\n let resolvedLocation = resolveTo(\n location,\n routePathnames,\n new URL(request.url).pathname\n );\n invariant(\n createPath(resolvedLocation),\n `Unable to resolve redirect location: ${location}`\n );\n\n // Prepend the basename to the redirect location if we have one\n if (basename) {\n let path = resolvedLocation.pathname;\n resolvedLocation.pathname =\n path === \"/\" ? basename : joinPaths([basename, path]);\n }\n\n location = createPath(resolvedLocation);\n } else if (!isStaticRequest) {\n // Strip off the protocol+origin for same-origin absolute redirects.\n // If this is a static reques, we can let it go back to the browser\n // as-is\n let currentUrl = new URL(request.url);\n let url = location.startsWith(\"//\")\n ? new URL(currentUrl.protocol + location)\n : new URL(location);\n if (url.origin === currentUrl.origin) {\n location = url.pathname + url.search + url.hash;\n }\n }\n\n // Don't process redirects in the router during static requests requests.\n // Instead, throw the Response and let the server handle it with an HTTP\n // redirect. We also update the Location header in place in this flow so\n // basename and relative routing is taken into account\n if (isStaticRequest) {\n result.headers.set(\"Location\", location);\n throw result;\n }\n\n return {\n type: ResultType.redirect,\n status,\n location,\n revalidate: result.headers.get(\"X-Remix-Revalidate\") !== null,\n };\n }\n\n // For SSR single-route requests, we want to hand Responses back directly\n // without unwrapping. We do this with the QueryRouteResponse wrapper\n // interface so we can know whether it was returned or thrown\n if (isRouteRequest) {\n // eslint-disable-next-line no-throw-literal\n throw {\n type: resultType || ResultType.data,\n response: result,\n };\n }\n\n let data: any;\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 data = await result.json();\n } else {\n data = await result.text();\n }\n\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: new ErrorResponse(status, result.statusText, data),\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 (resultType === ResultType.error) {\n return { type: resultType, error: result };\n }\n\n if (result instanceof DeferredData) {\n return { type: ResultType.deferred, deferredData: result };\n }\n\n return { type: ResultType.data, data: result };\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, formData } = submission;\n init.method = formMethod.toUpperCase();\n init.body =\n formEncType === \"application/x-www-form-urlencoded\"\n ? convertFormDataToSearchParams(formData)\n : formData;\n }\n\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\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 invariant(\n typeof value === \"string\",\n 'File inputs are not supported with encType \"application/x-www-form-urlencoded\", ' +\n 'please use \"multipart/form-data\" instead.'\n );\n searchParams.append(key, value);\n }\n\n return searchParams;\n}\n\nfunction processRouteLoaderData(\n matches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n pendingError: RouteData | undefined,\n activeDeferreds: Map\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\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 // Look upwards from the matched route for the closest ancestor\n // error boundary, defaulting to the root match\n let boundaryMatch = findNearestBoundary(matches, id);\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) {\n error = Object.values(pendingError)[0];\n pendingError = undefined;\n }\n\n errors = errors || {};\n\n // Prefer higher error values if lower errors bubble to the same boundary\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\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 } else {\n loaderData[id] = result.data;\n }\n\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 }\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) {\n errors = pendingError;\n loaderData[Object.keys(pendingError)[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 pendingError: RouteData | 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 pendingError,\n activeDeferreds\n );\n\n // Process results from our revalidating fetchers\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let [key, , match] = 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 (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: FetcherStates[\"Idle\"] = {\n state: \"idle\",\n data: result.data,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n \" _hasFetcherDoneAnything \": true,\n };\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) {\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\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 = 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 }: {\n pathname?: string;\n routeId?: string;\n method?: string;\n type?: \"defer-action\";\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 (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 {\n errorMessage = \"Cannot submit binary form data using GET\";\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 ErrorResponse(\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(results: DataResult[]): RedirectResult | undefined {\n for (let i = results.length - 1; i >= 0; i--) {\n let result = results[i];\n if (isRedirectResult(result)) {\n return result;\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 return (\n a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash\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\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 isQueryRouteResponse(obj: any): obj is QueryRouteResponse {\n return (\n obj &&\n isResponse(obj.response) &&\n (obj.type === ResultType.data || ResultType.error)\n );\n}\n\nfunction isValidMethod(method: string): method is FormMethod {\n return validRequestMethods.has(method as FormMethod);\n}\n\nfunction isMutationMethod(method?: string): method is MutationFormMethod {\n return validMutationMethods.has(method as MutationFormMethod);\n}\n\nasync function resolveDeferredResults(\n currentMatches: AgnosticDataRouteMatch[],\n matchesToLoad: AgnosticDataRouteMatch[],\n results: DataResult[],\n signal: AbortSignal,\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 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 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\n// Note: This should match the format exported by useMatches, so if you change\n// this please also change that :) Eventually we'll DRY this up\nfunction createUseMatchesMatch(\n match: AgnosticDataRouteMatch,\n loaderData: RouteData\n): UseMatchesMatch {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id] as unknown,\n handle: route.handle as unknown,\n };\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//#endregion\n"],"names":["Action","exports","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","nextAction","nextIndex","delta","createURL","base","origin","href","URL","replaceState","listen","fn","addEventListener","removeEventListener","encodeLocation","url","push","Push","historyState","pushState","error","assign","replace","Replace","go","n","ResultType","convertRoutesToDataRoutes","routes","parentPath","allIds","Set","map","route","treePath","id","join","children","has","add","isIndexRoute","undefined","matchRoutes","locationArg","basename","stripBasename","branches","flattenRoutes","sort","a","b","score","length","slice","every","i","compareIndexes","routesMeta","meta","childrenIndex","rankRouteBranches","matches","matchRouteBranch","safelyDecodeURI","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","match","matchPath","Object","params","pathnameBase","normalizePathname","pattern","matcher","paramNames","regexpSource","_","paramName","RegExp","compilePath","captureGroups","memo","splatValue","decodeURIComponent","safelyDecodeURIComponent","decodeURI","toLowerCase","startIndex","nextChar","resolvePath","fromPathname","toPathname","pop","resolvePathname","normalizeSearch","normalizeHash","getInvalidPathError","char","field","dest","JSON","stringify","getPathContributingMatches","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","from","isEmptyPath","routePathnameIndex","toSegments","shift","hasExplicitTrailingSlash","hasCurrentTrailingSlash","paths","AbortedDeferredError","DeferredData","constructor","data","responseInit","reject","this","pendingKeysSet","subscribers","deferredKeys","Array","isArray","abortPromise","Promise","r","controller","AbortController","onAbort","unlistenAbortSignal","signal","entries","acc","trackPromise","init","promise","race","then","onSettle","catch","defineProperty","get","aborted","delete","done","emit","settledKey","subscriber","subscribe","cancel","abort","v","k","async","resolve","size","unwrappedData","_ref2","unwrapTrackedPromise","pendingKeys","_tracked","isTrackedPromise","_error","_data","ErrorResponse","status","statusText","internal","isRouteErrorResponse","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","formMethod","formAction","formEncType","formData","IDLE_FETCHER","IDLE_BLOCKER","proceed","reset","isBrowser","createElement","isServer","UNSAFE_DEFERRED_SYMBOL","Symbol","normalizeNavigateOptions","opts","isFetcher","submission","isSubmissionNavigation","isValidMethod","getInternalRouterError","method","stripHashFromPath","isMutationMethod","searchParams","convertFormDataToSearchParams","hasNakedIndexQuery","append","getLoaderMatchesUntilBoundary","boundaryId","boundaryMatches","findIndex","m","getMatchesToLoad","isRevalidationRequired","cancelledDeferredRoutes","cancelledFetcherLoads","pendingActionData","pendingError","fetchLoadMatches","actionResult","values","navigationMatches","keys","loader","currentLoaderData","currentMatch","isNew","isMissingData","isNewLoader","loaderData","shouldRevalidateLoader","revalidatingFetchers","_ref11","fetchMatches","isNewRouteInstance","currentPath","currentLocation","currentUrl","currentParams","nextUrl","nextParams","defaultShouldRevalidate","shouldRevalidate","routeChoice","callLoaderOrAction","type","request","isStaticRequest","isRouteRequest","requestContext","resultType","onReject","handler","context","isResponse","headers","protocol","resolvedLocation","set","redirect","revalidate","response","contentType","json","text","statusCode","deferred","deferredData","createClientSideRequest","toUpperCase","body","Request","URLSearchParams","processRouteLoaderData","matchesToLoad","results","activeDeferreds","errors","foundError","loaderHeaders","isRedirectResult","isErrorResult","boundaryMatch","findNearestBoundary","isDeferredResult","processLoaderData","fetcherResults","fetchers","doneFetcher","mergeLoaderData","newLoaderData","mergedLoaderData","hasOwnProperty","routeId","reverse","find","hasErrorBoundary","getShortCircuitMatches","_temp4","errorMessage","findRedirect","isRedirectResponse","resolveDeferredResults","currentMatches","isRevalidatingLoader","resolveDeferredData","unwrap","resolveData","getAll","createUseMatchesMatch","handle","getTargetMatch","pathMatches","querySelector","getAttribute","initialEntries","initialIndex","entry","createMemoryLocation","clampIndex","min","max","getCurrentLocation","nextLocation","splice","dataRoutes","unlistenHistory","savedScrollPositions","getScrollRestorationKey","getScrollPosition","initialScrollRestored","hydrationData","initialMatches","initialErrors","router","pendingNavigationController","initialized","historyAction","navigation","restoreScrollPosition","preventScrollReset","revalidation","actionData","Map","blockers","pendingAction","HistoryAction","pendingPreventScrollReset","isUninterruptedRevalidation","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","activeBlocker","blockerFunctions","ignoreNextHistoryUpdate","updateState","newState","completeNavigation","_location$state","_location$state2","isActionReload","_isRedirect","deleteBlocker","getSavedScrollPosition","startNavigation","startUninterruptedRevalidation","userMatches","saveScrollPosition","loadingNavigation","overrideNavigation","notFoundMatches","cancelActiveDeferreds","actionOutput","interruptActiveLoads","actionMatch","shortCircuited","startRedirectNavigation","pendingActionError","handleAction","activeSubmission","fetcher","revalidatingFetcher","_ref3","loaderResults","callLoadersAndMaybeResolveData","_ref4","doneKeys","markFetchersDone","markFetchRedirectsDone","didAbortFetchLoads","abortStaleFetchLoads","handleLoaders","getFetcher","_temp","_window","isFetchActionRedirect","redirectLocation","_isFetchActionRedirect","newOrigin","redirectHistoryAction","fetchersToLoad","all","_ref8","_ref9","abortFetcher","setFetcherError","deleteFetcher","landedId","yeetedKeys","updateBlocker","newBlocker","blocker","shouldBlockNavigation","_ref10","blockerFunction","predicate","cancelledRouteIds","dfd","y","initialize","blockerKey","enableScrollRestoration","positions","getPosition","getKey","navigate","userReplace","fetch","requestMatches","existingFetcher","abortController","fetchRequest","loadingFetcher","revalidationRequest","loadId","loadFetcher","_ref5","staleKey","_ref6","_ref7","handleFetcherAction","handleFetcherLoader","dispose","clear","getBlocker","_internalFetchControllers","_internalActiveDeferreds","queryImpl","routeMatch","Response","Location","actionHeaders","loadRouteData","loaderRequest","submit","obj","executedLoaders","fromEntries","query","_temp2","methodNotAllowedMatches","queryRoute","_temp3","_result$activeDeferre","originalPath","optional","param","prefix","__","str","_deepestRenderedBoundaryId","Headers"],"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 0000000..113dffb --- /dev/null +++ b/node_modules/@remix-run/router/dist/utils.d.ts @@ -0,0 +1,389 @@ +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: any; + 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; + status: number; + location: string; + revalidate: boolean; +} +/** + * Unsuccessful result from a loader or action + */ +export interface ErrorResult { + type: ResultType.error; + error: any; + headers?: Headers; +} +/** + * Result from a loader or action - potentially successful or unsuccessful + */ +export declare type DataResult = SuccessResult | DeferredResult | RedirectResult | ErrorResult; +export declare type MutationFormMethod = "post" | "put" | "patch" | "delete"; +export declare type FormMethod = "get" | MutationFormMethod; +export declare type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data"; +/** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ +export interface Submission { + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; +} +/** + * @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?: any; +} +/** + * Arguments passed to loader functions + */ +export interface LoaderFunctionArgs extends DataFunctionArgs { +} +/** + * Arguments passed to action functions + */ +export interface ActionFunctionArgs extends DataFunctionArgs { +} +/** + * Route loader function signature + */ +export interface LoaderFunction { + (args: LoaderFunctionArgs): Promise | Response | Promise | any; +} +/** + * Route action function signature + */ +export interface ActionFunction { + (args: ActionFunctionArgs): Promise | Response | Promise | any; +} +/** + * 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: { + currentUrl: URL; + currentParams: AgnosticDataRouteMatch["params"]; + nextUrl: URL; + nextParams: AgnosticDataRouteMatch["params"]; + formMethod?: Submission["formMethod"]; + formAction?: Submission["formAction"]; + formEncType?: Submission["formEncType"]; + formData?: Submission["formData"]; + actionResult?: DataResult; + defaultShouldRevalidate: boolean; + }): boolean; +} +/** + * Base RouteObject with common props shared by all types of routes + */ +declare type AgnosticBaseRouteObject = { + caseSensitive?: boolean; + path?: string; + id?: string; + loader?: LoaderFunction; + action?: ActionFunction; + hasErrorBoundary?: boolean; + shouldRevalidate?: ShouldRevalidateFunction; + handle?: any; +}; +/** + * Index routes must not have children + */ +export declare type AgnosticIndexRouteObject = AgnosticBaseRouteObject & { + children?: undefined; + index: true; +}; +/** + * Non-index routes may have children, but cannot have index + */ +export declare 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 declare type AgnosticRouteObject = AgnosticIndexRouteObject | AgnosticNonIndexRouteObject; +export declare type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & { + id: string; +}; +export declare type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & { + children?: AgnosticDataRouteObject[]; + id: string; +}; +/** + * A data route object, which is just a RouteObject with a required unique ID + */ +export declare type AgnosticDataRouteObject = AgnosticDataIndexRouteObject | AgnosticDataNonIndexRouteObject; +declare 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" | "*" + */ +declare type PathParam = Path extends "*" ? "*" : Path extends `${infer Rest}/*` ? "*" | _PathParam : _PathParam; +export declare type ParamParseKey = [ + PathParam +] extends [never] ? string : PathParam; +/** + * The parameters that were parsed from the URL path. + */ +export declare 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[], parentPath?: number[], allIds?: Set): 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; +/** + * 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; +/** + * @private + */ +export declare function stripBasename(pathname: string, basename: string): string | null; +/** + * @private + */ +export declare function warning(cond: any, message: string): void; +/** + * 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[]; +/** + * @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 declare 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 declare type DeferFunction = (data: Record, init?: number | ResponseInit) => DeferredData; +export declare const defer: DeferFunction; +export declare 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; +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + */ +export declare class ErrorResponse { + status: number; + statusText: string; + data: any; + error?: Error; + internal: boolean; + constructor(status: number, statusText: string | undefined, data: any, internal?: boolean); +} +/** + * Check if the given error is an ErrorResponse generated from a 4xx/5xx + * Response throw from an action/loader + */ +export declare function isRouteErrorResponse(e: any): e 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 0000000..fee3e11 --- /dev/null +++ b/node_modules/@remix-run/router/history.ts @@ -0,0 +1,737 @@ +//////////////////////////////////////////////////////////////////////////////// +//#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; +} + +/** + * 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: any; + + /** + * 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; +} + +/** + * 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`. 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)); + 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); + } +} + +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() { + let nextAction = Action.Pop; + let nextIndex = getIndex(); + + if (nextIndex != null) { + let delta = nextIndex - index; + action = nextAction; + index = nextIndex; + if (listener) { + listener({ action, location: history.location, delta }); + } + } else { + warning( + false, + // TODO: Write up a doc that explains our blocking strategy in detail + // and link to it here so people can understand better what is going on + // and how to avoid it. + `You are trying to block a POP navigation to a location that was not ` + + `created by @remix-run/router. The block will fail silently in ` + + `production, but in general you should do all navigation with the ` + + `router (instead of using window.history.pushState directly) ` + + `to avoid this situation.` + ); + } + } + + 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) { + // 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); + 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 0000000..2167063 --- /dev/null +++ b/node_modules/@remix-run/router/index.ts @@ -0,0 +1,84 @@ +export type { + ActionFunction, + ActionFunctionArgs, + AgnosticDataIndexRouteObject, + AgnosticDataNonIndexRouteObject, + AgnosticDataRouteMatch, + AgnosticDataRouteObject, + AgnosticIndexRouteObject, + AgnosticNonIndexRouteObject, + AgnosticRouteMatch, + AgnosticRouteObject, + TrackedPromise, + FormEncType, + FormMethod, + JsonFunction, + LoaderFunction, + LoaderFunctionArgs, + ParamParseKey, + Params, + PathMatch, + PathPattern, + RedirectFunction, + ShouldRevalidateFunction, + Submission, +} from "./utils"; + +export { + AbortedDeferredError, + ErrorResponse, + defer, + generatePath, + getToPathname, + isRouteErrorResponse, + joinPaths, + json, + matchPath, + matchRoutes, + normalizePathname, + redirect, + resolvePath, + resolveTo, + stripBasename, + warning, +} from "./utils"; + +export type { + BrowserHistory, + BrowserHistoryOptions, + HashHistory, + HashHistoryOptions, + History, + InitialEntry, + Location, + MemoryHistory, + MemoryHistoryOptions, + Path, + To, +} from "./history"; + +export { + Action, + createBrowserHistory, + createPath, + createHashHistory, + createMemoryHistory, + invariant, + 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 { + DeferredData as UNSAFE_DeferredData, + convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, + getPathContributingMatches as UNSAFE_getPathContributingMatches, +} from "./utils"; diff --git a/node_modules/@remix-run/router/package.json b/node_modules/@remix-run/router/package.json new file mode 100644 index 0000000..dcccad7 --- /dev/null +++ b/node_modules/@remix-run/router/package.json @@ -0,0 +1,33 @@ +{ + "name": "@remix-run/router", + "version": "1.3.0", + "description": "Nested/Data-driven/Framework-agnostic Routing", + "keywords": [ + "remix", + "router", + "location" + ], + "repository": { + "type": "git", + "url": "https://github.com/remix-run/react-router", + "directory": "packages/router" + }, + "license": "MIT", + "author": "Remix Software ", + "sideEffects": false, + "main": "./dist/router.cjs.js", + "unpkg": "./dist/router.umd.min.js", + "module": "./dist/router.js", + "types": "./dist/index.d.ts", + "files": [ + "dist/", + "*.ts", + "CHANGELOG.md" + ], + "engines": { + "node": ">=14" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/node_modules/@remix-run/router/router.ts b/node_modules/@remix-run/router/router.ts new file mode 100644 index 0000000..0924aa4 --- /dev/null +++ b/node_modules/@remix-run/router/router.ts @@ -0,0 +1,3692 @@ +import type { History, Location, Path, To } from "./history"; +import { + Action as HistoryAction, + createLocation, + createPath, + invariant, + parsePath, +} from "./history"; +import type { + DataResult, + AgnosticDataRouteMatch, + AgnosticDataRouteObject, + DeferredResult, + ErrorResult, + FormEncType, + FormMethod, + RedirectResult, + RouteData, + AgnosticRouteObject, + Submission, + SuccessResult, + AgnosticRouteMatch, + MutationFormMethod, +} from "./utils"; +import { + DeferredData, + ErrorResponse, + ResultType, + convertRoutesToDataRoutes, + getPathContributingMatches, + isRouteErrorResponse, + joinPaths, + matchRoutes, + resolveTo, + warning, +} 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 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 + * + * 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, 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, + opts?: RouterNavigateOptions + ): 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 + * + * 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 +>; + +/** + * Initialization options for createRouter + */ +export interface RouterInit { + basename?: string; + routes: AgnosticRouteObject[]; + history: History; + hydrationData?: HydrationState; +} + +/** + * 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 } + ): Promise; + queryRoute( + request: Request, + opts?: { routeId?: string; requestContext?: unknown } + ): Promise; +} + +/** + * Subscriber function signature for changes to router state + */ +export interface RouterSubscriber { + (state: RouterState): void; +} + +interface UseMatchesMatch { + id: string; + pathname: string; + params: AgnosticRouteMatch["params"]; + data: unknown; + handle: unknown; +} + +/** + * Function signature for determining the key to be used in scroll restoration + * for a given location + */ +export interface GetScrollRestorationKeyFunction { + (location: Location, matches: UseMatchesMatch[]): string | null; +} + +/** + * Function signature for determining the current scroll position + */ +export interface GetScrollPositionFunction { + (): number; +} + +/** + * Options for a navigate() call for a Link navigation + */ +type LinkNavigateOptions = { + replace?: boolean; + state?: any; + preventScrollReset?: boolean; +}; + +/** + * Options for a navigate() call for a Form navigation + */ +type SubmissionNavigateOptions = { + replace?: boolean; + state?: any; + preventScrollReset?: boolean; + formMethod?: FormMethod; + formEncType?: FormEncType; + formData: FormData; +}; + +/** + * Options to pass to navigate() for either a Link or Form navigation + */ +export type RouterNavigateOptions = + | LinkNavigateOptions + | SubmissionNavigateOptions; + +/** + * Options to pass to fetch() + */ +export type RouterFetchOptions = + | Omit + | Omit; + +/** + * Potential states for state.navigation + */ +export type NavigationStates = { + Idle: { + state: "idle"; + location: undefined; + formMethod: undefined; + formAction: undefined; + formEncType: undefined; + formData: undefined; + }; + Loading: { + state: "loading"; + location: Location; + formMethod: FormMethod | undefined; + formAction: string | undefined; + formEncType: FormEncType | undefined; + formData: FormData | undefined; + }; + Submitting: { + state: "submitting"; + location: Location; + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + }; +}; + +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; + formData: undefined; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; + Loading: { + state: "loading"; + formMethod: FormMethod | undefined; + formAction: string | undefined; + formEncType: FormEncType | undefined; + formData: FormData | undefined; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; + Submitting: { + state: "submitting"; + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; + data: TData | undefined; + " _hasFetcherDoneAnything "?: boolean; + }; +}; + +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; +} + +interface HandleActionResult extends ShortCircuitable { + /** + * Error thrown from the current action, keyed by the route containing the + * error boundary to render the error. To be committed to the state after + * loaders have completed + */ + pendingActionError?: RouteData; + /** + * Data returned from the current action, keyed by the route owning the action. + * To be committed to the state after loaders have completed + */ + pendingActionData?: RouteData; +} + +interface HandleLoadersResult extends ShortCircuitable { + /** + * loaderData returned from the current set of loaders + */ + loaderData?: RouterState["loaderData"]; + /** + * errors thrown from the current set of loaders + */ + errors?: RouterState["errors"]; +} + +/** + * Tuple of [key, href, DataRouteMatch, DataRouteMatch[]] for a revalidating + * fetcher.load() + */ +type RevalidatingFetcher = [ + string, + string, + AgnosticDataRouteMatch, + AgnosticDataRouteMatch[] +]; + +/** + * Tuple of [href, DataRouteMatch, DataRouteMatch[]] for an active + * fetcher.load() + */ +type FetchLoadMatch = [ + string, + AgnosticDataRouteMatch, + AgnosticDataRouteMatch[] +]; + +/** + * Wrapper object to allow us to throw any response out from callLoaderOrAction + * for queryRouter while preserving whether or not it was thrown or returned + * from the loader/action + */ +interface QueryRouteResponse { + type: ResultType.data | ResultType.error; + response: Response; +} + +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, +}; + +export const IDLE_FETCHER: FetcherStates["Idle"] = { + state: "idle", + data: undefined, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, +}; + +export const IDLE_BLOCKER: BlockerUnblocked = { + state: "unblocked", + proceed: undefined, + reset: undefined, + location: undefined, +}; + +const isBrowser = + typeof window !== "undefined" && + typeof window.document !== "undefined" && + typeof window.document.createElement !== "undefined"; +const isServer = !isBrowser; +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createRouter +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a router and listen to history POP navigations + */ +export function createRouter(init: RouterInit): Router { + invariant( + init.routes.length > 0, + "You must provide a non-empty routes array to createRouter" + ); + + let dataRoutes = convertRoutesToDataRoutes(init.routes); + // 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, + init.basename + ); + let initialErrors: RouteData | null = null; + + if (initialMatches == null) { + // 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 }; + } + + let initialized = + !initialMatches.some((m) => m.route.loader) || 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; + + // 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) + // - useRevalidate() + // - 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 from their actions + let fetchRedirectIds = new Set(); + + // Most recent href/match for fetcher.load calls for fetchers + let fetchLoadMatches = new Map(); + + // 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(); + + // We ony support a single active blocker at the moment since we don't have + // any compelling use cases for multi-blocker yet + let activeBlocker: string | null = null; + + // 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(); + + // 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; + } + + let blockerKey = shouldBlockNavigation({ + currentLocation: state.location, + nextLocation: location, + historyAction, + }); + if (blockerKey) { + // 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() { + deleteBlocker(blockerKey!); + updateState({ blockers: new Map(router.state.blockers) }); + }, + }); + return; + } + + return startNavigation(historyAction, location); + } + ); + + // Kick off initial data load if needed. Use Pop to avoid modifying history + if (!state.initialized) { + startNavigation(HistoryAction.Pop, state.location); + } + + return router; + } + + // Clean up a router and it's side effects + function dispose() { + if (unlistenHistory) { + unlistenHistory(); + } + 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): void { + state = { + ...state, + ...newState, + }; + subscribers.forEach((subscriber) => subscriber(state)); + } + + // 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> + ): 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 + for (let [key] of blockerFunctions) { + deleteBlocker(key); + } + + // 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); + + 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: new Map(state.blockers), + }); + + 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); + } + + // Reset stateful navigation vars + pendingAction = HistoryAction.Pop; + pendingPreventScrollReset = 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, + opts?: RouterNavigateOptions + ): Promise { + if (typeof to === "number") { + init.history.go(to); + return; + } + + let { path, submission, error } = normalizeNavigateOptions(to, 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 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() { + deleteBlocker(blockerKey!); + updateState({ blockers: new Map(state.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, + }); + } + + // 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?: { + submission?: Submission; + overrideNavigation?: Navigation; + pendingError?: ErrorResponse; + startUninterruptedRevalidation?: boolean; + preventScrollReset?: boolean; + replace?: 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; + + let loadingNavigation = opts && opts.overrideNavigation; + let matches = matchRoutes(dataRoutes, location, init.basename); + + // Short circuit with a 404 on the root error boundary if we match nothing + if (!matches) { + let error = getInternalRouterError(404, { pathname: location.pathname }); + let { matches: notFoundMatches, route } = + getShortCircuitMatches(dataRoutes); + // Cancel all pending deferred on 404s since we don't keep any routes + cancelActiveDeferreds(); + completeNavigation(location, { + matches: notFoundMatches, + loaderData: {}, + errors: { + [route.id]: error, + }, + }); + return; + } + + // Short circuit if it's only a hash change + if (isHashChangeOnly(state.location, location)) { + completeNavigation(location, { matches }); + return; + } + + // Create a controller/Request for this navigation + pendingNavigationController = new AbortController(); + let request = createClientSideRequest( + init.history, + location, + pendingNavigationController.signal, + opts && opts.submission + ); + let pendingActionData: RouteData | undefined; + let pendingError: RouteData | 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. + pendingError = { + [findNearestBoundary(matches).route.id]: opts.pendingError, + }; + } else if ( + opts && + opts.submission && + isMutationMethod(opts.submission.formMethod) + ) { + // Call action if we received an action submission + let actionOutput = await handleAction( + request, + location, + opts.submission, + matches, + { replace: opts.replace } + ); + + if (actionOutput.shortCircuited) { + return; + } + + pendingActionData = actionOutput.pendingActionData; + pendingError = actionOutput.pendingActionError; + + let navigation: NavigationStates["Loading"] = { + state: "loading", + location, + ...opts.submission, + }; + loadingNavigation = navigation; + + // Create a GET request for the loaders + request = new Request(request.url, { signal: request.signal }); + } + + // Call loaders + let { shortCircuited, loaderData, errors } = await handleLoaders( + request, + location, + matches, + loadingNavigation, + opts && opts.submission, + opts && opts.replace, + pendingActionData, + pendingError + ); + + 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, + ...(pendingActionData ? { actionData: pendingActionData } : {}), + 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[], + opts?: { replace?: boolean } + ): Promise { + interruptActiveLoads(); + + // Put us in a submitting state + let navigation: NavigationStates["Submitting"] = { + state: "submitting", + location, + ...submission, + }; + updateState({ navigation }); + + // Call our action and get the result + let result: DataResult; + let actionMatch = getTargetMatch(matches, location); + + if (!actionMatch.route.action) { + result = { + type: ResultType.error, + error: getInternalRouterError(405, { + method: request.method, + pathname: location.pathname, + routeId: actionMatch.route.id, + }), + }; + } else { + result = await callLoaderOrAction( + "action", + request, + actionMatch, + matches, + router.basename + ); + + 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 + replace = + result.location === state.location.pathname + state.location.search; + } + await startRedirectNavigation(state, result, { submission, replace }); + return { shortCircuited: true }; + } + + 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 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 { + // Send back an empty object we can use to clear out any prior actionData + pendingActionData: {}, + pendingActionError: { [boundaryMatch.route.id]: result.error }, + }; + } + + if (isDeferredResult(result)) { + throw getInternalRouterError(400, { type: "defer-action" }); + } + + return { + pendingActionData: { [actionMatch.route.id]: result.data }, + }; + } + + // Call all applicable loaders for the given matches, handling redirects, + // errors, etc. + async function handleLoaders( + request: Request, + location: Location, + matches: AgnosticDataRouteMatch[], + overrideNavigation?: Navigation, + submission?: Submission, + replace?: boolean, + pendingActionData?: RouteData, + pendingError?: RouteData + ): Promise { + // Figure out the right navigation we want to use for data loading + let loadingNavigation = overrideNavigation; + if (!loadingNavigation) { + let navigation: NavigationStates["Loading"] = { + state: "loading", + location, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + ...submission, + }; + loadingNavigation = navigation; + } + + // 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 + ? submission + : loadingNavigation.formMethod && + loadingNavigation.formAction && + loadingNavigation.formData && + loadingNavigation.formEncType + ? { + formMethod: loadingNavigation.formMethod, + formAction: loadingNavigation.formAction, + formData: loadingNavigation.formData, + formEncType: loadingNavigation.formEncType, + } + : undefined; + + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad( + init.history, + state, + matches, + activeSubmission, + location, + isRevalidationRequired, + cancelledDeferredRoutes, + cancelledFetcherLoads, + pendingActionData, + pendingError, + fetchLoadMatches + ); + + // 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)) + ); + + // Short circuit if we have no loaders to run + if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) { + completeNavigation(location, { + matches, + loaderData: {}, + // Commit pending error if we're short circuiting + errors: pendingError || null, + ...(pendingActionData ? { actionData: pendingActionData } : {}), + }); + return { shortCircuited: true }; + } + + // 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 (!isUninterruptedRevalidation) { + revalidatingFetchers.forEach(([key]) => { + let fetcher = state.fetchers.get(key); + let revalidatingFetcher: FetcherStates["Loading"] = { + state: "loading", + data: fetcher && fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, revalidatingFetcher); + }); + let actionData = pendingActionData || state.actionData; + updateState({ + navigation: loadingNavigation, + ...(actionData + ? Object.keys(actionData).length === 0 + ? { actionData: null } + : { actionData } + : {}), + ...(revalidatingFetchers.length > 0 + ? { fetchers: new Map(state.fetchers) } + : {}), + }); + } + + pendingNavigationLoadId = ++incrementingLoadId; + revalidatingFetchers.forEach(([key]) => + fetchControllers.set(key, pendingNavigationController!) + ); + + let { results, 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 + revalidatingFetchers.forEach(([key]) => fetchControllers.delete(key)); + + // If any loaders returned a redirect Response, start a new REPLACE navigation + let redirect = findRedirect(results); + if (redirect) { + await startRedirectNavigation(state, redirect, { replace }); + return { shortCircuited: true }; + } + + // Process and commit output from loaders + let { loaderData, errors } = processLoaderData( + state, + matches, + matchesToLoad, + loaderResults, + pendingError, + 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); + } + }); + }); + + markFetchRedirectsDone(); + let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); + + return { + loaderData, + errors, + ...(didAbortFetchLoads || revalidatingFetchers.length > 0 + ? { fetchers: new Map(state.fetchers) } + : {}), + }; + } + + function getFetcher(key: string): Fetcher { + return state.fetchers.get(key) || IDLE_FETCHER; + } + + // Trigger a fetcher load/submit for the given fetcher key + function fetch( + key: string, + routeId: string, + href: string, + 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 matches = matchRoutes(dataRoutes, href, init.basename); + if (!matches) { + setFetcherError( + key, + routeId, + getInternalRouterError(404, { pathname: href }) + ); + return; + } + + let { path, submission } = normalizeNavigateOptions(href, opts, true); + let match = getTargetMatch(matches, path); + + if (submission && isMutationMethod(submission.formMethod)) { + handleFetcherAction(key, routeId, path, match, matches, submission); + return; + } + + // Store off the match so we can call it's shouldRevalidate on subsequent + // revalidations + fetchLoadMatches.set(key, [path, match, matches]); + handleFetcherLoader(key, routeId, path, match, matches, 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[], + submission: Submission + ) { + interruptActiveLoads(); + fetchLoadMatches.delete(key); + + if (!match.route.action) { + let error = getInternalRouterError(405, { + method: submission.formMethod, + pathname: path, + routeId: routeId, + }); + setFetcherError(key, routeId, error); + return; + } + + // Put this fetcher into it's submitting state + let existingFetcher = state.fetchers.get(key); + let fetcher: FetcherStates["Submitting"] = { + state: "submitting", + ...submission, + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, fetcher); + updateState({ fetchers: new Map(state.fetchers) }); + + // Call the action for the fetcher + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest( + init.history, + path, + abortController.signal, + submission + ); + fetchControllers.set(key, abortController); + + let actionResult = await callLoaderOrAction( + "action", + fetchRequest, + match, + requestMatches, + router.basename + ); + + if (fetchRequest.signal.aborted) { + // We can delete this so long as we weren't aborted by ou our own fetcher + // re-submit which would have put _new_ controller is in fetchControllers + if (fetchControllers.get(key) === abortController) { + fetchControllers.delete(key); + } + return; + } + + if (isRedirectResult(actionResult)) { + fetchControllers.delete(key); + fetchRedirectIds.add(key); + let loadingFetcher: FetcherStates["Loading"] = { + state: "loading", + ...submission, + data: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, loadingFetcher); + updateState({ fetchers: new Map(state.fetchers) }); + + return startRedirectNavigation(state, actionResult, { + isFetchActionRedirect: true, + }); + } + + // 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 matches = + state.navigation.state !== "idle" + ? matchRoutes(dataRoutes, state.navigation.location, init.basename) + : state.matches; + + invariant(matches, "Didn't find any matches after fetcher action"); + + let loadId = ++incrementingLoadId; + fetchReloadIds.set(key, loadId); + + let loadFetcher: FetcherStates["Loading"] = { + state: "loading", + data: actionResult.data, + ...submission, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, loadFetcher); + + let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad( + init.history, + state, + matches, + submission, + nextLocation, + isRevalidationRequired, + cancelledDeferredRoutes, + cancelledFetcherLoads, + { [match.route.id]: actionResult.data }, + undefined, // No need to send through errors since we short circuit above + fetchLoadMatches + ); + + // 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(([staleKey]) => staleKey !== key) + .forEach(([staleKey]) => { + let existingFetcher = state.fetchers.get(staleKey); + let revalidatingFetcher: FetcherStates["Loading"] = { + state: "loading", + data: existingFetcher && existingFetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(staleKey, revalidatingFetcher); + fetchControllers.set(staleKey, abortController); + }); + + updateState({ fetchers: new Map(state.fetchers) }); + + let { results, loaderResults, fetcherResults } = + await callLoadersAndMaybeResolveData( + state.matches, + matches, + matchesToLoad, + revalidatingFetchers, + revalidationRequest + ); + + if (abortController.signal.aborted) { + return; + } + + fetchReloadIds.delete(key); + fetchControllers.delete(key); + revalidatingFetchers.forEach(([staleKey]) => + fetchControllers.delete(staleKey) + ); + + let redirect = findRedirect(results); + if (redirect) { + return startRedirectNavigation(state, redirect); + } + + // Process and commit output from loaders + let { loaderData, errors } = processLoaderData( + state, + state.matches, + matchesToLoad, + loaderResults, + undefined, + revalidatingFetchers, + fetcherResults, + activeDeferreds + ); + + let doneFetcher: FetcherStates["Idle"] = { + state: "idle", + data: actionResult.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, doneFetcher); + + let didAbortFetchLoads = 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 + ), + ...(didAbortFetchLoads ? { 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[], + submission?: Submission + ) { + let existingFetcher = state.fetchers.get(key); + // Put this fetcher into it's loading state + let loadingFetcher: FetcherStates["Loading"] = { + state: "loading", + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + ...submission, + data: existingFetcher && existingFetcher.data, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, loadingFetcher); + updateState({ fetchers: new Map(state.fetchers) }); + + // Call the loader for this fetcher route match + let abortController = new AbortController(); + let fetchRequest = createClientSideRequest( + init.history, + path, + abortController.signal + ); + fetchControllers.set(key, abortController); + let result: DataResult = await callLoaderOrAction( + "loader", + fetchRequest, + match, + matches, + router.basename + ); + + // 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 ou 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; + } + + // If the loader threw a redirect Response, start a new REPLACE navigation + if (isRedirectResult(result)) { + await startRedirectNavigation(state, result); + return; + } + + // Process any non-redirect errors thrown + if (isErrorResult(result)) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + state.fetchers.delete(key); + // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch - + // do we need to behave any differently with our non-redirect errors? + // What if it was a non-redirect Response? + updateState({ + fetchers: new Map(state.fetchers), + errors: { + [boundaryMatch.route.id]: result.error, + }, + }); + return; + } + + invariant(!isDeferredResult(result), "Unhandled fetcher deferred data"); + + // Put the fetcher back into an idle state + let doneFetcher: FetcherStates["Idle"] = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, doneFetcher); + updateState({ fetchers: new Map(state.fetchers) }); + } + + /** + * 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( + state: RouterState, + redirect: RedirectResult, + { + submission, + replace, + isFetchActionRedirect, + }: { + submission?: Submission; + replace?: boolean; + isFetchActionRedirect?: boolean; + } = {} + ) { + if (redirect.revalidate) { + isRevalidationRequired = true; + } + + let redirectLocation = createLocation( + state.location, + redirect.location, + // TODO: This can be removed once we get rid of useTransition in Remix v2 + { + _isRedirect: true, + ...(isFetchActionRedirect ? { _isFetchActionRedirect: true } : {}), + } + ); + invariant( + redirectLocation, + "Expected a location on the redirect navigation" + ); + + // Check if this an external redirect that goes to a new origin + if (isBrowser && typeof window?.location !== "undefined") { + let newOrigin = init.history.createURL(redirect.location).origin; + if (window.location.origin !== newOrigin) { + if (replace) { + window.location.replace(redirect.location); + } else { + window.location.assign(redirect.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, formData } = state.navigation; + if (!submission && formMethod && formAction && formData && formEncType) { + submission = { + formMethod, + formAction, + formEncType, + formData, + }; + } + + // 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 + if ( + redirectPreserveMethodStatusCodes.has(redirect.status) && + submission && + isMutationMethod(submission.formMethod) + ) { + await startNavigation(redirectHistoryAction, redirectLocation, { + submission: { + ...submission, + formAction: redirect.location, + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset, + }); + } else { + // Otherwise, we kick off a new loading navigation, preserving the + // submission info for the duration of this navigation + await startNavigation(redirectHistoryAction, redirectLocation, { + overrideNavigation: { + state: "loading", + location: redirectLocation, + formMethod: submission ? submission.formMethod : undefined, + formAction: submission ? submission.formAction : undefined, + formEncType: submission ? submission.formEncType : undefined, + formData: submission ? submission.formData : undefined, + }, + // Preserve this flag across redirects + preventScrollReset: pendingPreventScrollReset, + }); + } + } + + async function callLoadersAndMaybeResolveData( + currentMatches: AgnosticDataRouteMatch[], + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + fetchersToLoad: RevalidatingFetcher[], + request: Request + ) { + // Call all navigation loaders and revalidating fetcher loaders in parallel, + // then slice off the results into separate arrays so we can handle them + // accordingly + let results = await Promise.all([ + ...matchesToLoad.map((match) => + callLoaderOrAction("loader", request, match, matches, router.basename) + ), + ...fetchersToLoad.map(([, href, match, fetchMatches]) => + callLoaderOrAction( + "loader", + createClientSideRequest(init.history, href, request.signal), + match, + fetchMatches, + router.basename + ) + ), + ]); + let loaderResults = results.slice(0, matchesToLoad.length); + let fetcherResults = results.slice(matchesToLoad.length); + + await Promise.all([ + resolveDeferredResults( + currentMatches, + matchesToLoad, + loaderResults, + request.signal, + false, + state.loaderData + ), + resolveDeferredResults( + currentMatches, + fetchersToLoad.map(([, , match]) => match), + fetcherResults, + request.signal, + true + ), + ]); + + return { results, 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 setFetcherError(key: string, routeId: string, error: any) { + let boundaryMatch = findNearestBoundary(state.matches, routeId); + deleteFetcher(key); + updateState({ + errors: { + [boundaryMatch.route.id]: error, + }, + fetchers: new Map(state.fetchers), + }); + } + + function deleteFetcher(key: string): void { + if (fetchControllers.has(key)) abortFetcher(key); + fetchLoadMatches.delete(key); + fetchReloadIds.delete(key); + fetchRedirectIds.delete(key); + state.fetchers.delete(key); + } + + 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: FetcherStates["Idle"] = { + state: "idle", + data: fetcher.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + state.fetchers.set(key, doneFetcher); + } + } + + function markFetchRedirectsDone(): void { + let doneKeys = []; + 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); + } + } + markFetchersDone(doneKeys); + } + + 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); + if (activeBlocker == null) { + // This is now the active blocker + activeBlocker = key; + } else if (key !== activeBlocker) { + warning(false, "A router only supports one blocker at a time"); + } + } + + return blocker; + } + + function deleteBlocker(key: string) { + state.blockers.delete(key); + blockerFunctions.delete(key); + if (activeBlocker === key) { + activeBlocker = null; + } + } + + // 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}` + ); + + state.blockers.set(key, newBlocker); + updateState({ blockers: new Map(state.blockers) }); + } + + function shouldBlockNavigation({ + currentLocation, + nextLocation, + historyAction, + }: { + currentLocation: Location; + nextLocation: Location; + historyAction: HistoryAction; + }): string | undefined { + if (activeBlocker == null) { + return; + } + + // We only allow a single blocker at the moment. This will need to be + // updated if we enhance to support multiple blockers in the future + let blockerFunction = blockerFunctions.get(activeBlocker); + invariant( + blockerFunction, + "Could not find a function for the active blocker" + ); + let blocker = state.blockers.get(activeBlocker); + + 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 activeBlocker; + } + } + + 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 || ((location) => location.key); + + // 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 saveScrollPosition( + location: Location, + matches: AgnosticDataRouteMatch[] + ): void { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map((m) => + createUseMatchesMatch(m, state.loaderData) + ); + let key = getScrollRestorationKey(location, userMatches) || location.key; + savedScrollPositions[key] = getScrollPosition(); + } + } + + function getSavedScrollPosition( + location: Location, + matches: AgnosticDataRouteMatch[] + ): number | null { + if (savedScrollPositions && getScrollRestorationKey && getScrollPosition) { + let userMatches = matches.map((m) => + createUseMatchesMatch(m, state.loaderData) + ); + let key = getScrollRestorationKey(location, userMatches) || location.key; + let y = savedScrollPositions[key]; + if (typeof y === "number") { + return y; + } + } + return null; + } + + router = { + get basename() { + return init.basename; + }, + get state() { + return state; + }, + get routes() { + return dataRoutes; + }, + 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, + dispose, + getBlocker, + deleteBlocker, + _internalFetchControllers: fetchControllers, + _internalActiveDeferreds: activeDeferreds, + }; + + return router; +} +//#endregion + +//////////////////////////////////////////////////////////////////////////////// +//#region createStaticHandler +//////////////////////////////////////////////////////////////////////////////// + +export const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred"); + +export function createStaticHandler( + routes: AgnosticRouteObject[], + opts?: { + basename?: string; + } +): StaticHandler { + invariant( + routes.length > 0, + "You must provide a non-empty routes array to createStaticHandler" + ); + + let dataRoutes = convertRoutesToDataRoutes(routes); + let basename = (opts ? opts.basename : null) || "/"; + + /** + * 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. + */ + async function query( + request: Request, + { requestContext }: { requestContext?: unknown } = {} + ): Promise { + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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); + 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. + */ + async function queryRoute( + request: Request, + { + routeId, + requestContext, + }: { requestContext?: unknown; routeId?: string } = {} + ): Promise { + let url = new URL(request.url); + let method = request.method.toLowerCase(); + 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, + 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, + routeMatch?: AgnosticDataRouteMatch + ): 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, + routeMatch != null + ); + return result; + } + + let result = await loadRouteData( + request, + matches, + requestContext, + routeMatch + ); + return isResponse(result) + ? result + : { + ...result, + actionData: null, + actionHeaders: {}, + }; + } catch (e) { + // If the user threw/returned a Response in callLoaderOrAction, we throw + // it to bail out and then return or throw here based on whether the user + // returned or threw + if (isQueryRouteResponse(e)) { + if (e.type === ResultType.error && !isRedirectResponse(e.response)) { + throw e.response; + } + return e.response; + } + // 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, + isRouteRequest: boolean + ): Promise | Response> { + let result: DataResult; + + if (!actionMatch.route.action) { + 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 { + result = await callLoaderOrAction( + "action", + request, + actionMatch, + matches, + basename, + true, + isRouteRequest, + requestContext + ); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(`${method}() call aborted`); + } + } + + 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.status, + headers: { + Location: result.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, + }; + } + + 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); + let context = await loadRouteData( + request, + matches, + requestContext, + undefined, + { + [boundaryMatch.route.id]: result.error, + } + ); + + // action status codes take precedence over loader status codes + return { + ...context, + statusCode: isRouteErrorResponse(result.error) + ? result.error.status + : 500, + actionData: null, + actionHeaders: { + ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}), + }, + }; + } + + // Create a GET request for the loaders + let loaderRequest = new Request(request.url, { + headers: request.headers, + redirect: request.redirect, + signal: request.signal, + }); + let context = await loadRouteData(loaderRequest, matches, requestContext); + + return { + ...context, + // action status codes take precedence over loader status codes + ...(result.statusCode ? { statusCode: result.statusCode } : {}), + actionData: { + [actionMatch.route.id]: result.data, + }, + actionHeaders: { + ...(result.headers ? { [actionMatch.route.id]: result.headers } : {}), + }, + }; + } + + async function loadRouteData( + request: Request, + matches: AgnosticDataRouteMatch[], + requestContext: unknown, + routeMatch?: AgnosticDataRouteMatch, + pendingActionError?: RouteData + ): 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) { + throw getInternalRouterError(400, { + method: request.method, + pathname: new URL(request.url).pathname, + routeId: routeMatch?.route.id, + }); + } + + let requestMatches = routeMatch + ? [routeMatch] + : getLoaderMatchesUntilBoundary( + matches, + Object.keys(pendingActionError || {})[0] + ); + let matchesToLoad = requestMatches.filter((m) => m.route.loader); + + // 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: pendingActionError || null, + statusCode: 200, + loaderHeaders: {}, + activeDeferreds: null, + }; + } + + let results = await Promise.all([ + ...matchesToLoad.map((match) => + callLoaderOrAction( + "loader", + request, + match, + matches, + basename, + true, + isRouteRequest, + requestContext + ) + ), + ]); + + if (request.signal.aborted) { + let method = isRouteRequest ? "queryRoute" : "query"; + throw new Error(`${method}() call aborted`); + } + + // Process and commit output from loaders + let activeDeferreds = new Map(); + let context = processRouteLoaderData( + matches, + matchesToLoad, + results, + pendingActionError, + activeDeferreds + ); + + // 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, + }; + } + + 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: 500, + errors: { + [context._deepestRenderedBoundaryId || routes[0].id]: error, + }, + }; + return newContext; +} + +function isSubmissionNavigation( + opts: RouterNavigateOptions +): opts is SubmissionNavigateOptions { + return opts != null && "formData" in opts; +} + +// Normalize navigation options by converting formMethod=GET formData objects to +// URLSearchParams so they behave identically to links with query params +function normalizeNavigateOptions( + to: To, + opts?: RouterNavigateOptions, + isFetcher = false +): { + path: string; + submission?: Submission; + error?: ErrorResponse; +} { + let path = typeof to === "string" ? to : createPath(to); + + // 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 }), + }; + } + + // Create a Submission on non-GET navigations + let submission: Submission | undefined; + if (opts.formData) { + submission = { + formMethod: opts.formMethod || "get", + formAction: stripHashFromPath(path), + formEncType: + (opts && opts.formEncType) || "application/x-www-form-urlencoded", + formData: opts.formData, + }; + + if (isMutationMethod(submission.formMethod)) { + return { path, submission }; + } + } + + // Flatten submission onto URLSearchParams for GET submissions + let parsedPath = parsePath(path); + try { + let searchParams = convertFormDataToSearchParams(opts.formData); + // Since fetcher GET submissions only run a single loader (as opposed to + // navigation GET submissions which run all loaders), we need to preserve + // any incoming ?index params + if ( + isFetcher && + parsedPath.search && + hasNakedIndexQuery(parsedPath.search) + ) { + searchParams.append("index", ""); + } + parsedPath.search = `?${searchParams}`; + } catch (e) { + return { + path, + error: getInternalRouterError(400), + }; + } + + 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, + isRevalidationRequired: boolean, + cancelledDeferredRoutes: string[], + cancelledFetcherLoads: string[], + pendingActionData?: RouteData, + pendingError?: RouteData, + fetchLoadMatches?: Map +): [AgnosticDataRouteMatch[], RevalidatingFetcher[]] { + let actionResult = pendingError + ? Object.values(pendingError)[0] + : pendingActionData + ? Object.values(pendingActionData)[0] + : undefined; + + // Pick navigation matches that are net-new or qualify for revalidation + let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined; + let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId); + let navigationMatches = boundaryMatches.filter( + (match, index) => + match.route.loader != null && + (isNewLoader(state.loaderData, state.matches[index], match) || + // If this route had a pending deferred cancelled it must be revalidated + cancelledDeferredRoutes.some((id) => id === match.route.id) || + shouldRevalidateLoader( + history, + state.location, + state.matches[index], + submission, + location, + match, + isRevalidationRequired, + actionResult + )) + ); + + // Pick fetcher.loads that need to be revalidated + let revalidatingFetchers: RevalidatingFetcher[] = []; + fetchLoadMatches && + fetchLoadMatches.forEach(([href, match, fetchMatches], key) => { + // This fetcher was cancelled from a prior action submission - force reload + if (cancelledFetcherLoads.includes(key)) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } else if (isRevalidationRequired) { + let shouldRevalidate = shouldRevalidateLoader( + history, + href, + match, + submission, + href, + match, + isRevalidationRequired, + actionResult + ); + if (shouldRevalidate) { + revalidatingFetchers.push([key, href, match, fetchMatches]); + } + } + }); + + 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 && + currentPath.endsWith("*") && + currentMatch.params["*"] !== match.params["*"]) + ); +} + +function shouldRevalidateLoader( + history: History, + currentLocation: string | Location, + currentMatch: AgnosticDataRouteMatch, + submission: Submission | undefined, + location: string | Location, + match: AgnosticDataRouteMatch, + isRevalidationRequired: boolean, + actionResult: DataResult | undefined +) { + let currentUrl = history.createURL(currentLocation); + let currentParams = currentMatch.params; + let nextUrl = history.createURL(location); + let nextParams = match.params; + + // This is the default implementation as to 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 + // Note that fetchers always provide the same current/next locations so the + // URL-based checks here don't apply to fetcher shouldRevalidate calls + let defaultShouldRevalidate = + isNewRouteInstance(currentMatch, match) || + // Clicked the same link, resubmitted a GET form + currentUrl.toString() === nextUrl.toString() || + // Search params affect all loaders + currentUrl.search !== nextUrl.search || + // Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate + isRevalidationRequired; + + if (match.route.shouldRevalidate) { + let routeChoice = match.route.shouldRevalidate({ + currentUrl, + currentParams, + nextUrl, + nextParams, + ...submission, + actionResult, + defaultShouldRevalidate, + }); + if (typeof routeChoice === "boolean") { + return routeChoice; + } + } + + return defaultShouldRevalidate; +} + +async function callLoaderOrAction( + type: "loader" | "action", + request: Request, + match: AgnosticDataRouteMatch, + matches: AgnosticDataRouteMatch[], + basename = "/", + isStaticRequest: boolean = false, + isRouteRequest: boolean = false, + requestContext?: unknown +): Promise { + let resultType; + let result; + + // Setup a promise we can race against so that abort signals short circuit + let reject: () => void; + let abortPromise = new Promise((_, r) => (reject = r)); + let onReject = () => reject(); + request.signal.addEventListener("abort", onReject); + + try { + let handler = match.route[type]; + invariant( + handler, + `Could not find the ${type} to run on the "${match.route.id}" route` + ); + + result = await Promise.race([ + handler({ request, params: match.params, context: requestContext }), + abortPromise, + ]); + + invariant( + 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) { + resultType = ResultType.error; + result = e; + } finally { + request.signal.removeEventListener("abort", onReject); + } + + if (isResponse(result)) { + let status = result.status; + + // Process redirects + if (redirectStatusCodes.has(status)) { + let location = result.headers.get("Location"); + invariant( + location, + "Redirects returned/thrown from loaders/actions must have a Location header" + ); + + let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location); + + // Support relative routing in internal redirects + if (!isAbsolute) { + let activeMatches = matches.slice(0, matches.indexOf(match) + 1); + let routePathnames = getPathContributingMatches(activeMatches).map( + (match) => match.pathnameBase + ); + let resolvedLocation = resolveTo( + location, + routePathnames, + new URL(request.url).pathname + ); + invariant( + createPath(resolvedLocation), + `Unable to resolve redirect location: ${location}` + ); + + // Prepend the basename to the redirect location if we have one + if (basename) { + let path = resolvedLocation.pathname; + resolvedLocation.pathname = + path === "/" ? basename : joinPaths([basename, path]); + } + + location = createPath(resolvedLocation); + } else if (!isStaticRequest) { + // Strip off the protocol+origin for same-origin absolute redirects. + // If this is a static reques, we can let it go back to the browser + // as-is + let currentUrl = new URL(request.url); + let url = location.startsWith("//") + ? new URL(currentUrl.protocol + location) + : new URL(location); + if (url.origin === currentUrl.origin) { + location = url.pathname + url.search + url.hash; + } + } + + // Don't process redirects in the router during static requests requests. + // Instead, throw the Response and let the server handle it with an HTTP + // redirect. We also update the Location header in place in this flow so + // basename and relative routing is taken into account + if (isStaticRequest) { + result.headers.set("Location", location); + throw result; + } + + return { + type: ResultType.redirect, + status, + location, + revalidate: result.headers.get("X-Remix-Revalidate") !== null, + }; + } + + // For SSR single-route requests, we want to hand Responses back directly + // without unwrapping. We do this with the QueryRouteResponse wrapper + // interface so we can know whether it was returned or thrown + if (isRouteRequest) { + // eslint-disable-next-line no-throw-literal + throw { + type: resultType || ResultType.data, + response: result, + }; + } + + let data: any; + 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)) { + data = await result.json(); + } else { + data = await result.text(); + } + + if (resultType === ResultType.error) { + return { + type: resultType, + error: new ErrorResponse(status, result.statusText, data), + headers: result.headers, + }; + } + + return { + type: ResultType.data, + data, + statusCode: result.status, + headers: result.headers, + }; + } + + if (resultType === ResultType.error) { + return { type: resultType, error: result }; + } + + if (result instanceof DeferredData) { + return { type: ResultType.deferred, deferredData: result }; + } + + return { type: ResultType.data, data: result }; +} + +// 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, formData } = submission; + init.method = formMethod.toUpperCase(); + init.body = + formEncType === "application/x-www-form-urlencoded" + ? convertFormDataToSearchParams(formData) + : formData; + } + + // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request) + return new Request(url, init); +} + +function convertFormDataToSearchParams(formData: FormData): URLSearchParams { + let searchParams = new URLSearchParams(); + + for (let [key, value] of formData.entries()) { + invariant( + typeof value === "string", + 'File inputs are not supported with encType "application/x-www-form-urlencoded", ' + + 'please use "multipart/form-data" instead.' + ); + searchParams.append(key, value); + } + + return searchParams; +} + +function processRouteLoaderData( + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + results: DataResult[], + pendingError: RouteData | undefined, + activeDeferreds: Map +): { + 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 = {}; + + // 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)) { + // Look upwards from the matched route for the closest ancestor + // error boundary, defaulting to the root match + let boundaryMatch = findNearestBoundary(matches, id); + 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) { + error = Object.values(pendingError)[0]; + pendingError = undefined; + } + + errors = errors || {}; + + // Prefer higher error values if lower errors bubble to the same boundary + 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; + } 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 != null && + 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) { + errors = pendingError; + loaderData[Object.keys(pendingError)[0]] = undefined; + } + + return { + loaderData, + errors, + statusCode: statusCode || 200, + loaderHeaders, + }; +} + +function processLoaderData( + state: RouterState, + matches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + results: DataResult[], + pendingError: RouteData | undefined, + revalidatingFetchers: RevalidatingFetcher[], + fetcherResults: DataResult[], + activeDeferreds: Map +): { + loaderData: RouterState["loaderData"]; + errors?: RouterState["errors"]; +} { + let { loaderData, errors } = processRouteLoaderData( + matches, + matchesToLoad, + results, + pendingError, + activeDeferreds + ); + + // Process results from our revalidating fetchers + for (let index = 0; index < revalidatingFetchers.length; index++) { + let [key, , match] = revalidatingFetchers[index]; + invariant( + fetcherResults !== undefined && fetcherResults[index] !== undefined, + "Did not find corresponding fetcher result" + ); + let result = fetcherResults[index]; + + // Process fetcher non-redirect errors + 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: FetcherStates["Idle"] = { + state: "idle", + data: result.data, + formMethod: undefined, + formAction: undefined, + formEncType: undefined, + formData: undefined, + " _hasFetcherDoneAnything ": true, + }; + 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) { + mergedLoaderData[id] = loaderData[id]; + } + + if (errors && errors.hasOwnProperty(id)) { + // Don't keep any loader data below the boundary + break; + } + } + return mergedLoaderData; +} + +// 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.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, + }: { + pathname?: string; + routeId?: string; + method?: string; + type?: "defer-action"; + } = {} +) { + let statusText = "Unknown Server Error"; + let errorMessage = "Unknown @remix-run/router error"; + + if (status === 400) { + statusText = "Bad Request"; + 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 { + errorMessage = "Cannot submit binary form data using GET"; + } + } 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 ErrorResponse( + status || 500, + statusText, + new Error(errorMessage), + true + ); +} + +// Find any returned redirect errors, starting from the lowest match +function findRedirect(results: DataResult[]): RedirectResult | undefined { + for (let i = results.length - 1; i >= 0; i--) { + let result = results[i]; + if (isRedirectResult(result)) { + return result; + } + } +} + +function stripHashFromPath(path: To) { + let parsedPath = typeof path === "string" ? parsePath(path) : path; + return createPath({ ...parsedPath, hash: "" }); +} + +function isHashChangeOnly(a: Location, b: Location): boolean { + return ( + a.pathname === b.pathname && a.search === b.search && a.hash !== b.hash + ); +} + +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; +} + +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 isQueryRouteResponse(obj: any): obj is QueryRouteResponse { + return ( + obj && + isResponse(obj.response) && + (obj.type === ResultType.data || ResultType.error) + ); +} + +function isValidMethod(method: string): method is FormMethod { + return validRequestMethods.has(method as FormMethod); +} + +function isMutationMethod(method?: string): method is MutationFormMethod { + return validMutationMethods.has(method as MutationFormMethod); +} + +async function resolveDeferredResults( + currentMatches: AgnosticDataRouteMatch[], + matchesToLoad: AgnosticDataRouteMatch[], + results: DataResult[], + signal: AbortSignal, + isFetcher: boolean, + currentLoaderData?: RouteData +) { + for (let index = 0; index < results.length; index++) { + let result = results[index]; + let match = matchesToLoad[index]; + 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 + 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 === ""); +} + +// Note: This should match the format exported by useMatches, so if you change +// this please also change that :) Eventually we'll DRY this up +function createUseMatchesMatch( + match: AgnosticDataRouteMatch, + loaderData: RouteData +): UseMatchesMatch { + let { route, pathname, params } = match; + return { + id: route.id, + pathname, + params, + data: loaderData[route.id] as unknown, + handle: route.handle as unknown, + }; +} + +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]; +} +//#endregion diff --git a/node_modules/@remix-run/router/utils.ts b/node_modules/@remix-run/router/utils.ts new file mode 100644 index 0000000..1a01048 --- /dev/null +++ b/node_modules/@remix-run/router/utils.ts @@ -0,0 +1,1402 @@ +import type { Location, Path, To } from "./history"; +import { invariant, parsePath } 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: any; + 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; + status: number; + location: string; + revalidate: boolean; +} + +/** + * Unsuccessful result from a loader or action + */ +export interface ErrorResult { + type: ResultType.error; + error: any; + headers?: Headers; +} + +/** + * Result from a loader or action - potentially successful or unsuccessful + */ +export type DataResult = + | SuccessResult + | DeferredResult + | RedirectResult + | ErrorResult; + +export type MutationFormMethod = "post" | "put" | "patch" | "delete"; +export type FormMethod = "get" | MutationFormMethod; + +export type FormEncType = + | "application/x-www-form-urlencoded" + | "multipart/form-data"; + +/** + * @private + * Internal interface to pass around for action submissions, not intended for + * external consumption + */ +export interface Submission { + formMethod: FormMethod; + formAction: string; + formEncType: FormEncType; + formData: FormData; +} + +/** + * @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?: any; +} + +/** + * Arguments passed to loader functions + */ +export interface LoaderFunctionArgs extends DataFunctionArgs {} + +/** + * Arguments passed to action functions + */ +export interface ActionFunctionArgs extends DataFunctionArgs {} + +/** + * Route loader function signature + */ +export interface LoaderFunction { + (args: LoaderFunctionArgs): Promise | Response | Promise | any; +} + +/** + * Route action function signature + */ +export interface ActionFunction { + (args: ActionFunctionArgs): Promise | Response | Promise | any; +} + +/** + * 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: { + currentUrl: URL; + currentParams: AgnosticDataRouteMatch["params"]; + nextUrl: URL; + nextParams: AgnosticDataRouteMatch["params"]; + formMethod?: Submission["formMethod"]; + formAction?: Submission["formAction"]; + formEncType?: Submission["formEncType"]; + formData?: Submission["formData"]; + actionResult?: DataResult; + defaultShouldRevalidate: boolean; + }): boolean; +} + +/** + * Base RouteObject with common props shared by all types of routes + */ +type AgnosticBaseRouteObject = { + caseSensitive?: boolean; + path?: string; + id?: string; + loader?: LoaderFunction; + action?: ActionFunction; + hasErrorBoundary?: boolean; + shouldRevalidate?: ShouldRevalidateFunction; + handle?: any; +}; + +/** + * 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; + +// 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" | "*" + */ +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 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[], + parentPath: number[] = [], + allIds: Set = new Set() +): AgnosticDataRouteObject[] { + return routes.map((route, index) => { + let treePath = [...parentPath, 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( + !allIds.has(id), + `Found a route id collision on id "${id}". Route ` + + "id's must be globally unique within Data Router usages" + ); + allIds.add(id); + + if (isIndexRoute(route)) { + let indexRoute: AgnosticDataIndexRouteObject = { ...route, id }; + return indexRoute; + } else { + let pathOrLayoutRoute: AgnosticDataNonIndexRouteObject = { + ...route, + id, + children: route.children + ? convertRoutesToDataRoutes(route.children, treePath, allIds) + : undefined, + }; + 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 { + 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) { + matches = matchRouteBranch( + branches[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. + safelyDecodeURI(pathname) + ); + } + + return matches; +} + +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 explodes _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 +): 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 + ); + + if (!match) return null; + + Object.assign(matchedParams, match.params); + + let route = meta.route; + + 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 = 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; + } + + return ( + path + .replace( + /^:(\w+)(\??)/g, + (_, key: PathParam, optional: string | undefined) => { + let param = params[key]; + if (optional === "?") { + return param == null ? "" : param; + } + if (param == null) { + invariant(false, `Missing ":${key}" param`); + } + return param; + } + ) + .replace( + /\/:(\w+)(\??)/g, + (_, key: PathParam, optional: string | undefined) => { + let param = params[key]; + if (optional === "?") { + return param == null ? "" : `/${param}`; + } + if (param == null) { + invariant(false, `Missing ":${key}" param`); + } + return `/${param}`; + } + ) + // Remove any optional markers from optional static segments + .replace(/\?/g, "") + .replace(/(\/?)\*/, (_, prefix, __, str) => { + const star = "*" as PathParam; + + if (params[star] == null) { + // If no splat was provided, trim the trailing slash _unless_ it's + // the entire path + return str === "/*" ? "/" : ""; + } + + // Apply the splat + return `${prefix}${params[star]}`; + }) + ); +} + +/** + * 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, paramNames] = 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 = paramNames.reduce>( + (memo, paramName, 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"); + } + + memo[paramName] = safelyDecodeURIComponent( + captureGroups[index] || "", + paramName + ); + return memo; + }, + {} + ); + + return { + params, + pathname: matchedPathname, + pathnameBase, + pattern, + }; +} + +function compilePath( + path: string, + caseSensitive = false, + end = true +): [RegExp, string[]] { + 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 paramNames: string[] = []; + 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) => { + paramNames.push(paramName); + return "/([^\\/]+)"; + }); + + if (path.endsWith("*")) { + paramNames.push("*"); + 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, paramNames]; +} + +function safelyDecodeURI(value: string) { + try { + return decodeURI(value); + } 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; + } +} + +function safelyDecodeURIComponent(value: string, paramName: string) { + try { + return decodeURIComponent(value); + } catch (error) { + warning( + false, + `The value for the URL param "${paramName}" will not be decoded because` + + ` the string "${value}" 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) || "/"; +} + +/** + * @private + */ +export function warning(cond: any, message: string): void { + if (!cond) { + // eslint-disable-next-line no-console + if (typeof console !== "undefined") console.warn(message); + + try { + // Welcome to debugging @remix-run/router! + // + // 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) {} + } +} + +/** + * 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) + ); +} + +/** + * @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 (isPathRelative || toPathname == null) { + from = locationPathname; + } else { + let routePathnameIndex = routePathnames.length - 1; + + if (toPathname.startsWith("..")) { + let toSegments = toPathname.split("/"); + + // 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". + while (toSegments[0] === "..") { + toSegments.shift(); + routePathnameIndex -= 1; + } + + to.pathname = toSegments.join("/"); + } + + // If there are more ".." segments than parent routes, resolve relative to + // the root / URL. + 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), + }), + {} + ); + + 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, null, 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 (error) { + 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, + }); +}; + +/** + * @private + * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies + */ +export class ErrorResponse { + status: number; + statusText: string; + data: any; + error?: Error; + 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 throw from an action/loader + */ +export function isRouteErrorResponse(e: any): e is ErrorResponse { + return e instanceof ErrorResponse; +} diff --git a/node_modules/react-router-dom/CHANGELOG.md b/node_modules/react-router-dom/CHANGELOG.md new file mode 100644 index 0000000..a715094 --- /dev/null +++ b/node_modules/react-router-dom/CHANGELOG.md @@ -0,0 +1,142 @@ +# `react-router-dom` + +## 6.7.0 + +### Minor Changes + +- Add `unstable_useBlocker` hook for blocking navigations within the app's location origin ([#9709](https://github.com/remix-run/react-router/pull/9709)) +- Add `unstable_usePrompt` hook for blocking navigations within the app's location origin ([#9932](https://github.com/remix-run/react-router/pull/9932)) +- Add `preventScrollReset` prop to `
` ([#9886](https://github.com/remix-run/react-router/pull/9886)) + +### Patch Changes + +- Added pass-through event listener options argument to `useBeforeUnload` ([#9709](https://github.com/remix-run/react-router/pull/9709)) +- Streamline jsdom bug workaround in tests ([#9824](https://github.com/remix-run/react-router/pull/9824)) +- Updated dependencies: + - `@remix-run/router@1.3.0` + - `react-router@6.7.0` + +## 6.6.2 + +### Patch Changes + +- Ensure `useId` consistency during SSR ([#9805](https://github.com/remix-run/react-router/pull/9805)) +- Updated dependencies: + - `react-router@6.6.2` + +## 6.6.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/router@1.2.1` + - `react-router@6.6.1` + +## 6.6.0 + +### Minor Changes + +- Add `useBeforeUnload()` hook ([#9664](https://github.com/remix-run/react-router/pull/9664)) +- Remove `unstable_` prefix from `createStaticHandler`/`createStaticRouter`/`StaticRouterProvider` ([#9738](https://github.com/remix-run/react-router/pull/9738)) + +### Patch Changes + +- Proper hydration of `Error` objects from `StaticRouterProvider` ([#9664](https://github.com/remix-run/react-router/pull/9664)) +- Support uppercase `` and `useSubmit` method values ([#9664](https://github.com/remix-run/react-router/pull/9664)) +- Skip initial scroll restoration for SSR apps with `hydrationData` ([#9664](https://github.com/remix-run/react-router/pull/9664)) +- Fix `