@tanstack/react-router 0.0.1-beta.21 → 0.0.1-beta.211

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