@tanstack/react-router 0.0.1-beta.214 → 0.0.1-beta.216

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.
@@ -24,8 +24,11 @@ export type MakeMatchRouteOptions<TRouteTree extends AnyRoute = RegisteredRouter
24
24
  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;
25
25
  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> & {
26
26
  select?: (match: TRouteMatchState) => TSelected;
27
- }): TStrict extends true ? TRouteMatchState : TRouteMatchState | undefined;
27
+ }): TStrict extends true ? TSelected : TSelected | undefined;
28
28
  export declare const matchesContext: React.Context<RouteMatch<AnyRoute, any>[]>;
29
29
  export declare function useMatches<T = RouteMatch[]>(opts?: {
30
30
  select?: (matches: RouteMatch[]) => T;
31
31
  }): T;
32
+ 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 = TRouteMatch['loaderData']>(opts: StrictOrFrom<TFrom> & {
33
+ select?: (match: TRouteMatch) => TSelected;
34
+ }): TStrict extends true ? TSelected : TSelected | undefined;
@@ -19,7 +19,7 @@ export interface MatchLocation {
19
19
  from?: string;
20
20
  }
21
21
  export type BuildLinkFn<TRouteTree extends AnyRoute> = <TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = ''>(dest: LinkOptions<TRouteTree, TFrom, TTo>) => LinkInfo;
22
- export type NavigateFn<TRouteTree extends AnyRoute> = <TRouteTree extends AnyRoute, TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = TFrom, TMaskTo extends string = ''>({ from, to, ...rest }: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<void>;
22
+ export type NavigateFn<TRouteTree extends AnyRoute> = <TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> = TFrom, TMaskTo extends string = ''>(opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<void>;
23
23
  export type MatchRouteFn<TRouteTree extends AnyRoute> = <TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string = '', TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<TRouteTree, TFrom, TTo>, opts?: MatchRouteOptions) => false | RouteById<TRouteTree, TResolved>['types']['allParams'];
24
24
  export type LoadFn = (opts?: {
25
25
  next?: ParsedLocation;
@@ -70,6 +70,7 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
70
70
  searchError: unknown;
71
71
  updatedAt: number;
72
72
  loadPromise?: Promise<void>;
73
+ loaderData?: RouteById<TRouteTree, TRouteId>['types']['loaderData'];
73
74
  __resolveLoadPromise?: () => void;
74
75
  context: RouteById<TRouteTree, TRouteId>['types']['allContext'];
75
76
  routeSearch: RouteById<TRouteTree, TRouteId>['types']['searchSchema'];
@@ -12,12 +12,12 @@ export type FileRoutePath<TParentRoute extends AnyRoute, TFilePath extends strin
12
12
  export declare class FileRoute<TFilePath extends keyof FileRoutesByPath, TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'], TId extends RouteConstraints['TId'] = TFilePath, TPath extends RouteConstraints['TPath'] = FileRoutePath<TParentRoute, TFilePath>, TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<TParentRoute, RemoveUnderScores<TPath>>> {
13
13
  path: TFilePath;
14
14
  constructor(path: TFilePath);
15
- createRoute: <TSearchSchema extends import("./route").AnySearchSchema = {}, TFullSearchSchema extends import("./route").AnySearchSchema = Expand<Assign<import("./route").InferFullSearchSchema<TParentRoute>, TSearchSchema>>, TParams extends Record<string, any> = (TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> extends infer T ? T extends TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> ? T extends `$${infer L}` ? L : never : never : never) extends never ? AnyPathParams : Record<TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> extends infer T ? T extends TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> ? T extends `$${infer L}` ? L : never : never : never, string>, TAllParams extends Record<string, any> = IsAny<TParentRoute["types"]["allParams"], TParams, TParentRoute["types"]["allParams"] & TParams>, TRouteContext extends RouteContext = RouteContext, TContext extends Expand<Assign<IsAny<TParentRoute["types"]["allContext"], {}, TParentRoute["types"]["allContext"]>, TRouteContext>> = Expand<Assign<IsAny<TParentRoute["types"]["allContext"], {}, TParentRoute["types"]["allContext"]>, TRouteContext>>, TRouterContext extends AnyContext = AnyContext, TChildren extends unknown = unknown, TRouteTree extends AnyRoute = AnyRoute>(options: Omit<RouteOptions<TParentRoute, string, string, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TContext>, "path" | "id" | "getParentRoute"> & {
15
+ createRoute: <TSearchSchema extends import("./route").AnySearchSchema = {}, TFullSearchSchema extends import("./route").AnySearchSchema = Expand<Assign<import("./route").InferFullSearchSchema<TParentRoute>, TSearchSchema>>, TParams extends Record<string, any> = (TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> extends infer T ? T extends TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> ? T extends `$${infer L}` ? L : never : never : never) extends never ? AnyPathParams : Record<TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> extends infer T ? T extends TrimLeft<TrimRight<import("./link").Split<TPath, true>[number], "_">, "_"> ? T extends `$${infer L}` ? L : never : never : never, string>, TAllParams extends Record<string, any> = IsAny<TParentRoute["types"]["allParams"], TParams, TParentRoute["types"]["allParams"] & TParams>, TRouteContext extends RouteContext = RouteContext, TContext extends Expand<Assign<IsAny<TParentRoute["types"]["allContext"], {}, TParentRoute["types"]["allContext"]>, TRouteContext>> = Expand<Assign<IsAny<TParentRoute["types"]["allContext"], {}, TParentRoute["types"]["allContext"]>, TRouteContext>>, TRouterContext extends AnyContext = AnyContext, TLoaderData extends unknown = unknown, TChildren extends unknown = unknown, TRouteTree extends AnyRoute = AnyRoute>(options: Omit<RouteOptions<TParentRoute, string, string, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TContext, TLoaderData>, "path" | "id" | "getParentRoute"> & {
16
16
  meta?: import("./route").RouteMeta | undefined;
17
17
  } & {
18
18
  caseSensitive?: boolean | undefined;
19
19
  wrapInSuspense?: boolean | undefined;
20
- component?: import("./route").RouteComponent<TFullSearchSchema, TAllParams, TContext> | undefined;
20
+ component?: import("./route").RouteComponent<TFullSearchSchema, TAllParams, TContext, TLoaderData> | undefined;
21
21
  errorComponent?: import("./route").ErrorRouteComponent<TFullSearchSchema, TAllParams, {}> | undefined;
22
22
  pendingComponent?: import("./route").PendingRouteComponent<TFullSearchSchema, TAllParams, TContext> | undefined;
23
23
  preSearchFilters?: import("./route").SearchFilter<TFullSearchSchema, TFullSearchSchema>[] | undefined;
@@ -27,6 +27,6 @@ export declare class FileRoute<TFilePath extends keyof FileRoutesByPath, TParent
27
27
  onTransition?: ((match: import("./RouterProvider").AnyRouteMatch) => void) | undefined;
28
28
  onLeave?: ((match: import("./RouterProvider").AnyRouteMatch) => void) | undefined;
29
29
  reloadOnWindowFocus?: boolean | undefined;
30
- }) => Route<TParentRoute, TPath, TFullPath, TFilePath, TId, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TContext, TRouterContext, TChildren, TRouteTree>;
30
+ }) => Route<TParentRoute, TPath, TFullPath, TFilePath, TId, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TContext, TRouterContext, TLoaderData, TChildren, TRouteTree>;
31
31
  }
32
32
  export {};
@@ -29,17 +29,18 @@ export type MetaOptions = keyof PickRequired<RouteMeta> extends never ? {
29
29
  } : {
30
30
  meta: RouteMeta;
31
31
  };
32
- export type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = AnyPathParams, TAllParams extends AnyPathParams = TParams, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext> = BaseRouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext> & NoInfer<UpdatableRouteOptions<TFullSearchSchema, TAllParams, TAllContext>>;
32
+ export type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = AnyPathParams, TAllParams extends AnyPathParams = TParams, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = BaseRouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TLoaderData> & NoInfer<UpdatableRouteOptions<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>>;
33
33
  export type ParamsFallback<TPath extends string, TParams> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams;
34
- export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = {}, TAllParams = ParamsFallback<TPath, TParams>, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext> = RoutePathOptions<TCustomId, TPath> & {
34
+ export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = {}, TAllParams = ParamsFallback<TPath, TParams>, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = RoutePathOptions<TCustomId, TPath> & {
35
35
  getParentRoute: () => TParentRoute;
36
36
  validateSearch?: SearchSchemaValidator<TSearchSchema>;
37
+ shouldReload?: (match: LoaderFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext>) => any;
37
38
  } & (keyof PickRequired<RouteContext> extends never ? {
38
39
  beforeLoad?: BeforeLoadFn<TFullSearchSchema, TParentRoute, TAllParams, TRouteContext>;
39
40
  } : {
40
41
  beforeLoad: BeforeLoadFn<TFullSearchSchema, TParentRoute, TAllParams, TRouteContext>;
41
42
  }) & {
42
- load?: RouteLoadFn<TAllParams, TFullSearchSchema, NoInfer<TAllContext>, NoInfer<TRouteContext>>;
43
+ loader?: RouteLoadFn<TAllParams, TFullSearchSchema, NoInfer<TAllContext>, NoInfer<TRouteContext>, TLoaderData>;
43
44
  } & ({
44
45
  parseParams?: (rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>) => TParams extends Record<ParsePathParams<TPath>, any> ? TParams : 'parseParams must return an object';
45
46
  stringifyParams?: (params: NoInfer<ParamsFallback<TPath, TParams>>) => Record<ParsePathParams<TPath>, string>;
@@ -57,10 +58,10 @@ type BeforeLoadFn<TFullSearchSchema extends Record<string, any>, TParentRoute ex
57
58
  navigate: NavigateFn<AnyRoute>;
58
59
  buildLocation: BuildLocationFn<AnyRoute>;
59
60
  }) => Promise<TRouteContext> | TRouteContext | void;
60
- export type UpdatableRouteOptions<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends AnyContext> = MetaOptions & {
61
+ export type UpdatableRouteOptions<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends AnyContext, TLoaderData extends any = unknown> = MetaOptions & {
61
62
  caseSensitive?: boolean;
62
63
  wrapInSuspense?: boolean;
63
- component?: RouteComponent<TFullSearchSchema, TAllParams, TAllContext>;
64
+ component?: RouteComponent<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>;
64
65
  errorComponent?: ErrorRouteComponent<TFullSearchSchema, TAllParams, {}>;
65
66
  pendingComponent?: PendingRouteComponent<TFullSearchSchema, TAllParams, TAllContext>;
66
67
  preSearchFilters?: SearchFilter<TFullSearchSchema>[];
@@ -85,10 +86,8 @@ export type DefinedPathParamWarning = 'Path params cannot be redefined by child
85
86
  export type ParentParams<TParentParams> = AnyPathParams extends TParentParams ? {} : {
86
87
  [Key in keyof TParentParams]?: DefinedPathParamWarning;
87
88
  };
88
- export type RouteLoadFn<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext> = (match: LoadFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext> & {
89
- parentMatchPromise?: Promise<void>;
90
- }) => any;
91
- export interface LoadFnContext<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext> {
89
+ export type RouteLoadFn<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = (match: LoaderFnContext<TAllParams, TFullSearchSchema, TAllContext, TRouteContext>) => Promise<TLoaderData> | TLoaderData;
90
+ export interface LoaderFnContext<TAllParams = {}, TFullSearchSchema extends Record<string, any> = {}, TAllContext extends Record<string, any> = AnyContext, TRouteContext extends Record<string, any> = AnyContext> {
92
91
  abortController: AbortController;
93
92
  preload: boolean;
94
93
  params: TAllParams;
@@ -96,6 +95,8 @@ export interface LoadFnContext<TAllParams = {}, TFullSearchSchema extends Record
96
95
  context: Expand<Assign<TAllContext, TRouteContext>>;
97
96
  location: ParsedLocation<TFullSearchSchema>;
98
97
  navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>;
98
+ parentMatchPromise?: Promise<void>;
99
+ cause: 'enter' | 'stay';
99
100
  }
100
101
  export type SearchFilter<T, U = T> = (prev: T) => U;
101
102
  export type ResolveId<TParentRoute, TCustomId extends string, TPath extends string> = TParentRoute extends {
@@ -134,9 +135,9 @@ export type RouteConstraints = {
134
135
  TChildren: unknown;
135
136
  TRouteTree: AnyRoute;
136
137
  };
137
- export declare class Route<TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute, TPath extends RouteConstraints['TPath'] = '/', TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<TParentRoute, TPath>, TCustomId extends RouteConstraints['TCustomId'] = string, TId extends RouteConstraints['TId'] = ResolveId<TParentRoute, TCustomId, TPath>, TSearchSchema extends RouteConstraints['TSearchSchema'] = {}, TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<TParentRoute, TSearchSchema>, TParams extends RouteConstraints['TParams'] = Expand<Record<ParsePathParams<TPath>, string>>, TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<TParentRoute, TParams>, TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext, TAllContext extends Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>> = Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>>, TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext, TChildren extends RouteConstraints['TChildren'] = unknown, TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute> {
138
+ export declare class Route<TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute, TPath extends RouteConstraints['TPath'] = '/', TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<TParentRoute, TPath>, TCustomId extends RouteConstraints['TCustomId'] = string, TId extends RouteConstraints['TId'] = ResolveId<TParentRoute, TCustomId, TPath>, TSearchSchema extends RouteConstraints['TSearchSchema'] = {}, TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<TParentRoute, TSearchSchema>, TParams extends RouteConstraints['TParams'] = Expand<Record<ParsePathParams<TPath>, string>>, TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<TParentRoute, TParams>, TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext, TAllContext extends Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>> = Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>>, TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext, TLoaderData extends any = unknown, TChildren extends RouteConstraints['TChildren'] = unknown, TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute> {
138
139
  isRoot: TParentRoute extends Route<any> ? true : false;
139
- options: RouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext>;
140
+ options: RouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TLoaderData>;
140
141
  test: Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>>;
141
142
  parentRoute: TParentRoute;
142
143
  id: TId;
@@ -147,7 +148,7 @@ export declare class Route<TParentRoute extends RouteConstraints['TParentRoute']
147
148
  originalIndex?: number;
148
149
  router?: AnyRouter;
149
150
  rank: number;
150
- constructor(options: RouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext>);
151
+ constructor(options: RouteOptions<TParentRoute, TCustomId, TPath, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TLoaderData>);
151
152
  types: {
152
153
  parentRoute: TParentRoute;
153
154
  path: TPath;
@@ -164,12 +165,13 @@ export declare class Route<TParentRoute extends RouteConstraints['TParentRoute']
164
165
  children: TChildren;
165
166
  routeTree: TRouteTree;
166
167
  routerContext: TRouterContext;
168
+ loaderData: TLoaderData;
167
169
  };
168
170
  init: (opts: {
169
171
  originalIndex: number;
170
172
  }) => void;
171
- addChildren: <TNewChildren extends AnyRoute[]>(children: TNewChildren) => Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TRouterContext, TNewChildren, TRouteTree>;
172
- update: (options: UpdatableRouteOptions<TFullSearchSchema, TAllParams, Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>>>) => this;
173
+ addChildren: <TNewChildren extends AnyRoute[]>(children: TNewChildren) => Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TRouterContext, TNewChildren, TRouteTree, AnyRoute>;
174
+ update: (options: UpdatableRouteOptions<TFullSearchSchema, TAllParams, Expand<Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>>, TLoaderData>) => this;
173
175
  static __onInit: (route: any) => void;
174
176
  useMatch: <TSelected = TAllContext>(opts?: {
175
177
  select?: ((search: TAllContext) => TSelected) | undefined;
@@ -183,10 +185,13 @@ export declare class Route<TParentRoute extends RouteConstraints['TParentRoute']
183
185
  useParams: <TSelected = TAllParams>(opts?: {
184
186
  select?: ((search: TAllParams) => TSelected) | undefined;
185
187
  } | undefined) => TSelected;
188
+ useLoaderData: <TSelected = TLoaderData>(opts?: {
189
+ select?: ((search: TLoaderData) => TSelected) | undefined;
190
+ } | undefined) => TSelected;
186
191
  }
187
192
  export type AnyRootRoute = RootRoute<any, any, any>;
188
- export declare function rootRouteWithContext<TRouterContext extends {}>(): <TSearchSchema extends Record<string, any> = {}, TRouteContext extends RouteContext = RouteContext>(options?: Omit<RouteOptions<AnyRoute, "__root__", "", TSearchSchema, TSearchSchema, {}, {}, TRouteContext, Assign<TRouterContext, TRouteContext>>, "path" | "id" | "getParentRoute" | "stringifyParams" | "parseParams" | "caseSensitive"> | undefined) => RootRoute<TSearchSchema, TRouteContext, TRouterContext>;
189
- export declare class RootRoute<TSearchSchema extends Record<string, any> = {}, TRouteContext extends RouteContext = RouteContext, TRouterContext extends {} = {}> extends Route<any, // TParentRoute
193
+ export declare function rootRouteWithContext<TRouterContext extends {}>(): <TSearchSchema extends Record<string, any> = {}, TRouteContext extends RouteContext = RouteContext, TLoaderData extends unknown = unknown>(options?: Omit<RouteOptions<AnyRoute, "__root__", "", TSearchSchema, TSearchSchema, {}, {}, TRouteContext, Assign<TRouterContext, TRouteContext>, TLoaderData>, "path" | "id" | "getParentRoute" | "stringifyParams" | "parseParams" | "caseSensitive"> | undefined) => RootRoute<TSearchSchema, TRouteContext, TRouterContext, unknown>;
194
+ export declare class RootRoute<TSearchSchema extends Record<string, any> = {}, TRouteContext extends RouteContext = RouteContext, TRouterContext extends {} = {}, TLoaderData extends any = unknown> extends Route<any, // TParentRoute
190
195
  '/', // TPath
191
196
  '/', // TFullPath
192
197
  string, // TCustomId
@@ -198,7 +203,7 @@ TSearchSchema, // TFullSearchSchema
198
203
  TRouteContext, // TRouteContext
199
204
  Expand<Assign<TRouterContext, TRouteContext>>, // TAllContext
200
205
  TRouterContext, // TRouterContext
201
- any, // TChildren
206
+ TLoaderData, any, // TChildren
202
207
  any> {
203
208
  constructor(options?: Omit<RouteOptions<AnyRoute, // TParentRoute
204
209
  RootRouteId, // TCustomId
@@ -208,7 +213,8 @@ any> {
208
213
  {}, // TParams
209
214
  {}, // TAllParams
210
215
  TRouteContext, // TRouteContext
211
- Assign<TRouterContext, TRouteContext>>, 'path' | 'id' | 'getParentRoute' | 'caseSensitive' | 'parseParams' | 'stringifyParams'>);
216
+ Assign<TRouterContext, TRouteContext>, // TAllContext
217
+ TLoaderData>, 'path' | 'id' | 'getParentRoute' | 'caseSensitive' | 'parseParams' | 'stringifyParams'>);
212
218
  }
213
219
  export type ResolveFullPath<TParentRoute extends AnyRoute, TPath extends string, TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>> = TPrefixed extends RootRouteId ? '/' : TPrefixed;
214
220
  type RoutePrefix<TPrefix extends string, TPath extends string> = string extends TPath ? RootRouteId : TPath extends string ? TPrefix extends RootRouteId ? TPath extends '/' ? '/' : `/${TrimPath<TPath>}` : `${TPrefix}/${TPath}` extends '/' ? '/' : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}` : never;
@@ -228,7 +234,7 @@ export type RouteMask<TRouteTree extends AnyRoute> = {
228
234
  export declare function createRouteMask<TRouteTree extends AnyRoute, TFrom extends RoutePaths<TRouteTree>, TTo extends string>(opts: {
229
235
  routeTree: TRouteTree;
230
236
  } & ToSubOptions<TRouteTree, TFrom, TTo>): RouteMask<TRouteTree>;
231
- export type RouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = {
237
+ export type RouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext, TLoaderData extends any = unknown> = {
232
238
  useMatch: <TSelected = TAllContext>(opts?: {
233
239
  select?: (search: TAllContext) => TSelected;
234
240
  }) => TSelected;
@@ -241,6 +247,9 @@ export type RouteProps<TFullSearchSchema extends Record<string, any> = AnySearch
241
247
  useParams: <TSelected = TAllParams>(opts?: {
242
248
  select?: (search: TAllParams) => TSelected;
243
249
  }) => TSelected;
250
+ useLoaderData: <TSelected = TLoaderData>(opts?: {
251
+ select?: (search: TLoaderData) => TSelected;
252
+ }) => TSelected;
244
253
  };
245
254
  export type ErrorRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = {
246
255
  error: unknown;
@@ -254,8 +263,8 @@ export type SyncRouteComponent<TProps> = ((props: TProps) => ReactNode) | React.
254
263
  export type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {
255
264
  preload?: () => Promise<void>;
256
265
  };
257
- export type RouteComponent<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends Record<string, any>> = AsyncRouteComponent<RouteProps<TFullSearchSchema, TAllParams, TAllContext>>;
266
+ export type RouteComponent<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends Record<string, any>, TLoaderData extends any = unknown> = AsyncRouteComponent<RouteProps<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>>;
258
267
  export type ErrorRouteComponent<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends Record<string, any>> = AsyncRouteComponent<ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>>;
259
268
  export type PendingRouteComponent<TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends Record<string, any>> = AsyncRouteComponent<PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>>;
260
- export type AnyRouteComponent = RouteComponent<any, any, any>;
269
+ export type AnyRouteComponent = RouteComponent<any, any, any, any>;
261
270
  export {};
@@ -17,7 +17,7 @@ declare global {
17
17
  }
18
18
  export interface Register {
19
19
  }
20
- export type AnyRouter = Router<any, any>;
20
+ export type AnyRouter = Router<AnyRoute, any>;
21
21
  export type RegisteredRouter = Register extends {
22
22
  router: infer TRouter extends AnyRouter;
23
23
  } ? TRouter : AnyRouter;
@@ -1169,10 +1169,12 @@
1169
1169
  const latestLocationRef = React__namespace.useRef(parseLocation());
1170
1170
  const [preState, setState] = React__namespace.useState(() => getInitialRouterState(latestLocationRef.current));
1171
1171
  const [isTransitioning, startReactTransition] = React__namespace.useTransition();
1172
+ const pendingMatchesRef = React__namespace.useRef([]);
1172
1173
  const state = React__namespace.useMemo(() => ({
1173
1174
  ...preState,
1174
1175
  status: isTransitioning ? 'pending' : 'idle',
1175
- location: isTransitioning ? latestLocationRef.current : preState.location
1176
+ location: isTransitioning ? latestLocationRef.current : preState.location,
1177
+ pendingMatches: pendingMatchesRef.current
1176
1178
  }), [preState, isTransitioning]);
1177
1179
  React__namespace.useLayoutEffect(() => {
1178
1180
  if (!isTransitioning && state.resolvedLocation !== state.location) {
@@ -1182,6 +1184,7 @@
1182
1184
  toLocation: state.location,
1183
1185
  pathChanged: state.location.href !== state.resolvedLocation?.href
1184
1186
  });
1187
+ pendingMatchesRef.current = [];
1185
1188
  setState(s => ({
1186
1189
  ...s,
1187
1190
  resolvedLocation: s.location
@@ -1335,7 +1338,7 @@
1335
1338
  }
1336
1339
 
1337
1340
  // Create a fresh route match
1338
- const hasLoaders = !!(route.options.load || componentTypes.some(d => route.options[d]?.preload));
1341
+ const hasLoaders = !!(route.options.loader || componentTypes.some(d => route.options[d]?.preload));
1339
1342
  const routeMatch = {
1340
1343
  id: matchId,
1341
1344
  routeId: route.id,
@@ -1666,9 +1669,6 @@
1666
1669
  matchPromises.push((async () => {
1667
1670
  const parentMatchPromise = matchPromises[index - 1];
1668
1671
  const route = looseRoutesById[match.routeId];
1669
- if (match.isFetching) {
1670
- return getRouteMatch(state, match.id)?.loadPromise;
1671
- }
1672
1672
  const handleIfRedirect = err => {
1673
1673
  if (isRedirect(err)) {
1674
1674
  if (!preload) {
@@ -1678,73 +1678,100 @@
1678
1678
  }
1679
1679
  return false;
1680
1680
  };
1681
- const load = async () => {
1682
- try {
1681
+ let loadPromise;
1682
+ matches[index] = match = {
1683
+ ...match,
1684
+ fetchedAt: Date.now(),
1685
+ invalid: false
1686
+ };
1687
+ if (match.isFetching) {
1688
+ loadPromise = getRouteMatch(state, match.id)?.loadPromise;
1689
+ } else {
1690
+ const cause = state.matches.find(d => d.id === match.id) ? 'stay' : 'enter';
1691
+ const loaderContext = {
1692
+ params: match.params,
1693
+ search: match.search,
1694
+ preload: !!preload,
1695
+ parentMatchPromise,
1696
+ abortController: match.abortController,
1697
+ context: match.context,
1698
+ location: state.location,
1699
+ navigate: opts => navigate({
1700
+ ...opts,
1701
+ from: match.pathname
1702
+ }),
1703
+ cause
1704
+ };
1705
+
1706
+ // Default to reloading the route all the time
1707
+ const shouldReload = route.options.shouldReload?.(loaderContext) ?? true;
1708
+
1709
+ // If the user doesn't want the route to reload, just
1710
+ // resolve with the existing loader data
1711
+
1712
+ if (!shouldReload) {
1713
+ loadPromise = Promise.resolve(match.loaderData);
1714
+ } else {
1715
+ // Otherwise, load the route
1716
+ matches[index] = match = {
1717
+ ...match,
1718
+ isFetching: true
1719
+ };
1683
1720
  const componentsPromise = Promise.all(componentTypes.map(async type => {
1684
1721
  const component = route.options[type];
1685
1722
  if (component?.preload) {
1686
1723
  await component.preload();
1687
1724
  }
1688
1725
  }));
1689
- const loaderPromise = route.options.load?.({
1690
- params: match.params,
1691
- search: match.search,
1692
- preload: !!preload,
1693
- parentMatchPromise,
1694
- abortController: match.abortController,
1695
- context: match.context,
1696
- location: state.location,
1697
- navigate: opts => navigate({
1698
- ...opts,
1699
- from: match.pathname
1700
- })
1701
- });
1702
- const [_, loaderContext] = await Promise.all([componentsPromise, loaderPromise]);
1703
- if (latestPromise = checkLatest()) return await latestPromise;
1704
- matches[index] = match = {
1705
- ...match,
1706
- error: undefined,
1707
- status: 'success',
1708
- isFetching: false,
1709
- updatedAt: Date.now()
1710
- };
1711
- } catch (error) {
1712
- if (latestPromise = checkLatest()) return await latestPromise;
1713
- if (handleIfRedirect(error)) return;
1714
- try {
1715
- route.options.onError?.(error);
1716
- } catch (onErrorError) {
1717
- error = onErrorError;
1718
- if (handleIfRedirect(onErrorError)) return;
1719
- }
1720
- matches[index] = match = {
1721
- ...match,
1722
- error,
1723
- status: 'error',
1724
- isFetching: false,
1725
- updatedAt: Date.now()
1726
- };
1727
- }
1728
- if (!preload) {
1729
- setState(s => ({
1730
- ...s,
1731
- matches: s.matches.map(d => d.id === match.id ? match : d)
1732
- }));
1726
+ const loaderPromise = route.options.loader?.(loaderContext);
1727
+ loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
1733
1728
  }
1734
- };
1735
- let loadPromise;
1736
- matches[index] = match = {
1737
- ...match,
1738
- isFetching: true,
1739
- fetchedAt: Date.now(),
1740
- invalid: false
1741
- };
1742
- loadPromise = load();
1729
+ }
1743
1730
  matches[index] = match = {
1744
1731
  ...match,
1745
1732
  loadPromise
1746
1733
  };
1747
- await loadPromise;
1734
+ if (!preload) {
1735
+ setState(s => ({
1736
+ ...s,
1737
+ matches: s.matches.map(d => d.id === match.id ? match : d)
1738
+ }));
1739
+ }
1740
+ try {
1741
+ const loaderData = await loadPromise;
1742
+ if (latestPromise = checkLatest()) return await latestPromise;
1743
+ matches[index] = match = {
1744
+ ...match,
1745
+ error: undefined,
1746
+ status: 'success',
1747
+ isFetching: false,
1748
+ updatedAt: Date.now(),
1749
+ loaderData,
1750
+ loadPromise: undefined
1751
+ };
1752
+ } catch (error) {
1753
+ if (latestPromise = checkLatest()) return await latestPromise;
1754
+ if (handleIfRedirect(error)) return;
1755
+ try {
1756
+ route.options.onError?.(error);
1757
+ } catch (onErrorError) {
1758
+ error = onErrorError;
1759
+ if (handleIfRedirect(onErrorError)) return;
1760
+ }
1761
+ matches[index] = match = {
1762
+ ...match,
1763
+ error,
1764
+ status: 'error',
1765
+ isFetching: false,
1766
+ updatedAt: Date.now()
1767
+ };
1768
+ }
1769
+ if (!preload) {
1770
+ setState(s => ({
1771
+ ...s,
1772
+ matches: s.matches.map(d => d.id === match.id ? match : d)
1773
+ }));
1774
+ }
1748
1775
  })());
1749
1776
  });
1750
1777
  await Promise.all(matchPromises);
@@ -1770,6 +1797,7 @@
1770
1797
  let matches = matchRoutes(next.pathname, next.search, {
1771
1798
  debug: true
1772
1799
  });
1800
+ pendingMatchesRef.current = matches;
1773
1801
  const previousMatches = state.matches;
1774
1802
 
1775
1803
  // Ingest the new matches
@@ -1795,9 +1823,9 @@
1795
1823
  if (latestPromise = checkLatest(promise)) {
1796
1824
  return latestPromise;
1797
1825
  }
1798
- const exitingMatchIds = previousMatches.filter(id => !state.pendingMatches.includes(id));
1799
- const enteringMatchIds = state.pendingMatches.filter(id => !previousMatches.includes(id));
1800
- const stayingMatchIds = previousMatches.filter(id => state.pendingMatches.includes(id))
1826
+ const exitingMatchIds = previousMatches.filter(id => !pendingMatchesRef.current.includes(id));
1827
+ const enteringMatchIds = pendingMatchesRef.current.filter(id => !previousMatches.includes(id));
1828
+ const stayingMatchIds = previousMatches.filter(id => pendingMatchesRef.current.includes(id))
1801
1829
 
1802
1830
  // setState((s) => ({
1803
1831
  // ...s,
@@ -1977,9 +2005,7 @@
1977
2005
  unsub();
1978
2006
  };
1979
2007
  }, [history]);
1980
- const initialLoad = React__namespace.useRef(true);
1981
- if (initialLoad.current) {
1982
- initialLoad.current = false;
2008
+ React__namespace.useLayoutEffect(() => {
1983
2009
  startReactTransition(() => {
1984
2010
  try {
1985
2011
  load();
@@ -1987,7 +2013,7 @@
1987
2013
  console.error(err);
1988
2014
  }
1989
2015
  });
1990
- }
2016
+ }, []);
1991
2017
  const matchRoute = useStableCallback((location, opts) => {
1992
2018
  location = {
1993
2019
  ...location,
@@ -2083,6 +2109,9 @@
2083
2109
  }) : null));
2084
2110
  }
2085
2111
  const defaultPending = () => null;
2112
+ function SafeFragment(props) {
2113
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.children);
2114
+ }
2086
2115
  function Match({
2087
2116
  matches
2088
2117
  }) {
@@ -2096,9 +2125,7 @@
2096
2125
  const locationKey = useRouterState().location.state?.key;
2097
2126
  const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent ?? defaultPending;
2098
2127
  const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
2099
- const ResolvedSuspenseBoundary = route.options.wrapInSuspense ?? React__namespace.Suspense;
2100
- // const ResolvedSuspenseBoundary = SafeFragment
2101
-
2128
+ const ResolvedSuspenseBoundary = route.options.wrapInSuspense ? React__namespace.Suspense : SafeFragment;
2102
2129
  const errorComponent = React__namespace.useCallback(props => {
2103
2130
  return /*#__PURE__*/React__namespace.createElement(routeErrorComponent, {
2104
2131
  ...props,
@@ -2148,7 +2175,8 @@
2148
2175
  useMatch: route.useMatch,
2149
2176
  useRouteContext: route.useRouteContext,
2150
2177
  useSearch: route.useSearch,
2151
- useParams: route.useParams
2178
+ useParams: route.useParams,
2179
+ useLoaderData: route.useLoaderData
2152
2180
  });
2153
2181
  }
2154
2182
  return /*#__PURE__*/React__namespace.createElement(Outlet, null);
@@ -2219,6 +2247,13 @@
2219
2247
  }
2220
2248
  });
2221
2249
  }
2250
+ function useLoaderData(opts) {
2251
+ const match = useMatch({
2252
+ ...opts,
2253
+ select: undefined
2254
+ });
2255
+ return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
2256
+ }
2222
2257
 
2223
2258
  function useParams(opts) {
2224
2259
  return useRouterState({
@@ -2324,6 +2359,12 @@
2324
2359
  from: this.id
2325
2360
  });
2326
2361
  };
2362
+ useLoaderData = opts => {
2363
+ return useLoaderData({
2364
+ ...opts,
2365
+ from: this.id
2366
+ });
2367
+ };
2327
2368
  }
2328
2369
  function rootRouteWithContext() {
2329
2370
  return options => {
@@ -2760,6 +2801,7 @@
2760
2801
  exports.useBlocker = useBlocker;
2761
2802
  exports.useLayoutEffect = useLayoutEffect$1;
2762
2803
  exports.useLinkProps = useLinkProps;
2804
+ exports.useLoaderData = useLoaderData;
2763
2805
  exports.useMatch = useMatch;
2764
2806
  exports.useMatchRoute = useMatchRoute;
2765
2807
  exports.useMatches = useMatches;