@tanstack/react-router 0.0.1-beta.27 → 0.0.1-beta.271

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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/build/cjs/CatchBoundary.js +128 -0
  3. package/build/cjs/CatchBoundary.js.map +1 -0
  4. package/build/cjs/Matches.js +220 -0
  5. package/build/cjs/Matches.js.map +1 -0
  6. package/build/cjs/RouterProvider.js +165 -0
  7. package/build/cjs/RouterProvider.js.map +1 -0
  8. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +2 -22
  9. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  10. package/build/cjs/awaited.js +43 -0
  11. package/build/cjs/awaited.js.map +1 -0
  12. package/build/cjs/defer.js +37 -0
  13. package/build/cjs/defer.js.map +1 -0
  14. package/build/cjs/fileRoute.js +27 -0
  15. package/build/cjs/fileRoute.js.map +1 -0
  16. package/build/cjs/index.js +126 -0
  17. package/build/cjs/index.js.map +1 -0
  18. package/build/cjs/lazyRouteComponent.js +54 -0
  19. package/build/cjs/lazyRouteComponent.js.map +1 -0
  20. package/build/cjs/link.js +223 -0
  21. package/build/cjs/link.js.map +1 -0
  22. package/build/cjs/path.js +214 -0
  23. package/build/cjs/path.js.map +1 -0
  24. package/build/cjs/qss.js +63 -0
  25. package/build/cjs/qss.js.map +1 -0
  26. package/build/cjs/redirects.js +28 -0
  27. package/build/cjs/redirects.js.map +1 -0
  28. package/build/cjs/route.js +179 -0
  29. package/build/cjs/route.js.map +1 -0
  30. package/build/cjs/router.js +1032 -0
  31. package/build/cjs/router.js.map +1 -0
  32. package/build/cjs/scroll-restoration.js +202 -0
  33. package/build/cjs/scroll-restoration.js.map +1 -0
  34. package/build/cjs/searchParams.js +81 -0
  35. package/build/cjs/searchParams.js.map +1 -0
  36. package/build/cjs/useBlocker.js +55 -0
  37. package/build/cjs/useBlocker.js.map +1 -0
  38. package/build/cjs/useNavigate.js +86 -0
  39. package/build/cjs/useNavigate.js.map +1 -0
  40. package/build/cjs/useParams.js +26 -0
  41. package/build/cjs/useParams.js.map +1 -0
  42. package/build/cjs/useSearch.js +25 -0
  43. package/build/cjs/useSearch.js.map +1 -0
  44. package/build/cjs/utils.js +239 -0
  45. package/build/cjs/utils.js.map +1 -0
  46. package/build/esm/index.js +2214 -2576
  47. package/build/esm/index.js.map +1 -1
  48. package/build/stats-html.html +3498 -2694
  49. package/build/stats-react.json +1204 -44
  50. package/build/types/CatchBoundary.d.ts +36 -0
  51. package/build/types/Matches.d.ts +59 -0
  52. package/build/types/RouterProvider.d.ts +35 -0
  53. package/build/types/awaited.d.ts +9 -0
  54. package/build/types/defer.d.ts +19 -0
  55. package/build/types/fileRoute.d.ts +34 -0
  56. package/build/types/history.d.ts +7 -0
  57. package/build/types/index.d.ts +27 -114
  58. package/build/types/lazyRouteComponent.d.ts +2 -0
  59. package/build/types/link.d.ts +91 -0
  60. package/build/types/location.d.ts +12 -0
  61. package/build/types/path.d.ts +17 -0
  62. package/build/types/qss.d.ts +2 -0
  63. package/build/types/redirects.d.ts +11 -0
  64. package/build/types/route.d.ts +273 -0
  65. package/build/types/routeInfo.d.ts +22 -0
  66. package/build/types/router.d.ts +180 -0
  67. package/build/types/scroll-restoration.d.ts +18 -0
  68. package/build/types/searchParams.d.ts +7 -0
  69. package/build/types/useBlocker.d.ts +9 -0
  70. package/build/types/useNavigate.d.ts +19 -0
  71. package/build/types/useParams.d.ts +7 -0
  72. package/build/types/useSearch.d.ts +7 -0
  73. package/build/types/utils.d.ts +66 -0
  74. package/build/umd/index.development.js +2815 -2551
  75. package/build/umd/index.development.js.map +1 -1
  76. package/build/umd/index.production.js +4 -4
  77. package/build/umd/index.production.js.map +1 -1
  78. package/package.json +11 -10
  79. package/src/CatchBoundary.tsx +101 -0
  80. package/src/Matches.tsx +394 -0
  81. package/src/RouterProvider.tsx +237 -0
  82. package/src/awaited.tsx +40 -0
  83. package/src/defer.ts +55 -0
  84. package/src/fileRoute.ts +149 -0
  85. package/src/history.ts +8 -0
  86. package/src/index.tsx +28 -761
  87. package/src/lazyRouteComponent.tsx +33 -0
  88. package/src/link.tsx +598 -0
  89. package/src/location.ts +13 -0
  90. package/src/path.ts +261 -0
  91. package/src/qss.ts +53 -0
  92. package/src/redirects.ts +39 -0
  93. package/src/route.ts +854 -0
  94. package/src/routeInfo.ts +68 -0
  95. package/src/router.ts +1592 -0
  96. package/src/scroll-restoration.tsx +230 -0
  97. package/src/searchParams.ts +79 -0
  98. package/src/useBlocker.tsx +27 -0
  99. package/src/useNavigate.tsx +111 -0
  100. package/src/useParams.tsx +25 -0
  101. package/src/useSearch.tsx +25 -0
  102. package/src/utils.ts +350 -0
  103. package/build/cjs/react-router/src/index.js +0 -507
  104. package/build/cjs/react-router/src/index.js.map +0 -1
  105. package/build/cjs/router-core/build/esm/index.js +0 -2530
  106. package/build/cjs/router-core/build/esm/index.js.map +0 -1
package/src/route.ts ADDED
@@ -0,0 +1,854 @@
1
+ import * as React from 'react'
2
+ import invariant from 'tiny-invariant'
3
+ import { useLoaderData, useMatch } from './Matches'
4
+ import { AnyRouteMatch } from './Matches'
5
+ import { NavigateOptions, ParsePathParams, ToSubOptions } from './link'
6
+ import { ParsedLocation } from './location'
7
+ import { joinPaths, trimPath } from './path'
8
+ import { RouteById, RouteIds, RoutePaths } from './routeInfo'
9
+ import { AnyRouter, RegisteredRouter } from './router'
10
+ import { useParams } from './useParams'
11
+ import { useSearch } from './useSearch'
12
+ import {
13
+ Assign,
14
+ Expand,
15
+ IsAny,
16
+ NoInfer,
17
+ PickRequired,
18
+ UnionToIntersection,
19
+ } from './utils'
20
+ import { BuildLocationFn, NavigateFn } from './RouterProvider'
21
+
22
+ export const rootRouteId = '__root__' as const
23
+ export type RootRouteId = typeof rootRouteId
24
+ export type AnyPathParams = {}
25
+
26
+ export type AnySearchSchema = {}
27
+
28
+ export type AnyContext = {}
29
+
30
+ export interface RouteContext {}
31
+
32
+ export interface RouteMeta {}
33
+
34
+ export type PreloadableObj = { preload?: () => Promise<void> }
35
+
36
+ export type RoutePathOptions<TCustomId, TPath> =
37
+ | {
38
+ path: TPath
39
+ }
40
+ | {
41
+ id: TCustomId
42
+ }
43
+
44
+ export type RoutePathOptionsIntersection<TCustomId, TPath> =
45
+ UnionToIntersection<RoutePathOptions<TCustomId, TPath>>
46
+
47
+ export type MetaOptions = keyof PickRequired<RouteMeta> extends never
48
+ ? {
49
+ meta?: RouteMeta
50
+ }
51
+ : {
52
+ meta: RouteMeta
53
+ }
54
+
55
+ export type RouteOptions<
56
+ TParentRoute extends AnyRoute = AnyRoute,
57
+ TCustomId extends string = string,
58
+ TPath extends string = string,
59
+ TSearchSchema extends Record<string, any> = {},
60
+ TFullSearchSchema extends Record<string, any> = TSearchSchema,
61
+ TParams extends AnyPathParams = AnyPathParams,
62
+ TAllParams extends AnyPathParams = TParams,
63
+ TRouteContext extends RouteContext = RouteContext,
64
+ TAllContext extends Record<string, any> = AnyContext,
65
+ TLoaderData extends any = unknown,
66
+ > = BaseRouteOptions<
67
+ TParentRoute,
68
+ TCustomId,
69
+ TPath,
70
+ TSearchSchema,
71
+ TFullSearchSchema,
72
+ TParams,
73
+ TAllParams,
74
+ TRouteContext,
75
+ TAllContext,
76
+ TLoaderData
77
+ > &
78
+ UpdatableRouteOptions<NoInfer<TFullSearchSchema>>
79
+
80
+ export type ParamsFallback<
81
+ TPath extends string,
82
+ TParams,
83
+ > = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams
84
+
85
+ type Prefix<T extends string, U extends string> = U extends `${T}${infer _}`
86
+ ? U
87
+ : never
88
+
89
+ export type BaseRouteOptions<
90
+ TParentRoute extends AnyRoute = AnyRoute,
91
+ TCustomId extends string = string,
92
+ TPath extends string = string,
93
+ TSearchSchema extends Record<string, any> = {},
94
+ TFullSearchSchema extends Record<string, any> = TSearchSchema,
95
+ TParams extends AnyPathParams = {},
96
+ TAllParams = ParamsFallback<TPath, TParams>,
97
+ TRouteContext extends RouteContext = RouteContext,
98
+ TAllContext extends Record<string, any> = AnyContext,
99
+ TLoaderData extends any = unknown,
100
+ > = RoutePathOptions<TCustomId, TPath> & {
101
+ getParentRoute: () => TParentRoute
102
+ validateSearch?: SearchSchemaValidator<TSearchSchema>
103
+ shouldReload?:
104
+ | boolean
105
+ | ((
106
+ match: LoaderFnContext<
107
+ TAllParams,
108
+ TFullSearchSchema,
109
+ TAllContext,
110
+ TRouteContext
111
+ >,
112
+ ) => any)
113
+ } & (keyof PickRequired<RouteContext> extends never
114
+ ? // This async function is called before a route is loaded.
115
+ // If an error is thrown here, the route's loader will not be called.
116
+ // If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.
117
+ // If thrown during a preload event, the error will be logged to the console.
118
+ {
119
+ beforeLoad?: BeforeLoadFn<
120
+ TFullSearchSchema,
121
+ TParentRoute,
122
+ TAllParams,
123
+ TRouteContext
124
+ >
125
+ }
126
+ : {
127
+ beforeLoad: BeforeLoadFn<
128
+ TFullSearchSchema,
129
+ TParentRoute,
130
+ TAllParams,
131
+ TRouteContext
132
+ >
133
+ }) & {
134
+ key?: (opts: { search: TFullSearchSchema; location: ParsedLocation }) => any
135
+ loader?: RouteLoaderFn<
136
+ TAllParams,
137
+ TFullSearchSchema,
138
+ NoInfer<TAllContext>,
139
+ NoInfer<TRouteContext>,
140
+ TLoaderData
141
+ >
142
+ } & (
143
+ | {
144
+ // Both or none
145
+ parseParams?: (
146
+ rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,
147
+ ) => TParams extends Record<ParsePathParams<TPath>, any>
148
+ ? TParams
149
+ : 'parseParams must return an object'
150
+ stringifyParams?: (
151
+ params: NoInfer<ParamsFallback<TPath, TParams>>,
152
+ ) => Record<ParsePathParams<TPath>, string>
153
+ }
154
+ | {
155
+ stringifyParams?: never
156
+ parseParams?: never
157
+ }
158
+ )
159
+
160
+ type BeforeLoadFn<
161
+ TFullSearchSchema extends Record<string, any>,
162
+ TParentRoute extends AnyRoute,
163
+ TAllParams,
164
+ TRouteContext,
165
+ > = (opts: {
166
+ search: TFullSearchSchema
167
+ abortController: AbortController
168
+ preload: boolean
169
+ params: TAllParams
170
+ context: TParentRoute['types']['allContext']
171
+ location: ParsedLocation
172
+ navigate: NavigateFn<AnyRoute>
173
+ buildLocation: BuildLocationFn<AnyRoute>
174
+ cause: 'enter' | 'stay'
175
+ }) => Promise<TRouteContext> | TRouteContext | void
176
+
177
+ export type UpdatableRouteOptions<
178
+ TFullSearchSchema extends Record<string, any>,
179
+ > = MetaOptions & {
180
+ // test?: (args: TAllContext) => void
181
+ // If true, this route will be matched as case-sensitive
182
+ caseSensitive?: boolean
183
+ // If true, this route will be forcefully wrapped in a suspense boundary
184
+ wrapInSuspense?: boolean
185
+ // The content to be rendered when the route is matched. If no component is provided, defaults to `<Outlet />`
186
+ component?: RouteComponent
187
+ errorComponent?: false | null | ErrorRouteComponent
188
+ pendingComponent?: RouteComponent
189
+ pendingMs?: number
190
+ pendingMinMs?: number
191
+ // Filter functions that can manipulate search params *before* they are passed to links and navigate
192
+ // calls that match this route.
193
+ preSearchFilters?: SearchFilter<TFullSearchSchema>[]
194
+ // Filter functions that can manipulate search params *after* they are passed to links and navigate
195
+ // calls that match this route.
196
+ postSearchFilters?: SearchFilter<TFullSearchSchema>[]
197
+ onError?: (err: any) => void
198
+ // These functions are called as route matches are loaded, stick around and leave the active
199
+ // matches
200
+ onEnter?: (match: AnyRouteMatch) => void
201
+ onStay?: (match: AnyRouteMatch) => void
202
+ onLeave?: (match: AnyRouteMatch) => void
203
+ }
204
+
205
+ export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
206
+ TPath,
207
+ TParams
208
+ >
209
+
210
+ export type ParseParamsFn<TPath extends string, TParams> = (
211
+ rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,
212
+ ) => TParams extends Record<ParsePathParams<TPath>, any>
213
+ ? TParams
214
+ : 'parseParams must return an object'
215
+
216
+ export type ParseParamsObj<TPath extends string, TParams> = {
217
+ parse?: ParseParamsFn<TPath, TParams>
218
+ }
219
+
220
+ // The parse type here allows a zod schema to be passed directly to the validator
221
+ export type SearchSchemaValidator<TReturn> =
222
+ | SearchSchemaValidatorObj<TReturn>
223
+ | SearchSchemaValidatorFn<TReturn>
224
+
225
+ export type SearchSchemaValidatorObj<TReturn> = {
226
+ parse?: SearchSchemaValidatorFn<TReturn>
227
+ }
228
+
229
+ export type SearchSchemaValidatorFn<TReturn> = (
230
+ searchObj: Record<string, unknown>,
231
+ ) => TReturn
232
+
233
+ export type DefinedPathParamWarning =
234
+ 'Path params cannot be redefined by child routes!'
235
+
236
+ export type ParentParams<TParentParams> = AnyPathParams extends TParentParams
237
+ ? {}
238
+ : {
239
+ [Key in keyof TParentParams]?: DefinedPathParamWarning
240
+ }
241
+
242
+ export type RouteLoaderFn<
243
+ TAllParams = {},
244
+ TFullSearchSchema extends Record<string, any> = {},
245
+ TAllContext extends Record<string, any> = AnyContext,
246
+ TRouteContext extends Record<string, any> = AnyContext,
247
+ TLoaderData extends any = unknown,
248
+ > = (
249
+ match: LoaderFnContext<
250
+ TAllParams,
251
+ TFullSearchSchema,
252
+ TAllContext,
253
+ TRouteContext
254
+ >,
255
+ ) => Promise<TLoaderData> | TLoaderData
256
+
257
+ export interface LoaderFnContext<
258
+ TAllParams = {},
259
+ TFullSearchSchema extends Record<string, any> = {},
260
+ TAllContext extends Record<string, any> = AnyContext,
261
+ TRouteContext extends Record<string, any> = AnyContext,
262
+ > {
263
+ abortController: AbortController
264
+ preload: boolean
265
+ params: TAllParams
266
+ search: TFullSearchSchema
267
+ context: Expand<Assign<TAllContext, TRouteContext>>
268
+ location: ParsedLocation<TFullSearchSchema>
269
+ navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>
270
+ parentMatchPromise?: Promise<void>
271
+ cause: 'enter' | 'stay'
272
+ }
273
+
274
+ export type SearchFilter<T, U = T> = (prev: T) => U
275
+
276
+ export type ResolveId<
277
+ TParentRoute,
278
+ TCustomId extends string,
279
+ TPath extends string,
280
+ > = TParentRoute extends { id: infer TParentId extends string }
281
+ ? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId>
282
+ : RootRouteId
283
+
284
+ export type InferFullSearchSchema<TRoute> = TRoute extends {
285
+ types: {
286
+ fullSearchSchema: infer TFullSearchSchema
287
+ }
288
+ }
289
+ ? TFullSearchSchema
290
+ : {}
291
+
292
+ export type ResolveFullSearchSchema<TParentRoute, TSearchSchema> = Expand<
293
+ Assign<InferFullSearchSchema<TParentRoute>, TSearchSchema>
294
+ >
295
+
296
+ export interface AnyRoute
297
+ extends Route<
298
+ any,
299
+ any,
300
+ any,
301
+ any,
302
+ any,
303
+ any,
304
+ any,
305
+ any,
306
+ any,
307
+ any,
308
+ any,
309
+ any,
310
+ any,
311
+ any
312
+ > {}
313
+
314
+ export type MergeFromFromParent<T, U> = IsAny<T, U, T & U>
315
+
316
+ export type ResolveAllParams<
317
+ TParentRoute extends AnyRoute,
318
+ TParams extends AnyPathParams,
319
+ > = Record<never, string> extends TParentRoute['types']['allParams']
320
+ ? TParams
321
+ : Expand<
322
+ UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}
323
+ >
324
+
325
+ export type RouteConstraints = {
326
+ TParentRoute: AnyRoute
327
+ TPath: string
328
+ TFullPath: string
329
+ TCustomId: string
330
+ TId: string
331
+ TSearchSchema: AnySearchSchema
332
+ TFullSearchSchema: AnySearchSchema
333
+ TParams: Record<string, any>
334
+ TAllParams: Record<string, any>
335
+ TParentContext: AnyContext
336
+ TRouteContext: RouteContext
337
+ TAllContext: AnyContext
338
+ TRouterContext: AnyContext
339
+ TChildren: unknown
340
+ TRouteTree: AnyRoute
341
+ }
342
+
343
+ export class RouteApi<
344
+ TId extends RouteIds<RegisteredRouter['routeTree']>,
345
+ TRoute extends AnyRoute = RouteById<RegisteredRouter['routeTree'], TId>,
346
+ TFullSearchSchema extends Record<
347
+ string,
348
+ any
349
+ > = TRoute['types']['fullSearchSchema'],
350
+ TAllParams extends AnyPathParams = TRoute['types']['allParams'],
351
+ TAllContext extends Record<string, any> = TRoute['types']['allContext'],
352
+ TLoaderData extends any = TRoute['types']['loaderData'],
353
+ > {
354
+ id: TId
355
+
356
+ constructor({ id }: { id: TId }) {
357
+ this.id = id as any
358
+ }
359
+
360
+ useMatch = <TSelected = TAllContext>(opts?: {
361
+ select?: (search: TAllContext) => TSelected
362
+ }): TSelected => {
363
+ return useMatch({ ...opts, from: this.id }) as any
364
+ }
365
+
366
+ useRouteContext = <TSelected = TAllContext>(opts?: {
367
+ select?: (search: TAllContext) => TSelected
368
+ }): TSelected => {
369
+ return useMatch({
370
+ ...opts,
371
+ from: this.id,
372
+ select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
373
+ } as any)
374
+ }
375
+
376
+ useSearch = <TSelected = TFullSearchSchema>(opts?: {
377
+ select?: (search: TFullSearchSchema) => TSelected
378
+ }): TSelected => {
379
+ return useSearch({ ...opts, from: this.id } as any)
380
+ }
381
+
382
+ useParams = <TSelected = TAllParams>(opts?: {
383
+ select?: (search: TAllParams) => TSelected
384
+ }): TSelected => {
385
+ return useParams({ ...opts, from: this.id } as any)
386
+ }
387
+
388
+ useLoaderData = <TSelected = TLoaderData>(opts?: {
389
+ select?: (search: TLoaderData) => TSelected
390
+ }): TSelected => {
391
+ return useLoaderData({ ...opts, from: this.id } as any) as any
392
+ }
393
+ }
394
+
395
+ export class Route<
396
+ TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
397
+ TPath extends RouteConstraints['TPath'] = '/',
398
+ TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
399
+ TParentRoute,
400
+ TPath
401
+ >,
402
+ TCustomId extends RouteConstraints['TCustomId'] = string,
403
+ TId extends RouteConstraints['TId'] = ResolveId<
404
+ TParentRoute,
405
+ TCustomId,
406
+ TPath
407
+ >,
408
+ TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
409
+ TFullSearchSchema extends
410
+ RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
411
+ TParentRoute,
412
+ TSearchSchema
413
+ >,
414
+ TParams extends RouteConstraints['TParams'] = Expand<
415
+ Record<ParsePathParams<TPath>, string>
416
+ >,
417
+ TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<
418
+ TParentRoute,
419
+ TParams
420
+ >,
421
+ TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
422
+ TAllContext extends Expand<
423
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
424
+ > = Expand<
425
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
426
+ >,
427
+ TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
428
+ TLoaderData extends any = unknown,
429
+ TChildren extends RouteConstraints['TChildren'] = unknown,
430
+ TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
431
+ > {
432
+ isRoot: TParentRoute extends Route<any> ? true : false
433
+ options: RouteOptions<
434
+ TParentRoute,
435
+ TCustomId,
436
+ TPath,
437
+ TSearchSchema,
438
+ TFullSearchSchema,
439
+ TParams,
440
+ TAllParams,
441
+ TRouteContext,
442
+ TAllContext,
443
+ TLoaderData
444
+ >
445
+
446
+ test!: Expand<
447
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
448
+ >
449
+
450
+ // Set up in this.init()
451
+ parentRoute!: TParentRoute
452
+ id!: TId
453
+ // customId!: TCustomId
454
+ path!: TPath
455
+ fullPath!: TFullPath
456
+ to!: TrimPathRight<TFullPath>
457
+
458
+ // Optional
459
+ children?: TChildren
460
+ originalIndex?: number
461
+ router?: AnyRouter
462
+ rank!: number
463
+
464
+ constructor(
465
+ options: RouteOptions<
466
+ TParentRoute,
467
+ TCustomId,
468
+ TPath,
469
+ TSearchSchema,
470
+ TFullSearchSchema,
471
+ TParams,
472
+ TAllParams,
473
+ TRouteContext,
474
+ TAllContext,
475
+ TLoaderData
476
+ >,
477
+ ) {
478
+ this.options = (options as any) || {}
479
+ this.isRoot = !options?.getParentRoute as any
480
+ invariant(
481
+ !((options as any)?.id && (options as any)?.path),
482
+ `Route cannot have both an 'id' and a 'path' option.`,
483
+ )
484
+ ;(this as any).$$typeof = Symbol.for('react.memo')
485
+ }
486
+
487
+ types!: {
488
+ parentRoute: TParentRoute
489
+ path: TPath
490
+ to: TrimPathRight<TFullPath>
491
+ fullPath: TFullPath
492
+ customId: TCustomId
493
+ id: TId
494
+ searchSchema: TSearchSchema
495
+ fullSearchSchema: TFullSearchSchema
496
+ params: TParams
497
+ allParams: TAllParams
498
+ routeContext: TRouteContext
499
+ allContext: TAllContext
500
+ children: TChildren
501
+ routeTree: TRouteTree
502
+ routerContext: TRouterContext
503
+ loaderData: TLoaderData
504
+ }
505
+
506
+ init = (opts: { originalIndex: number }) => {
507
+ this.originalIndex = opts.originalIndex
508
+
509
+ const options = this.options as RouteOptions<
510
+ TParentRoute,
511
+ TCustomId,
512
+ TPath,
513
+ TSearchSchema,
514
+ TFullSearchSchema,
515
+ TParams,
516
+ TAllParams,
517
+ TRouteContext,
518
+ TAllContext,
519
+ TLoaderData
520
+ > &
521
+ RoutePathOptionsIntersection<TCustomId, TPath>
522
+
523
+ const isRoot = !options?.path && !options?.id
524
+
525
+ this.parentRoute = this.options?.getParentRoute?.()
526
+
527
+ if (isRoot) {
528
+ this.path = rootRouteId as TPath
529
+ } else {
530
+ invariant(
531
+ this.parentRoute,
532
+ `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,
533
+ )
534
+ }
535
+
536
+ let path: undefined | string = isRoot ? rootRouteId : options.path
537
+
538
+ // If the path is anything other than an index path, trim it up
539
+ if (path && path !== '/') {
540
+ path = trimPath(path)
541
+ }
542
+
543
+ const customId = options?.id || path
544
+
545
+ // Strip the parentId prefix from the first level of children
546
+ let id = isRoot
547
+ ? rootRouteId
548
+ : joinPaths([
549
+ (this.parentRoute.id as any) === rootRouteId
550
+ ? ''
551
+ : this.parentRoute.id,
552
+ customId,
553
+ ])
554
+
555
+ if (path === rootRouteId) {
556
+ path = '/'
557
+ }
558
+
559
+ if (id !== rootRouteId) {
560
+ id = joinPaths(['/', id])
561
+ }
562
+
563
+ const fullPath =
564
+ id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path])
565
+
566
+ this.path = path as TPath
567
+ this.id = id as TId
568
+ // this.customId = customId as TCustomId
569
+ this.fullPath = fullPath as TFullPath
570
+ this.to = fullPath as TrimPathRight<TFullPath>
571
+ }
572
+
573
+ addChildren = <TNewChildren extends AnyRoute[]>(
574
+ children: TNewChildren,
575
+ ): Route<
576
+ TParentRoute,
577
+ TPath,
578
+ TFullPath,
579
+ TCustomId,
580
+ TId,
581
+ TSearchSchema,
582
+ TFullSearchSchema,
583
+ TParams,
584
+ TAllParams,
585
+ TRouteContext,
586
+ TAllContext,
587
+ TRouterContext,
588
+ TNewChildren,
589
+ TRouteTree
590
+ > => {
591
+ this.children = children as any
592
+ return this as any
593
+ }
594
+
595
+ update = (options: UpdatableRouteOptions<TFullSearchSchema>) => {
596
+ Object.assign(this.options, options)
597
+ return this
598
+ }
599
+
600
+ useMatch = <TSelected = TAllContext>(opts?: {
601
+ select?: (search: TAllContext) => TSelected
602
+ }): TSelected => {
603
+ return useMatch({ ...opts, from: this.id }) as any
604
+ }
605
+
606
+ useRouteContext = <TSelected = TAllContext>(opts?: {
607
+ select?: (search: TAllContext) => TSelected
608
+ }): TSelected => {
609
+ return useMatch({
610
+ ...opts,
611
+ from: this.id,
612
+ select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
613
+ } as any)
614
+ }
615
+
616
+ useSearch = <TSelected = TFullSearchSchema>(opts?: {
617
+ select?: (search: TFullSearchSchema) => TSelected
618
+ }): TSelected => {
619
+ return useSearch({ ...opts, from: this.id } as any)
620
+ }
621
+
622
+ useParams = <TSelected = TAllParams>(opts?: {
623
+ select?: (search: TAllParams) => TSelected
624
+ }): TSelected => {
625
+ return useParams({ ...opts, from: this.id } as any)
626
+ }
627
+
628
+ useLoaderData = <TSelected = TLoaderData>(opts?: {
629
+ select?: (search: TLoaderData) => TSelected
630
+ }): TSelected => {
631
+ return useLoaderData({ ...opts, from: this.id } as any) as any
632
+ }
633
+ }
634
+
635
+ export type AnyRootRoute = RootRoute<any, any, any>
636
+
637
+ export function rootRouteWithContext<TRouterContext extends {}>() {
638
+ return <
639
+ TSearchSchema extends Record<string, any> = {},
640
+ TRouteContext extends RouteContext = RouteContext,
641
+ TLoaderData extends any = unknown,
642
+ >(
643
+ options?: Omit<
644
+ RouteOptions<
645
+ AnyRoute, // TParentRoute
646
+ RootRouteId, // TCustomId
647
+ '', // TPath
648
+ TSearchSchema, // TSearchSchema
649
+ TSearchSchema, // TFullSearchSchema
650
+ {}, // TParams
651
+ {}, // TAllParams
652
+ TRouteContext, // TRouteContext
653
+ Assign<TRouterContext, TRouteContext>, // TAllContext
654
+ TLoaderData // TLoaderData
655
+ >,
656
+ | 'path'
657
+ | 'id'
658
+ | 'getParentRoute'
659
+ | 'caseSensitive'
660
+ | 'parseParams'
661
+ | 'stringifyParams'
662
+ >,
663
+ ): RootRoute<TSearchSchema, TRouteContext, TRouterContext> => {
664
+ return new RootRoute(options) as any
665
+ }
666
+ }
667
+
668
+ export class RootRoute<
669
+ TSearchSchema extends Record<string, any> = {},
670
+ TRouteContext extends RouteContext = RouteContext,
671
+ TRouterContext extends {} = {},
672
+ TLoaderData extends any = unknown,
673
+ > extends Route<
674
+ any, // TParentRoute
675
+ '/', // TPath
676
+ '/', // TFullPath
677
+ string, // TCustomId
678
+ RootRouteId, // TId
679
+ TSearchSchema, // TSearchSchema
680
+ TSearchSchema, // TFullSearchSchema
681
+ {}, // TParams
682
+ {}, // TAllParams
683
+ TRouteContext, // TRouteContext
684
+ Expand<Assign<TRouterContext, TRouteContext>>, // TAllContext
685
+ TRouterContext, // TRouterContext
686
+ TLoaderData,
687
+ any, // TChildren
688
+ any // TRouteTree
689
+ > {
690
+ constructor(
691
+ options?: Omit<
692
+ RouteOptions<
693
+ AnyRoute, // TParentRoute
694
+ RootRouteId, // TCustomId
695
+ '', // TPath
696
+ TSearchSchema, // TSearchSchema
697
+ TSearchSchema, // TFullSearchSchema
698
+ {}, // TParams
699
+ {}, // TAllParams
700
+ TRouteContext, // TRouteContext
701
+ Assign<TRouterContext, TRouteContext>, // TAllContext
702
+ TLoaderData
703
+ >,
704
+ | 'path'
705
+ | 'id'
706
+ | 'getParentRoute'
707
+ | 'caseSensitive'
708
+ | 'parseParams'
709
+ | 'stringifyParams'
710
+ >,
711
+ ) {
712
+ super(options as any)
713
+ }
714
+ }
715
+
716
+ export type ResolveFullPath<
717
+ TParentRoute extends AnyRoute,
718
+ TPath extends string,
719
+ TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>,
720
+ > = TPrefixed extends RootRouteId ? '/' : TPrefixed
721
+
722
+ type RoutePrefix<
723
+ TPrefix extends string,
724
+ TPath extends string,
725
+ > = string extends TPath
726
+ ? RootRouteId
727
+ : TPath extends string
728
+ ? TPrefix extends RootRouteId
729
+ ? TPath extends '/'
730
+ ? '/'
731
+ : `/${TrimPath<TPath>}`
732
+ : `${TPrefix}/${TPath}` extends '/'
733
+ ? '/'
734
+ : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}`
735
+ : never
736
+
737
+ export type TrimPath<T extends string> = '' extends T
738
+ ? ''
739
+ : TrimPathRight<TrimPathLeft<T>>
740
+
741
+ export type TrimPathLeft<T extends string> =
742
+ T extends `${RootRouteId}/${infer U}`
743
+ ? TrimPathLeft<U>
744
+ : T extends `/${infer U}`
745
+ ? TrimPathLeft<U>
746
+ : T
747
+ export type TrimPathRight<T extends string> = T extends '/'
748
+ ? '/'
749
+ : T extends `${infer U}/`
750
+ ? TrimPathRight<U>
751
+ : T
752
+
753
+ export type RouteMask<TRouteTree extends AnyRoute> = {
754
+ routeTree: TRouteTree
755
+ from: RoutePaths<TRouteTree>
756
+ to?: any
757
+ params?: any
758
+ search?: any
759
+ hash?: any
760
+ state?: any
761
+ unmaskOnReload?: boolean
762
+ }
763
+
764
+ export function createRouteMask<
765
+ TRouteTree extends AnyRoute,
766
+ TFrom extends RoutePaths<TRouteTree>,
767
+ TTo extends string,
768
+ >(
769
+ opts: {
770
+ routeTree: TRouteTree
771
+ } & ToSubOptions<TRouteTree, TFrom, TTo>,
772
+ ): RouteMask<TRouteTree> {
773
+ return opts as any
774
+ }
775
+
776
+ export type ErrorRouteProps = {
777
+ error: unknown
778
+ info: { componentStack: string }
779
+ }
780
+ //
781
+
782
+ export type ReactNode = any
783
+
784
+ export type SyncRouteComponent<TProps> =
785
+ | ((props: TProps) => ReactNode)
786
+ | React.LazyExoticComponent<(props: TProps) => ReactNode>
787
+
788
+ export type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {
789
+ preload?: () => Promise<void>
790
+ }
791
+
792
+ export type RouteComponent<TProps = any> = SyncRouteComponent<TProps> &
793
+ AsyncRouteComponent<TProps>
794
+
795
+ export type ErrorRouteComponent = RouteComponent<ErrorRouteProps>
796
+
797
+ export class NotFoundRoute<
798
+ TParentRoute extends AnyRootRoute,
799
+ TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
800
+ TFullSearchSchema extends
801
+ RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
802
+ TParentRoute,
803
+ TSearchSchema
804
+ >,
805
+ TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
806
+ TAllContext extends Expand<
807
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
808
+ > = Expand<
809
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
810
+ >,
811
+ TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
812
+ TLoaderData extends any = unknown,
813
+ TChildren extends RouteConstraints['TChildren'] = unknown,
814
+ TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
815
+ > extends Route<
816
+ TParentRoute,
817
+ '/404',
818
+ '/404',
819
+ '404',
820
+ '404',
821
+ TSearchSchema,
822
+ TFullSearchSchema,
823
+ {},
824
+ {},
825
+ TRouteContext,
826
+ TAllContext,
827
+ TRouterContext,
828
+ TLoaderData,
829
+ TChildren,
830
+ TRouteTree
831
+ > {
832
+ constructor(
833
+ options: Omit<
834
+ RouteOptions<
835
+ TParentRoute,
836
+ string,
837
+ string,
838
+ TSearchSchema,
839
+ TFullSearchSchema,
840
+ {},
841
+ {},
842
+ TRouteContext,
843
+ TAllContext,
844
+ TLoaderData
845
+ >,
846
+ 'caseSensitive' | 'parseParams' | 'stringifyParams' | 'path' | 'id'
847
+ >,
848
+ ) {
849
+ super({
850
+ ...(options as any),
851
+ id: '404',
852
+ })
853
+ }
854
+ }