@tanstack/react-router 1.78.3 → 1.81.0
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.
- package/dist/cjs/Match.cjs +10 -11
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Matches.cjs +8 -4
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +8 -9
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +3 -3
- package/dist/cjs/Transitioner.cjs +9 -8
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/fileRoute.cjs +15 -3
- package/dist/cjs/fileRoute.cjs.map +1 -1
- package/dist/cjs/fileRoute.d.cts +12 -19
- package/dist/cjs/link.cjs +4 -1
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +1 -1
- package/dist/cjs/path.cjs +12 -2
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +2 -1
- package/dist/cjs/route.cjs +33 -9
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +20 -38
- package/dist/cjs/router.cjs +15 -4
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +25 -11
- package/dist/cjs/routerContext.cjs.map +1 -1
- package/dist/cjs/routerContext.d.cts +1 -1
- package/dist/cjs/structuralSharing.d.cts +12 -0
- package/dist/cjs/useLoaderData.cjs +4 -2
- package/dist/cjs/useLoaderData.cjs.map +1 -1
- package/dist/cjs/useLoaderData.d.cts +12 -9
- package/dist/cjs/useLoaderDeps.cjs +3 -2
- package/dist/cjs/useLoaderDeps.cjs.map +1 -1
- package/dist/cjs/useLoaderDeps.d.cts +12 -8
- package/dist/cjs/useLocation.cjs.map +1 -1
- package/dist/cjs/useLocation.d.cts +6 -3
- package/dist/cjs/useMatch.cjs +2 -1
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/useMatch.d.cts +10 -8
- package/dist/cjs/useParams.cjs +3 -1
- package/dist/cjs/useParams.cjs.map +1 -1
- package/dist/cjs/useParams.d.cts +12 -8
- package/dist/cjs/useRouteContext.cjs.map +1 -1
- package/dist/cjs/useRouteContext.d.cts +11 -8
- package/dist/cjs/useRouterState.cjs +18 -1
- package/dist/cjs/useRouterState.cjs.map +1 -1
- package/dist/cjs/useRouterState.d.cts +6 -3
- package/dist/cjs/useSearch.cjs +3 -1
- package/dist/cjs/useSearch.cjs.map +1 -1
- package/dist/cjs/useSearch.d.cts +12 -8
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +10 -4
- package/dist/esm/Match.js +10 -11
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.d.ts +8 -9
- package/dist/esm/Matches.js +8 -4
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.d.ts +3 -3
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/Transitioner.js +10 -9
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/fileRoute.d.ts +12 -19
- package/dist/esm/fileRoute.js +15 -3
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/link.d.ts +1 -1
- package/dist/esm/link.js +4 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/path.d.ts +2 -1
- package/dist/esm/path.js +12 -2
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/route.d.ts +20 -38
- package/dist/esm/route.js +33 -9
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +25 -11
- package/dist/esm/router.js +15 -4
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerContext.d.ts +1 -1
- package/dist/esm/routerContext.js.map +1 -1
- package/dist/esm/structuralSharing.d.ts +12 -0
- package/dist/esm/useLoaderData.d.ts +12 -9
- package/dist/esm/useLoaderData.js +4 -2
- package/dist/esm/useLoaderData.js.map +1 -1
- package/dist/esm/useLoaderDeps.d.ts +12 -8
- package/dist/esm/useLoaderDeps.js +3 -2
- package/dist/esm/useLoaderDeps.js.map +1 -1
- package/dist/esm/useLocation.d.ts +6 -3
- package/dist/esm/useLocation.js.map +1 -1
- package/dist/esm/useMatch.d.ts +10 -8
- package/dist/esm/useMatch.js +2 -1
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useParams.d.ts +12 -8
- package/dist/esm/useParams.js +3 -1
- package/dist/esm/useParams.js.map +1 -1
- package/dist/esm/useRouteContext.d.ts +11 -8
- package/dist/esm/useRouteContext.js.map +1 -1
- package/dist/esm/useRouterState.d.ts +6 -3
- package/dist/esm/useRouterState.js +18 -1
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/esm/useSearch.d.ts +12 -8
- package/dist/esm/useSearch.js +3 -1
- package/dist/esm/useSearch.js.map +1 -1
- package/dist/esm/utils.d.ts +10 -4
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/Match.tsx +6 -7
- package/src/Matches.tsx +52 -24
- package/src/RouterProvider.tsx +4 -1
- package/src/Transitioner.tsx +9 -10
- package/src/fileRoute.ts +29 -29
- package/src/link.tsx +6 -3
- package/src/path.ts +16 -1
- package/src/route.ts +57 -101
- package/src/router.ts +60 -4
- package/src/routerContext.tsx +1 -1
- package/src/structuralSharing.ts +49 -0
- package/src/useLoaderData.tsx +76 -28
- package/src/useLoaderDeps.tsx +55 -20
- package/src/useLocation.tsx +30 -8
- package/src/useMatch.tsx +71 -21
- package/src/useParams.tsx +70 -21
- package/src/useRouteContext.ts +45 -23
- package/src/useRouterState.tsx +45 -6
- package/src/useSearch.tsx +69 -20
- package/src/utils.ts +16 -3
package/src/router.ts
CHANGED
|
@@ -103,7 +103,7 @@ declare global {
|
|
|
103
103
|
cleanScripts: () => void
|
|
104
104
|
dehydrated?: any
|
|
105
105
|
}
|
|
106
|
-
__TSR_ROUTER_CONTEXT__?: React.Context<Router<any, any>>
|
|
106
|
+
__TSR_ROUTER_CONTEXT__?: React.Context<Router<any, any, any>>
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -111,7 +111,7 @@ export interface Register {
|
|
|
111
111
|
// router: Router
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
export type AnyRouter = Router<any, any, any, any>
|
|
114
|
+
export type AnyRouter = Router<any, any, any, any, any>
|
|
115
115
|
|
|
116
116
|
export type AnyRouterWithContext<TContext> = Router<
|
|
117
117
|
AnyRouteWithContext<TContext>,
|
|
@@ -173,6 +173,7 @@ export type TrailingSlashOption = 'always' | 'never' | 'preserve'
|
|
|
173
173
|
export interface RouterOptions<
|
|
174
174
|
TRouteTree extends AnyRoute,
|
|
175
175
|
TTrailingSlashOption extends TrailingSlashOption,
|
|
176
|
+
TDefaultStructuralSharingOption extends boolean = false,
|
|
176
177
|
TDehydrated extends Record<string, any> = Record<string, any>,
|
|
177
178
|
TSerializedError extends Record<string, any> = Record<string, any>,
|
|
178
179
|
> {
|
|
@@ -464,6 +465,23 @@ export interface RouterOptions<
|
|
|
464
465
|
*/
|
|
465
466
|
strict?: boolean
|
|
466
467
|
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Configures whether structural sharing is enabled by default for fine-grained selectors.
|
|
471
|
+
*
|
|
472
|
+
* @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultstructuralsharing-property)
|
|
473
|
+
*/
|
|
474
|
+
defaultStructuralSharing?: TDefaultStructuralSharingOption
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Configures which URI characters are allowed in path params that would ordinarily be escaped by encodeURIComponent.
|
|
478
|
+
*
|
|
479
|
+
* @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#pathparamsallowedcharacters-property)
|
|
480
|
+
* @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/path-params#allowed-characters)
|
|
481
|
+
*/
|
|
482
|
+
pathParamsAllowedCharacters?: Array<
|
|
483
|
+
';' | ':' | '@' | '&' | '=' | '+' | '$' | ','
|
|
484
|
+
>
|
|
467
485
|
}
|
|
468
486
|
|
|
469
487
|
export interface RouterErrorSerializer<TSerializedError> {
|
|
@@ -530,12 +548,14 @@ export interface DehydratedRouter {
|
|
|
530
548
|
export type RouterConstructorOptions<
|
|
531
549
|
TRouteTree extends AnyRoute,
|
|
532
550
|
TTrailingSlashOption extends TrailingSlashOption,
|
|
551
|
+
TDefaultStructuralSharingOption extends boolean,
|
|
533
552
|
TDehydrated extends Record<string, any>,
|
|
534
553
|
TSerializedError extends Record<string, any>,
|
|
535
554
|
> = Omit<
|
|
536
555
|
RouterOptions<
|
|
537
556
|
TRouteTree,
|
|
538
557
|
TTrailingSlashOption,
|
|
558
|
+
TDefaultStructuralSharingOption,
|
|
539
559
|
TDehydrated,
|
|
540
560
|
TSerializedError
|
|
541
561
|
>,
|
|
@@ -627,6 +647,7 @@ export type RouterListener<TRouterEvent extends RouterEvent> = {
|
|
|
627
647
|
export function createRouter<
|
|
628
648
|
TRouteTree extends AnyRoute,
|
|
629
649
|
TTrailingSlashOption extends TrailingSlashOption,
|
|
650
|
+
TDefaultStructuralSharingOption extends boolean,
|
|
630
651
|
TDehydrated extends Record<string, any> = Record<string, any>,
|
|
631
652
|
TSerializedError extends Record<string, any> = Record<string, any>,
|
|
632
653
|
>(
|
|
@@ -635,6 +656,7 @@ export function createRouter<
|
|
|
635
656
|
: RouterConstructorOptions<
|
|
636
657
|
TRouteTree,
|
|
637
658
|
TTrailingSlashOption,
|
|
659
|
+
TDefaultStructuralSharingOption,
|
|
638
660
|
TDehydrated,
|
|
639
661
|
TSerializedError
|
|
640
662
|
>,
|
|
@@ -642,6 +664,7 @@ export function createRouter<
|
|
|
642
664
|
return new Router<
|
|
643
665
|
TRouteTree,
|
|
644
666
|
TTrailingSlashOption,
|
|
667
|
+
TDefaultStructuralSharingOption,
|
|
645
668
|
TDehydrated,
|
|
646
669
|
TSerializedError
|
|
647
670
|
>(options)
|
|
@@ -657,6 +680,7 @@ type MatchRoutesOpts = {
|
|
|
657
680
|
export class Router<
|
|
658
681
|
in out TRouteTree extends AnyRoute,
|
|
659
682
|
in out TTrailingSlashOption extends TrailingSlashOption,
|
|
683
|
+
in out TDefaultStructuralSharingOption extends boolean,
|
|
660
684
|
in out TDehydrated extends Record<string, any> = Record<string, any>,
|
|
661
685
|
in out TSerializedError extends Record<string, any> = Record<string, any>,
|
|
662
686
|
> {
|
|
@@ -694,6 +718,7 @@ export class Router<
|
|
|
694
718
|
RouterOptions<
|
|
695
719
|
TRouteTree,
|
|
696
720
|
TTrailingSlashOption,
|
|
721
|
+
TDefaultStructuralSharingOption,
|
|
697
722
|
TDehydrated,
|
|
698
723
|
TSerializedError
|
|
699
724
|
>,
|
|
@@ -711,6 +736,7 @@ export class Router<
|
|
|
711
736
|
routesByPath!: RoutesByPath<TRouteTree>
|
|
712
737
|
flatRoutes!: Array<AnyRoute>
|
|
713
738
|
isServer!: boolean
|
|
739
|
+
pathParamsDecodeCharMap?: Map<string, string>
|
|
714
740
|
|
|
715
741
|
/**
|
|
716
742
|
* @deprecated Use the `createRouter` function instead
|
|
@@ -719,6 +745,7 @@ export class Router<
|
|
|
719
745
|
options: RouterConstructorOptions<
|
|
720
746
|
TRouteTree,
|
|
721
747
|
TTrailingSlashOption,
|
|
748
|
+
TDefaultStructuralSharingOption,
|
|
722
749
|
TDehydrated,
|
|
723
750
|
TSerializedError
|
|
724
751
|
>,
|
|
@@ -750,6 +777,7 @@ export class Router<
|
|
|
750
777
|
newOptions: RouterConstructorOptions<
|
|
751
778
|
TRouteTree,
|
|
752
779
|
TTrailingSlashOption,
|
|
780
|
+
TDefaultStructuralSharingOption,
|
|
753
781
|
TDehydrated,
|
|
754
782
|
TSerializedError
|
|
755
783
|
>,
|
|
@@ -768,6 +796,15 @@ export class Router<
|
|
|
768
796
|
|
|
769
797
|
this.isServer = this.options.isServer ?? typeof document === 'undefined'
|
|
770
798
|
|
|
799
|
+
this.pathParamsDecodeCharMap = this.options.pathParamsAllowedCharacters
|
|
800
|
+
? new Map(
|
|
801
|
+
this.options.pathParamsAllowedCharacters.map((char) => [
|
|
802
|
+
encodeURIComponent(char),
|
|
803
|
+
char,
|
|
804
|
+
]),
|
|
805
|
+
)
|
|
806
|
+
: undefined
|
|
807
|
+
|
|
771
808
|
if (
|
|
772
809
|
!this.basepath ||
|
|
773
810
|
(newOptions.basepath && newOptions.basepath !== previousOptions.basepath)
|
|
@@ -1187,6 +1224,7 @@ export class Router<
|
|
|
1187
1224
|
const interpolatedPath = interpolatePath({
|
|
1188
1225
|
path: route.fullPath,
|
|
1189
1226
|
params: routeParams,
|
|
1227
|
+
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1190
1228
|
})
|
|
1191
1229
|
|
|
1192
1230
|
const matchId =
|
|
@@ -1194,6 +1232,7 @@ export class Router<
|
|
|
1194
1232
|
path: route.id,
|
|
1195
1233
|
params: routeParams,
|
|
1196
1234
|
leaveWildcards: true,
|
|
1235
|
+
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1197
1236
|
}) + loaderDepsHash
|
|
1198
1237
|
|
|
1199
1238
|
// Waste not, want not. If we already have a match for this route,
|
|
@@ -1431,6 +1470,7 @@ export class Router<
|
|
|
1431
1470
|
const interpolatedPath = interpolatePath({
|
|
1432
1471
|
path: route.fullPath,
|
|
1433
1472
|
params: matchedRoutesResult?.routeParams ?? {},
|
|
1473
|
+
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1434
1474
|
})
|
|
1435
1475
|
const pathname = joinPaths([this.basepath, interpolatedPath])
|
|
1436
1476
|
return pathname === fromPath
|
|
@@ -1467,6 +1507,7 @@ export class Router<
|
|
|
1467
1507
|
params: nextParams ?? {},
|
|
1468
1508
|
leaveWildcards: false,
|
|
1469
1509
|
leaveParams: opts.leaveParams,
|
|
1510
|
+
decodeCharMap: this.pathParamsDecodeCharMap,
|
|
1470
1511
|
})
|
|
1471
1512
|
|
|
1472
1513
|
let search = fromSearch
|
|
@@ -1637,6 +1678,7 @@ export class Router<
|
|
|
1637
1678
|
}
|
|
1638
1679
|
maskedNext = build(maskedDest)
|
|
1639
1680
|
}
|
|
1681
|
+
// console.log('buildWithMatches', {foundMask, dest, maskedDest, maskedNext})
|
|
1640
1682
|
}
|
|
1641
1683
|
|
|
1642
1684
|
const nextMatches = this.getMatchedRoutes(next, dest)
|
|
@@ -2186,6 +2228,8 @@ export class Router<
|
|
|
2186
2228
|
let pendingTimeout: ReturnType<typeof setTimeout>
|
|
2187
2229
|
|
|
2188
2230
|
if (shouldPending) {
|
|
2231
|
+
console.log('### 2186 setting timeout', pendingMs)
|
|
2232
|
+
|
|
2189
2233
|
// If we might show a pending component, we need to wait for the
|
|
2190
2234
|
// pending promise to resolve before we start showing that state
|
|
2191
2235
|
pendingTimeout = setTimeout(() => {
|
|
@@ -2649,7 +2693,13 @@ export class Router<
|
|
|
2649
2693
|
TMaskTo extends string = '',
|
|
2650
2694
|
>(
|
|
2651
2695
|
opts: NavigateOptions<
|
|
2652
|
-
Router<
|
|
2696
|
+
Router<
|
|
2697
|
+
TRouteTree,
|
|
2698
|
+
TTrailingSlashOption,
|
|
2699
|
+
TDefaultStructuralSharingOption,
|
|
2700
|
+
TDehydrated,
|
|
2701
|
+
TSerializedError
|
|
2702
|
+
>,
|
|
2653
2703
|
TFrom,
|
|
2654
2704
|
TTo,
|
|
2655
2705
|
TMaskFrom,
|
|
@@ -2723,7 +2773,13 @@ export class Router<
|
|
|
2723
2773
|
TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
|
|
2724
2774
|
>(
|
|
2725
2775
|
location: ToOptions<
|
|
2726
|
-
Router<
|
|
2776
|
+
Router<
|
|
2777
|
+
TRouteTree,
|
|
2778
|
+
TTrailingSlashOption,
|
|
2779
|
+
TDefaultStructuralSharingOption,
|
|
2780
|
+
TDehydrated,
|
|
2781
|
+
TSerializedError
|
|
2782
|
+
>,
|
|
2727
2783
|
TFrom,
|
|
2728
2784
|
TTo
|
|
2729
2785
|
>,
|
package/src/routerContext.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import type { Router } from './router'
|
|
3
3
|
|
|
4
|
-
const routerContext = React.createContext<Router<any, any>>(null!)
|
|
4
|
+
const routerContext = React.createContext<Router<any, any, any>>(null!)
|
|
5
5
|
|
|
6
6
|
export function getRouterContext() {
|
|
7
7
|
if (typeof document === 'undefined') {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Constrain, ValidateJSON } from './utils'
|
|
2
|
+
import type { AnyRouter } from './router'
|
|
3
|
+
|
|
4
|
+
export type DefaultStructuralSharingEnabled<TRouter extends AnyRouter> =
|
|
5
|
+
boolean extends TRouter['options']['defaultStructuralSharing']
|
|
6
|
+
? // for now, default to false.
|
|
7
|
+
// TODO in V2: default to true
|
|
8
|
+
false
|
|
9
|
+
: NonNullable<TRouter['options']['defaultStructuralSharing']>
|
|
10
|
+
|
|
11
|
+
export interface OptionalStructuralSharing<TStructuralSharing, TConstraint> {
|
|
12
|
+
readonly structuralSharing?:
|
|
13
|
+
| Constrain<TStructuralSharing, TConstraint>
|
|
14
|
+
| undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface RequiredStructuralSharing<TStructuralSharing, TConstraint> {
|
|
18
|
+
readonly structuralSharing: Constrain<TStructuralSharing, TConstraint>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type StructuralSharingOption<
|
|
22
|
+
TRouter extends AnyRouter,
|
|
23
|
+
TSelected,
|
|
24
|
+
TStructuralSharing,
|
|
25
|
+
> = unknown extends TSelected
|
|
26
|
+
? OptionalStructuralSharing<TStructuralSharing, boolean>
|
|
27
|
+
: unknown extends TRouter['routeTree']
|
|
28
|
+
? OptionalStructuralSharing<TStructuralSharing, boolean>
|
|
29
|
+
: TSelected extends ValidateJSON<TSelected>
|
|
30
|
+
? OptionalStructuralSharing<TStructuralSharing, boolean>
|
|
31
|
+
: DefaultStructuralSharingEnabled<TRouter> extends true
|
|
32
|
+
? RequiredStructuralSharing<TStructuralSharing, false>
|
|
33
|
+
: OptionalStructuralSharing<TStructuralSharing, false>
|
|
34
|
+
|
|
35
|
+
export type StructuralSharingEnabled<
|
|
36
|
+
TRouter extends AnyRouter,
|
|
37
|
+
TStructuralSharing,
|
|
38
|
+
> = boolean extends TStructuralSharing
|
|
39
|
+
? DefaultStructuralSharingEnabled<TRouter>
|
|
40
|
+
: TStructuralSharing
|
|
41
|
+
|
|
42
|
+
export type ValidateSelected<
|
|
43
|
+
TRouter extends AnyRouter,
|
|
44
|
+
TSelected,
|
|
45
|
+
TStructuralSharing,
|
|
46
|
+
> =
|
|
47
|
+
StructuralSharingEnabled<TRouter, TStructuralSharing> extends true
|
|
48
|
+
? ValidateJSON<TSelected>
|
|
49
|
+
: TSelected
|
package/src/useLoaderData.tsx
CHANGED
|
@@ -1,45 +1,93 @@
|
|
|
1
1
|
import { useMatch } from './useMatch'
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
StructuralSharingOption,
|
|
4
|
+
ValidateSelected,
|
|
5
|
+
} from './structuralSharing'
|
|
6
|
+
import type { AnyRouter, RegisteredRouter } from './router'
|
|
7
|
+
import type { AllLoaderData, RouteById } from './routeInfo'
|
|
8
|
+
import type { Expand, StrictOrFrom } from './utils'
|
|
7
9
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
+
export interface UseLoaderDataBaseOptions<
|
|
11
|
+
TRouter extends AnyRouter,
|
|
10
12
|
TFrom,
|
|
11
13
|
TStrict extends boolean,
|
|
12
|
-
TRouteMatch extends MakeRouteMatch<TRouteTree, TFrom, TStrict>,
|
|
13
14
|
TSelected,
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
TStructuralSharing,
|
|
16
|
+
> {
|
|
17
|
+
select?: (
|
|
18
|
+
match: ResolveLoaderData<TRouter, TFrom, TStrict>,
|
|
19
|
+
) => ValidateSelected<TRouter, TSelected, TStructuralSharing>
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
export type UseLoaderDataOptions<
|
|
23
|
+
TRouter extends AnyRouter,
|
|
24
|
+
TFrom extends string | undefined,
|
|
25
|
+
TStrict extends boolean,
|
|
26
|
+
TSelected,
|
|
27
|
+
TStructuralSharing,
|
|
28
|
+
> = StrictOrFrom<TRouter, TFrom, TStrict> &
|
|
29
|
+
UseLoaderDataBaseOptions<
|
|
30
|
+
TRouter,
|
|
31
|
+
TFrom,
|
|
32
|
+
TStrict,
|
|
33
|
+
TSelected,
|
|
34
|
+
TStructuralSharing
|
|
35
|
+
> &
|
|
36
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>
|
|
37
|
+
|
|
38
|
+
export type ResolveLoaderData<
|
|
39
|
+
TRouter extends AnyRouter,
|
|
40
|
+
TFrom,
|
|
41
|
+
TStrict extends boolean,
|
|
42
|
+
> = TStrict extends false
|
|
43
|
+
? AllLoaderData<TRouter['routeTree']>
|
|
44
|
+
: Expand<RouteById<TRouter['routeTree'], TFrom>['types']['loaderData']>
|
|
45
|
+
|
|
46
|
+
export type UseLoaderDataResult<
|
|
47
|
+
TRouter extends AnyRouter,
|
|
48
|
+
TFrom,
|
|
49
|
+
TStrict extends boolean,
|
|
50
|
+
TSelected,
|
|
51
|
+
> = unknown extends TSelected
|
|
52
|
+
? ResolveLoaderData<TRouter, TFrom, TStrict>
|
|
53
|
+
: TSelected
|
|
54
|
+
|
|
55
|
+
export type UseLoaderDataRoute<out TId> = <
|
|
56
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
57
|
+
TSelected = unknown,
|
|
58
|
+
TStructuralSharing extends boolean = boolean,
|
|
59
|
+
>(
|
|
60
|
+
opts?: UseLoaderDataBaseOptions<
|
|
61
|
+
TRouter,
|
|
62
|
+
TId,
|
|
63
|
+
true,
|
|
64
|
+
TSelected,
|
|
65
|
+
TStructuralSharing
|
|
66
|
+
> &
|
|
67
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,
|
|
68
|
+
) => UseLoaderDataResult<TRouter, TId, true, TSelected>
|
|
69
|
+
|
|
18
70
|
export function useLoaderData<
|
|
19
|
-
|
|
71
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
20
72
|
TFrom extends string | undefined = undefined,
|
|
21
73
|
TStrict extends boolean = true,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
TFrom,
|
|
25
|
-
TStrict
|
|
26
|
-
> = MakeRouteMatch<TRouteTree, TFrom, TStrict>,
|
|
27
|
-
TSelected = Required<TRouteMatch>['loaderData'],
|
|
74
|
+
TSelected = unknown,
|
|
75
|
+
TStructuralSharing extends boolean = boolean,
|
|
28
76
|
>(
|
|
29
77
|
opts: UseLoaderDataOptions<
|
|
30
|
-
|
|
78
|
+
TRouter,
|
|
31
79
|
TFrom,
|
|
32
80
|
TStrict,
|
|
33
|
-
|
|
34
|
-
|
|
81
|
+
TSelected,
|
|
82
|
+
TStructuralSharing
|
|
35
83
|
>,
|
|
36
|
-
): TSelected {
|
|
37
|
-
return useMatch
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
84
|
+
): UseLoaderDataResult<TRouter, TFrom, TStrict, TSelected> {
|
|
85
|
+
return useMatch({
|
|
86
|
+
from: opts.from!,
|
|
87
|
+
strict: opts.strict,
|
|
88
|
+
structuralSharing: opts.structuralSharing,
|
|
89
|
+
select: (s: any) => {
|
|
90
|
+
return opts.select ? opts.select(s.loaderData) : s.loaderData
|
|
43
91
|
},
|
|
44
|
-
})
|
|
92
|
+
} as any) as UseLoaderDataResult<TRouter, TFrom, TStrict, TSelected>
|
|
45
93
|
}
|
package/src/useLoaderDeps.tsx
CHANGED
|
@@ -1,29 +1,64 @@
|
|
|
1
1
|
import { useMatch } from './useMatch'
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
StructuralSharingOption,
|
|
4
|
+
ValidateSelected,
|
|
5
|
+
} from './structuralSharing'
|
|
6
|
+
import type { AnyRouter, RegisteredRouter } from './router'
|
|
7
|
+
import type { RouteById } from './routeInfo'
|
|
8
|
+
import type { Expand, StrictOrFrom } from './utils'
|
|
9
|
+
|
|
10
|
+
export interface UseLoaderDepsBaseOptions<
|
|
11
|
+
TRouter extends AnyRouter,
|
|
12
|
+
TFrom,
|
|
13
|
+
TSelected,
|
|
14
|
+
TStructuralSharing,
|
|
15
|
+
> {
|
|
16
|
+
select?: (
|
|
17
|
+
deps: ResolveLoaderDeps<TRouter, TFrom>,
|
|
18
|
+
) => ValidateSelected<TRouter, TSelected, TStructuralSharing>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type UseLoaderDepsOptions<
|
|
22
|
+
TRouter extends AnyRouter,
|
|
23
|
+
TFrom extends string | undefined,
|
|
24
|
+
TSelected,
|
|
25
|
+
TStructuralSharing,
|
|
26
|
+
> = StrictOrFrom<TRouter, TFrom> &
|
|
27
|
+
UseLoaderDepsBaseOptions<TRouter, TFrom, TSelected, TStructuralSharing> &
|
|
28
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>
|
|
29
|
+
|
|
30
|
+
export type ResolveLoaderDeps<TRouter extends AnyRouter, TFrom> = Expand<
|
|
31
|
+
RouteById<TRouter['routeTree'], TFrom>['types']['loaderDeps']
|
|
32
|
+
>
|
|
33
|
+
|
|
34
|
+
export type UseLoaderDepsResult<
|
|
35
|
+
TRouter extends AnyRouter,
|
|
36
|
+
TFrom,
|
|
37
|
+
TSelected,
|
|
38
|
+
> = unknown extends TSelected ? ResolveLoaderDeps<TRouter, TFrom> : TSelected
|
|
39
|
+
|
|
40
|
+
export type UseLoaderDepsRoute<out TId> = <
|
|
41
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
42
|
+
TSelected = unknown,
|
|
43
|
+
TStructuralSharing extends boolean = boolean,
|
|
44
|
+
>(
|
|
45
|
+
opts?: UseLoaderDepsBaseOptions<TRouter, TId, TSelected, TStructuralSharing> &
|
|
46
|
+
StructuralSharingOption<TRouter, TSelected, false>,
|
|
47
|
+
) => UseLoaderDepsResult<TRouter, TId, TSelected>
|
|
7
48
|
|
|
8
49
|
export function useLoaderDeps<
|
|
9
|
-
|
|
50
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
10
51
|
TFrom extends string | undefined = undefined,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
TFrom
|
|
14
|
-
>,
|
|
15
|
-
TSelected = Required<TRouteMatch>['loaderDeps'],
|
|
52
|
+
TSelected = unknown,
|
|
53
|
+
TStructuralSharing extends boolean = boolean,
|
|
16
54
|
>(
|
|
17
|
-
opts:
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
): TSelected {
|
|
55
|
+
opts: UseLoaderDepsOptions<TRouter, TFrom, TSelected, TStructuralSharing>,
|
|
56
|
+
): UseLoaderDepsResult<TRouter, TFrom, TSelected> {
|
|
57
|
+
const { select, ...rest } = opts
|
|
21
58
|
return useMatch({
|
|
22
|
-
...
|
|
59
|
+
...rest,
|
|
23
60
|
select: (s) => {
|
|
24
|
-
return
|
|
25
|
-
? opts.select(s.loaderDeps)
|
|
26
|
-
: s.loaderDeps
|
|
61
|
+
return select ? select(s.loaderDeps) : s.loaderDeps
|
|
27
62
|
},
|
|
28
|
-
})
|
|
63
|
+
}) as UseLoaderDepsResult<TRouter, TFrom, TSelected>
|
|
29
64
|
}
|
package/src/useLocation.tsx
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import { useRouterState } from './useRouterState'
|
|
2
|
+
import type {
|
|
3
|
+
StructuralSharingOption,
|
|
4
|
+
ValidateSelected,
|
|
5
|
+
} from './structuralSharing'
|
|
2
6
|
import type { AnyRouter, RegisteredRouter, RouterState } from './router'
|
|
3
7
|
|
|
8
|
+
export interface UseLocationBaseOptions<
|
|
9
|
+
TRouter extends AnyRouter,
|
|
10
|
+
TSelected,
|
|
11
|
+
TStructuralSharing extends boolean = boolean,
|
|
12
|
+
> {
|
|
13
|
+
select?: (
|
|
14
|
+
state: RouterState<TRouter['routeTree']>['location'],
|
|
15
|
+
) => ValidateSelected<TRouter, TSelected, TStructuralSharing>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type UseLocationResult<
|
|
19
|
+
TRouter extends AnyRouter,
|
|
20
|
+
TSelected,
|
|
21
|
+
> = unknown extends TSelected
|
|
22
|
+
? RouterState<TRouter['routeTree']>['location']
|
|
23
|
+
: TSelected
|
|
24
|
+
|
|
4
25
|
export function useLocation<
|
|
5
26
|
TRouter extends AnyRouter = RegisteredRouter,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
>(
|
|
27
|
+
TSelected = unknown,
|
|
28
|
+
TStructuralSharing extends boolean = boolean,
|
|
29
|
+
>(
|
|
30
|
+
opts?: UseLocationBaseOptions<TRouter, TSelected, TStructuralSharing> &
|
|
31
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,
|
|
32
|
+
): UseLocationResult<TRouter, TSelected> {
|
|
9
33
|
return useRouterState({
|
|
10
|
-
select: (state) =>
|
|
11
|
-
opts?.select
|
|
12
|
-
|
|
13
|
-
: (state.location as TSelected),
|
|
14
|
-
})
|
|
34
|
+
select: (state: any) =>
|
|
35
|
+
opts?.select ? opts.select(state.location) : state.location,
|
|
36
|
+
} as any) as UseLocationResult<TRouter, TSelected>
|
|
15
37
|
}
|
package/src/useMatch.tsx
CHANGED
|
@@ -2,44 +2,93 @@ import * as React from 'react'
|
|
|
2
2
|
import invariant from 'tiny-invariant'
|
|
3
3
|
import { useRouterState } from './useRouterState'
|
|
4
4
|
import { matchContext } from './matchContext'
|
|
5
|
-
import type {
|
|
6
|
-
|
|
5
|
+
import type {
|
|
6
|
+
StructuralSharingOption,
|
|
7
|
+
ValidateSelected,
|
|
8
|
+
} from './structuralSharing'
|
|
9
|
+
import type { AnyRouter, RegisteredRouter } from './router'
|
|
7
10
|
import type { MakeRouteMatch } from './Matches'
|
|
8
|
-
import type {
|
|
9
|
-
import type { Constrain, StrictOrFrom } from './utils'
|
|
11
|
+
import type { StrictOrFrom, ThrowOrOptional } from './utils'
|
|
10
12
|
|
|
11
|
-
export
|
|
13
|
+
export interface UseMatchBaseOptions<
|
|
14
|
+
TRouter extends AnyRouter,
|
|
12
15
|
TFrom,
|
|
13
16
|
TStrict extends boolean,
|
|
14
|
-
|
|
17
|
+
TThrow,
|
|
15
18
|
TSelected,
|
|
16
|
-
|
|
17
|
-
>
|
|
18
|
-
select?: (
|
|
19
|
+
TStructuralSharing extends boolean,
|
|
20
|
+
> {
|
|
21
|
+
select?: (
|
|
22
|
+
match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,
|
|
23
|
+
) => ValidateSelected<TRouter, TSelected, TStructuralSharing>
|
|
19
24
|
shouldThrow?: TThrow
|
|
20
25
|
}
|
|
21
26
|
|
|
27
|
+
export type UseMatchRoute<out TFrom> = <
|
|
28
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
29
|
+
TSelected = unknown,
|
|
30
|
+
TStructuralSharing extends boolean = boolean,
|
|
31
|
+
>(
|
|
32
|
+
opts?: UseMatchBaseOptions<
|
|
33
|
+
TRouter,
|
|
34
|
+
TFrom,
|
|
35
|
+
true,
|
|
36
|
+
true,
|
|
37
|
+
TSelected,
|
|
38
|
+
TStructuralSharing
|
|
39
|
+
> &
|
|
40
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,
|
|
41
|
+
) => UseMatchResult<TRouter, TFrom, true, TSelected>
|
|
42
|
+
|
|
43
|
+
export type UseMatchOptions<
|
|
44
|
+
TRouter extends AnyRouter,
|
|
45
|
+
TFrom extends string | undefined,
|
|
46
|
+
TStrict extends boolean,
|
|
47
|
+
TSelected,
|
|
48
|
+
TThrow extends boolean,
|
|
49
|
+
TStructuralSharing extends boolean,
|
|
50
|
+
> = StrictOrFrom<TRouter, TFrom, TStrict> &
|
|
51
|
+
UseMatchBaseOptions<
|
|
52
|
+
TRouter,
|
|
53
|
+
TFrom,
|
|
54
|
+
TStrict,
|
|
55
|
+
TThrow,
|
|
56
|
+
TSelected,
|
|
57
|
+
TStructuralSharing
|
|
58
|
+
> &
|
|
59
|
+
StructuralSharingOption<TRouter, TSelected, TStructuralSharing>
|
|
60
|
+
|
|
61
|
+
export type UseMatchResult<
|
|
62
|
+
TRouter extends AnyRouter,
|
|
63
|
+
TFrom,
|
|
64
|
+
TStrict extends boolean,
|
|
65
|
+
TSelected,
|
|
66
|
+
> = unknown extends TSelected
|
|
67
|
+
? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>
|
|
68
|
+
: TSelected
|
|
69
|
+
|
|
22
70
|
export function useMatch<
|
|
23
|
-
|
|
71
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
24
72
|
TFrom extends string | undefined = undefined,
|
|
25
73
|
TStrict extends boolean = true,
|
|
26
|
-
TRouteMatch = MakeRouteMatch<TRouteTree, TFrom, TStrict>,
|
|
27
|
-
TSelected = TRouteMatch,
|
|
28
74
|
TThrow extends boolean = true,
|
|
75
|
+
TSelected = unknown,
|
|
76
|
+
TStructuralSharing extends boolean = boolean,
|
|
29
77
|
>(
|
|
30
78
|
opts: UseMatchOptions<
|
|
31
|
-
|
|
79
|
+
TRouter,
|
|
80
|
+
TFrom,
|
|
32
81
|
TStrict,
|
|
33
|
-
TRouteMatch,
|
|
34
82
|
TSelected,
|
|
35
|
-
TThrow
|
|
83
|
+
TThrow,
|
|
84
|
+
TStructuralSharing
|
|
36
85
|
>,
|
|
37
|
-
):
|
|
86
|
+
): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {
|
|
38
87
|
const nearestMatchId = React.useContext(matchContext)
|
|
39
88
|
|
|
40
89
|
const matchSelection = useRouterState({
|
|
41
|
-
select: (state) => {
|
|
42
|
-
const match = state.matches.find((d) =>
|
|
90
|
+
select: (state: any) => {
|
|
91
|
+
const match = state.matches.find((d: any) =>
|
|
43
92
|
opts.from ? opts.from === d.routeId : d.id === nearestMatchId,
|
|
44
93
|
)
|
|
45
94
|
invariant(
|
|
@@ -51,9 +100,10 @@ export function useMatch<
|
|
|
51
100
|
return undefined
|
|
52
101
|
}
|
|
53
102
|
|
|
54
|
-
return opts.select ? opts.select(match
|
|
103
|
+
return opts.select ? opts.select(match) : match
|
|
55
104
|
},
|
|
56
|
-
|
|
105
|
+
structuralSharing: opts.structuralSharing,
|
|
106
|
+
} as any)
|
|
57
107
|
|
|
58
|
-
return matchSelection as
|
|
108
|
+
return matchSelection as any
|
|
59
109
|
}
|