router.d.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. import type { History, Location, Path, To } from "./history";
  2. import { Action as HistoryAction } from "./history";
  3. import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, FormEncType, FormMethod, RouteData, AgnosticRouteObject, AgnosticRouteMatch } from "./utils";
  4. import { DeferredData } from "./utils";
  5. /**
  6. * A Router instance manages all navigation and data loading/mutations
  7. */
  8. export interface Router {
  9. /**
  10. * @internal
  11. * PRIVATE - DO NOT USE
  12. *
  13. * Return the basename for the router
  14. */
  15. get basename(): RouterInit["basename"];
  16. /**
  17. * @internal
  18. * PRIVATE - DO NOT USE
  19. *
  20. * Return the current state of the router
  21. */
  22. get state(): RouterState;
  23. /**
  24. * @internal
  25. * PRIVATE - DO NOT USE
  26. *
  27. * Return the routes for this router instance
  28. */
  29. get routes(): AgnosticDataRouteObject[];
  30. /**
  31. * @internal
  32. * PRIVATE - DO NOT USE
  33. *
  34. * Initialize the router, including adding history listeners and kicking off
  35. * initial data fetches. Returns a function to cleanup listeners and abort
  36. * any in-progress loads
  37. */
  38. initialize(): Router;
  39. /**
  40. * @internal
  41. * PRIVATE - DO NOT USE
  42. *
  43. * Subscribe to router.state updates
  44. *
  45. * @param fn function to call with the new state
  46. */
  47. subscribe(fn: RouterSubscriber): () => void;
  48. /**
  49. * @internal
  50. * PRIVATE - DO NOT USE
  51. *
  52. * Enable scroll restoration behavior in the router
  53. *
  54. * @param savedScrollPositions Object that will manage positions, in case
  55. * it's being restored from sessionStorage
  56. * @param getScrollPosition Function to get the active Y scroll position
  57. * @param getKey Function to get the key to use for restoration
  58. */
  59. enableScrollRestoration(savedScrollPositions: Record<string, number>, getScrollPosition: GetScrollPositionFunction, getKey?: GetScrollRestorationKeyFunction): () => void;
  60. /**
  61. * @internal
  62. * PRIVATE - DO NOT USE
  63. *
  64. * Navigate forward/backward in the history stack
  65. * @param to Delta to move in the history stack
  66. */
  67. navigate(to: number): Promise<void>;
  68. /**
  69. * Navigate to the given path
  70. * @param to Path to navigate to
  71. * @param opts Navigation options (method, submission, etc.)
  72. */
  73. navigate(to: To, opts?: RouterNavigateOptions): Promise<void>;
  74. /**
  75. * @internal
  76. * PRIVATE - DO NOT USE
  77. *
  78. * Trigger a fetcher load/submission
  79. *
  80. * @param key Fetcher key
  81. * @param routeId Route that owns the fetcher
  82. * @param href href to fetch
  83. * @param opts Fetcher options, (method, submission, etc.)
  84. */
  85. fetch(key: string, routeId: string, href: string, opts?: RouterNavigateOptions): void;
  86. /**
  87. * @internal
  88. * PRIVATE - DO NOT USE
  89. *
  90. * Trigger a revalidation of all current route loaders and fetcher loads
  91. */
  92. revalidate(): void;
  93. /**
  94. * @internal
  95. * PRIVATE - DO NOT USE
  96. *
  97. * Utility function to create an href for the given location
  98. * @param location
  99. */
  100. createHref(location: Location | URL): string;
  101. /**
  102. * @internal
  103. * PRIVATE - DO NOT USE
  104. *
  105. * Utility function to URL encode a destination path according to the internal
  106. * history implementation
  107. * @param to
  108. */
  109. encodeLocation(to: To): Path;
  110. /**
  111. * @internal
  112. * PRIVATE - DO NOT USE
  113. *
  114. * Get/create a fetcher for the given key
  115. * @param key
  116. */
  117. getFetcher<TData = any>(key?: string): Fetcher<TData>;
  118. /**
  119. * @internal
  120. * PRIVATE - DO NOT USE
  121. *
  122. * Delete the fetcher for a given key
  123. * @param key
  124. */
  125. deleteFetcher(key?: string): void;
  126. /**
  127. * @internal
  128. * PRIVATE - DO NOT USE
  129. *
  130. * Cleanup listeners and abort any in-progress loads
  131. */
  132. dispose(): void;
  133. /**
  134. * @internal
  135. * PRIVATE - DO NOT USE
  136. *
  137. * Get a navigation blocker
  138. * @param key The identifier for the blocker
  139. * @param fn The blocker function implementation
  140. */
  141. getBlocker(key: string, fn: BlockerFunction): Blocker;
  142. /**
  143. * @internal
  144. * PRIVATE - DO NOT USE
  145. *
  146. * Delete a navigation blocker
  147. * @param key The identifier for the blocker
  148. */
  149. deleteBlocker(key: string): void;
  150. /**
  151. * @internal
  152. * PRIVATE - DO NOT USE
  153. *
  154. * Internal fetch AbortControllers accessed by unit tests
  155. */
  156. _internalFetchControllers: Map<string, AbortController>;
  157. /**
  158. * @internal
  159. * PRIVATE - DO NOT USE
  160. *
  161. * Internal pending DeferredData instances accessed by unit tests
  162. */
  163. _internalActiveDeferreds: Map<string, DeferredData>;
  164. }
  165. /**
  166. * State maintained internally by the router. During a navigation, all states
  167. * reflect the the "old" location unless otherwise noted.
  168. */
  169. export interface RouterState {
  170. /**
  171. * The action of the most recent navigation
  172. */
  173. historyAction: HistoryAction;
  174. /**
  175. * The current location reflected by the router
  176. */
  177. location: Location;
  178. /**
  179. * The current set of route matches
  180. */
  181. matches: AgnosticDataRouteMatch[];
  182. /**
  183. * Tracks whether we've completed our initial data load
  184. */
  185. initialized: boolean;
  186. /**
  187. * Current scroll position we should start at for a new view
  188. * - number -> scroll position to restore to
  189. * - false -> do not restore scroll at all (used during submissions)
  190. * - null -> don't have a saved position, scroll to hash or top of page
  191. */
  192. restoreScrollPosition: number | false | null;
  193. /**
  194. * Indicate whether this navigation should skip resetting the scroll position
  195. * if we are unable to restore the scroll position
  196. */
  197. preventScrollReset: boolean;
  198. /**
  199. * Tracks the state of the current navigation
  200. */
  201. navigation: Navigation;
  202. /**
  203. * Tracks any in-progress revalidations
  204. */
  205. revalidation: RevalidationState;
  206. /**
  207. * Data from the loaders for the current matches
  208. */
  209. loaderData: RouteData;
  210. /**
  211. * Data from the action for the current matches
  212. */
  213. actionData: RouteData | null;
  214. /**
  215. * Errors caught from loaders for the current matches
  216. */
  217. errors: RouteData | null;
  218. /**
  219. * Map of current fetchers
  220. */
  221. fetchers: Map<string, Fetcher>;
  222. /**
  223. * Map of current blockers
  224. */
  225. blockers: Map<string, Blocker>;
  226. }
  227. /**
  228. * Data that can be passed into hydrate a Router from SSR
  229. */
  230. export declare type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionData" | "errors">>;
  231. /**
  232. * Initialization options for createRouter
  233. */
  234. export interface RouterInit {
  235. basename?: string;
  236. routes: AgnosticRouteObject[];
  237. history: History;
  238. hydrationData?: HydrationState;
  239. }
  240. /**
  241. * State returned from a server-side query() call
  242. */
  243. export interface StaticHandlerContext {
  244. basename: Router["basename"];
  245. location: RouterState["location"];
  246. matches: RouterState["matches"];
  247. loaderData: RouterState["loaderData"];
  248. actionData: RouterState["actionData"];
  249. errors: RouterState["errors"];
  250. statusCode: number;
  251. loaderHeaders: Record<string, Headers>;
  252. actionHeaders: Record<string, Headers>;
  253. activeDeferreds: Record<string, DeferredData> | null;
  254. _deepestRenderedBoundaryId?: string | null;
  255. }
  256. /**
  257. * A StaticHandler instance manages a singular SSR navigation/fetch event
  258. */
  259. export interface StaticHandler {
  260. dataRoutes: AgnosticDataRouteObject[];
  261. query(request: Request, opts?: {
  262. requestContext?: unknown;
  263. }): Promise<StaticHandlerContext | Response>;
  264. queryRoute(request: Request, opts?: {
  265. routeId?: string;
  266. requestContext?: unknown;
  267. }): Promise<any>;
  268. }
  269. /**
  270. * Subscriber function signature for changes to router state
  271. */
  272. export interface RouterSubscriber {
  273. (state: RouterState): void;
  274. }
  275. interface UseMatchesMatch {
  276. id: string;
  277. pathname: string;
  278. params: AgnosticRouteMatch["params"];
  279. data: unknown;
  280. handle: unknown;
  281. }
  282. /**
  283. * Function signature for determining the key to be used in scroll restoration
  284. * for a given location
  285. */
  286. export interface GetScrollRestorationKeyFunction {
  287. (location: Location, matches: UseMatchesMatch[]): string | null;
  288. }
  289. /**
  290. * Function signature for determining the current scroll position
  291. */
  292. export interface GetScrollPositionFunction {
  293. (): number;
  294. }
  295. /**
  296. * Options for a navigate() call for a Link navigation
  297. */
  298. declare type LinkNavigateOptions = {
  299. replace?: boolean;
  300. state?: any;
  301. preventScrollReset?: boolean;
  302. };
  303. /**
  304. * Options for a navigate() call for a Form navigation
  305. */
  306. declare type SubmissionNavigateOptions = {
  307. replace?: boolean;
  308. state?: any;
  309. preventScrollReset?: boolean;
  310. formMethod?: FormMethod;
  311. formEncType?: FormEncType;
  312. formData: FormData;
  313. };
  314. /**
  315. * Options to pass to navigate() for either a Link or Form navigation
  316. */
  317. export declare type RouterNavigateOptions = LinkNavigateOptions | SubmissionNavigateOptions;
  318. /**
  319. * Options to pass to fetch()
  320. */
  321. export declare type RouterFetchOptions = Omit<LinkNavigateOptions, "replace"> | Omit<SubmissionNavigateOptions, "replace">;
  322. /**
  323. * Potential states for state.navigation
  324. */
  325. export declare type NavigationStates = {
  326. Idle: {
  327. state: "idle";
  328. location: undefined;
  329. formMethod: undefined;
  330. formAction: undefined;
  331. formEncType: undefined;
  332. formData: undefined;
  333. };
  334. Loading: {
  335. state: "loading";
  336. location: Location;
  337. formMethod: FormMethod | undefined;
  338. formAction: string | undefined;
  339. formEncType: FormEncType | undefined;
  340. formData: FormData | undefined;
  341. };
  342. Submitting: {
  343. state: "submitting";
  344. location: Location;
  345. formMethod: FormMethod;
  346. formAction: string;
  347. formEncType: FormEncType;
  348. formData: FormData;
  349. };
  350. };
  351. export declare type Navigation = NavigationStates[keyof NavigationStates];
  352. export declare type RevalidationState = "idle" | "loading";
  353. /**
  354. * Potential states for fetchers
  355. */
  356. declare type FetcherStates<TData = any> = {
  357. Idle: {
  358. state: "idle";
  359. formMethod: undefined;
  360. formAction: undefined;
  361. formEncType: undefined;
  362. formData: undefined;
  363. data: TData | undefined;
  364. " _hasFetcherDoneAnything "?: boolean;
  365. };
  366. Loading: {
  367. state: "loading";
  368. formMethod: FormMethod | undefined;
  369. formAction: string | undefined;
  370. formEncType: FormEncType | undefined;
  371. formData: FormData | undefined;
  372. data: TData | undefined;
  373. " _hasFetcherDoneAnything "?: boolean;
  374. };
  375. Submitting: {
  376. state: "submitting";
  377. formMethod: FormMethod;
  378. formAction: string;
  379. formEncType: FormEncType;
  380. formData: FormData;
  381. data: TData | undefined;
  382. " _hasFetcherDoneAnything "?: boolean;
  383. };
  384. };
  385. export declare type Fetcher<TData = any> = FetcherStates<TData>[keyof FetcherStates<TData>];
  386. interface BlockerBlocked {
  387. state: "blocked";
  388. reset(): void;
  389. proceed(): void;
  390. location: Location;
  391. }
  392. interface BlockerUnblocked {
  393. state: "unblocked";
  394. reset: undefined;
  395. proceed: undefined;
  396. location: undefined;
  397. }
  398. interface BlockerProceeding {
  399. state: "proceeding";
  400. reset: undefined;
  401. proceed: undefined;
  402. location: Location;
  403. }
  404. export declare type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;
  405. export declare type BlockerFunction = (args: {
  406. currentLocation: Location;
  407. nextLocation: Location;
  408. historyAction: HistoryAction;
  409. }) => boolean;
  410. export declare const IDLE_NAVIGATION: NavigationStates["Idle"];
  411. export declare const IDLE_FETCHER: FetcherStates["Idle"];
  412. export declare const IDLE_BLOCKER: BlockerUnblocked;
  413. /**
  414. * Create a router and listen to history POP navigations
  415. */
  416. export declare function createRouter(init: RouterInit): Router;
  417. export declare const UNSAFE_DEFERRED_SYMBOL: unique symbol;
  418. export declare function createStaticHandler(routes: AgnosticRouteObject[], opts?: {
  419. basename?: string;
  420. }): StaticHandler;
  421. /**
  422. * Given an existing StaticHandlerContext and an error thrown at render time,
  423. * provide an updated StaticHandlerContext suitable for a second SSR render
  424. */
  425. export declare function getStaticContextFromError(routes: AgnosticDataRouteObject[], context: StaticHandlerContext, error: any): StaticHandlerContext;
  426. export {};