@tanstack/react-router 0.0.1-beta.25 → 0.0.1-beta.250

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