Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions packages/router-core/src/new-process-route-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ export type ProcessedTree<
/** @deprecated keep until v2 so that `router.matchRoute` can keep not caring about the actual route tree */
singleCache: LRUCache<string, AnySegmentNode<TSingle>>
/** a cache of route matches from the `segmentTree` */
matchCache: LRUCache<string, ReturnType<typeof findMatch<TTree>>>
matchCache: LRUCache<string, RouteMatch<TTree> | null>
/** a cache of route matches from the `masksTree` */
flatCache: LRUCache<string, ReturnType<typeof findMatch<TFlat>>> | null
}
Expand Down Expand Up @@ -603,6 +603,12 @@ export function findSingleMatch(
return findMatch(path, tree, fuzzy)
}

type RouteMatch<T extends Extract<RouteLike, { fullPath: string }>> = {
route: T
params: Record<string, string>
branch: ReadonlyArray<T>
}

export function findRouteMatch<
T extends Extract<RouteLike, { fullPath: string }>,
>(
Expand All @@ -612,12 +618,17 @@ export function findRouteMatch<
processedTree: ProcessedTree<T, any, any>,
/** If `true`, allows fuzzy matching (partial matches), i.e. which node in the tree would have been an exact match if the `path` had been shorter? */
fuzzy = false,
) {
const key = fuzzy ? `fuzzy\0${path}` : path
): RouteMatch<T> | null {
const key = fuzzy ? path : `nofuzz\0${path}` // the main use for `findRouteMatch` is fuzzy:true, so we optimize for that case
const cached = processedTree.matchCache.get(key)
if (cached) return cached
if (cached !== undefined) return cached
path ||= '/'
const result = findMatch(path, processedTree.segmentTree, fuzzy)
const result = findMatch(
path,
processedTree.segmentTree,
fuzzy,
) as RouteMatch<T> | null
if (result) result.branch = buildRouteBranch(result.route)
processedTree.matchCache.set(key, result)
return result
}
Expand Down Expand Up @@ -676,10 +687,7 @@ export function processRouteTree<
const processedTree: ProcessedTree<TRouteLike, any, any> = {
segmentTree,
singleCache: createLRUCache<string, AnySegmentNode<any>>(1000),
matchCache: createLRUCache<
string,
ReturnType<typeof findMatch<TRouteLike>>
>(1000),
matchCache: createLRUCache<string, RouteMatch<TRouteLike> | null>(1000),
flatCache: null,
masksTree: null,
}
Expand Down Expand Up @@ -780,6 +788,16 @@ function extractParams<T extends RouteLike>(
return params
}

function buildRouteBranch<T extends RouteLike>(route: T) {
const list = [route]
while (route.parentRoute) {
route = route.parentRoute as T
list.push(route)
}
list.reverse()
return list
}

function buildBranch<T extends RouteLike>(node: AnySegmentNode<T>) {
const list: Array<AnySegmentNode<T>> = Array(node.depth + 1)
do {
Expand Down
20 changes: 6 additions & 14 deletions packages/router-core/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ export type ParseLocationFn<TRouteTree extends AnyRoute> = (
) => ParsedLocation<FullSearchSchema<TRouteTree>>

export type GetMatchRoutesFn = (pathname: string) => {
matchedRoutes: Array<AnyRoute>
matchedRoutes: ReadonlyArray<AnyRoute>
routeParams: Record<string, string>
foundRoute: AnyRoute | undefined
}
Expand Down Expand Up @@ -1248,9 +1248,9 @@ export class RouterCore<
next: ParsedLocation,
opts?: MatchRoutesOpts,
): Array<AnyRouteMatch> {
const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
next.pathname,
)
const matchedRoutesResult = this.getMatchedRoutes(next.pathname)
const { foundRoute, routeParams } = matchedRoutesResult
let { matchedRoutes } = matchedRoutesResult
let isGlobalNotFound = false

// Check to see if the route needs a 404 entry
Expand All @@ -1263,7 +1263,7 @@ export class RouterCore<
) {
// If the user has defined an (old) 404 route, use it
if (this.options.notFoundRoute) {
matchedRoutes.push(this.options.notFoundRoute)
matchedRoutes = [...matchedRoutes, this.options.notFoundRoute]
} else {
// If there is no routes found during path matching
isGlobalNotFound = true
Expand Down Expand Up @@ -2642,15 +2642,7 @@ export function getMatchedRoutes<TRouteLike extends RouteLike>({
Object.assign(routeParams, match.params) // Copy params, because they're cached
}

let routeCursor: TRouteLike = foundRoute || routesById[rootRouteId]!

const matchedRoutes: Array<TRouteLike> = [routeCursor]

while (routeCursor.parentRoute) {
routeCursor = routeCursor.parentRoute as TRouteLike
matchedRoutes.push(routeCursor)
}
matchedRoutes.reverse()
const matchedRoutes = match?.branch || [routesById[rootRouteId]!]

return { matchedRoutes, routeParams, foundRoute }
}
Expand Down
Loading