@tanstack/react-router 1.4.7 → 1.4.9

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.
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { ResolveRelativePath, ToOptions } from './link';
3
3
  import { AnyRoute, ReactNode } from './route';
4
- import { FullSearchSchema, ParseRoute, RouteById, RouteByPath, RouteIds, RoutePaths } from './routeInfo';
4
+ import { ParseRoute, RouteById, RouteByPath, RouteIds, RoutePaths } from './routeInfo';
5
5
  import { RegisteredRouter, RouterState } from './router';
6
- import { NoInfer, StrictOrFrom } from './utils';
6
+ import { GetTFrom, NoInfer, StrictOrFrom } from './utils';
7
7
  export declare const matchContext: React.Context<string | undefined>;
8
8
  export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id']> {
9
9
  id: string;
@@ -21,7 +21,7 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
21
21
  loaderData?: RouteById<TRouteTree, TRouteId>['types']['loaderData'];
22
22
  routeContext: RouteById<TRouteTree, TRouteId>['types']['routeContext'];
23
23
  context: RouteById<TRouteTree, TRouteId>['types']['allContext'];
24
- search: FullSearchSchema<TRouteTree> & RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'];
24
+ search: RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'];
25
25
  fetchCount: number;
26
26
  abortController: AbortController;
27
27
  cause: 'preload' | 'enter' | 'stay';
@@ -49,18 +49,18 @@ export type MakeMatchRouteOptions<TRouteTree extends AnyRoute = RegisteredRouter
49
49
  };
50
50
  export declare function MatchRoute<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = '/', TMaskTo extends string = ''>(props: MakeMatchRouteOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): any;
51
51
  export declare function getRenderedMatches(state: RouterState): RouteMatch<AnyRoute, any>[];
52
- export declare function useMatch<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TRouteMatchState = RouteMatch<TRouteTree, TFrom>, TSelected = TRouteMatchState>(opts: StrictOrFrom<TFrom> & {
52
+ export declare function useMatch<TOpts extends StrictOrFrom<TFrom>, TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TFromInferred extends RouteIds<TRouteTree> = GetTFrom<TOpts, TRouteTree>, TRouteMatchState = RouteMatch<TRouteTree, TFromInferred>, TSelected = TRouteMatchState>(opts: TOpts & {
53
53
  select?: (match: TRouteMatchState) => TSelected;
54
- }): TStrict extends true ? TSelected : TSelected | undefined;
54
+ }): TSelected;
55
55
  export declare function useMatches<T = RouteMatch[]>(opts?: {
56
56
  select?: (matches: RouteMatch[]) => T;
57
57
  }): T;
58
58
  export declare function useParentMatches<T = RouteMatch[]>(opts?: {
59
59
  select?: (matches: RouteMatch[]) => T;
60
60
  }): T;
61
- export declare function useLoaderDeps<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TRouteMatch extends RouteMatch<TRouteTree, TFrom> = RouteMatch<TRouteTree, TFrom>, TSelected = Required<TRouteMatch>['loaderDeps']>(opts: StrictOrFrom<TFrom> & {
61
+ export declare function useLoaderDeps<TOpts extends StrictOrFrom<TFrom>, TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TFromInferred extends RouteIds<TRouteTree> = GetTFrom<TOpts, TRouteTree>, TRouteMatch extends RouteMatch<TRouteTree, TFromInferred> = RouteMatch<TRouteTree, TFromInferred>, TSelected = Required<TRouteMatch>['loaderDeps']>(opts: TOpts & {
62
62
  select?: (match: TRouteMatch) => TSelected;
63
- }): TStrict extends true ? TSelected : TSelected | undefined;
64
- export declare function useLoaderData<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TRouteMatch extends RouteMatch<TRouteTree, TFrom> = RouteMatch<TRouteTree, TFrom>, TSelected = Required<TRouteMatch>['loaderData']>(opts: StrictOrFrom<TFrom> & {
63
+ }): TSelected;
64
+ export declare function useLoaderData<TOpts extends StrictOrFrom<TFrom>, TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TFromInferred extends RouteIds<TRouteTree> = GetTFrom<TOpts, TRouteTree>, TRouteMatch extends RouteMatch<TRouteTree, TFromInferred> = RouteMatch<TRouteTree, TFromInferred>, TSelected = Required<TRouteMatch>['loaderData']>(opts: TOpts & {
65
65
  select?: (match: TRouteMatch) => TSelected;
66
- }): TStrict extends true ? TSelected : TSelected | undefined;
66
+ }): TSelected;
@@ -4,7 +4,7 @@ import { AnyRoute, ReactNode, RootSearchSchema } from './route';
4
4
  import { RouteByPath, RoutePaths } from './routeInfo';
5
5
  import { RegisteredRouter } from './router';
6
6
  import { LinkProps, UseLinkPropsOptions } from './useNavigate';
7
- import { Expand, NoInfer, NonNullableUpdater, PickRequired, Updater, WithoutEmpty } from './utils';
7
+ import { Expand, NoInfer, NonNullableUpdater, PickRequired, StringLiteral, Updater, WithoutEmpty } from './utils';
8
8
  import { HistoryState } from '@tanstack/history';
9
9
  export type CleanPath<T extends string> = T extends `${infer L}//${infer R}` ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`> : T extends `${infer L}//` ? `${CleanPath<L>}/` : T extends `//${infer L}` ? `/${CleanPath<L>}` : T;
10
10
  export type Split<S, TIncludeTrailingSlash = true> = S extends unknown ? string extends S ? string[] : S extends string ? CleanPath<S> extends '' ? [] : TIncludeTrailingSlash extends true ? CleanPath<S> extends `${infer T}/` ? [...Split<T>, '/'] : CleanPath<S> extends `/${infer U}` ? Split<U> : CleanPath<S> extends `${infer T}/${infer U}` ? [...Split<T>, ...Split<U>] : [S] : CleanPath<S> extends `${infer T}/${infer U}` ? [...Split<T>, ...Split<U>] : S extends string ? [S] : never : never : never;
@@ -26,22 +26,22 @@ export type RelativeToPathAutoComplete<AllPaths extends string, TFrom extends st
26
26
  ] ? `${TTo}${Join<RestPath>}` : never : (TFrom extends `/` ? never : SplitPaths extends [...Split<TFrom, false>, ...infer RestPath] ? Join<RestPath> extends {
27
27
  length: 0;
28
28
  } ? never : './' : never) | (TFrom extends `/` ? never : '../') | AllPaths;
29
- export type NavigateOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
29
+ export type NavigateOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
30
30
  replace?: boolean;
31
31
  resetScroll?: boolean;
32
32
  startTransition?: boolean;
33
33
  };
34
- export type ToOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TFrom, TTo> & {
34
+ export type ToOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TFrom, TTo> & {
35
35
  mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>;
36
36
  };
37
- export type ToMaskOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TMaskFrom extends RoutePaths<TRouteTree> | string = string, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
37
+ export type ToMaskOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TMaskFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
38
38
  unmaskOnReload?: boolean;
39
39
  };
40
- export type ToSubOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>> = {
40
+ export type ToSubOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>, TTo extends string = '', TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>> = {
41
41
  to?: ToPathOption<TRouteTree, TFrom, TTo>;
42
42
  hash?: true | Updater<string>;
43
43
  state?: true | NonNullableUpdater<HistoryState>;
44
- from?: TFrom;
44
+ from?: StringLiteral<TFrom>;
45
45
  } & CheckPath<TRouteTree, NoInfer<TResolved>, {}> & SearchParamOptions<TRouteTree, TFrom, TTo, TResolved> & PathParamOptions<TRouteTree, TFrom, TTo, TResolved>;
46
46
  type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo);
47
47
  type ParamVariant = 'PATH' | 'SEARCH';
@@ -3,8 +3,9 @@ import { LinkOptions, NavigateOptions } from './link';
3
3
  import { AnyRoute } from './route';
4
4
  import { RoutePaths } from './routeInfo';
5
5
  import { RegisteredRouter } from './router';
6
- export declare function useNavigate<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TDefaultFrom extends RoutePaths<TRouteTree> | string = string>(_defaultOpts?: {
7
- from?: TDefaultFrom;
6
+ import { StringLiteral } from './utils';
7
+ export declare function useNavigate<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TDefaultFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>>(_defaultOpts?: {
8
+ from?: StringLiteral<TDefaultFrom>;
8
9
  }): <TFrom extends string | import("./routeInfo").ParseRoute<TRouteTree>["fullPath"] = TDefaultFrom, TTo extends string = "", TMaskFrom extends string | import("./routeInfo").ParseRoute<TRouteTree>["fullPath"] = TFrom, TMaskTo extends string = "">({ from, ...rest }: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<void>;
9
10
  export declare function Navigate<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''>(props: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): null;
10
11
  export type UseLinkPropsOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & React.AnchorHTMLAttributes<HTMLAnchorElement>;
@@ -1,7 +1,7 @@
1
1
  import { AnyRoute } from './route';
2
- import { RouteIds, RouteById, AllParams } from './routeInfo';
2
+ import { RouteIds, RouteById } from './routeInfo';
3
3
  import { RegisteredRouter } from './router';
4
- import { StrictOrFrom } from './utils';
5
- export declare function useParams<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TDefaultSelected = AllParams<TRouteTree> & RouteById<TRouteTree, TFrom>['types']['allParams'], TSelected = TDefaultSelected>(opts: StrictOrFrom<TFrom> & {
6
- select?: (search: TDefaultSelected) => TSelected;
4
+ import { StrictOrFrom, GetTFrom } from './utils';
5
+ export declare function useParams<TOpts extends StrictOrFrom<TFrom>, TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TFromInferred = GetTFrom<TOpts, TRouteTree>, TParams = RouteById<TRouteTree, TFromInferred>['types']['allParams'], TSelected = TParams>(opts: TOpts & {
6
+ select?: (params: TParams) => TSelected;
7
7
  }): TSelected;
@@ -1,7 +1,7 @@
1
1
  import { AnyRoute } from './route';
2
2
  import { RouteIds, RouteById } from './routeInfo';
3
3
  import { RegisteredRouter } from './router';
4
- import { StrictOrFrom } from './utils';
5
- export declare function useSearch<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TSearch = RouteById<TRouteTree, TFrom>['types']['fullSearchSchema'], TSelected = TSearch>(opts: StrictOrFrom<TFrom> & {
4
+ import { StrictOrFrom, GetTFrom } from './utils';
5
+ export declare function useSearch<TOpts extends StrictOrFrom<TFrom>, TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TFromInferred = GetTFrom<TOpts, TRouteTree>, TSearch = RouteById<TRouteTree, TFromInferred>['types']['fullSearchSchema'], TSelected = TSearch>(opts: TOpts & {
6
6
  select?: (search: TSearch) => TSelected;
7
- }): TStrict extends true ? TSelected : TSelected | undefined;
7
+ }): TSelected;
@@ -36,16 +36,18 @@ export declare function isPlainArray(value: unknown): boolean;
36
36
  export declare function deepEqual(a: any, b: any, partial?: boolean): boolean;
37
37
  export declare function useStableCallback<T extends (...args: any[]) => any>(fn: T): T;
38
38
  export declare function shallow<T>(objA: T, objB: T): boolean;
39
+ export type StringLiteral<T> = T extends string ? string extends T ? string : T : never;
39
40
  export type StrictOrFrom<TFrom> = {
40
- from: TFrom;
41
+ from: StringLiteral<TFrom> | TFrom;
41
42
  strict?: true;
42
43
  } | {
43
44
  from?: never;
44
45
  strict: false;
45
46
  };
46
- export declare function useRouteContext<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TRouteContext = RouteById<TRouteTree, TFrom>['types']['allContext'], TSelected = TRouteContext>(opts: StrictOrFrom<TFrom> & {
47
+ export type GetTFrom<T, TRouteTree extends AnyRoute> = T extends StrictOrFrom<infer TFrom extends RouteIds<TRouteTree>> ? TFrom : never;
48
+ export declare function useRouteContext<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TRouteContext = RouteById<TRouteTree, TFrom>['types']['allContext'], TSelected = TRouteContext>(opts: StrictOrFrom<TFrom> & {
47
49
  select?: (search: TRouteContext) => TSelected;
48
- }): TStrict extends true ? TSelected : TSelected | undefined;
50
+ }): TSelected;
49
51
  export declare const useLayoutEffect: typeof React.useLayoutEffect;
50
52
  export declare function escapeJSON(jsonString: string): string;
51
53
  export {};
@@ -809,16 +809,22 @@
809
809
  const next = _next;
810
810
  const array = isPlainArray(prev) && isPlainArray(next);
811
811
  if (array || isPlainObject(prev) && isPlainObject(next)) {
812
- const prevSize = array ? prev.length : Object.keys(prev).length;
812
+ const prevItems = array ? prev : Object.keys(prev);
813
+ const prevSize = prevItems.length;
813
814
  const nextItems = array ? next : Object.keys(next);
814
815
  const nextSize = nextItems.length;
815
816
  const copy = array ? [] : {};
816
817
  let equalItems = 0;
817
818
  for (let i = 0; i < nextSize; i++) {
818
819
  const key = array ? i : nextItems[i];
819
- copy[key] = replaceEqualDeep(prev[key], next[key]);
820
- if (copy[key] === prev[key] && prev[key] !== undefined) {
820
+ if (!array && prev[key] === undefined && next[key] === undefined && prevItems.includes(key)) {
821
+ copy[key] = undefined;
821
822
  equalItems++;
823
+ } else {
824
+ copy[key] = replaceEqualDeep(prev[key], next[key]);
825
+ if (copy[key] === prev[key] && prev[key] !== undefined) {
826
+ equalItems++;
827
+ }
822
828
  }
823
829
  }
824
830
  return prevSize === nextSize && equalItems === prevSize ? prev : copy;
@@ -1603,13 +1609,12 @@
1603
1609
  }
1604
1610
  useMatch = opts => {
1605
1611
  return useMatch({
1606
- ...opts,
1612
+ select: opts?.select,
1607
1613
  from: this.id
1608
1614
  });
1609
1615
  };
1610
1616
  useRouteContext = opts => {
1611
1617
  return useMatch({
1612
- ...opts,
1613
1618
  from: this.id,
1614
1619
  select: d => opts?.select ? opts.select(d.context) : d.context
1615
1620
  });
@@ -2713,7 +2718,7 @@
2713
2718
  }
2714
2719
  const parentContext = parentMatch?.context ?? this.options.context ?? {};
2715
2720
  const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
2716
- const pendingPromise = new Promise(r => setTimeout(r, pendingMs));
2721
+ const pendingPromise = typeof pendingMs === 'number' && pendingMs <= 0 ? Promise.resolve() : new Promise(r => setTimeout(r, pendingMs));
2717
2722
  const beforeLoadContext = (await route.options.beforeLoad?.({
2718
2723
  search: match.search,
2719
2724
  abortController,
@@ -2778,7 +2783,7 @@
2778
2783
  let didShowPending = false;
2779
2784
  const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
2780
2785
  const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
2781
- const shouldPending = !preload && pendingMs && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
2786
+ const shouldPending = !preload && typeof pendingMs === 'number' && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
2782
2787
  const loaderContext = {
2783
2788
  params: match.params,
2784
2789
  deps: match.loaderDeps,
@@ -3362,8 +3367,7 @@
3362
3367
 
3363
3368
  function useNavigate(_defaultOpts) {
3364
3369
  const {
3365
- navigate,
3366
- buildLocation
3370
+ navigate
3367
3371
  } = useRouter();
3368
3372
  const matchPathname = useMatch({
3369
3373
  strict: false,