@tanstack/react-router 0.0.1-beta.22 → 0.0.1-beta.221

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