@tanstack/react-router 0.0.1-beta.204 → 0.0.1-beta.206

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/build/cjs/RouterProvider.js +963 -0
  2. package/build/cjs/RouterProvider.js.map +1 -0
  3. package/build/cjs/fileRoute.js +29 -0
  4. package/build/cjs/fileRoute.js.map +1 -0
  5. package/build/cjs/index.js +69 -21
  6. package/build/cjs/index.js.map +1 -1
  7. package/build/cjs/path.js +211 -0
  8. package/build/cjs/path.js.map +1 -0
  9. package/build/cjs/qss.js +65 -0
  10. package/build/cjs/qss.js.map +1 -0
  11. package/build/cjs/react.js +148 -190
  12. package/build/cjs/react.js.map +1 -1
  13. package/build/cjs/redirects.js +27 -0
  14. package/build/cjs/redirects.js.map +1 -0
  15. package/build/cjs/route.js +136 -0
  16. package/build/cjs/route.js.map +1 -0
  17. package/build/cjs/router.js +203 -0
  18. package/build/cjs/router.js.map +1 -0
  19. package/build/cjs/searchParams.js +83 -0
  20. package/build/cjs/searchParams.js.map +1 -0
  21. package/build/cjs/utils.js +196 -0
  22. package/build/cjs/utils.js.map +1 -0
  23. package/build/esm/index.js +1801 -211
  24. package/build/esm/index.js.map +1 -1
  25. package/build/stats-html.html +1 -1
  26. package/build/stats-react.json +385 -164
  27. package/build/types/RouteMatch.d.ts +23 -0
  28. package/build/types/RouterProvider.d.ts +54 -0
  29. package/build/types/awaited.d.ts +0 -8
  30. package/build/types/defer.d.ts +0 -0
  31. package/build/types/fileRoute.d.ts +17 -0
  32. package/build/types/history.d.ts +7 -0
  33. package/build/types/index.d.ts +17 -4
  34. package/build/types/link.d.ts +98 -0
  35. package/build/types/location.d.ts +14 -0
  36. package/build/types/path.d.ts +16 -0
  37. package/build/types/qss.d.ts +2 -0
  38. package/build/types/react.d.ts +23 -83
  39. package/build/types/redirects.d.ts +10 -0
  40. package/build/types/route.d.ts +222 -0
  41. package/build/types/routeInfo.d.ts +22 -0
  42. package/build/types/router.d.ts +115 -0
  43. package/build/types/scroll-restoration.d.ts +0 -3
  44. package/build/types/searchParams.d.ts +7 -0
  45. package/build/types/utils.d.ts +48 -0
  46. package/build/umd/index.development.js +1118 -1540
  47. package/build/umd/index.development.js.map +1 -1
  48. package/build/umd/index.production.js +2 -33
  49. package/build/umd/index.production.js.map +1 -1
  50. package/package.json +2 -4
  51. package/src/RouteMatch.ts +28 -0
  52. package/src/RouterProvider.tsx +1390 -0
  53. package/src/awaited.tsx +40 -40
  54. package/src/defer.ts +55 -0
  55. package/src/fileRoute.ts +143 -0
  56. package/src/history.ts +8 -0
  57. package/src/index.tsx +18 -5
  58. package/src/link.ts +347 -0
  59. package/src/location.ts +14 -0
  60. package/src/path.ts +256 -0
  61. package/src/qss.ts +53 -0
  62. package/src/react.tsx +174 -422
  63. package/src/redirects.ts +31 -0
  64. package/src/route.ts +710 -0
  65. package/src/routeInfo.ts +68 -0
  66. package/src/router.ts +373 -0
  67. package/src/scroll-restoration.tsx +205 -27
  68. package/src/searchParams.ts +78 -0
  69. package/src/utils.ts +257 -0
  70. package/build/cjs/awaited.js +0 -45
  71. package/build/cjs/awaited.js.map +0 -1
  72. package/build/cjs/scroll-restoration.js +0 -56
  73. package/build/cjs/scroll-restoration.js.map +0 -1
package/src/react.tsx CHANGED
@@ -1,193 +1,46 @@
1
1
  import * as React from 'react'
2
- import { NoInfer, useStore } from '@tanstack/react-store'
3
2
  import invariant from 'tiny-invariant'
4
3
  import warning from 'tiny-warning'
5
4
  import {
6
- functionalUpdate,
7
- last,
8
- pick,
9
- MatchRouteOptions,
10
- RegisteredRouter,
11
- RouterOptions,
12
- Router,
13
- RouteMatch,
14
- RouteByPath,
15
- AnyRoute,
16
- AnyRouteProps,
17
5
  LinkOptions,
18
6
  ToOptions,
19
7
  ResolveRelativePath,
20
8
  NavigateOptions,
21
- ResolveFullPath,
22
- ResolveId,
9
+ } from './link'
10
+ import {
23
11
  AnySearchSchema,
24
- ParsePathParams,
25
- RouteContext,
12
+ AnyPathParams,
26
13
  AnyContext,
27
- UseLoaderResult,
28
- ResolveFullSearchSchema,
29
- Route,
30
- RouteConstraints,
14
+ AnyRoute,
15
+ rootRouteId,
16
+ } from './route'
17
+ import {
31
18
  RoutePaths,
32
- RoutesById,
19
+ RouteByPath,
33
20
  RouteIds,
34
- RouteById,
35
21
  ParseRoute,
22
+ RoutesById,
23
+ RouteById,
36
24
  AllParams,
37
- rootRouteId,
38
- AnyPathParams,
39
- Expand,
40
- ResolveAllParams,
41
- DeepMergeAll,
42
- IsAny,
43
- } from '@tanstack/router-core'
25
+ } from './routeInfo'
26
+ import { RegisteredRouter, RouterOptions, Router, RouterState } from './router'
27
+ import { RouteMatch } from './RouteMatch'
28
+ import { NoInfer, functionalUpdate, last } from './utils'
29
+ import { MatchRouteOptions, RouterContext } from './RouterProvider'
30
+ import { routerContext } from './RouterProvider'
44
31
 
45
32
  const useLayoutEffect =
46
33
  typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect
47
34
 
48
- declare module '@tanstack/router-core' {
49
- interface RouterOptions<
50
- TRouteTree extends AnyRoute,
51
- TDehydrated extends Record<string, any>,
52
- > {
53
- Wrap?: React.ComponentType<{
54
- children: React.ReactNode
55
- dehydratedState?: TDehydrated
56
- }>
57
- }
58
-
59
- interface RegisterRouteComponent<
60
- TLoader = unknown,
61
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
62
- TAllParams extends AnyPathParams = AnyPathParams,
63
- TAllContext extends Record<string, any> = AnyContext,
64
- > {
65
- RouteComponent: RouteComponent<
66
- RouteProps<TLoader, TFullSearchSchema, TAllParams, TAllContext>
67
- >
68
- }
69
-
70
- interface RegisterErrorRouteComponent<
71
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
72
- TAllParams extends AnyPathParams = AnyPathParams,
73
- TAllContext extends Record<string, any> = AnyContext,
74
- > {
75
- ErrorRouteComponent: RouteComponent<
76
- ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>
77
- >
78
- }
79
-
80
- interface RegisterPendingRouteComponent<
81
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
82
- TAllParams extends AnyPathParams = AnyPathParams,
83
- TAllContext extends Record<string, any> = AnyContext,
84
- > {
85
- PendingRouteComponent: RouteComponent<
86
- PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>
87
- >
88
- }
89
-
90
- interface Route<
91
- TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
92
- TPath extends RouteConstraints['TPath'] = '/',
93
- TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
94
- TParentRoute,
95
- TPath
96
- >,
97
- TCustomId extends RouteConstraints['TCustomId'] = string,
98
- TId extends RouteConstraints['TId'] = ResolveId<
99
- TParentRoute,
100
- TCustomId,
101
- TPath
102
- >,
103
- TLoaderContext extends RouteConstraints['TLoaderContext'] = AnyContext,
104
- TLoader = unknown,
105
- TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
106
- TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
107
- TParentRoute,
108
- TSearchSchema
109
- >,
110
- TParams extends RouteConstraints['TParams'] = Expand<
111
- Record<ParsePathParams<TPath>, string>
112
- >,
113
- TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<
114
- TParentRoute,
115
- TParams
116
- >,
117
- TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
118
- TAllContext extends RouteConstraints['TAllContext'] = Expand<
119
- DeepMergeAll<
120
- [
121
- IsAny<TParentRoute['types']['context'], {}>,
122
- TLoaderContext,
123
- TRouteContext,
124
- ]
125
- >
126
- >,
127
- TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
128
- TChildren extends RouteConstraints['TChildren'] = unknown,
129
- TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
130
- > {
131
- useMatch: <TSelected = TAllContext>(opts?: {
132
- select?: (search: TAllContext) => TSelected
133
- }) => TSelected
134
- useLoader: <TSelected = TLoader>(opts?: {
135
- select?: (search: TLoader) => TSelected
136
- }) => UseLoaderResult<TSelected>
137
- useRouteContext: <TSelected = TAllContext>(opts?: {
138
- select?: (search: TAllContext) => TSelected
139
- }) => TSelected
140
- useSearch: <TSelected = TFullSearchSchema>(opts?: {
141
- select?: (search: TFullSearchSchema) => TSelected
142
- }) => TSelected
143
- useParams: <TSelected = TAllParams>(opts?: {
144
- select?: (search: TAllParams) => TSelected
145
- }) => TSelected
146
- }
147
-
148
- interface RegisterRouteProps<
149
- TLoader = unknown,
150
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
151
- TAllParams extends AnyPathParams = AnyPathParams,
152
- TAllContext extends Record<string, any> = AnyContext,
153
- > {
154
- RouteProps: RouteProps<TLoader, TFullSearchSchema, TAllParams, TAllContext>
155
- }
156
-
157
- interface RegisterPendingRouteProps<
158
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
159
- TAllParams extends AnyPathParams = AnyPathParams,
160
- TAllContext extends Record<string, any> = AnyContext,
161
- > {
162
- PendingRouteProps: PendingRouteProps<
163
- TFullSearchSchema,
164
- TAllParams,
165
- TAllContext
166
- >
167
- }
168
-
169
- interface RegisterErrorRouteProps<
170
- TFullSearchSchema extends Record<string, any> = AnySearchSchema,
171
- TAllParams extends AnyPathParams = AnyPathParams,
172
- TAllContext extends Record<string, any> = AnyContext,
173
- > {
174
- ErrorRouteProps: ErrorRouteProps
175
- }
176
- }
177
-
178
35
  export type RouteProps<
179
- TLoader = unknown,
180
36
  TFullSearchSchema extends Record<string, any> = AnySearchSchema,
181
37
  TAllParams extends AnyPathParams = AnyPathParams,
182
38
  TAllContext extends Record<string, any> = AnyContext,
183
39
  > = {
184
- useLoader: <TSelected = TLoader>(opts?: {
185
- select?: (search: TLoader) => TSelected
186
- }) => UseLoaderResult<TSelected>
187
40
  useMatch: <TSelected = TAllContext>(opts?: {
188
41
  select?: (search: TAllContext) => TSelected
189
42
  }) => TSelected
190
- useRouteContext: <TSelected = TAllContext>(opts?: {
43
+ useRouteMeta: <TSelected = TAllContext>(opts?: {
191
44
  select?: (search: TAllContext) => TSelected
192
45
  }) => TSelected
193
46
  useSearch: <TSelected = TFullSearchSchema>(opts?: {
@@ -205,43 +58,13 @@ export type ErrorRouteProps<
205
58
  > = {
206
59
  error: unknown
207
60
  info: { componentStack: string }
208
- } & Omit<
209
- RouteProps<unknown, TFullSearchSchema, TAllParams, TAllContext>,
210
- 'useLoader'
211
- >
61
+ } & RouteProps<TFullSearchSchema, TAllParams, TAllContext>
212
62
 
213
63
  export type PendingRouteProps<
214
64
  TFullSearchSchema extends Record<string, any> = AnySearchSchema,
215
65
  TAllParams extends AnyPathParams = AnyPathParams,
216
66
  TAllContext extends Record<string, any> = AnyContext,
217
- > = Omit<
218
- RouteProps<unknown, TFullSearchSchema, TAllParams, TAllContext>,
219
- 'useLoader'
220
- >
221
-
222
- Route.__onInit = (route) => {
223
- Object.assign(route, {
224
- useMatch: (opts = {}) => {
225
- return useMatch({ ...opts, from: route.id }) as any
226
- },
227
- useLoader: (opts = {}) => {
228
- return useLoader({ ...opts, from: route.id }) as any
229
- },
230
- useRouteContext: (opts: any = {}) => {
231
- return useMatch({
232
- ...opts,
233
- from: route.id,
234
- select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
235
- } as any)
236
- },
237
- useSearch: (opts = {}) => {
238
- return useSearch({ ...opts, from: route.id } as any)
239
- },
240
- useParams: (opts = {}) => {
241
- return useParams({ ...opts, from: route.id } as any)
242
- },
243
- })
244
- }
67
+ > = RouteProps<TFullSearchSchema, TAllParams, TAllContext>
245
68
 
246
69
  //
247
70
 
@@ -255,16 +78,29 @@ export type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {
255
78
  preload?: () => Promise<void>
256
79
  }
257
80
 
258
- export type ErrorRouteComponent = AsyncRouteComponent<ErrorRouteComponentProps>
81
+ export type RouteComponent<
82
+ TFullSearchSchema extends Record<string, any>,
83
+ TAllParams extends AnyPathParams,
84
+ TAllContext extends Record<string, any>,
85
+ > = AsyncRouteComponent<RouteProps<TFullSearchSchema, TAllParams, TAllContext>>
259
86
 
260
- export type ErrorRouteComponentProps = {
261
- error: Error
262
- info: { componentStack: string }
263
- }
87
+ export type ErrorRouteComponent<
88
+ TFullSearchSchema extends Record<string, any>,
89
+ TAllParams extends AnyPathParams,
90
+ TAllContext extends Record<string, any>,
91
+ > = AsyncRouteComponent<
92
+ ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>
93
+ >
264
94
 
265
- export type AnyRouteComponent = RouteComponent<AnyRouteProps>
95
+ export type PendingRouteComponent<
96
+ TFullSearchSchema extends Record<string, any>,
97
+ TAllParams extends AnyPathParams,
98
+ TAllContext extends Record<string, any>,
99
+ > = AsyncRouteComponent<
100
+ PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>
101
+ >
266
102
 
267
- export type RouteComponent<TProps> = AsyncRouteComponent<TProps>
103
+ export type AnyRouteComponent = RouteComponent<any, any, any>
268
104
 
269
105
  export function lazyRouteComponent<
270
106
  T extends Record<string, any>,
@@ -384,7 +220,7 @@ export function useLinkProps<
384
220
  >(
385
221
  options: MakeLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
386
222
  ): React.AnchorHTMLAttributes<HTMLAnchorElement> {
387
- const router = useRouter()
223
+ const { buildLink, state: routerState } = useRouter()
388
224
  const match = useMatch({
389
225
  strict: false,
390
226
  })
@@ -418,7 +254,7 @@ export function useLinkProps<
418
254
  ...rest
419
255
  } = options
420
256
 
421
- const linkInfo = router.buildLink({
257
+ const linkInfo = buildLink(routerState, {
422
258
  from: options.to ? match.pathname : undefined,
423
259
  ...options,
424
260
  } as any)
@@ -543,11 +379,11 @@ export function Navigate<
543
379
  TMaskFrom extends RoutePaths<TRouteTree> = '/',
544
380
  TMaskTo extends string = '',
545
381
  >(props: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): null {
546
- const router = useRouter()
382
+ const { navigate } = useRouter()
547
383
  const match = useMatch({ strict: false })
548
384
 
549
385
  useLayoutEffect(() => {
550
- router.navigate({
386
+ navigate({
551
387
  from: props.to ? match.pathname : undefined,
552
388
  ...props,
553
389
  } as any)
@@ -556,112 +392,42 @@ export function Navigate<
556
392
  return null
557
393
  }
558
394
 
559
- export const matchIdsContext = React.createContext<string[]>(null!)
560
- export const routerContext = React.createContext<RegisteredRouter>(null!)
561
-
395
+ export const matchesContext = React.createContext<RouteMatch[]>(null!)
562
396
  export type RouterProps<
563
397
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
564
398
  TDehydrated extends Record<string, any> = Record<string, any>,
565
399
  > = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {
566
400
  router: Router<TRouteTree>
567
- context?: Partial<RouterOptions<TRouteTree, TDehydrated>['context']>
401
+ context?: Partial<RouterOptions<TRouteTree, TDehydrated>['meta']>
568
402
  }
569
403
 
570
- export function useRouterState<TSelected = RegisteredRouter['state']>(opts?: {
571
- select: (state: RegisteredRouter['state']) => TSelected
572
- }): TSelected {
573
- const router = useRouter()
574
- return useStore(router.__store, opts?.select as any)
575
- }
576
-
577
- export function RouterProvider<
404
+ export function useRouter<
578
405
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
579
- TDehydrated extends Record<string, any> = Record<string, any>,
580
- >({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>) {
581
- router.update(rest)
582
-
583
- React.useEffect(() => {
584
- let unsub
585
-
586
- React.startTransition(() => {
587
- unsub = router.mount()
588
- })
589
-
590
- return unsub
591
- }, [router])
592
-
593
- const Wrap = router.options.Wrap || React.Fragment
594
-
595
- return (
596
- <Wrap>
597
- <routerContext.Provider value={router as any}>
598
- <Matches />
599
- </routerContext.Provider>
600
- </Wrap>
601
- )
602
- }
603
-
604
- function Matches() {
605
- const router = useRouter()
606
-
607
- const matchIds = useRouterState({
608
- select: (state) => {
609
- return state.renderedMatchIds
610
- },
611
- })
612
-
613
- const locationKey = useRouterState({
614
- select: (d) => d.resolvedLocation.state?.key,
615
- })
616
-
617
- const route = router.getRoute(rootRouteId)
618
-
619
- const errorComponent = React.useCallback(
620
- (props: any) => {
621
- return React.createElement(ErrorComponent, {
622
- ...props,
623
- useMatch: route.useMatch,
624
- useRouteContext: route.useRouteContext,
625
- useSearch: route.useSearch,
626
- useParams: route.useParams,
627
- })
628
- },
629
- [route],
630
- )
631
-
632
- return (
633
- <matchIdsContext.Provider value={[undefined!, ...matchIds]}>
634
- <CatchBoundary
635
- resetKey={locationKey}
636
- errorComponent={errorComponent}
637
- onCatch={() => {
638
- warning(
639
- false,
640
- `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`,
641
- )
642
- }}
643
- >
644
- <Outlet />
645
- </CatchBoundary>
646
- </matchIdsContext.Provider>
647
- )
406
+ >(): RouterContext<TRouteTree> {
407
+ const value = React.useContext(routerContext)
408
+ warning(value, 'useRouter must be used inside a <RouterProvider> component!')
409
+ return value as any
648
410
  }
649
411
 
650
- export function useRouter(): RegisteredRouter {
651
- const value = React.useContext(routerContext)
652
- warning(value, 'useRouter must be used inside a <Router> component!')
653
- return value
412
+ export function useRouterState<
413
+ TSelected = RouterState<RegisteredRouter['routeTree']>,
414
+ >(opts?: {
415
+ select: (state: RouterState<RegisteredRouter['routeTree']>) => TSelected
416
+ }): TSelected {
417
+ const { state } = useRouter()
418
+ // return useStore(router.__store, opts?.select as any)
419
+ return opts?.select ? opts.select(state) : (state as any)
654
420
  }
655
421
 
656
422
  export function useMatches<T = RouteMatch[]>(opts?: {
657
423
  select?: (matches: RouteMatch[]) => T
658
424
  }): T {
659
- const matchIds = React.useContext(matchIdsContext)
425
+ const contextMatches = React.useContext(matchesContext)
660
426
 
661
427
  return useRouterState({
662
428
  select: (state) => {
663
- const matches = state.renderedMatches.slice(
664
- state.renderedMatches.findIndex((d) => d.id === matchIds[0]),
429
+ const matches = state.matches.slice(
430
+ state.matches.findIndex((d) => d.id === contextMatches[0]?.id),
665
431
  )
666
432
  return opts?.select ? opts.select(matches) : (matches as T)
667
433
  },
@@ -689,15 +455,14 @@ export function useMatch<
689
455
  select?: (match: TRouteMatchState) => TSelected
690
456
  },
691
457
  ): TStrict extends true ? TRouteMatchState : TRouteMatchState | undefined {
692
- const router = useRouter()
693
- const nearestMatchId = React.useContext(matchIdsContext)[0]!
694
- const nearestMatchRouteId = router.getRouteMatch(nearestMatchId)?.routeId
458
+ const nearestMatch = React.useContext(matchesContext)[0]!
459
+ const nearestMatchRouteId = nearestMatch?.routeId
695
460
 
696
461
  const matchRouteId = useRouterState({
697
462
  select: (state) => {
698
463
  const match = opts?.from
699
- ? state.renderedMatches.find((d) => d.routeId === opts?.from)
700
- : state.renderedMatches.find((d) => d.id === nearestMatchId)
464
+ ? state.matches.find((d) => d.routeId === opts?.from)
465
+ : state.matches.find((d) => d.id === nearestMatch.id)
701
466
 
702
467
  return match!.routeId
703
468
  },
@@ -719,8 +484,8 @@ export function useMatch<
719
484
  const matchSelection = useRouterState({
720
485
  select: (state) => {
721
486
  const match = opts?.from
722
- ? state.renderedMatches.find((d) => d.routeId === opts?.from)
723
- : state.renderedMatches.find((d) => d.id === nearestMatchId)
487
+ ? state.matches.find((d) => d.routeId === opts?.from)
488
+ : state.matches.find((d) => d.id === nearestMatch.id)
724
489
 
725
490
  invariant(
726
491
  match,
@@ -749,61 +514,21 @@ export type RouteFromIdOrRoute<
749
514
  ? RouteIds<TRouteTree>
750
515
  : never
751
516
 
752
- export function useLoader<
753
- TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
754
- TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
755
- TStrict extends boolean = true,
756
- TLoader = RouteById<TRouteTree, TFrom>['types']['loader'],
757
- TSelected = TLoader,
758
- >(
759
- opts: StrictOrFrom<TFrom> & {
760
- select?: (search: TLoader) => TSelected
761
- },
762
- ): TStrict extends true ? TSelected : TSelected | undefined {
763
- return useMatch({
764
- ...(opts as any),
765
- select: (match: RouteMatch) =>
766
- opts?.select
767
- ? opts?.select(match.loaderData as TLoader)
768
- : match.loaderData,
769
- })
770
- }
771
-
772
- export function useRouterContext<
773
- TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
774
- TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
775
- TStrict extends boolean = true,
776
- TContext = RouteById<TRouteTree, TFrom>['types']['context'],
777
- TSelected = TContext,
778
- >(
779
- opts: StrictOrFrom<TFrom> & {
780
- select?: (search: TContext) => TSelected
781
- },
782
- ): TStrict extends true ? TSelected : TSelected | undefined {
783
- return useMatch({
784
- ...(opts as any),
785
- select: (match: RouteMatch) =>
786
- opts?.select ? opts.select(match.context as TContext) : match.context,
787
- })
788
- }
789
-
790
- export function useRouteContext<
517
+ export function useRouteMeta<
791
518
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
792
519
  TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
793
520
  TStrict extends boolean = true,
794
- TRouteContext = RouteById<TRouteTree, TFrom>['types']['context'],
795
- TSelected = TRouteContext,
521
+ TRouteMeta = RouteById<TRouteTree, TFrom>['types']['allMeta'],
522
+ TSelected = TRouteMeta,
796
523
  >(
797
524
  opts: StrictOrFrom<TFrom> & {
798
- select?: (search: TRouteContext) => TSelected
525
+ select?: (search: TRouteMeta) => TSelected
799
526
  },
800
527
  ): TStrict extends true ? TSelected : TSelected | undefined {
801
528
  return useMatch({
802
529
  ...(opts as any),
803
530
  select: (match: RouteMatch) =>
804
- opts?.select
805
- ? opts.select(match.context as TRouteContext)
806
- : match.context,
531
+ opts?.select ? opts.select(match.meta as TRouteMeta) : match.meta,
807
532
  })
808
533
  }
809
534
 
@@ -839,7 +564,7 @@ export function useParams<
839
564
  ): TSelected {
840
565
  return useRouterState({
841
566
  select: (state: any) => {
842
- const params = (last(state.renderedMatches) as any)?.params
567
+ const params = (last(state.matches) as any)?.params
843
568
  return opts?.select ? opts.select(params) : params
844
569
  },
845
570
  })
@@ -849,7 +574,7 @@ export function useNavigate<
849
574
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
850
575
  TDefaultFrom extends RoutePaths<TRouteTree> = '/',
851
576
  >(defaultOpts?: { from?: TDefaultFrom }) {
852
- const router = useRouter()
577
+ const { navigate } = useRouter()
853
578
  const match = useMatch({
854
579
  strict: false,
855
580
  })
@@ -862,7 +587,7 @@ export function useNavigate<
862
587
  >(
863
588
  opts?: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
864
589
  ) => {
865
- return router.navigate({
590
+ return navigate({
866
591
  from: opts?.to ? match.pathname : undefined,
867
592
  ...defaultOpts,
868
593
  ...(opts as any),
@@ -875,7 +600,7 @@ export function useNavigate<
875
600
  export function useMatchRoute<
876
601
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
877
602
  >() {
878
- const router = useRouter()
603
+ const { state, matchRoute } = useRouter()
879
604
 
880
605
  return React.useCallback(
881
606
  <
@@ -895,7 +620,7 @@ export function useMatchRoute<
895
620
  ): false | RouteById<TRouteTree, TResolved>['types']['allParams'] => {
896
621
  const { pending, caseSensitive, ...rest } = opts
897
622
 
898
- return router.matchRoute(rest as any, {
623
+ return matchRoute(state, rest as any, {
899
624
  pending,
900
625
  caseSensitive,
901
626
  })
@@ -904,6 +629,54 @@ export function useMatchRoute<
904
629
  )
905
630
  }
906
631
 
632
+ export function Matches() {
633
+ const { routesById, state } = useRouter()
634
+
635
+ // const matches = useRouterState({
636
+ // select: (state) => {
637
+ // return state.matches
638
+ // },
639
+ // })
640
+
641
+ const { matches } = state
642
+
643
+ const locationKey = useRouterState({
644
+ select: (d) => d.resolvedLocation.state?.key,
645
+ })
646
+
647
+ const route = routesById[rootRouteId]
648
+
649
+ const errorComponent = React.useCallback(
650
+ (props: any) => {
651
+ return React.createElement(ErrorComponent, {
652
+ ...props,
653
+ useMatch: route.useMatch,
654
+ useRouteMeta: route.useRouteMeta,
655
+ useSearch: route.useSearch,
656
+ useParams: route.useParams,
657
+ })
658
+ },
659
+ [route],
660
+ )
661
+
662
+ return (
663
+ <matchesContext.Provider value={matches}>
664
+ <CatchBoundary
665
+ resetKey={locationKey}
666
+ errorComponent={errorComponent}
667
+ onCatch={() => {
668
+ warning(
669
+ false,
670
+ `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`,
671
+ )
672
+ }}
673
+ >
674
+ {matches.length ? <Match matches={matches} /> : null}
675
+ </CatchBoundary>
676
+ </matchesContext.Provider>
677
+ )
678
+ }
679
+
907
680
  export function MatchRoute<
908
681
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
909
682
  TFrom extends RoutePaths<TRouteTree> = '/',
@@ -924,33 +697,33 @@ export function MatchRoute<
924
697
  }
925
698
 
926
699
  export function Outlet() {
927
- const matchIds = React.useContext(matchIdsContext).slice(1)
700
+ const matches = React.useContext(matchesContext).slice(1)
928
701
 
929
- if (!matchIds[0]) {
702
+ if (!matches[0]) {
930
703
  return null
931
704
  }
932
705
 
933
- return <Match matchIds={matchIds} />
706
+ return <Match matches={matches} />
934
707
  }
935
708
 
936
709
  const defaultPending = () => null
937
710
 
938
- function Match({ matchIds }: { matchIds: string[] }) {
939
- const router = useRouter()
940
- const matchId = matchIds[0]!
941
- const routeId = router.getRouteMatch(matchId)!.routeId
942
- const route = router.getRoute(routeId)
711
+ function Match({ matches }: { matches: RouteMatch[] }) {
712
+ const { options, routesById } = useRouter()
713
+ const match = matches[0]!
714
+ const routeId = match?.routeId
715
+ const route = routesById[routeId]
943
716
  const locationKey = useRouterState({
944
717
  select: (s) => s.resolvedLocation.state?.key,
945
718
  })
946
719
 
947
720
  const PendingComponent = (route.options.pendingComponent ??
948
- router.options.defaultPendingComponent ??
721
+ options.defaultPendingComponent ??
949
722
  defaultPending) as any
950
723
 
951
724
  const routeErrorComponent =
952
725
  route.options.errorComponent ??
953
- router.options.defaultErrorComponent ??
726
+ options.defaultErrorComponent ??
954
727
  ErrorComponent
955
728
 
956
729
  const ResolvedSuspenseBoundary =
@@ -967,7 +740,7 @@ function Match({ matchIds }: { matchIds: string[] }) {
967
740
  return React.createElement(routeErrorComponent, {
968
741
  ...props,
969
742
  useMatch: route.useMatch,
970
- useRouteContext: route.useRouteContext,
743
+ useRouteMeta: route.useRouteMeta,
971
744
  useSearch: route.useSearch,
972
745
  useParams: route.useParams,
973
746
  })
@@ -976,11 +749,11 @@ function Match({ matchIds }: { matchIds: string[] }) {
976
749
  )
977
750
 
978
751
  return (
979
- <matchIdsContext.Provider value={matchIds}>
752
+ <matchesContext.Provider value={matches}>
980
753
  <ResolvedSuspenseBoundary
981
754
  fallback={React.createElement(PendingComponent, {
982
755
  useMatch: route.useMatch,
983
- useRouteContext: route.useRouteContext,
756
+ useRouteMeta: route.useRouteMeta,
984
757
  useSearch: route.useSearch,
985
758
  useParams: route.useParams,
986
759
  })}
@@ -989,56 +762,35 @@ function Match({ matchIds }: { matchIds: string[] }) {
989
762
  resetKey={locationKey}
990
763
  errorComponent={errorComponent}
991
764
  onCatch={() => {
992
- warning(false, `Error in route match: ${matchId}`)
765
+ warning(false, `Error in route match: ${match.id}`)
993
766
  }}
994
767
  >
995
- <MatchInner matchId={matchId} PendingComponent={PendingComponent} />
768
+ <MatchInner match={match} />
996
769
  </ResolvedCatchBoundary>
997
770
  </ResolvedSuspenseBoundary>
998
- </matchIdsContext.Provider>
771
+ </matchesContext.Provider>
999
772
  )
1000
773
  }
1001
774
 
1002
- function MatchInner({
1003
- matchId,
1004
- PendingComponent,
1005
- }: {
1006
- matchId: string
1007
- PendingComponent: any
1008
- }): any {
1009
- const router = useRouter()
1010
-
1011
- const match = useRouterState({
1012
- select: (d) => {
1013
- const match = d.matchesById[matchId]
1014
- return pick(match!, ['status', 'loadPromise', 'routeId', 'error'])
1015
- },
1016
- })
1017
-
1018
- const route = router.getRoute(match.routeId)
775
+ function MatchInner({ match }: { match: RouteMatch }): any {
776
+ const { options, routesById } = useRouter()
777
+ const route = routesById[match.routeId]
1019
778
 
1020
779
  if (match.status === 'error') {
1021
780
  throw match.error
1022
781
  }
1023
782
 
1024
783
  if (match.status === 'pending') {
1025
- return React.createElement(PendingComponent, {
1026
- useLoader: route.useLoader,
1027
- useMatch: route.useMatch,
1028
- useRouteContext: route.useRouteContext,
1029
- useSearch: route.useSearch,
1030
- useParams: route.useParams,
1031
- })
784
+ throw match.loadPromise
1032
785
  }
1033
786
 
1034
787
  if (match.status === 'success') {
1035
- let comp = route.options.component ?? router.options.defaultComponent
788
+ let comp = route.options.component ?? options.defaultComponent
1036
789
 
1037
790
  if (comp) {
1038
791
  return React.createElement(comp, {
1039
- useLoader: route.useLoader,
1040
792
  useMatch: route.useMatch,
1041
- useRouteContext: route.useRouteContext as any,
793
+ useRouteMeta: route.useRouteMeta as any,
1042
794
  useSearch: route.useSearch,
1043
795
  useParams: route.useParams as any,
1044
796
  } as any)
@@ -1057,36 +809,36 @@ function SafeFragment(props: any) {
1057
809
  return <>{props.children}</>
1058
810
  }
1059
811
 
1060
- export function useInjectHtml() {
1061
- const router = useRouter()
812
+ // export function useInjectHtml() {
813
+ // const { } = useRouter()
1062
814
 
1063
- return React.useCallback(
1064
- (html: string | (() => Promise<string> | string)) => {
1065
- router.injectHtml(html)
1066
- },
1067
- [],
1068
- )
1069
- }
815
+ // return React.useCallback(
816
+ // (html: string | (() => Promise<string> | string)) => {
817
+ // router.injectHtml(html)
818
+ // },
819
+ // [],
820
+ // )
821
+ // }
1070
822
 
1071
- export function useDehydrate() {
1072
- const router = useRouter()
823
+ // export function useDehydrate() {
824
+ // const { } = useRouter()
1073
825
 
1074
- return React.useCallback(function dehydrate<T>(
1075
- key: any,
1076
- data: T | (() => Promise<T> | T),
1077
- ) {
1078
- return router.dehydrateData(key, data)
1079
- },
1080
- [])
1081
- }
826
+ // return React.useCallback(function dehydrate<T>(
827
+ // key: any,
828
+ // data: T | (() => Promise<T> | T),
829
+ // ) {
830
+ // return router.dehydrateData(key, data)
831
+ // },
832
+ // [])
833
+ // }
1082
834
 
1083
- export function useHydrate() {
1084
- const router = useRouter()
835
+ // export function useHydrate() {
836
+ // const { } = useRouter()
1085
837
 
1086
- return function hydrate<T = unknown>(key: any) {
1087
- return router.hydrateData(key) as T
1088
- }
1089
- }
838
+ // return function hydrate<T = unknown>(key: any) {
839
+ // return router.hydrateData(key) as T
840
+ // }
841
+ // }
1090
842
 
1091
843
  // This is the messiest thing ever... I'm either seriously tired (likely) or
1092
844
  // there has to be a better way to reset error boundaries when the
@@ -1192,12 +944,12 @@ export function useBlocker(
1192
944
  message: string,
1193
945
  condition: boolean | any = true,
1194
946
  ): void {
1195
- const router = useRouter()
947
+ const { history } = useRouter()
1196
948
 
1197
949
  React.useEffect(() => {
1198
950
  if (!condition) return
1199
951
 
1200
- let unblock = router.history.block((retry, cancel) => {
952
+ let unblock = history.block((retry, cancel) => {
1201
953
  if (window.confirm(message)) {
1202
954
  unblock()
1203
955
  retry()