From 82b4c14a8d91d987e61fcf5b48581cb8432d1958 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sun, 21 Dec 2025 16:42:03 +0100 Subject: [PATCH] refactor(router-core): index nodes can skip the stack loop, they cannot have children --- .../router-core/src/new-process-route-tree.ts | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/packages/router-core/src/new-process-route-tree.ts b/packages/router-core/src/new-process-route-tree.ts index 9fa3f91a0b..1cfcc8aa53 100644 --- a/packages/router-core/src/new-process-route-tree.ts +++ b/packages/router-core/src/new-process-route-tree.ts @@ -895,22 +895,8 @@ function getNodeMatch( const isBeyondPath = index === partsLength if (isBeyondPath) { - if (node.route && (!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX)) { - if (isFrameMoreSpecific(bestMatch, frame)) { - bestMatch = frame - } - - // perfect match, no need to continue - // this is an optimization, algorithm should work correctly without this block - if ( - statics === partsLength && - !dynamics && - !optionals && - !skipped && - node.kind === SEGMENT_TYPE_INDEX - ) { - return bestMatch - } + if (node.route && !pathIsIndex && isFrameMoreSpecific(bestMatch, frame)) { + bestMatch = frame } // beyond the length of the path parts, only index segments, or skipped optional segments, or wildcard segments can match if (!node.optional && !node.wildcard && !node.index) continue @@ -919,6 +905,28 @@ function getNodeMatch( const part = isBeyondPath ? undefined : parts[index]! let lowerPart: string + // 0. Try index match + if (isBeyondPath && node.index) { + const indexFrame = { + node: node.index, + index, + skipped, + depth: depth + 1, + statics, + dynamics, + optionals, + } + // perfect match, no need to continue + // this is an optimization, algorithm should work correctly without this block + if (statics === partsLength && !dynamics && !optionals && !skipped) { + return indexFrame + } + if (isFrameMoreSpecific(bestMatch, indexFrame)) { + // index matches skip the stack because they cannot have children + bestMatch = indexFrame + } + } + // 5. Try wildcard match if (node.wildcard && isFrameMoreSpecific(wildcardMatch, frame)) { for (const segment of node.wildcard) { @@ -937,9 +945,10 @@ function getNodeMatch( if (casePart !== suffix) continue } // the first wildcard match is the highest priority one + // wildcard matches skip the stack because they cannot have children wildcardMatch = { node: segment, - index, + index: partsLength, skipped, depth, statics, @@ -1048,19 +1057,6 @@ function getNodeMatch( }) } } - - // 0. Try index match - if (isBeyondPath && node.index) { - stack.push({ - node: node.index, - index, - skipped, - depth: depth + 1, - statics, - dynamics, - optionals, - }) - } } if (bestMatch && wildcardMatch) {