@tanstack/router-core 1.128.3 → 1.128.6
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/path.cjs +242 -228
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +11 -6
- package/dist/cjs/router.cjs +58 -47
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/esm/path.d.ts +11 -6
- package/dist/esm/path.js +242 -228
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/router.js +59 -48
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/path.ts +315 -296
- package/src/router.ts +79 -59
package/src/router.ts
CHANGED
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
replaceEqualDeep,
|
|
15
15
|
} from './utils'
|
|
16
16
|
import {
|
|
17
|
+
SEGMENT_TYPE_OPTIONAL_PARAM,
|
|
18
|
+
SEGMENT_TYPE_PARAM,
|
|
19
|
+
SEGMENT_TYPE_PATHNAME,
|
|
20
|
+
SEGMENT_TYPE_WILDCARD,
|
|
17
21
|
cleanPath,
|
|
18
22
|
interpolatePath,
|
|
19
23
|
joinPaths,
|
|
@@ -29,6 +33,7 @@ import { setupScrollRestoration } from './scroll-restoration'
|
|
|
29
33
|
import { defaultParseSearch, defaultStringifySearch } from './searchParams'
|
|
30
34
|
import { rootRouteId } from './root'
|
|
31
35
|
import { isRedirect, redirect } from './redirect'
|
|
36
|
+
import type { Segment } from './path'
|
|
32
37
|
import type { SearchParser, SearchSerializer } from './searchParams'
|
|
33
38
|
import type { AnyRedirect, ResolvedRedirect } from './redirect'
|
|
34
39
|
import type {
|
|
@@ -3178,6 +3183,27 @@ export type ProcessRouteTreeResult<TRouteLike extends RouteLike> = {
|
|
|
3178
3183
|
routesByPath: Record<string, TRouteLike>
|
|
3179
3184
|
flatRoutes: Array<TRouteLike>
|
|
3180
3185
|
}
|
|
3186
|
+
|
|
3187
|
+
const REQUIRED_PARAM_BASE_SCORE = 0.5
|
|
3188
|
+
const OPTIONAL_PARAM_BASE_SCORE = 0.4
|
|
3189
|
+
const WILDCARD_PARAM_BASE_SCORE = 0.25
|
|
3190
|
+
|
|
3191
|
+
function handleParam(segment: Segment, baseScore: number) {
|
|
3192
|
+
if (segment.prefixSegment && segment.suffixSegment) {
|
|
3193
|
+
return baseScore + 0.05
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
if (segment.prefixSegment) {
|
|
3197
|
+
return baseScore + 0.02
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
if (segment.suffixSegment) {
|
|
3201
|
+
return baseScore + 0.01
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
return baseScore
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3181
3207
|
export function processRouteTree<TRouteLike extends RouteLike>({
|
|
3182
3208
|
routeTree,
|
|
3183
3209
|
initRoute,
|
|
@@ -3224,9 +3250,11 @@ export function processRouteTree<TRouteLike extends RouteLike>({
|
|
|
3224
3250
|
const scoredRoutes: Array<{
|
|
3225
3251
|
child: TRouteLike
|
|
3226
3252
|
trimmed: string
|
|
3227
|
-
parsed:
|
|
3253
|
+
parsed: ReadonlyArray<Segment>
|
|
3228
3254
|
index: number
|
|
3229
3255
|
scores: Array<number>
|
|
3256
|
+
hasStaticAfter: boolean
|
|
3257
|
+
optionalParamCount: number
|
|
3230
3258
|
}> = []
|
|
3231
3259
|
|
|
3232
3260
|
const routes: Array<TRouteLike> = Object.values(routesById)
|
|
@@ -3237,70 +3265,62 @@ export function processRouteTree<TRouteLike extends RouteLike>({
|
|
|
3237
3265
|
}
|
|
3238
3266
|
|
|
3239
3267
|
const trimmed = trimPathLeft(d.fullPath)
|
|
3240
|
-
|
|
3268
|
+
let parsed = parsePathname(trimmed)
|
|
3241
3269
|
|
|
3242
3270
|
// Removes the leading slash if it is not the only remaining segment
|
|
3243
|
-
|
|
3244
|
-
|
|
3271
|
+
let skip = 0
|
|
3272
|
+
while (parsed.length > skip + 1 && parsed[skip]?.value === '/') {
|
|
3273
|
+
skip++
|
|
3245
3274
|
}
|
|
3275
|
+
if (skip > 0) parsed = parsed.slice(skip)
|
|
3246
3276
|
|
|
3247
|
-
|
|
3277
|
+
let optionalParamCount = 0
|
|
3278
|
+
let hasStaticAfter = false
|
|
3279
|
+
const scores = parsed.map((segment, index) => {
|
|
3248
3280
|
if (segment.value === '/') {
|
|
3249
3281
|
return 0.75
|
|
3250
3282
|
}
|
|
3251
3283
|
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
if (segment.suffixSegment) {
|
|
3262
|
-
return 0.51
|
|
3263
|
-
}
|
|
3264
|
-
|
|
3265
|
-
return 0.5
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
|
-
if (segment.type === 'optional-param') {
|
|
3269
|
-
if (segment.prefixSegment && segment.suffixSegment) {
|
|
3270
|
-
return 0.45
|
|
3271
|
-
}
|
|
3272
|
-
|
|
3273
|
-
if (segment.prefixSegment) {
|
|
3274
|
-
return 0.42
|
|
3275
|
-
}
|
|
3276
|
-
|
|
3277
|
-
if (segment.suffixSegment) {
|
|
3278
|
-
return 0.41
|
|
3279
|
-
}
|
|
3280
|
-
|
|
3281
|
-
return 0.4
|
|
3284
|
+
let baseScore: number | undefined = undefined
|
|
3285
|
+
if (segment.type === SEGMENT_TYPE_PARAM) {
|
|
3286
|
+
baseScore = REQUIRED_PARAM_BASE_SCORE
|
|
3287
|
+
} else if (segment.type === SEGMENT_TYPE_OPTIONAL_PARAM) {
|
|
3288
|
+
baseScore = OPTIONAL_PARAM_BASE_SCORE
|
|
3289
|
+
optionalParamCount++
|
|
3290
|
+
} else if (segment.type === SEGMENT_TYPE_WILDCARD) {
|
|
3291
|
+
baseScore = WILDCARD_PARAM_BASE_SCORE
|
|
3282
3292
|
}
|
|
3283
3293
|
|
|
3284
|
-
if (
|
|
3285
|
-
if
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3294
|
+
if (baseScore) {
|
|
3295
|
+
// if there is any static segment (that is not an index) after a required / optional param,
|
|
3296
|
+
// we will boost this param so it ranks higher than a required/optional param without a static segment after it
|
|
3297
|
+
// JUST FOR SORTING, NOT FOR MATCHING
|
|
3298
|
+
for (let i = index + 1; i < parsed.length; i++) {
|
|
3299
|
+
const nextSegment = parsed[i]!
|
|
3300
|
+
if (
|
|
3301
|
+
nextSegment.type === SEGMENT_TYPE_PATHNAME &&
|
|
3302
|
+
nextSegment.value !== '/'
|
|
3303
|
+
) {
|
|
3304
|
+
hasStaticAfter = true
|
|
3305
|
+
return handleParam(segment, baseScore + 0.2)
|
|
3306
|
+
}
|
|
3295
3307
|
}
|
|
3296
3308
|
|
|
3297
|
-
return
|
|
3309
|
+
return handleParam(segment, baseScore)
|
|
3298
3310
|
}
|
|
3299
3311
|
|
|
3300
3312
|
return 1
|
|
3301
3313
|
})
|
|
3302
3314
|
|
|
3303
|
-
scoredRoutes.push({
|
|
3315
|
+
scoredRoutes.push({
|
|
3316
|
+
child: d,
|
|
3317
|
+
trimmed,
|
|
3318
|
+
parsed,
|
|
3319
|
+
index: i,
|
|
3320
|
+
scores,
|
|
3321
|
+
optionalParamCount,
|
|
3322
|
+
hasStaticAfter,
|
|
3323
|
+
})
|
|
3304
3324
|
})
|
|
3305
3325
|
|
|
3306
3326
|
const flatRoutes = scoredRoutes
|
|
@@ -3316,17 +3336,16 @@ export function processRouteTree<TRouteLike extends RouteLike>({
|
|
|
3316
3336
|
|
|
3317
3337
|
// If all common segments have equal scores, then consider length and specificity
|
|
3318
3338
|
if (a.scores.length !== b.scores.length) {
|
|
3319
|
-
// Count optional parameters in each route
|
|
3320
|
-
const aOptionalCount = a.parsed.filter(
|
|
3321
|
-
(seg) => seg.type === 'optional-param',
|
|
3322
|
-
).length
|
|
3323
|
-
const bOptionalCount = b.parsed.filter(
|
|
3324
|
-
(seg) => seg.type === 'optional-param',
|
|
3325
|
-
).length
|
|
3326
|
-
|
|
3327
3339
|
// If different number of optional parameters, fewer optional parameters wins (more specific)
|
|
3328
|
-
if
|
|
3329
|
-
|
|
3340
|
+
// only if both or none of the routes has static segments after the params
|
|
3341
|
+
if (a.optionalParamCount !== b.optionalParamCount) {
|
|
3342
|
+
if (a.hasStaticAfter === b.hasStaticAfter) {
|
|
3343
|
+
return a.optionalParamCount - b.optionalParamCount
|
|
3344
|
+
} else if (a.hasStaticAfter && !b.hasStaticAfter) {
|
|
3345
|
+
return -1
|
|
3346
|
+
} else if (!a.hasStaticAfter && b.hasStaticAfter) {
|
|
3347
|
+
return 1
|
|
3348
|
+
}
|
|
3330
3349
|
}
|
|
3331
3350
|
|
|
3332
3351
|
// If same number of optional parameters, longer path wins (for static segments)
|
|
@@ -3402,8 +3421,9 @@ export function getMatchedRoutes<TRouteLike extends RouteLike>({
|
|
|
3402
3421
|
|
|
3403
3422
|
while (routeCursor.parentRoute) {
|
|
3404
3423
|
routeCursor = routeCursor.parentRoute as TRouteLike
|
|
3405
|
-
matchedRoutes.
|
|
3424
|
+
matchedRoutes.push(routeCursor)
|
|
3406
3425
|
}
|
|
3426
|
+
matchedRoutes.reverse()
|
|
3407
3427
|
|
|
3408
3428
|
return { matchedRoutes, routeParams, foundRoute }
|
|
3409
3429
|
}
|