@tanstack/router-core 0.0.1-beta.159 → 0.0.1-beta.160
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.
- package/build/cjs/route.js +0 -2
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +65 -48
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +65 -50
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +118 -118
- package/build/types/index.d.ts +13 -14
- package/build/umd/index.development.js +65 -50
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/route.ts +18 -38
- package/src/router.ts +87 -71
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-core",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "0.0.1-beta.
|
|
4
|
+
"version": "0.0.1-beta.160",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "tanstack/router",
|
|
7
7
|
"homepage": "https://tanstack.com/router",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"tiny-invariant": "^1.3.1",
|
|
44
44
|
"tiny-warning": "^1.0.3",
|
|
45
45
|
"@gisatcz/cross-package-react-context": "^0.2.0",
|
|
46
|
-
"@tanstack/react-store": "0.0.1-beta.
|
|
46
|
+
"@tanstack/react-store": "0.0.1-beta.160"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "rollup --config rollup.config.js",
|
package/src/route.ts
CHANGED
|
@@ -90,7 +90,7 @@ export type RouteLoaderFromRoute<TRoute extends AnyRoute> = LoaderFn<
|
|
|
90
90
|
>
|
|
91
91
|
|
|
92
92
|
export type RouteProps<
|
|
93
|
-
TLoader = unknown,
|
|
93
|
+
TLoader extends any = unknown,
|
|
94
94
|
TFullSearchSchema extends AnySearchSchema = AnySearchSchema,
|
|
95
95
|
TAllParams extends AnyPathParams = AnyPathParams,
|
|
96
96
|
TRouteContext extends AnyContext = AnyContext,
|
|
@@ -173,10 +173,6 @@ type Prefix<T extends string, U extends string> = U extends `${T}${infer _}`
|
|
|
173
173
|
? U
|
|
174
174
|
: never
|
|
175
175
|
|
|
176
|
-
type PrefixOrExact<T extends string, U extends string> = U extends T
|
|
177
|
-
? U
|
|
178
|
-
: Prefix<T, U>
|
|
179
|
-
|
|
180
176
|
export type BaseRouteOptions<
|
|
181
177
|
TParentRoute extends AnyRoute = AnyRoute,
|
|
182
178
|
TCustomId extends string = string,
|
|
@@ -185,7 +181,7 @@ export type BaseRouteOptions<
|
|
|
185
181
|
TParentSearchSchema extends AnySearchSchema = {},
|
|
186
182
|
TSearchSchema extends AnySearchSchema = {},
|
|
187
183
|
TFullSearchSchema extends AnySearchSchema = TSearchSchema,
|
|
188
|
-
TParams =
|
|
184
|
+
TParams extends AnyPathParams = {},
|
|
189
185
|
TAllParams = ParamsFallback<TPath, TParams>,
|
|
190
186
|
TParentContext extends AnyContext = AnyContext,
|
|
191
187
|
TAllParentContext extends AnyContext = AnyContext,
|
|
@@ -194,7 +190,7 @@ export type BaseRouteOptions<
|
|
|
194
190
|
> = RoutePathOptions<TCustomId, TPath> & {
|
|
195
191
|
layoutLimit?: string
|
|
196
192
|
getParentRoute: () => TParentRoute
|
|
197
|
-
validateSearch?: SearchSchemaValidator<TSearchSchema
|
|
193
|
+
validateSearch?: SearchSchemaValidator<TSearchSchema>
|
|
198
194
|
loader?: LoaderFn<
|
|
199
195
|
TLoader,
|
|
200
196
|
TSearchSchema,
|
|
@@ -203,7 +199,12 @@ export type BaseRouteOptions<
|
|
|
203
199
|
NoInfer<TRouteContext>,
|
|
204
200
|
TAllContext
|
|
205
201
|
>
|
|
206
|
-
} & (
|
|
202
|
+
} & ([TLoader] extends [never]
|
|
203
|
+
? {
|
|
204
|
+
loader: 'Loaders must return a type other than never. If you are throwing a redirect() and not returning anything, return a redirect() instead.'
|
|
205
|
+
}
|
|
206
|
+
: {}) &
|
|
207
|
+
(
|
|
207
208
|
| {
|
|
208
209
|
// Both or none
|
|
209
210
|
parseParams?: (
|
|
@@ -211,17 +212,6 @@ export type BaseRouteOptions<
|
|
|
211
212
|
) => TParams extends Record<ParsePathParams<TPath>, any>
|
|
212
213
|
? TParams
|
|
213
214
|
: 'parseParams must return an object'
|
|
214
|
-
// | {
|
|
215
|
-
// parse: (
|
|
216
|
-
// rawParams: IsAny<
|
|
217
|
-
// TPath,
|
|
218
|
-
// any,
|
|
219
|
-
// Record<ParsePathParams<TPath>, string>
|
|
220
|
-
// >,
|
|
221
|
-
// ) => TParams extends Record<ParsePathParams<TPath>, any>
|
|
222
|
-
// ? TParams
|
|
223
|
-
// : 'parseParams must return an object'
|
|
224
|
-
// }
|
|
225
215
|
stringifyParams?: (
|
|
226
216
|
params: NoInfer<ParamsFallback<TPath, TParams>>,
|
|
227
217
|
) => Record<ParsePathParams<TPath>, string>
|
|
@@ -364,7 +354,6 @@ export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
|
|
|
364
354
|
TPath,
|
|
365
355
|
TParams
|
|
366
356
|
>
|
|
367
|
-
// | ParseParamsObj<TPath, TParams>
|
|
368
357
|
|
|
369
358
|
export type ParseParamsFn<TPath extends string, TParams> = (
|
|
370
359
|
rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,
|
|
@@ -377,24 +366,17 @@ export type ParseParamsObj<TPath extends string, TParams> = {
|
|
|
377
366
|
}
|
|
378
367
|
|
|
379
368
|
// The parse type here allows a zod schema to be passed directly to the validator
|
|
380
|
-
export type SearchSchemaValidator<TReturn
|
|
381
|
-
| SearchSchemaValidatorObj<TReturn
|
|
382
|
-
| SearchSchemaValidatorFn<TReturn
|
|
369
|
+
export type SearchSchemaValidator<TReturn> =
|
|
370
|
+
| SearchSchemaValidatorObj<TReturn>
|
|
371
|
+
| SearchSchemaValidatorFn<TReturn>
|
|
383
372
|
|
|
384
|
-
export type SearchSchemaValidatorObj<TReturn
|
|
385
|
-
parse?: SearchSchemaValidatorFn<TReturn
|
|
373
|
+
export type SearchSchemaValidatorObj<TReturn> = {
|
|
374
|
+
parse?: SearchSchemaValidatorFn<TReturn>
|
|
386
375
|
}
|
|
387
376
|
|
|
388
|
-
export type SearchSchemaValidatorFn<TReturn
|
|
377
|
+
export type SearchSchemaValidatorFn<TReturn> = (
|
|
389
378
|
searchObj: Record<string, unknown>,
|
|
390
|
-
) =>
|
|
391
|
-
? TReturn
|
|
392
|
-
: keyof TReturn extends keyof TParentSchema
|
|
393
|
-
? {
|
|
394
|
-
error: 'Top level search params cannot be redefined by child routes!'
|
|
395
|
-
keys: keyof TReturn & keyof TParentSchema
|
|
396
|
-
}
|
|
397
|
-
: TReturn
|
|
379
|
+
) => TReturn
|
|
398
380
|
|
|
399
381
|
export type DefinedPathParamWarning =
|
|
400
382
|
'Path params cannot be redefined by child routes!'
|
|
@@ -805,10 +787,8 @@ export class RouterContext<TRouterContext extends {}> {
|
|
|
805
787
|
| 'parseParams'
|
|
806
788
|
| 'stringifyParams'
|
|
807
789
|
>,
|
|
808
|
-
) => {
|
|
809
|
-
return new RootRoute
|
|
810
|
-
options as any,
|
|
811
|
-
)
|
|
790
|
+
): RootRoute<TLoader, TSearchSchema, TRouteContext, TRouterContext> => {
|
|
791
|
+
return new RootRoute(options) as any
|
|
812
792
|
}
|
|
813
793
|
}
|
|
814
794
|
|
package/src/router.ts
CHANGED
|
@@ -107,8 +107,8 @@ export type HydrationCtx = {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
export interface RouteMatch<
|
|
110
|
-
TRouteTree extends AnyRoute =
|
|
111
|
-
TRoute extends AnyRoute =
|
|
110
|
+
TRouteTree extends AnyRoute = AnyRoute,
|
|
111
|
+
TRoute extends AnyRoute = AnyRoute,
|
|
112
112
|
> {
|
|
113
113
|
id: string
|
|
114
114
|
key?: string
|
|
@@ -182,7 +182,7 @@ export interface RouterOptions<
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
export interface RouterState<
|
|
185
|
-
TRouteTree extends AnyRoute =
|
|
185
|
+
TRouteTree extends AnyRoute = AnyRoute,
|
|
186
186
|
// TState extends LocationState = LocationState,
|
|
187
187
|
> {
|
|
188
188
|
status: 'idle' | 'pending'
|
|
@@ -250,7 +250,7 @@ export const componentTypes = [
|
|
|
250
250
|
] as const
|
|
251
251
|
|
|
252
252
|
export class Router<
|
|
253
|
-
TRouteTree extends AnyRoute =
|
|
253
|
+
TRouteTree extends AnyRoute = AnyRoute,
|
|
254
254
|
TDehydrated extends Record<string, any> = Record<string, any>,
|
|
255
255
|
> {
|
|
256
256
|
types!: {
|
|
@@ -290,40 +290,43 @@ export class Router<
|
|
|
290
290
|
onUpdate: () => {
|
|
291
291
|
const prev = this.state
|
|
292
292
|
|
|
293
|
-
|
|
293
|
+
const next = this.__store.state
|
|
294
|
+
|
|
295
|
+
console.log(
|
|
296
|
+
Object.values(next.matchesById).find((d) => d.status === 'error'),
|
|
297
|
+
)
|
|
294
298
|
|
|
295
|
-
const matchesByIdChanged = prev.matchesById !==
|
|
299
|
+
const matchesByIdChanged = prev.matchesById !== next.matchesById
|
|
296
300
|
let matchesChanged
|
|
297
301
|
let pendingMatchesChanged
|
|
298
302
|
|
|
299
303
|
if (!matchesByIdChanged) {
|
|
300
304
|
matchesChanged =
|
|
301
|
-
prev.matchIds.length !==
|
|
302
|
-
prev.matchIds.some((d, i) => d !==
|
|
305
|
+
prev.matchIds.length !== next.matchIds.length ||
|
|
306
|
+
prev.matchIds.some((d, i) => d !== next.matchIds[i])
|
|
303
307
|
|
|
304
308
|
pendingMatchesChanged =
|
|
305
|
-
prev.pendingMatchIds.length !==
|
|
306
|
-
prev.pendingMatchIds.some(
|
|
307
|
-
(d, i) => d !== this.state.pendingMatchIds[i],
|
|
308
|
-
)
|
|
309
|
+
prev.pendingMatchIds.length !== next.pendingMatchIds.length ||
|
|
310
|
+
prev.pendingMatchIds.some((d, i) => d !== next.pendingMatchIds[i])
|
|
309
311
|
}
|
|
310
312
|
|
|
311
313
|
if (matchesByIdChanged || matchesChanged) {
|
|
312
|
-
|
|
313
|
-
return
|
|
314
|
+
next.matches = next.matchIds.map((id) => {
|
|
315
|
+
return next.matchesById[id] as any
|
|
314
316
|
})
|
|
315
317
|
}
|
|
316
318
|
|
|
317
319
|
if (matchesByIdChanged || pendingMatchesChanged) {
|
|
318
|
-
|
|
319
|
-
return
|
|
320
|
+
next.pendingMatches = next.pendingMatchIds.map((id) => {
|
|
321
|
+
return next.matchesById[id] as any
|
|
320
322
|
})
|
|
321
323
|
}
|
|
322
324
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
325
|
+
next.isFetching = [...next.matches, ...next.pendingMatches].some(
|
|
326
|
+
(d) => d.isFetching,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
this.state = next
|
|
327
330
|
},
|
|
328
331
|
defaultPriority: 'low',
|
|
329
332
|
})
|
|
@@ -424,11 +427,12 @@ export class Router<
|
|
|
424
427
|
this.getRouteMatch(id)?.abortController?.abort()
|
|
425
428
|
}
|
|
426
429
|
|
|
427
|
-
safeLoad = (opts?: { next?: ParsedLocation }) => {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
430
|
+
safeLoad = async (opts?: { next?: ParsedLocation }) => {
|
|
431
|
+
try {
|
|
432
|
+
return this.load(opts)
|
|
433
|
+
} catch (err) {
|
|
434
|
+
// Don't do anything
|
|
435
|
+
}
|
|
432
436
|
}
|
|
433
437
|
|
|
434
438
|
latestLoadPromise: Promise<void> = Promise.resolve()
|
|
@@ -477,11 +481,16 @@ export class Router<
|
|
|
477
481
|
|
|
478
482
|
try {
|
|
479
483
|
// Load the matches
|
|
480
|
-
|
|
484
|
+
try {
|
|
485
|
+
await this.loadMatches(pendingMatches)
|
|
486
|
+
} catch (err) {
|
|
487
|
+
// swallow this error, since we'll display the
|
|
488
|
+
// errors on the route components
|
|
489
|
+
}
|
|
481
490
|
|
|
482
491
|
// Only apply the latest transition
|
|
483
492
|
if ((latestPromise = checkLatest())) {
|
|
484
|
-
return
|
|
493
|
+
return latestPromise
|
|
485
494
|
}
|
|
486
495
|
|
|
487
496
|
const prevLocation = this.state.resolvedLocation
|
|
@@ -502,7 +511,7 @@ export class Router<
|
|
|
502
511
|
} catch (err) {
|
|
503
512
|
// Only apply the latest transition
|
|
504
513
|
if ((latestPromise = checkLatest())) {
|
|
505
|
-
return
|
|
514
|
+
return latestPromise
|
|
506
515
|
}
|
|
507
516
|
|
|
508
517
|
reject(err)
|
|
@@ -519,7 +528,7 @@ export class Router<
|
|
|
519
528
|
string,
|
|
520
529
|
RouteMatch<TRouteTree, ParseRoute<TRouteTree>>
|
|
521
530
|
>,
|
|
522
|
-
nextMatches:
|
|
531
|
+
nextMatches: AnyRouteMatch[],
|
|
523
532
|
): Record<string, RouteMatch<TRouteTree, ParseRoute<TRouteTree>>> => {
|
|
524
533
|
const nextMatchesById: any = {
|
|
525
534
|
...prevMatchesById,
|
|
@@ -697,7 +706,7 @@ export class Router<
|
|
|
697
706
|
componentTypes.some((d) => (route.options[d] as any)?.preload)
|
|
698
707
|
)
|
|
699
708
|
|
|
700
|
-
const routeMatch:
|
|
709
|
+
const routeMatch: AnyRouteMatch = {
|
|
701
710
|
id: matchId,
|
|
702
711
|
key: stringifiedKey,
|
|
703
712
|
routeId: route.id,
|
|
@@ -860,6 +869,7 @@ export class Router<
|
|
|
860
869
|
}
|
|
861
870
|
}
|
|
862
871
|
|
|
872
|
+
console.log('set error')
|
|
863
873
|
this.setRouteMatch(match.id, (s) => ({
|
|
864
874
|
...s,
|
|
865
875
|
error: err,
|
|
@@ -926,25 +936,9 @@ export class Router<
|
|
|
926
936
|
: undefined
|
|
927
937
|
}
|
|
928
938
|
|
|
929
|
-
const
|
|
939
|
+
const load = async () => {
|
|
930
940
|
let latestPromise
|
|
931
941
|
|
|
932
|
-
const componentsPromise = Promise.all(
|
|
933
|
-
componentTypes.map(async (type) => {
|
|
934
|
-
const component = route.options[type]
|
|
935
|
-
|
|
936
|
-
if ((component as any)?.preload) {
|
|
937
|
-
await (component as any).preload()
|
|
938
|
-
}
|
|
939
|
-
}),
|
|
940
|
-
)
|
|
941
|
-
|
|
942
|
-
const loaderPromise = route.options.loader?.({
|
|
943
|
-
...match,
|
|
944
|
-
preload: !!opts?.preload,
|
|
945
|
-
parentMatchPromise,
|
|
946
|
-
})
|
|
947
|
-
|
|
948
942
|
const handleError = (err: any) => {
|
|
949
943
|
if (isRedirect(err)) {
|
|
950
944
|
if (!opts?.preload) {
|
|
@@ -957,6 +951,22 @@ export class Router<
|
|
|
957
951
|
}
|
|
958
952
|
|
|
959
953
|
try {
|
|
954
|
+
const componentsPromise = Promise.all(
|
|
955
|
+
componentTypes.map(async (type) => {
|
|
956
|
+
const component = route.options[type]
|
|
957
|
+
|
|
958
|
+
if ((component as any)?.preload) {
|
|
959
|
+
await (component as any).preload()
|
|
960
|
+
}
|
|
961
|
+
}),
|
|
962
|
+
)
|
|
963
|
+
|
|
964
|
+
const loaderPromise = route.options.loader?.({
|
|
965
|
+
...match,
|
|
966
|
+
preload: !!opts?.preload,
|
|
967
|
+
parentMatchPromise,
|
|
968
|
+
})
|
|
969
|
+
|
|
960
970
|
const [_, loader] = await Promise.all([
|
|
961
971
|
componentsPromise,
|
|
962
972
|
loaderPromise,
|
|
@@ -964,37 +974,36 @@ export class Router<
|
|
|
964
974
|
if ((latestPromise = checkLatest())) return await latestPromise
|
|
965
975
|
|
|
966
976
|
this.setRouteMatchData(match.id, () => loader, opts)
|
|
967
|
-
} catch (
|
|
977
|
+
} catch (loaderError) {
|
|
968
978
|
if ((latestPromise = checkLatest())) return await latestPromise
|
|
979
|
+
handleError(loaderError)
|
|
969
980
|
|
|
970
|
-
|
|
971
|
-
return
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
const errorHandler =
|
|
975
|
-
route.options.onLoadError ?? route.options.onError
|
|
976
|
-
|
|
977
|
-
let caughtError = err
|
|
981
|
+
let error = loaderError
|
|
978
982
|
|
|
979
983
|
try {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
if (handleError(errorHandlerErr)) {
|
|
985
|
-
return
|
|
984
|
+
if (route.options.onLoadError) {
|
|
985
|
+
route.options.onLoadError?.(loaderError)
|
|
986
|
+
} else {
|
|
987
|
+
route.options.onError?.(loaderError)
|
|
986
988
|
}
|
|
989
|
+
} catch (errorHandlerErr) {
|
|
990
|
+
error = errorHandlerErr
|
|
991
|
+
handleError(error)
|
|
987
992
|
}
|
|
988
993
|
|
|
994
|
+
console.log('set error')
|
|
989
995
|
this.setRouteMatch(match.id, (s) => ({
|
|
990
996
|
...s,
|
|
991
|
-
error:
|
|
997
|
+
error: error,
|
|
992
998
|
status: 'error',
|
|
993
999
|
isFetching: false,
|
|
994
1000
|
updatedAt: Date.now(),
|
|
995
1001
|
}))
|
|
1002
|
+
console.log(this.getRouteMatch(match.id)?.status)
|
|
996
1003
|
}
|
|
997
|
-
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const loadPromise = load()
|
|
998
1007
|
|
|
999
1008
|
this.setRouteMatch(match.id, (s) => ({
|
|
1000
1009
|
...s,
|
|
@@ -1602,13 +1611,19 @@ export class Router<
|
|
|
1602
1611
|
prev: RouteMatch<TRouteTree, AnyRoute>,
|
|
1603
1612
|
) => RouteMatch<TRouteTree, AnyRoute>,
|
|
1604
1613
|
) => {
|
|
1605
|
-
this.__store.setState((prev) =>
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1614
|
+
this.__store.setState((prev) => {
|
|
1615
|
+
if (!prev.matchesById[id]) {
|
|
1616
|
+
console.warn(`No match found with id: ${id}`)
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
return {
|
|
1620
|
+
...prev,
|
|
1621
|
+
matchesById: {
|
|
1622
|
+
...prev.matchesById,
|
|
1623
|
+
[id]: updater(prev.matchesById[id] as any),
|
|
1624
|
+
},
|
|
1625
|
+
}
|
|
1626
|
+
})
|
|
1612
1627
|
}
|
|
1613
1628
|
|
|
1614
1629
|
setRouteMatchData = (
|
|
@@ -1640,6 +1655,7 @@ export class Router<
|
|
|
1640
1655
|
this.options.defaultMaxAge ??
|
|
1641
1656
|
Infinity)
|
|
1642
1657
|
|
|
1658
|
+
console.log('set success')
|
|
1643
1659
|
this.setRouteMatch(id, (s) => ({
|
|
1644
1660
|
...s,
|
|
1645
1661
|
error: undefined,
|