@tanstack/router-core 0.0.1-beta.177 → 0.0.1-beta.179
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.map +1 -1
- package/build/cjs/router.js +33 -45
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +33 -45
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +124 -124
- package/build/types/fileRoute.d.ts +0 -1
- package/build/types/route.d.ts +11 -10
- package/build/types/router.d.ts +2 -1
- package/build/umd/index.development.js +33 -45
- 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 +1 -1
- package/src/route.ts +36 -48
- package/src/router.ts +42 -49
package/package.json
CHANGED
package/src/route.ts
CHANGED
|
@@ -254,7 +254,6 @@ export type BaseRouteOptions<
|
|
|
254
254
|
TRouteContext extends RouteContext = RouteContext,
|
|
255
255
|
TAllContext extends AnyContext = AnyContext,
|
|
256
256
|
> = RoutePathOptions<TCustomId, TPath> & {
|
|
257
|
-
layoutLimit?: string
|
|
258
257
|
getParentRoute: () => TParentRoute
|
|
259
258
|
validateSearch?: SearchSchemaValidator<TSearchSchema>
|
|
260
259
|
loader?: LoaderFn<
|
|
@@ -265,7 +264,34 @@ export type BaseRouteOptions<
|
|
|
265
264
|
NoInfer<TRouteContext>,
|
|
266
265
|
TAllContext
|
|
267
266
|
>
|
|
268
|
-
} & (
|
|
267
|
+
} & (keyof PickRequired<RouteContext> extends never
|
|
268
|
+
? // This async function is called before a route is loaded.
|
|
269
|
+
// If an error is thrown here, the route's loader will not be called.
|
|
270
|
+
// If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.
|
|
271
|
+
// If thrown during a preload event, the error will be logged to the console.
|
|
272
|
+
{
|
|
273
|
+
beforeLoad?: BeforeLoadFn<
|
|
274
|
+
TParentRoute,
|
|
275
|
+
TAllParams,
|
|
276
|
+
TSearchSchema,
|
|
277
|
+
TFullSearchSchema,
|
|
278
|
+
TParentContext,
|
|
279
|
+
TAllParentContext,
|
|
280
|
+
TRouteContext
|
|
281
|
+
>
|
|
282
|
+
}
|
|
283
|
+
: {
|
|
284
|
+
beforeLoad: BeforeLoadFn<
|
|
285
|
+
TParentRoute,
|
|
286
|
+
TAllParams,
|
|
287
|
+
TSearchSchema,
|
|
288
|
+
TFullSearchSchema,
|
|
289
|
+
TParentContext,
|
|
290
|
+
TAllParentContext,
|
|
291
|
+
TRouteContext
|
|
292
|
+
>
|
|
293
|
+
}) &
|
|
294
|
+
([TLoader] extends [never]
|
|
269
295
|
? {
|
|
270
296
|
loader: 'Loaders must return a type other than never. If you are throwing a redirect() and not returning anything, return a redirect() instead.'
|
|
271
297
|
}
|
|
@@ -286,32 +312,12 @@ export type BaseRouteOptions<
|
|
|
286
312
|
stringifyParams?: never
|
|
287
313
|
parseParams?: never
|
|
288
314
|
}
|
|
289
|
-
)
|
|
290
|
-
(keyof PickRequired<RouteContext> extends never
|
|
291
|
-
? {
|
|
292
|
-
getContext?: GetContextFn<
|
|
293
|
-
TParentRoute,
|
|
294
|
-
TAllParams,
|
|
295
|
-
TFullSearchSchema,
|
|
296
|
-
TParentContext,
|
|
297
|
-
TAllParentContext,
|
|
298
|
-
TRouteContext
|
|
299
|
-
>
|
|
300
|
-
}
|
|
301
|
-
: {
|
|
302
|
-
getContext: GetContextFn<
|
|
303
|
-
TParentRoute,
|
|
304
|
-
TAllParams,
|
|
305
|
-
TFullSearchSchema,
|
|
306
|
-
TParentContext,
|
|
307
|
-
TAllParentContext,
|
|
308
|
-
TRouteContext
|
|
309
|
-
>
|
|
310
|
-
})
|
|
315
|
+
)
|
|
311
316
|
|
|
312
|
-
type
|
|
317
|
+
type BeforeLoadFn<
|
|
313
318
|
TParentRoute,
|
|
314
319
|
TAllParams,
|
|
320
|
+
TSearchSchema,
|
|
315
321
|
TFullSearchSchema,
|
|
316
322
|
TParentContext,
|
|
317
323
|
TAllParentContext,
|
|
@@ -319,7 +325,10 @@ type GetContextFn<
|
|
|
319
325
|
> = (
|
|
320
326
|
opts: {
|
|
321
327
|
params: TAllParams
|
|
328
|
+
routeSearch: TSearchSchema
|
|
322
329
|
search: TFullSearchSchema
|
|
330
|
+
abortController: AbortController
|
|
331
|
+
preload: boolean
|
|
323
332
|
} & (TParentRoute extends undefined
|
|
324
333
|
? {
|
|
325
334
|
context?: TAllParentContext
|
|
@@ -329,7 +338,7 @@ type GetContextFn<
|
|
|
329
338
|
context: TAllParentContext
|
|
330
339
|
parentContext: TParentContext
|
|
331
340
|
}),
|
|
332
|
-
) => TRouteContext
|
|
341
|
+
) => Promise<TRouteContext> | TRouteContext | void
|
|
333
342
|
|
|
334
343
|
export type UpdatableRouteOptions<
|
|
335
344
|
TLoader,
|
|
@@ -378,19 +387,6 @@ export type UpdatableRouteOptions<
|
|
|
378
387
|
maxAge?: number
|
|
379
388
|
// If set, a match of this route that becomes inactive (or unused) will be garbage collected after this many milliseconds
|
|
380
389
|
gcMaxAge?: number
|
|
381
|
-
// This async function is called before a route is loaded.
|
|
382
|
-
// If an error is thrown here, the route's loader will not be called.
|
|
383
|
-
// If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.
|
|
384
|
-
// If thrown during a preload event, the error will be logged to the console.
|
|
385
|
-
beforeLoad?: (
|
|
386
|
-
opts: LoaderContext<
|
|
387
|
-
TSearchSchema,
|
|
388
|
-
TFullSearchSchema,
|
|
389
|
-
TAllParams,
|
|
390
|
-
NoInfer<TRouteContext>,
|
|
391
|
-
TAllContext
|
|
392
|
-
>,
|
|
393
|
-
) => Promise<void> | void
|
|
394
390
|
onError?: (err: any) => void
|
|
395
391
|
// These functions are called as route matches are loaded, stick around and leave the active
|
|
396
392
|
// matches
|
|
@@ -641,15 +637,7 @@ export class Route<
|
|
|
641
637
|
TAllParentContext,
|
|
642
638
|
TRouteContext,
|
|
643
639
|
TAllContext
|
|
644
|
-
>
|
|
645
|
-
UpdatableRouteOptions<
|
|
646
|
-
TLoader,
|
|
647
|
-
TSearchSchema,
|
|
648
|
-
TFullSearchSchema,
|
|
649
|
-
TAllParams,
|
|
650
|
-
TRouteContext,
|
|
651
|
-
TAllContext
|
|
652
|
-
>
|
|
640
|
+
>
|
|
653
641
|
|
|
654
642
|
// Set up in this.init()
|
|
655
643
|
parentRoute!: TParentRoute
|
package/src/router.ts
CHANGED
|
@@ -243,6 +243,7 @@ type LinkCurrentTargetElement = {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export interface DehydratedRouterState {
|
|
246
|
+
matchIds: string[]
|
|
246
247
|
dehydratedMatches: DehydratedRouteMatch[]
|
|
247
248
|
}
|
|
248
249
|
|
|
@@ -298,6 +299,7 @@ export type RouterListener<TRouterEvent extends RouterEvent> = {
|
|
|
298
299
|
|
|
299
300
|
const visibilityChangeEvent = 'visibilitychange'
|
|
300
301
|
const focusEvent = 'focus'
|
|
302
|
+
const preloadWarning = 'Error preloading route! ☝️'
|
|
301
303
|
|
|
302
304
|
export class Router<
|
|
303
305
|
TRouteTree extends AnyRoute = AnyRoute,
|
|
@@ -914,52 +916,24 @@ export class Router<
|
|
|
914
916
|
}
|
|
915
917
|
})()
|
|
916
918
|
|
|
917
|
-
Object.assign(match,
|
|
918
|
-
...searchInfo,
|
|
919
|
-
})
|
|
920
|
-
|
|
921
|
-
const contextInfo = (() => {
|
|
922
|
-
try {
|
|
923
|
-
const routeContext =
|
|
924
|
-
route.options.getContext?.({
|
|
925
|
-
parentContext: parentMatch?.routeContext ?? {},
|
|
926
|
-
context: parentMatch?.context ?? this?.options.context ?? {},
|
|
927
|
-
params: match.params,
|
|
928
|
-
search: match.search,
|
|
929
|
-
}) || ({} as any)
|
|
930
|
-
|
|
931
|
-
const context = {
|
|
932
|
-
...(parentMatch?.context ?? this?.options.context),
|
|
933
|
-
...routeContext,
|
|
934
|
-
} as any
|
|
935
|
-
|
|
936
|
-
return {
|
|
937
|
-
context,
|
|
938
|
-
routeContext,
|
|
939
|
-
}
|
|
940
|
-
} catch (err) {
|
|
941
|
-
route.options.onError?.(err)
|
|
942
|
-
throw err
|
|
943
|
-
}
|
|
944
|
-
})()
|
|
945
|
-
|
|
946
|
-
Object.assign(match, {
|
|
947
|
-
...contextInfo,
|
|
948
|
-
})
|
|
919
|
+
Object.assign(match, searchInfo)
|
|
949
920
|
})
|
|
950
921
|
|
|
951
922
|
return matches as any
|
|
952
923
|
}
|
|
953
924
|
|
|
954
925
|
loadMatches = async (
|
|
955
|
-
|
|
926
|
+
_resolvedMatches: AnyRouteMatch[],
|
|
956
927
|
opts?: {
|
|
957
928
|
preload?: boolean
|
|
958
929
|
maxAge?: number
|
|
959
930
|
},
|
|
960
931
|
) => {
|
|
932
|
+
const getFreshMatches = () =>
|
|
933
|
+
_resolvedMatches.map((d) => this.getRouteMatch(d.id)!)
|
|
934
|
+
|
|
961
935
|
if (!opts?.preload) {
|
|
962
|
-
|
|
936
|
+
getFreshMatches().forEach((match) => {
|
|
963
937
|
// Update each match with its latest route data
|
|
964
938
|
this.setRouteMatch(match.id, (s) => ({
|
|
965
939
|
...s,
|
|
@@ -980,7 +954,8 @@ export class Router<
|
|
|
980
954
|
|
|
981
955
|
// Check each match middleware to see if the route can be accessed
|
|
982
956
|
try {
|
|
983
|
-
for (const [index, match] of
|
|
957
|
+
for (const [index, match] of getFreshMatches().entries()) {
|
|
958
|
+
const parentMatch = getFreshMatches()[index - 1]
|
|
984
959
|
const route = this.getRoute(match.routeId)
|
|
985
960
|
|
|
986
961
|
const handleError = (err: any, code: string) => {
|
|
@@ -1020,10 +995,24 @@ export class Router<
|
|
|
1020
995
|
let didError = false
|
|
1021
996
|
|
|
1022
997
|
try {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
998
|
+
const routeContext =
|
|
999
|
+
(await route.options.beforeLoad?.({
|
|
1000
|
+
...match,
|
|
1001
|
+
preload: !!opts?.preload,
|
|
1002
|
+
parentContext: parentMatch?.routeContext ?? {},
|
|
1003
|
+
context: parentMatch?.context ?? this?.options.context ?? {},
|
|
1004
|
+
})) ?? ({} as any)
|
|
1005
|
+
|
|
1006
|
+
const context = {
|
|
1007
|
+
...(parentMatch?.context ?? this?.options.context),
|
|
1008
|
+
...routeContext,
|
|
1009
|
+
} as any
|
|
1010
|
+
|
|
1011
|
+
this.setRouteMatch(match.id, (s) => ({
|
|
1012
|
+
...s,
|
|
1013
|
+
context,
|
|
1014
|
+
routeContext,
|
|
1015
|
+
}))
|
|
1027
1016
|
} catch (err) {
|
|
1028
1017
|
handleError(err, 'BEFORE_LOAD')
|
|
1029
1018
|
didError = true
|
|
@@ -1042,7 +1031,7 @@ export class Router<
|
|
|
1042
1031
|
throw err
|
|
1043
1032
|
}
|
|
1044
1033
|
|
|
1045
|
-
const validResolvedMatches =
|
|
1034
|
+
const validResolvedMatches = getFreshMatches().slice(0, firstBadMatchIndex)
|
|
1046
1035
|
const matchPromises: Promise<any>[] = []
|
|
1047
1036
|
|
|
1048
1037
|
validResolvedMatches.forEach((match, index) => {
|
|
@@ -1335,7 +1324,7 @@ export class Router<
|
|
|
1335
1324
|
if (preload) {
|
|
1336
1325
|
this.preloadRoute(nextOpts).catch((err) => {
|
|
1337
1326
|
console.warn(err)
|
|
1338
|
-
console.warn(
|
|
1327
|
+
console.warn(preloadWarning)
|
|
1339
1328
|
})
|
|
1340
1329
|
}
|
|
1341
1330
|
}
|
|
@@ -1343,7 +1332,7 @@ export class Router<
|
|
|
1343
1332
|
const handleTouchStart = (e: TouchEvent) => {
|
|
1344
1333
|
this.preloadRoute(nextOpts).catch((err) => {
|
|
1345
1334
|
console.warn(err)
|
|
1346
|
-
console.warn(
|
|
1335
|
+
console.warn(preloadWarning)
|
|
1347
1336
|
})
|
|
1348
1337
|
}
|
|
1349
1338
|
|
|
@@ -1359,7 +1348,7 @@ export class Router<
|
|
|
1359
1348
|
target.preloadTimeout = null
|
|
1360
1349
|
this.preloadRoute(nextOpts).catch((err) => {
|
|
1361
1350
|
console.warn(err)
|
|
1362
|
-
console.warn(
|
|
1351
|
+
console.warn(preloadWarning)
|
|
1363
1352
|
})
|
|
1364
1353
|
}, preloadDelay)
|
|
1365
1354
|
}
|
|
@@ -1390,6 +1379,7 @@ export class Router<
|
|
|
1390
1379
|
dehydrate = (): DehydratedRouter => {
|
|
1391
1380
|
return {
|
|
1392
1381
|
state: {
|
|
1382
|
+
matchIds: this.state.matchIds,
|
|
1393
1383
|
dehydratedMatches: this.state.matches.map((d) =>
|
|
1394
1384
|
pick(d, [
|
|
1395
1385
|
'fetchedAt',
|
|
@@ -1421,13 +1411,15 @@ export class Router<
|
|
|
1421
1411
|
const ctx = _ctx
|
|
1422
1412
|
this.dehydratedData = ctx.payload as any
|
|
1423
1413
|
this.options.hydrate?.(ctx.payload as any)
|
|
1424
|
-
const
|
|
1414
|
+
const dehydratedState = ctx.router.state
|
|
1425
1415
|
|
|
1426
1416
|
let matches = this.matchRoutes(
|
|
1427
1417
|
this.state.location.pathname,
|
|
1428
1418
|
this.state.location.search,
|
|
1429
1419
|
).map((match) => {
|
|
1430
|
-
const dehydratedMatch = dehydratedMatches.find(
|
|
1420
|
+
const dehydratedMatch = dehydratedState.dehydratedMatches.find(
|
|
1421
|
+
(d) => d.id === match.id,
|
|
1422
|
+
)
|
|
1431
1423
|
|
|
1432
1424
|
invariant(
|
|
1433
1425
|
dehydratedMatch,
|
|
@@ -1446,6 +1438,7 @@ export class Router<
|
|
|
1446
1438
|
this.__store.setState((s) => {
|
|
1447
1439
|
return {
|
|
1448
1440
|
...s,
|
|
1441
|
+
matchIds: dehydratedState.matchIds,
|
|
1449
1442
|
matches,
|
|
1450
1443
|
matchesById: this.#mergeMatches(s.matchesById, matches),
|
|
1451
1444
|
}
|
|
@@ -1469,10 +1462,10 @@ export class Router<
|
|
|
1469
1462
|
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(
|
|
1470
1463
|
strKey,
|
|
1471
1464
|
)}"] = ${JSON.stringify(data)}
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1465
|
+
;(() => {
|
|
1466
|
+
var el = document.getElementById('${id}')
|
|
1467
|
+
el.parentElement.removeChild(el)
|
|
1468
|
+
})()
|
|
1476
1469
|
</script>`
|
|
1477
1470
|
})
|
|
1478
1471
|
|