@tanstack/router-core 1.154.2 → 1.154.4
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/new-process-route-tree.cjs +20 -4
- package/dist/cjs/new-process-route-tree.cjs.map +1 -1
- package/dist/cjs/router.cjs +15 -7
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +5 -0
- package/dist/esm/new-process-route-tree.js +20 -4
- package/dist/esm/new-process-route-tree.js.map +1 -1
- package/dist/esm/router.d.ts +5 -0
- package/dist/esm/router.js +15 -7
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/new-process-route-tree.ts +40 -10
- package/src/router.ts +24 -8
package/package.json
CHANGED
|
@@ -846,6 +846,13 @@ function findMatch<T extends RouteLike>(
|
|
|
846
846
|
}
|
|
847
847
|
}
|
|
848
848
|
|
|
849
|
+
type ParamExtractionState = {
|
|
850
|
+
part: number
|
|
851
|
+
node: number
|
|
852
|
+
path: number
|
|
853
|
+
segment: number
|
|
854
|
+
}
|
|
855
|
+
|
|
849
856
|
/**
|
|
850
857
|
* This function is "resumable":
|
|
851
858
|
* - the `leaf` input can contain `extract` and `rawParams` properties from a previous `extractParams` call
|
|
@@ -859,27 +866,42 @@ function extractParams<T extends RouteLike>(
|
|
|
859
866
|
leaf: {
|
|
860
867
|
node: AnySegmentNode<T>
|
|
861
868
|
skipped: number
|
|
862
|
-
extract?:
|
|
869
|
+
extract?: ParamExtractionState
|
|
863
870
|
rawParams?: Record<string, string>
|
|
864
871
|
},
|
|
865
|
-
): [
|
|
866
|
-
rawParams: Record<string, string>,
|
|
867
|
-
state: { part: number; node: number; path: number },
|
|
868
|
-
] {
|
|
872
|
+
): [rawParams: Record<string, string>, state: ParamExtractionState] {
|
|
869
873
|
const list = buildBranch(leaf.node)
|
|
870
874
|
let nodeParts: Array<string> | null = null
|
|
871
875
|
const rawParams: Record<string, string> = {}
|
|
876
|
+
/** which segment of the path we're currently processing */
|
|
872
877
|
let partIndex = leaf.extract?.part ?? 0
|
|
878
|
+
/** which node of the route tree branch we're currently processing */
|
|
873
879
|
let nodeIndex = leaf.extract?.node ?? 0
|
|
880
|
+
/** index of the 1st character of the segment we're processing in the path string */
|
|
874
881
|
let pathIndex = leaf.extract?.path ?? 0
|
|
875
|
-
|
|
882
|
+
/** which fullPath segment we're currently processing */
|
|
883
|
+
let segmentCount = leaf.extract?.segment ?? 0
|
|
884
|
+
for (
|
|
885
|
+
;
|
|
886
|
+
nodeIndex < list.length;
|
|
887
|
+
partIndex++, nodeIndex++, pathIndex++, segmentCount++
|
|
888
|
+
) {
|
|
876
889
|
const node = list[nodeIndex]!
|
|
890
|
+
// index nodes are terminating nodes, nothing to extract, just leave
|
|
891
|
+
if (node.kind === SEGMENT_TYPE_INDEX) break
|
|
892
|
+
// pathless nodes do not consume a path segment
|
|
893
|
+
if (node.kind === SEGMENT_TYPE_PATHLESS) {
|
|
894
|
+
segmentCount--
|
|
895
|
+
partIndex--
|
|
896
|
+
pathIndex--
|
|
897
|
+
continue
|
|
898
|
+
}
|
|
877
899
|
const part = parts[partIndex]
|
|
878
900
|
const currentPathIndex = pathIndex
|
|
879
901
|
if (part) pathIndex += part.length
|
|
880
902
|
if (node.kind === SEGMENT_TYPE_PARAM) {
|
|
881
903
|
nodeParts ??= leaf.node.fullPath.split('/')
|
|
882
|
-
const nodePart = nodeParts[
|
|
904
|
+
const nodePart = nodeParts[segmentCount]!
|
|
883
905
|
const preLength = node.prefix?.length ?? 0
|
|
884
906
|
// we can't rely on the presence of prefix/suffix to know whether it's curly-braced or not, because `/{$param}/` is valid, but has no prefix/suffix
|
|
885
907
|
const isCurlyBraced = nodePart.charCodeAt(preLength) === 123 // '{'
|
|
@@ -903,7 +925,7 @@ function extractParams<T extends RouteLike>(
|
|
|
903
925
|
continue
|
|
904
926
|
}
|
|
905
927
|
nodeParts ??= leaf.node.fullPath.split('/')
|
|
906
|
-
const nodePart = nodeParts[
|
|
928
|
+
const nodePart = nodeParts[segmentCount]!
|
|
907
929
|
const preLength = node.prefix?.length ?? 0
|
|
908
930
|
const sufLength = node.suffix?.length ?? 0
|
|
909
931
|
const name = nodePart.substring(
|
|
@@ -929,7 +951,15 @@ function extractParams<T extends RouteLike>(
|
|
|
929
951
|
}
|
|
930
952
|
}
|
|
931
953
|
if (leaf.rawParams) Object.assign(rawParams, leaf.rawParams)
|
|
932
|
-
return [
|
|
954
|
+
return [
|
|
955
|
+
rawParams,
|
|
956
|
+
{
|
|
957
|
+
part: partIndex,
|
|
958
|
+
node: nodeIndex,
|
|
959
|
+
path: pathIndex,
|
|
960
|
+
segment: segmentCount,
|
|
961
|
+
},
|
|
962
|
+
]
|
|
933
963
|
}
|
|
934
964
|
|
|
935
965
|
function buildRouteBranch<T extends RouteLike>(route: T) {
|
|
@@ -968,7 +998,7 @@ type MatchStackFrame<T extends RouteLike> = {
|
|
|
968
998
|
dynamics: number
|
|
969
999
|
optionals: number
|
|
970
1000
|
/** intermediary state for param extraction */
|
|
971
|
-
extract?:
|
|
1001
|
+
extract?: ParamExtractionState
|
|
972
1002
|
/** intermediary params from param extraction */
|
|
973
1003
|
rawParams?: Record<string, string>
|
|
974
1004
|
parsedParams?: Record<string, unknown>
|
package/src/router.ts
CHANGED
|
@@ -594,6 +594,12 @@ export interface MatchRoutesOpts {
|
|
|
594
594
|
snapshot?: MatchSnapshot
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
export interface MatchRoutesResult {
|
|
598
|
+
matches: Array<AnyRouteMatch>
|
|
599
|
+
/** Raw string params extracted from path (before parsing) */
|
|
600
|
+
rawParams: Record<string, string>
|
|
601
|
+
}
|
|
602
|
+
|
|
597
603
|
export type InferRouterContext<TRouteTree extends AnyRoute> =
|
|
598
604
|
TRouteTree['types']['routerContext']
|
|
599
605
|
|
|
@@ -1265,16 +1271,17 @@ export class RouterCore<
|
|
|
1265
1271
|
search: locationSearchOrOpts,
|
|
1266
1272
|
} as ParsedLocation,
|
|
1267
1273
|
opts,
|
|
1268
|
-
)
|
|
1274
|
+
).matches
|
|
1269
1275
|
}
|
|
1270
1276
|
|
|
1271
1277
|
return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts)
|
|
1278
|
+
.matches
|
|
1272
1279
|
}
|
|
1273
1280
|
|
|
1274
1281
|
private matchRoutesInternal(
|
|
1275
1282
|
next: ParsedLocation,
|
|
1276
1283
|
opts?: MatchRoutesOpts,
|
|
1277
|
-
):
|
|
1284
|
+
): MatchRoutesResult {
|
|
1278
1285
|
// Fast-path: use snapshot hint if valid
|
|
1279
1286
|
const snapshot = opts?.snapshot
|
|
1280
1287
|
const snapshotValid =
|
|
@@ -1284,6 +1291,7 @@ export class RouterCore<
|
|
|
1284
1291
|
|
|
1285
1292
|
let matchedRoutes: ReadonlyArray<AnyRoute>
|
|
1286
1293
|
let routeParams: Record<string, string>
|
|
1294
|
+
let rawParams: Record<string, string>
|
|
1287
1295
|
let globalNotFoundRouteId: string | undefined
|
|
1288
1296
|
let parsedParams: Record<string, unknown>
|
|
1289
1297
|
|
|
@@ -1291,6 +1299,7 @@ export class RouterCore<
|
|
|
1291
1299
|
// Rebuild matched routes from snapshot
|
|
1292
1300
|
matchedRoutes = snapshot.routeIds.map((id) => this.routesById[id]!)
|
|
1293
1301
|
routeParams = { ...snapshot.params }
|
|
1302
|
+
rawParams = { ...snapshot.params }
|
|
1294
1303
|
globalNotFoundRouteId = snapshot.globalNotFoundRouteId
|
|
1295
1304
|
parsedParams = snapshot.parsedParams
|
|
1296
1305
|
} else {
|
|
@@ -1298,6 +1307,7 @@ export class RouterCore<
|
|
|
1298
1307
|
const matchedRoutesResult = this.getMatchedRoutes(next.pathname)
|
|
1299
1308
|
const { foundRoute, routeParams: rp } = matchedRoutesResult
|
|
1300
1309
|
routeParams = rp
|
|
1310
|
+
rawParams = { ...rp } // Capture before routeParams gets modified
|
|
1301
1311
|
matchedRoutes = matchedRoutesResult.matchedRoutes
|
|
1302
1312
|
parsedParams = matchedRoutesResult.parsedParams
|
|
1303
1313
|
|
|
@@ -1642,7 +1652,7 @@ export class RouterCore<
|
|
|
1642
1652
|
}
|
|
1643
1653
|
})
|
|
1644
1654
|
|
|
1645
|
-
return matches
|
|
1655
|
+
return { matches, rawParams }
|
|
1646
1656
|
}
|
|
1647
1657
|
|
|
1648
1658
|
getMatchedRoutes: GetMatchRoutesFn = (pathname) => {
|
|
@@ -1765,9 +1775,10 @@ export class RouterCore<
|
|
|
1765
1775
|
params: nextParams,
|
|
1766
1776
|
}).interpolatedPath
|
|
1767
1777
|
|
|
1768
|
-
const destMatches = this.
|
|
1769
|
-
|
|
1770
|
-
|
|
1778
|
+
const { matches: destMatches, rawParams } = this.matchRoutesInternal(
|
|
1779
|
+
{ pathname: interpolatedNextTo } as ParsedLocation,
|
|
1780
|
+
{ _buildLocation: true },
|
|
1781
|
+
)
|
|
1771
1782
|
const destRoutes = destMatches.map(
|
|
1772
1783
|
(d) => this.looseRoutesById[d.routeId]!,
|
|
1773
1784
|
)
|
|
@@ -1856,10 +1867,15 @@ export class RouterCore<
|
|
|
1856
1867
|
nextState = replaceEqualDeep(currentLocation.state, nextState)
|
|
1857
1868
|
|
|
1858
1869
|
// Build match snapshot for fast-path on back/forward navigation
|
|
1859
|
-
// Use
|
|
1870
|
+
// Use raw params captured during matchRoutesInternal (needed for literal path navigation
|
|
1871
|
+
// where nextParams may be empty but path contains param values)
|
|
1872
|
+
const snapshotParams = {
|
|
1873
|
+
...rawParams,
|
|
1874
|
+
...nextParams,
|
|
1875
|
+
}
|
|
1860
1876
|
const matchSnapshot = buildMatchSnapshotFromRoutes({
|
|
1861
1877
|
routes: destRoutes,
|
|
1862
|
-
params:
|
|
1878
|
+
params: snapshotParams,
|
|
1863
1879
|
searchStr,
|
|
1864
1880
|
globalNotFoundRouteId: globalNotFoundMatch?.routeId,
|
|
1865
1881
|
})
|