@tanstack/router-core 1.120.5 → 1.121.0-alpha.3

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.
Files changed (51) hide show
  1. package/dist/cjs/fileRoute.d.cts +6 -2
  2. package/dist/cjs/index.cjs +3 -0
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.cts +6 -6
  5. package/dist/cjs/link.cjs.map +1 -1
  6. package/dist/cjs/link.d.cts +18 -1
  7. package/dist/cjs/path.cjs +130 -16
  8. package/dist/cjs/path.cjs.map +1 -1
  9. package/dist/cjs/path.d.cts +17 -0
  10. package/dist/cjs/redirect.cjs +17 -14
  11. package/dist/cjs/redirect.cjs.map +1 -1
  12. package/dist/cjs/redirect.d.cts +13 -7
  13. package/dist/cjs/route.cjs +12 -1
  14. package/dist/cjs/route.cjs.map +1 -1
  15. package/dist/cjs/route.d.cts +19 -18
  16. package/dist/cjs/router.cjs +268 -195
  17. package/dist/cjs/router.cjs.map +1 -1
  18. package/dist/cjs/router.d.cts +46 -3
  19. package/dist/cjs/typePrimitives.d.cts +2 -2
  20. package/dist/cjs/utils.cjs.map +1 -1
  21. package/dist/cjs/utils.d.cts +3 -0
  22. package/dist/esm/fileRoute.d.ts +6 -2
  23. package/dist/esm/index.d.ts +6 -6
  24. package/dist/esm/index.js +5 -2
  25. package/dist/esm/link.d.ts +18 -1
  26. package/dist/esm/link.js.map +1 -1
  27. package/dist/esm/path.d.ts +17 -0
  28. package/dist/esm/path.js +130 -16
  29. package/dist/esm/path.js.map +1 -1
  30. package/dist/esm/redirect.d.ts +13 -7
  31. package/dist/esm/redirect.js +17 -14
  32. package/dist/esm/redirect.js.map +1 -1
  33. package/dist/esm/route.d.ts +19 -18
  34. package/dist/esm/route.js +12 -1
  35. package/dist/esm/route.js.map +1 -1
  36. package/dist/esm/router.d.ts +46 -3
  37. package/dist/esm/router.js +271 -198
  38. package/dist/esm/router.js.map +1 -1
  39. package/dist/esm/typePrimitives.d.ts +2 -2
  40. package/dist/esm/utils.d.ts +3 -0
  41. package/dist/esm/utils.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/fileRoute.ts +90 -1
  44. package/src/index.ts +14 -6
  45. package/src/link.ts +97 -11
  46. package/src/path.ts +181 -16
  47. package/src/redirect.ts +37 -22
  48. package/src/route.ts +109 -39
  49. package/src/router.ts +373 -250
  50. package/src/typePrimitives.ts +2 -2
  51. package/src/utils.ts +15 -0
@@ -48,6 +48,7 @@ class RouterCore {
48
48
  this.isScrollRestoring = false;
49
49
  this.isScrollRestorationSetup = false;
50
50
  this.startTransition = (fn) => fn();
51
+ this.isShell = false;
51
52
  this.update = (newOptions) => {
52
53
  var _a;
53
54
  if (newOptions.notFoundRoute) {
@@ -74,10 +75,7 @@ class RouterCore {
74
75
  this.basepath = `/${path.trimPath(newOptions.basepath)}`;
75
76
  }
76
77
  }
77
- if (
78
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
79
- !this.history || this.options.history && this.options.history !== this.history
80
- ) {
78
+ if (!this.history || this.options.history && this.options.history !== this.history) {
81
79
  this.history = this.options.history ?? (this.isServer ? history.createMemoryHistory({
82
80
  initialEntries: [this.basepath || "/"]
83
81
  }) : history.createBrowserHistory());
@@ -100,16 +98,28 @@ class RouterCore {
100
98
  });
101
99
  scrollRestoration.setupScrollRestoration(this);
102
100
  }
103
- if (typeof window !== "undefined" && "CSS" in window && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
104
- typeof ((_a = window.CSS) == null ? void 0 : _a.supports) === "function") {
101
+ if (typeof window !== "undefined" && "CSS" in window && typeof ((_a = window.CSS) == null ? void 0 : _a.supports) === "function") {
105
102
  this.isViewTransitionTypesSupported = window.CSS.supports(
106
103
  "selector(:active-view-transition-type(a)"
107
104
  );
108
105
  }
106
+ if (this.latestLocation.search.__TSS_SHELL) {
107
+ this.isShell = true;
108
+ }
109
109
  };
110
110
  this.buildRouteTree = () => {
111
- this.routesById = {};
112
- this.routesByPath = {};
111
+ const { routesById, routesByPath, flatRoutes } = processRouteTree({
112
+ routeTree: this.routeTree,
113
+ initRoute: (route, i) => {
114
+ route.init({
115
+ originalIndex: i,
116
+ defaultSsr: this.options.defaultSsr
117
+ });
118
+ }
119
+ });
120
+ this.routesById = routesById;
121
+ this.routesByPath = routesByPath;
122
+ this.flatRoutes = flatRoutes;
113
123
  const notFoundRoute = this.options.notFoundRoute;
114
124
  if (notFoundRoute) {
115
125
  notFoundRoute.init({
@@ -118,77 +128,6 @@ class RouterCore {
118
128
  });
119
129
  this.routesById[notFoundRoute.id] = notFoundRoute;
120
130
  }
121
- const recurseRoutes = (childRoutes) => {
122
- childRoutes.forEach((childRoute, i) => {
123
- childRoute.init({
124
- originalIndex: i,
125
- defaultSsr: this.options.defaultSsr
126
- });
127
- const existingRoute = this.routesById[childRoute.id];
128
- invariant(
129
- !existingRoute,
130
- `Duplicate routes found with id: ${String(childRoute.id)}`
131
- );
132
- this.routesById[childRoute.id] = childRoute;
133
- if (!childRoute.isRoot && childRoute.path) {
134
- const trimmedFullPath = path.trimPathRight(childRoute.fullPath);
135
- if (!this.routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
136
- this.routesByPath[trimmedFullPath] = childRoute;
137
- }
138
- }
139
- const children = childRoute.children;
140
- if (children == null ? void 0 : children.length) {
141
- recurseRoutes(children);
142
- }
143
- });
144
- };
145
- recurseRoutes([this.routeTree]);
146
- const scoredRoutes = [];
147
- const routes = Object.values(this.routesById);
148
- routes.forEach((d, i) => {
149
- var _a;
150
- if (d.isRoot || !d.path) {
151
- return;
152
- }
153
- const trimmed = path.trimPathLeft(d.fullPath);
154
- const parsed = path.parsePathname(trimmed);
155
- while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
156
- parsed.shift();
157
- }
158
- const scores = parsed.map((segment) => {
159
- if (segment.value === "/") {
160
- return 0.75;
161
- }
162
- if (segment.type === "param") {
163
- return 0.5;
164
- }
165
- if (segment.type === "wildcard") {
166
- return 0.25;
167
- }
168
- return 1;
169
- });
170
- scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
171
- });
172
- this.flatRoutes = scoredRoutes.sort((a, b) => {
173
- const minLength = Math.min(a.scores.length, b.scores.length);
174
- for (let i = 0; i < minLength; i++) {
175
- if (a.scores[i] !== b.scores[i]) {
176
- return b.scores[i] - a.scores[i];
177
- }
178
- }
179
- if (a.scores.length !== b.scores.length) {
180
- return b.scores.length - a.scores.length;
181
- }
182
- for (let i = 0; i < minLength; i++) {
183
- if (a.parsed[i].value !== b.parsed[i].value) {
184
- return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
185
- }
186
- }
187
- return a.index - b.index;
188
- }).map((d, i) => {
189
- d.child.rank = i;
190
- return d.child;
191
- });
192
131
  };
193
132
  this.subscribe = (eventType, fn) => {
194
133
  const listener = {
@@ -261,37 +200,16 @@ class RouterCore {
261
200
  return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
262
201
  }
263
202
  };
264
- this.getMatchedRoutes = (next, dest) => {
265
- let routeParams = {};
266
- const trimmedPath = path.trimPathRight(next.pathname);
267
- const getMatchedParams = (route) => {
268
- const result = path.matchPathname(this.basepath, trimmedPath, {
269
- to: route.fullPath,
270
- caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive,
271
- fuzzy: true
272
- });
273
- return result;
274
- };
275
- let foundRoute = (dest == null ? void 0 : dest.to) !== void 0 ? this.routesByPath[dest.to] : void 0;
276
- if (foundRoute) {
277
- routeParams = getMatchedParams(foundRoute);
278
- } else {
279
- foundRoute = this.flatRoutes.find((route) => {
280
- const matchedParams = getMatchedParams(route);
281
- if (matchedParams) {
282
- routeParams = matchedParams;
283
- return true;
284
- }
285
- return false;
286
- });
287
- }
288
- let routeCursor = foundRoute || this.routesById[root.rootRouteId];
289
- const matchedRoutes = [routeCursor];
290
- while (routeCursor.parentRoute) {
291
- routeCursor = routeCursor.parentRoute;
292
- matchedRoutes.unshift(routeCursor);
293
- }
294
- return { matchedRoutes, routeParams, foundRoute };
203
+ this.getMatchedRoutes = (pathname, routePathname) => {
204
+ return getMatchedRoutes({
205
+ pathname,
206
+ routePathname,
207
+ basepath: this.basepath,
208
+ caseSensitive: this.options.caseSensitive,
209
+ routesByPath: this.routesByPath,
210
+ routesById: this.routesById,
211
+ flatRoutes: this.flatRoutes
212
+ });
295
213
  };
296
214
  this.cancelMatch = (id) => {
297
215
  const match = this.getMatch(id);
@@ -504,10 +422,16 @@ class RouterCore {
504
422
  maskedNext = build(maskedDest);
505
423
  }
506
424
  }
507
- const nextMatches = this.getMatchedRoutes(next, dest);
425
+ const nextMatches = this.getMatchedRoutes(
426
+ next.pathname,
427
+ dest.to
428
+ );
508
429
  const final = build(dest, nextMatches);
509
430
  if (maskedNext) {
510
- const maskedMatches = this.getMatchedRoutes(maskedNext, maskedDest);
431
+ const maskedMatches = this.getMatchedRoutes(
432
+ maskedNext.pathname,
433
+ maskedDest == null ? void 0 : maskedDest.to
434
+ );
511
435
  const maskedFinal = build(maskedDest, maskedMatches);
512
436
  final.maskedLocation = maskedFinal;
513
437
  }
@@ -618,6 +542,13 @@ class RouterCore {
618
542
  });
619
543
  };
620
544
  this.navigate = ({ to, reloadDocument, href, ...rest }) => {
545
+ if (!reloadDocument && href) {
546
+ try {
547
+ new URL(`${href}`);
548
+ reloadDocument = true;
549
+ } catch {
550
+ }
551
+ }
621
552
  if (reloadDocument) {
622
553
  if (!href) {
623
554
  const location = this.buildLocation({ to, ...rest });
@@ -636,8 +567,23 @@ class RouterCore {
636
567
  to
637
568
  });
638
569
  };
639
- this.load = async (opts) => {
570
+ this.beforeLoad = () => {
571
+ this.cancelMatches();
640
572
  this.latestLocation = this.parseLocation(this.latestLocation);
573
+ const pendingMatches = this.matchRoutes(this.latestLocation);
574
+ this.__store.setState((s) => ({
575
+ ...s,
576
+ status: "pending",
577
+ isLoading: true,
578
+ location: this.latestLocation,
579
+ pendingMatches,
580
+ // If a cached moved to pendingMatches, remove it from cachedMatches
581
+ cachedMatches: s.cachedMatches.filter((d) => {
582
+ return !pendingMatches.find((e) => e.id === d.id);
583
+ })
584
+ }));
585
+ };
586
+ this.load = async (opts) => {
641
587
  let redirect$1;
642
588
  let notFound$1;
643
589
  let loadPromise;
@@ -645,24 +591,9 @@ class RouterCore {
645
591
  this.startTransition(async () => {
646
592
  var _a;
647
593
  try {
594
+ this.beforeLoad();
648
595
  const next = this.latestLocation;
649
596
  const prevLocation = this.state.resolvedLocation;
650
- this.cancelMatches();
651
- let pendingMatches;
652
- store.batch(() => {
653
- pendingMatches = this.matchRoutes(next);
654
- this.__store.setState((s) => ({
655
- ...s,
656
- status: "pending",
657
- isLoading: true,
658
- location: next,
659
- pendingMatches,
660
- // If a cached moved to pendingMatches, remove it from cachedMatches
661
- cachedMatches: s.cachedMatches.filter((d) => {
662
- return !pendingMatches.find((e) => e.id === d.id);
663
- })
664
- }));
665
- });
666
597
  if (!this.state.redirect) {
667
598
  this.emit({
668
599
  type: "onBeforeNavigate",
@@ -681,7 +612,7 @@ class RouterCore {
681
612
  });
682
613
  await this.loadMatches({
683
614
  sync: opts == null ? void 0 : opts.sync,
684
- matches: pendingMatches,
615
+ matches: this.state.pendingMatches,
685
616
  location: next,
686
617
  // eslint-disable-next-line @typescript-eslint/require-await
687
618
  onReady: async () => {
@@ -730,11 +661,11 @@ class RouterCore {
730
661
  }
731
662
  });
732
663
  } catch (err) {
733
- if (redirect.isResolvedRedirect(err)) {
664
+ if (redirect.isRedirect(err)) {
734
665
  redirect$1 = err;
735
666
  if (!this.isServer) {
736
667
  this.navigate({
737
- ...redirect$1,
668
+ ...redirect$1.options,
738
669
  replace: true,
739
670
  ignoreBlocker: true
740
671
  });
@@ -744,7 +675,7 @@ class RouterCore {
744
675
  }
745
676
  this.__store.setState((s) => ({
746
677
  ...s,
747
- statusCode: redirect$1 ? redirect$1.statusCode : notFound$1 ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
678
+ statusCode: redirect$1 ? redirect$1.status : notFound$1 ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
748
679
  redirect: redirect$1
749
680
  }));
750
681
  }
@@ -842,12 +773,14 @@ class RouterCore {
842
773
  };
843
774
  const handleRedirectAndNotFound = (match, err) => {
844
775
  var _a, _b, _c, _d;
845
- if (redirect.isResolvedRedirect(err)) {
846
- if (!err.reloadDocument) {
847
- throw err;
848
- }
849
- }
850
776
  if (redirect.isRedirect(err) || notFound.isNotFound(err)) {
777
+ if (redirect.isRedirect(err)) {
778
+ if (err.redirectHandled) {
779
+ if (!err.options.reloadDocument) {
780
+ throw err;
781
+ }
782
+ }
783
+ }
851
784
  updateMatch(match.id, (prev) => ({
852
785
  ...prev,
853
786
  status: redirect.isRedirect(err) ? "redirected" : notFound.isNotFound(err) ? "notFound" : "error",
@@ -864,7 +797,9 @@ class RouterCore {
864
797
  (_c = match.loadPromise) == null ? void 0 : _c.resolve();
865
798
  if (redirect.isRedirect(err)) {
866
799
  rendered = true;
867
- err = this.resolveRedirect({ ...err, _fromLocation: location });
800
+ err.options._fromLocation = location;
801
+ err.redirectHandled = true;
802
+ err = this.resolveRedirect(err);
868
803
  throw err;
869
804
  } else if (notFound.isNotFound(err)) {
870
805
  this._handleNotFound(matches, err, {
@@ -1072,7 +1007,7 @@ class RouterCore {
1072
1007
  loaderPromise: utils.createControlledPromise(),
1073
1008
  preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
1074
1009
  }));
1075
- const executeHead = () => {
1010
+ const executeHead = async () => {
1076
1011
  var _a2, _b2, _c2, _d2, _e, _f;
1077
1012
  const match = this.getMatch(matchId);
1078
1013
  if (!match) {
@@ -1084,20 +1019,13 @@ class RouterCore {
1084
1019
  params: match.params,
1085
1020
  loaderData: match.loaderData
1086
1021
  };
1087
- const headFnContent = (_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext);
1022
+ const headFnContent = await ((_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext));
1088
1023
  const meta = headFnContent == null ? void 0 : headFnContent.meta;
1089
1024
  const links = headFnContent == null ? void 0 : headFnContent.links;
1090
1025
  const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
1091
- const scripts = (_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext);
1092
- const headers = (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext);
1093
- updateMatch(matchId, (prev) => ({
1094
- ...prev,
1095
- meta,
1096
- links,
1097
- headScripts,
1098
- headers,
1099
- scripts
1100
- }));
1026
+ const scripts = await ((_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext));
1027
+ const headers = await ((_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext));
1028
+ return { meta, links, headScripts, headers, scripts };
1101
1029
  };
1102
1030
  const runLoader = async () => {
1103
1031
  var _a2, _b2, _c2, _d2, _e;
@@ -1122,17 +1050,19 @@ class RouterCore {
1122
1050
  await route._lazyPromise;
1123
1051
  await potentialPendingMinPromise();
1124
1052
  await route._componentsPromise;
1125
- store.batch(() => {
1126
- updateMatch(matchId, (prev) => ({
1127
- ...prev,
1128
- error: void 0,
1129
- status: "success",
1130
- isFetching: false,
1131
- updatedAt: Date.now(),
1132
- loaderData
1133
- }));
1134
- executeHead();
1135
- });
1053
+ updateMatch(matchId, (prev) => ({
1054
+ ...prev,
1055
+ error: void 0,
1056
+ status: "success",
1057
+ isFetching: false,
1058
+ updatedAt: Date.now(),
1059
+ loaderData
1060
+ }));
1061
+ const head = await executeHead();
1062
+ updateMatch(matchId, (prev) => ({
1063
+ ...prev,
1064
+ ...head
1065
+ }));
1136
1066
  } catch (e) {
1137
1067
  let error = e;
1138
1068
  await potentialPendingMinPromise();
@@ -1146,28 +1076,26 @@ class RouterCore {
1146
1076
  onErrorError
1147
1077
  );
1148
1078
  }
1149
- store.batch(() => {
1150
- updateMatch(matchId, (prev) => ({
1151
- ...prev,
1152
- error,
1153
- status: "error",
1154
- isFetching: false
1155
- }));
1156
- executeHead();
1157
- });
1079
+ const head = await executeHead();
1080
+ updateMatch(matchId, (prev) => ({
1081
+ ...prev,
1082
+ error,
1083
+ status: "error",
1084
+ isFetching: false,
1085
+ ...head
1086
+ }));
1158
1087
  }
1159
1088
  (_e = this.serverSsr) == null ? void 0 : _e.onMatchSettled({
1160
1089
  router: this,
1161
1090
  match: this.getMatch(matchId)
1162
1091
  });
1163
1092
  } catch (err) {
1164
- store.batch(() => {
1165
- updateMatch(matchId, (prev) => ({
1166
- ...prev,
1167
- loaderPromise: void 0
1168
- }));
1169
- executeHead();
1170
- });
1093
+ const head = await executeHead();
1094
+ updateMatch(matchId, (prev) => ({
1095
+ ...prev,
1096
+ loaderPromise: void 0,
1097
+ ...head
1098
+ }));
1171
1099
  handleRedirectAndNotFound(this.getMatch(matchId), err);
1172
1100
  }
1173
1101
  };
@@ -1187,15 +1115,19 @@ class RouterCore {
1187
1115
  loaderPromise: void 0
1188
1116
  }));
1189
1117
  } catch (err) {
1190
- if (redirect.isResolvedRedirect(err)) {
1191
- await this.navigate(err);
1118
+ if (redirect.isRedirect(err)) {
1119
+ await this.navigate(err.options);
1192
1120
  }
1193
1121
  }
1194
1122
  })();
1195
1123
  } else if (status !== "success" || loaderShouldRunAsync && sync) {
1196
1124
  await runLoader();
1197
1125
  } else {
1198
- executeHead();
1126
+ const head = await executeHead();
1127
+ updateMatch(matchId, (prev) => ({
1128
+ ...prev,
1129
+ ...head
1130
+ }));
1199
1131
  }
1200
1132
  }
1201
1133
  if (!loaderIsRunningAsync) {
@@ -1254,10 +1186,13 @@ class RouterCore {
1254
1186
  });
1255
1187
  return this.load({ sync: opts == null ? void 0 : opts.sync });
1256
1188
  };
1257
- this.resolveRedirect = (err) => {
1258
- const redirect2 = err;
1259
- if (!redirect2.href) {
1260
- redirect2.href = this.buildLocation(redirect2).href;
1189
+ this.resolveRedirect = (redirect2) => {
1190
+ if (!redirect2.options.href) {
1191
+ redirect2.options.href = this.buildLocation(redirect2.options).href;
1192
+ redirect2.headers.set("Location", redirect2.options.href);
1193
+ }
1194
+ if (!redirect2.headers.get("Location")) {
1195
+ redirect2.headers.set("Location", redirect2.options.href);
1261
1196
  }
1262
1197
  return redirect2;
1263
1198
  };
@@ -1359,11 +1294,11 @@ class RouterCore {
1359
1294
  return matches;
1360
1295
  } catch (err) {
1361
1296
  if (redirect.isRedirect(err)) {
1362
- if (err.reloadDocument) {
1297
+ if (err.options.reloadDocument) {
1363
1298
  return void 0;
1364
1299
  }
1365
1300
  return await this.preloadRoute({
1366
- ...err,
1301
+ ...err.options,
1367
1302
  _fromLocation: next
1368
1303
  });
1369
1304
  }
@@ -1467,9 +1402,10 @@ class RouterCore {
1467
1402
  return this.routesById;
1468
1403
  }
1469
1404
  matchRoutesInternal(next, opts) {
1405
+ var _a;
1470
1406
  const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
1471
- next,
1472
- opts == null ? void 0 : opts.dest
1407
+ next.pathname,
1408
+ (_a = opts == null ? void 0 : opts.dest) == null ? void 0 : _a.to
1473
1409
  );
1474
1410
  let isGlobalNotFound = false;
1475
1411
  if (
@@ -1500,9 +1436,9 @@ class RouterCore {
1500
1436
  return root.rootRouteId;
1501
1437
  })();
1502
1438
  const parseErrors = matchedRoutes.map((route) => {
1503
- var _a;
1439
+ var _a2;
1504
1440
  let parsedParamsError;
1505
- const parseParams = ((_a = route.options.params) == null ? void 0 : _a.parse) ?? route.options.parseParams;
1441
+ const parseParams = ((_a2 = route.options.params) == null ? void 0 : _a2.parse) ?? route.options.parseParams;
1506
1442
  if (parseParams) {
1507
1443
  try {
1508
1444
  const parsedParams = parseParams(routeParams);
@@ -1526,7 +1462,7 @@ class RouterCore {
1526
1462
  return parentContext;
1527
1463
  };
1528
1464
  matchedRoutes.forEach((route, index) => {
1529
- var _a, _b;
1465
+ var _a2, _b;
1530
1466
  const parentMatch = matches[index - 1];
1531
1467
  const [preMatchSearch, strictMatchSearch, searchError] = (() => {
1532
1468
  const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
@@ -1554,7 +1490,7 @@ class RouterCore {
1554
1490
  return [parentSearch, {}, searchParamError];
1555
1491
  }
1556
1492
  })();
1557
- const loaderDeps = ((_b = (_a = route.options).loaderDeps) == null ? void 0 : _b.call(_a, {
1493
+ const loaderDeps = ((_b = (_a2 = route.options).loaderDeps) == null ? void 0 : _b.call(_a2, {
1558
1494
  search: preMatchSearch
1559
1495
  })) ?? "";
1560
1496
  const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
@@ -1632,7 +1568,7 @@ class RouterCore {
1632
1568
  matches.push(match);
1633
1569
  });
1634
1570
  matches.forEach((match, index) => {
1635
- var _a, _b;
1571
+ var _a2, _b;
1636
1572
  const route = this.looseRoutesById[match.routeId];
1637
1573
  const existingMatch = this.getMatch(match.id);
1638
1574
  if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
@@ -1650,7 +1586,7 @@ class RouterCore {
1650
1586
  preload: !!match.preload,
1651
1587
  matches
1652
1588
  };
1653
- match.__routeContext = ((_b = (_a = route.options).context) == null ? void 0 : _b.call(_a, contextFnContext)) ?? {};
1589
+ match.__routeContext = ((_b = (_a2 = route.options).context) == null ? void 0 : _b.call(_a2, contextFnContext)) ?? {};
1654
1590
  match.context = {
1655
1591
  ...parentContext,
1656
1592
  ...match.__routeContext,
@@ -1720,6 +1656,141 @@ function routeNeedsPreload(route) {
1720
1656
  }
1721
1657
  return false;
1722
1658
  }
1659
+ function processRouteTree({
1660
+ routeTree,
1661
+ initRoute
1662
+ }) {
1663
+ const routesById = {};
1664
+ const routesByPath = {};
1665
+ const recurseRoutes = (childRoutes) => {
1666
+ childRoutes.forEach((childRoute, i) => {
1667
+ initRoute == null ? void 0 : initRoute(childRoute, i);
1668
+ const existingRoute = routesById[childRoute.id];
1669
+ invariant(
1670
+ !existingRoute,
1671
+ `Duplicate routes found with id: ${String(childRoute.id)}`
1672
+ );
1673
+ routesById[childRoute.id] = childRoute;
1674
+ if (!childRoute.isRoot && childRoute.path) {
1675
+ const trimmedFullPath = path.trimPathRight(childRoute.fullPath);
1676
+ if (!routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
1677
+ routesByPath[trimmedFullPath] = childRoute;
1678
+ }
1679
+ }
1680
+ const children = childRoute.children;
1681
+ if (children == null ? void 0 : children.length) {
1682
+ recurseRoutes(children);
1683
+ }
1684
+ });
1685
+ };
1686
+ recurseRoutes([routeTree]);
1687
+ const scoredRoutes = [];
1688
+ const routes = Object.values(routesById);
1689
+ routes.forEach((d, i) => {
1690
+ var _a;
1691
+ if (d.isRoot || !d.path) {
1692
+ return;
1693
+ }
1694
+ const trimmed = path.trimPathLeft(d.fullPath);
1695
+ const parsed = path.parsePathname(trimmed);
1696
+ while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
1697
+ parsed.shift();
1698
+ }
1699
+ const scores = parsed.map((segment) => {
1700
+ if (segment.value === "/") {
1701
+ return 0.75;
1702
+ }
1703
+ if (segment.type === "param" && segment.prefixSegment && segment.suffixSegment) {
1704
+ return 0.55;
1705
+ }
1706
+ if (segment.type === "param" && segment.prefixSegment) {
1707
+ return 0.52;
1708
+ }
1709
+ if (segment.type === "param" && segment.suffixSegment) {
1710
+ return 0.51;
1711
+ }
1712
+ if (segment.type === "param") {
1713
+ return 0.5;
1714
+ }
1715
+ if (segment.type === "wildcard" && segment.prefixSegment && segment.suffixSegment) {
1716
+ return 0.3;
1717
+ }
1718
+ if (segment.type === "wildcard" && segment.prefixSegment) {
1719
+ return 0.27;
1720
+ }
1721
+ if (segment.type === "wildcard" && segment.suffixSegment) {
1722
+ return 0.26;
1723
+ }
1724
+ if (segment.type === "wildcard") {
1725
+ return 0.25;
1726
+ }
1727
+ return 1;
1728
+ });
1729
+ scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
1730
+ });
1731
+ const flatRoutes = scoredRoutes.sort((a, b) => {
1732
+ const minLength = Math.min(a.scores.length, b.scores.length);
1733
+ for (let i = 0; i < minLength; i++) {
1734
+ if (a.scores[i] !== b.scores[i]) {
1735
+ return b.scores[i] - a.scores[i];
1736
+ }
1737
+ }
1738
+ if (a.scores.length !== b.scores.length) {
1739
+ return b.scores.length - a.scores.length;
1740
+ }
1741
+ for (let i = 0; i < minLength; i++) {
1742
+ if (a.parsed[i].value !== b.parsed[i].value) {
1743
+ return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
1744
+ }
1745
+ }
1746
+ return a.index - b.index;
1747
+ }).map((d, i) => {
1748
+ d.child.rank = i;
1749
+ return d.child;
1750
+ });
1751
+ return { routesById, routesByPath, flatRoutes };
1752
+ }
1753
+ function getMatchedRoutes({
1754
+ pathname,
1755
+ routePathname,
1756
+ basepath,
1757
+ caseSensitive,
1758
+ routesByPath,
1759
+ routesById,
1760
+ flatRoutes
1761
+ }) {
1762
+ let routeParams = {};
1763
+ const trimmedPath = path.trimPathRight(pathname);
1764
+ const getMatchedParams = (route) => {
1765
+ var _a;
1766
+ const result = path.matchPathname(basepath, trimmedPath, {
1767
+ to: route.fullPath,
1768
+ caseSensitive: ((_a = route.options) == null ? void 0 : _a.caseSensitive) ?? caseSensitive,
1769
+ fuzzy: true
1770
+ });
1771
+ return result;
1772
+ };
1773
+ let foundRoute = routePathname !== void 0 ? routesByPath[routePathname] : void 0;
1774
+ if (foundRoute) {
1775
+ routeParams = getMatchedParams(foundRoute);
1776
+ } else {
1777
+ foundRoute = flatRoutes.find((route) => {
1778
+ const matchedParams = getMatchedParams(route);
1779
+ if (matchedParams) {
1780
+ routeParams = matchedParams;
1781
+ return true;
1782
+ }
1783
+ return false;
1784
+ });
1785
+ }
1786
+ let routeCursor = foundRoute || routesById[root.rootRouteId];
1787
+ const matchedRoutes = [routeCursor];
1788
+ while (routeCursor.parentRoute) {
1789
+ routeCursor = routeCursor.parentRoute;
1790
+ matchedRoutes.unshift(routeCursor);
1791
+ }
1792
+ return { matchedRoutes, routeParams, foundRoute };
1793
+ }
1723
1794
  exports.PathParamError = PathParamError;
1724
1795
  exports.RouterCore = RouterCore;
1725
1796
  exports.SearchParamError = SearchParamError;
@@ -1727,5 +1798,7 @@ exports.componentTypes = componentTypes;
1727
1798
  exports.defaultSerializeError = defaultSerializeError;
1728
1799
  exports.getInitialRouterState = getInitialRouterState;
1729
1800
  exports.getLocationChangeInfo = getLocationChangeInfo;
1801
+ exports.getMatchedRoutes = getMatchedRoutes;
1730
1802
  exports.lazyFn = lazyFn;
1803
+ exports.processRouteTree = processRouteTree;
1731
1804
  //# sourceMappingURL=router.cjs.map