@tanstack/react-router 1.63.5 → 1.64.1
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/dist/cjs/router.cjs +66 -45
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +10 -0
- package/dist/esm/router.d.ts +10 -0
- package/dist/esm/router.js +67 -46
- package/dist/esm/router.js.map +1 -1
- package/package.json +2 -2
- package/src/router.ts +86 -70
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.64.1",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"react": ">=18",
|
|
68
68
|
"react-dom": ">=18",
|
|
69
|
-
"@tanstack/router-generator": "1.
|
|
69
|
+
"@tanstack/router-generator": "1.64.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"@tanstack/router-generator": {
|
package/src/router.ts
CHANGED
|
@@ -495,6 +495,11 @@ export interface BuildNextOptions {
|
|
|
495
495
|
_fromLocation?: ParsedLocation
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
+
export interface MatchedRoutesResult {
|
|
499
|
+
matchedRoutes: Array<AnyRoute>
|
|
500
|
+
routeParams: Record<string, string>
|
|
501
|
+
}
|
|
502
|
+
|
|
498
503
|
export interface DehydratedRouterState {
|
|
499
504
|
dehydratedMatches: Array<DehydratedRouteMatch>
|
|
500
505
|
}
|
|
@@ -602,6 +607,7 @@ type MatchRoutesOpts = {
|
|
|
602
607
|
preload?: boolean
|
|
603
608
|
throwOnError?: boolean
|
|
604
609
|
_buildLocation?: boolean
|
|
610
|
+
dest?: BuildNextOptions
|
|
605
611
|
}
|
|
606
612
|
|
|
607
613
|
export class Router<
|
|
@@ -1013,33 +1019,10 @@ export class Router<
|
|
|
1013
1019
|
next: ParsedLocation,
|
|
1014
1020
|
opts?: MatchRoutesOpts,
|
|
1015
1021
|
): Array<AnyRouteMatch> {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
this.basepath,
|
|
1021
|
-
trimPathRight(next.pathname),
|
|
1022
|
-
{
|
|
1023
|
-
to: route.fullPath,
|
|
1024
|
-
caseSensitive:
|
|
1025
|
-
route.options.caseSensitive ?? this.options.caseSensitive,
|
|
1026
|
-
fuzzy: true,
|
|
1027
|
-
},
|
|
1028
|
-
)
|
|
1029
|
-
|
|
1030
|
-
if (matchedParams) {
|
|
1031
|
-
routeParams = matchedParams
|
|
1032
|
-
return true
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
return false
|
|
1036
|
-
})
|
|
1037
|
-
|
|
1038
|
-
let routeCursor: AnyRoute =
|
|
1039
|
-
foundRoute || (this.routesById as any)[rootRouteId]
|
|
1040
|
-
|
|
1041
|
-
const matchedRoutes: Array<AnyRoute> = [routeCursor]
|
|
1042
|
-
|
|
1022
|
+
const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
|
|
1023
|
+
next,
|
|
1024
|
+
opts?.dest,
|
|
1025
|
+
)
|
|
1043
1026
|
let isGlobalNotFound = false
|
|
1044
1027
|
|
|
1045
1028
|
// Check to see if the route needs a 404 entry
|
|
@@ -1059,11 +1042,6 @@ export class Router<
|
|
|
1059
1042
|
}
|
|
1060
1043
|
}
|
|
1061
1044
|
|
|
1062
|
-
while (routeCursor.parentRoute) {
|
|
1063
|
-
routeCursor = routeCursor.parentRoute
|
|
1064
|
-
matchedRoutes.unshift(routeCursor)
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
1045
|
const globalNotFoundRouteId = (() => {
|
|
1068
1046
|
if (!isGlobalNotFound) {
|
|
1069
1047
|
return undefined
|
|
@@ -1307,6 +1285,49 @@ export class Router<
|
|
|
1307
1285
|
return matches as any
|
|
1308
1286
|
}
|
|
1309
1287
|
|
|
1288
|
+
getMatchedRoutes = (next: ParsedLocation, dest?: BuildNextOptions) => {
|
|
1289
|
+
let routeParams: Record<string, string> = {}
|
|
1290
|
+
const trimmedPath = trimPathRight(next.pathname)
|
|
1291
|
+
const getMatchedParams = (route: AnyRoute) => {
|
|
1292
|
+
const result = matchPathname(this.basepath, trimmedPath, {
|
|
1293
|
+
to: route.fullPath,
|
|
1294
|
+
caseSensitive:
|
|
1295
|
+
route.options.caseSensitive ?? this.options.caseSensitive,
|
|
1296
|
+
fuzzy: true,
|
|
1297
|
+
})
|
|
1298
|
+
return result
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
let foundRoute: AnyRoute | undefined =
|
|
1302
|
+
dest?.to !== undefined ? this.routesByPath[dest.to!] : undefined
|
|
1303
|
+
if (foundRoute) {
|
|
1304
|
+
routeParams = getMatchedParams(foundRoute)!
|
|
1305
|
+
} else {
|
|
1306
|
+
foundRoute = this.flatRoutes.find((route) => {
|
|
1307
|
+
const matchedParams = getMatchedParams(route)
|
|
1308
|
+
|
|
1309
|
+
if (matchedParams) {
|
|
1310
|
+
routeParams = matchedParams
|
|
1311
|
+
return true
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
return false
|
|
1315
|
+
})
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
let routeCursor: AnyRoute =
|
|
1319
|
+
foundRoute || (this.routesById as any)[rootRouteId]
|
|
1320
|
+
|
|
1321
|
+
const matchedRoutes: Array<AnyRoute> = [routeCursor]
|
|
1322
|
+
|
|
1323
|
+
while (routeCursor.parentRoute) {
|
|
1324
|
+
routeCursor = routeCursor.parentRoute
|
|
1325
|
+
matchedRoutes.unshift(routeCursor)
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
return { matchedRoutes, routeParams, foundRoute }
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1310
1331
|
cancelMatch = (id: string) => {
|
|
1311
1332
|
const match = this.getMatch(id)
|
|
1312
1333
|
|
|
@@ -1327,7 +1348,7 @@ export class Router<
|
|
|
1327
1348
|
dest: BuildNextOptions & {
|
|
1328
1349
|
unmaskOnReload?: boolean
|
|
1329
1350
|
} = {},
|
|
1330
|
-
|
|
1351
|
+
matchedRoutesResult?: MatchedRoutesResult,
|
|
1331
1352
|
): ParsedLocation => {
|
|
1332
1353
|
const fromMatches = dest._fromLocation
|
|
1333
1354
|
? this.matchRoutes(dest._fromLocation, { _buildLocation: true })
|
|
@@ -1355,22 +1376,30 @@ export class Router<
|
|
|
1355
1376
|
? last(this.state.pendingMatches)?.search
|
|
1356
1377
|
: last(fromMatches)?.search || this.latestLocation.search
|
|
1357
1378
|
|
|
1358
|
-
const stayingMatches =
|
|
1359
|
-
fromMatches.find((e) => e.routeId === d.
|
|
1379
|
+
const stayingMatches = matchedRoutesResult?.matchedRoutes.filter((d) =>
|
|
1380
|
+
fromMatches.find((e) => e.routeId === d.id),
|
|
1360
1381
|
)
|
|
1361
1382
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1383
|
+
let pathname: string
|
|
1384
|
+
if (dest.to) {
|
|
1385
|
+
pathname = this.resolvePathWithBase(fromPath, `${dest.to}`)
|
|
1386
|
+
} else {
|
|
1387
|
+
const fromRouteByFromPathRouteId =
|
|
1388
|
+
this.routesById[
|
|
1389
|
+
stayingMatches?.find((route) => {
|
|
1390
|
+
const interpolatedPath = interpolatePath({
|
|
1391
|
+
path: route.fullPath,
|
|
1392
|
+
params: matchedRoutesResult?.routeParams ?? {},
|
|
1393
|
+
})
|
|
1394
|
+
const pathname = joinPaths([this.basepath, interpolatedPath])
|
|
1395
|
+
return pathname === fromPath
|
|
1396
|
+
})?.id as keyof this['routesById']
|
|
1397
|
+
]
|
|
1398
|
+
pathname = this.resolvePathWithBase(
|
|
1399
|
+
fromPath,
|
|
1400
|
+
fromRouteByFromPathRouteId?.to ?? fromPath,
|
|
1401
|
+
)
|
|
1402
|
+
}
|
|
1374
1403
|
|
|
1375
1404
|
const prevParams = { ...last(fromMatches)?.params }
|
|
1376
1405
|
|
|
@@ -1380,11 +1409,10 @@ export class Router<
|
|
|
1380
1409
|
: { ...prevParams, ...functionalUpdate(dest.params, prevParams) }
|
|
1381
1410
|
|
|
1382
1411
|
if (Object.keys(nextParams).length > 0) {
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
const route = this.looseRoutesById[d.routeId]
|
|
1412
|
+
matchedRoutesResult?.matchedRoutes
|
|
1413
|
+
.map((route) => {
|
|
1386
1414
|
return (
|
|
1387
|
-
route
|
|
1415
|
+
route.options.params?.stringify ?? route.options.stringifyParams
|
|
1388
1416
|
)
|
|
1389
1417
|
})
|
|
1390
1418
|
.filter(Boolean)
|
|
@@ -1402,21 +1430,13 @@ export class Router<
|
|
|
1402
1430
|
|
|
1403
1431
|
const preSearchFilters =
|
|
1404
1432
|
stayingMatches
|
|
1405
|
-
?.map(
|
|
1406
|
-
(match) =>
|
|
1407
|
-
this.looseRoutesById[match.routeId]!.options.preSearchFilters ??
|
|
1408
|
-
[],
|
|
1409
|
-
)
|
|
1433
|
+
?.map((route) => route.options.preSearchFilters ?? [])
|
|
1410
1434
|
.flat()
|
|
1411
1435
|
.filter(Boolean) ?? []
|
|
1412
1436
|
|
|
1413
1437
|
const postSearchFilters =
|
|
1414
1438
|
stayingMatches
|
|
1415
|
-
?.map(
|
|
1416
|
-
(match) =>
|
|
1417
|
-
this.looseRoutesById[match.routeId]!.options.postSearchFilters ??
|
|
1418
|
-
[],
|
|
1419
|
-
)
|
|
1439
|
+
?.map((route) => route.options.postSearchFilters ?? [])
|
|
1420
1440
|
.flat()
|
|
1421
1441
|
.filter(Boolean) ?? []
|
|
1422
1442
|
|
|
@@ -1509,17 +1529,12 @@ export class Router<
|
|
|
1509
1529
|
}
|
|
1510
1530
|
}
|
|
1511
1531
|
|
|
1512
|
-
const nextMatches = this.
|
|
1513
|
-
const maskedMatches = maskedNext
|
|
1514
|
-
? this.matchRoutes(maskedNext, { _buildLocation: true })
|
|
1515
|
-
: undefined
|
|
1516
|
-
const maskedFinal = maskedNext
|
|
1517
|
-
? build(maskedDest, maskedMatches)
|
|
1518
|
-
: undefined
|
|
1519
|
-
|
|
1532
|
+
const nextMatches = this.getMatchedRoutes(next, dest)
|
|
1520
1533
|
const final = build(dest, nextMatches)
|
|
1521
1534
|
|
|
1522
|
-
if (
|
|
1535
|
+
if (maskedNext) {
|
|
1536
|
+
const maskedMatches = this.getMatchedRoutes(maskedNext, maskedDest)
|
|
1537
|
+
const maskedFinal = build(maskedDest, maskedMatches)
|
|
1523
1538
|
final.maskedLocation = maskedFinal
|
|
1524
1539
|
}
|
|
1525
1540
|
|
|
@@ -2497,6 +2512,7 @@ export class Router<
|
|
|
2497
2512
|
let matches = this.matchRoutes(next, {
|
|
2498
2513
|
throwOnError: true,
|
|
2499
2514
|
preload: true,
|
|
2515
|
+
dest: opts,
|
|
2500
2516
|
})
|
|
2501
2517
|
|
|
2502
2518
|
const loadedMatchIds = Object.fromEntries(
|