@tanstack/router-core 1.120.4 → 1.121.0-alpha.1

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 +17 -18
  16. package/dist/cjs/router.cjs +290 -211
  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 +2 -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 +17 -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 +293 -214
  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 +2 -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 +119 -39
  49. package/src/router.ts +393 -269
  50. package/src/typePrimitives.ts +2 -2
  51. package/src/utils.ts +14 -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,8 +1007,35 @@ class RouterCore {
1072
1007
  loaderPromise: utils.createControlledPromise(),
1073
1008
  preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
1074
1009
  }));
1010
+ const executeHead = () => {
1011
+ var _a2, _b2, _c2, _d2, _e, _f;
1012
+ const match = this.getMatch(matchId);
1013
+ if (!match) {
1014
+ return;
1015
+ }
1016
+ const assetContext = {
1017
+ matches,
1018
+ match,
1019
+ params: match.params,
1020
+ loaderData: match.loaderData
1021
+ };
1022
+ const headFnContent = (_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext);
1023
+ const meta = headFnContent == null ? void 0 : headFnContent.meta;
1024
+ const links = headFnContent == null ? void 0 : headFnContent.links;
1025
+ const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
1026
+ const scripts = (_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext);
1027
+ const headers = (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext);
1028
+ updateMatch(matchId, (prev) => ({
1029
+ ...prev,
1030
+ meta,
1031
+ links,
1032
+ headScripts,
1033
+ headers,
1034
+ scripts
1035
+ }));
1036
+ };
1075
1037
  const runLoader = async () => {
1076
- var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k;
1038
+ var _a2, _b2, _c2, _d2, _e;
1077
1039
  try {
1078
1040
  const potentialPendingMinPromise = async () => {
1079
1041
  const latestMatch = this.getMatch(matchId);
@@ -1094,40 +1056,24 @@ class RouterCore {
1094
1056
  );
1095
1057
  await route._lazyPromise;
1096
1058
  await potentialPendingMinPromise();
1097
- const assetContext = {
1098
- matches,
1099
- match: this.getMatch(matchId),
1100
- params: this.getMatch(matchId).params,
1101
- loaderData
1102
- };
1103
- const headFnContent = (_d2 = (_c2 = route.options).head) == null ? void 0 : _d2.call(_c2, assetContext);
1104
- const meta = headFnContent == null ? void 0 : headFnContent.meta;
1105
- const links = headFnContent == null ? void 0 : headFnContent.links;
1106
- const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
1107
- const scripts = (_f = (_e = route.options).scripts) == null ? void 0 : _f.call(_e, assetContext);
1108
- const headers = (_h = (_g = route.options).headers) == null ? void 0 : _h.call(_g, {
1109
- loaderData
1110
- });
1111
1059
  await route._componentsPromise;
1112
- updateMatch(matchId, (prev) => ({
1113
- ...prev,
1114
- error: void 0,
1115
- status: "success",
1116
- isFetching: false,
1117
- updatedAt: Date.now(),
1118
- loaderData,
1119
- meta,
1120
- links,
1121
- headScripts,
1122
- headers,
1123
- scripts
1124
- }));
1060
+ store.batch(() => {
1061
+ updateMatch(matchId, (prev) => ({
1062
+ ...prev,
1063
+ error: void 0,
1064
+ status: "success",
1065
+ isFetching: false,
1066
+ updatedAt: Date.now(),
1067
+ loaderData
1068
+ }));
1069
+ executeHead();
1070
+ });
1125
1071
  } catch (e) {
1126
1072
  let error = e;
1127
1073
  await potentialPendingMinPromise();
1128
1074
  handleRedirectAndNotFound(this.getMatch(matchId), e);
1129
1075
  try {
1130
- (_j = (_i = route.options).onError) == null ? void 0 : _j.call(_i, e);
1076
+ (_d2 = (_c2 = route.options).onError) == null ? void 0 : _d2.call(_c2, e);
1131
1077
  } catch (onErrorError) {
1132
1078
  error = onErrorError;
1133
1079
  handleRedirectAndNotFound(
@@ -1135,22 +1081,28 @@ class RouterCore {
1135
1081
  onErrorError
1136
1082
  );
1137
1083
  }
1138
- updateMatch(matchId, (prev) => ({
1139
- ...prev,
1140
- error,
1141
- status: "error",
1142
- isFetching: false
1143
- }));
1084
+ store.batch(() => {
1085
+ updateMatch(matchId, (prev) => ({
1086
+ ...prev,
1087
+ error,
1088
+ status: "error",
1089
+ isFetching: false
1090
+ }));
1091
+ executeHead();
1092
+ });
1144
1093
  }
1145
- (_k = this.serverSsr) == null ? void 0 : _k.onMatchSettled({
1094
+ (_e = this.serverSsr) == null ? void 0 : _e.onMatchSettled({
1146
1095
  router: this,
1147
1096
  match: this.getMatch(matchId)
1148
1097
  });
1149
1098
  } catch (err) {
1150
- updateMatch(matchId, (prev) => ({
1151
- ...prev,
1152
- loaderPromise: void 0
1153
- }));
1099
+ store.batch(() => {
1100
+ updateMatch(matchId, (prev) => ({
1101
+ ...prev,
1102
+ loaderPromise: void 0
1103
+ }));
1104
+ executeHead();
1105
+ });
1154
1106
  handleRedirectAndNotFound(this.getMatch(matchId), err);
1155
1107
  }
1156
1108
  };
@@ -1170,13 +1122,15 @@ class RouterCore {
1170
1122
  loaderPromise: void 0
1171
1123
  }));
1172
1124
  } catch (err) {
1173
- if (redirect.isResolvedRedirect(err)) {
1174
- await this.navigate(err);
1125
+ if (redirect.isRedirect(err)) {
1126
+ await this.navigate(err.options);
1175
1127
  }
1176
1128
  }
1177
1129
  })();
1178
1130
  } else if (status !== "success" || loaderShouldRunAsync && sync) {
1179
1131
  await runLoader();
1132
+ } else {
1133
+ executeHead();
1180
1134
  }
1181
1135
  }
1182
1136
  if (!loaderIsRunningAsync) {
@@ -1235,10 +1189,13 @@ class RouterCore {
1235
1189
  });
1236
1190
  return this.load({ sync: opts == null ? void 0 : opts.sync });
1237
1191
  };
1238
- this.resolveRedirect = (err) => {
1239
- const redirect2 = err;
1240
- if (!redirect2.href) {
1241
- redirect2.href = this.buildLocation(redirect2).href;
1192
+ this.resolveRedirect = (redirect2) => {
1193
+ if (!redirect2.options.href) {
1194
+ redirect2.options.href = this.buildLocation(redirect2.options).href;
1195
+ redirect2.headers.set("Location", redirect2.options.href);
1196
+ }
1197
+ if (!redirect2.headers.get("Location")) {
1198
+ redirect2.headers.set("Location", redirect2.options.href);
1242
1199
  }
1243
1200
  return redirect2;
1244
1201
  };
@@ -1340,11 +1297,11 @@ class RouterCore {
1340
1297
  return matches;
1341
1298
  } catch (err) {
1342
1299
  if (redirect.isRedirect(err)) {
1343
- if (err.reloadDocument) {
1300
+ if (err.options.reloadDocument) {
1344
1301
  return void 0;
1345
1302
  }
1346
1303
  return await this.preloadRoute({
1347
- ...err,
1304
+ ...err.options,
1348
1305
  _fromLocation: next
1349
1306
  });
1350
1307
  }
@@ -1448,9 +1405,10 @@ class RouterCore {
1448
1405
  return this.routesById;
1449
1406
  }
1450
1407
  matchRoutesInternal(next, opts) {
1408
+ var _a;
1451
1409
  const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
1452
- next,
1453
- opts == null ? void 0 : opts.dest
1410
+ next.pathname,
1411
+ (_a = opts == null ? void 0 : opts.dest) == null ? void 0 : _a.to
1454
1412
  );
1455
1413
  let isGlobalNotFound = false;
1456
1414
  if (
@@ -1481,9 +1439,9 @@ class RouterCore {
1481
1439
  return root.rootRouteId;
1482
1440
  })();
1483
1441
  const parseErrors = matchedRoutes.map((route) => {
1484
- var _a;
1442
+ var _a2;
1485
1443
  let parsedParamsError;
1486
- const parseParams = ((_a = route.options.params) == null ? void 0 : _a.parse) ?? route.options.parseParams;
1444
+ const parseParams = ((_a2 = route.options.params) == null ? void 0 : _a2.parse) ?? route.options.parseParams;
1487
1445
  if (parseParams) {
1488
1446
  try {
1489
1447
  const parsedParams = parseParams(routeParams);
@@ -1507,7 +1465,7 @@ class RouterCore {
1507
1465
  return parentContext;
1508
1466
  };
1509
1467
  matchedRoutes.forEach((route, index) => {
1510
- var _a, _b;
1468
+ var _a2, _b;
1511
1469
  const parentMatch = matches[index - 1];
1512
1470
  const [preMatchSearch, strictMatchSearch, searchError] = (() => {
1513
1471
  const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
@@ -1535,7 +1493,7 @@ class RouterCore {
1535
1493
  return [parentSearch, {}, searchParamError];
1536
1494
  }
1537
1495
  })();
1538
- const loaderDeps = ((_b = (_a = route.options).loaderDeps) == null ? void 0 : _b.call(_a, {
1496
+ const loaderDeps = ((_b = (_a2 = route.options).loaderDeps) == null ? void 0 : _b.call(_a2, {
1539
1497
  search: preMatchSearch
1540
1498
  })) ?? "";
1541
1499
  const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
@@ -1613,7 +1571,7 @@ class RouterCore {
1613
1571
  matches.push(match);
1614
1572
  });
1615
1573
  matches.forEach((match, index) => {
1616
- var _a, _b, _c, _d, _e, _f, _g, _h;
1574
+ var _a2, _b;
1617
1575
  const route = this.looseRoutesById[match.routeId];
1618
1576
  const existingMatch = this.getMatch(match.id);
1619
1577
  if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
@@ -1631,29 +1589,13 @@ class RouterCore {
1631
1589
  preload: !!match.preload,
1632
1590
  matches
1633
1591
  };
1634
- match.__routeContext = ((_b = (_a = route.options).context) == null ? void 0 : _b.call(_a, contextFnContext)) ?? {};
1592
+ match.__routeContext = ((_b = (_a2 = route.options).context) == null ? void 0 : _b.call(_a2, contextFnContext)) ?? {};
1635
1593
  match.context = {
1636
1594
  ...parentContext,
1637
1595
  ...match.__routeContext,
1638
1596
  ...match.__beforeLoadContext
1639
1597
  };
1640
1598
  }
1641
- if (match.status === "success") {
1642
- match.headers = (_d = (_c = route.options).headers) == null ? void 0 : _d.call(_c, {
1643
- loaderData: match.loaderData
1644
- });
1645
- const assetContext = {
1646
- matches,
1647
- match,
1648
- params: match.params,
1649
- loaderData: match.loaderData
1650
- };
1651
- const headFnContent = (_f = (_e = route.options).head) == null ? void 0 : _f.call(_e, assetContext);
1652
- match.links = headFnContent == null ? void 0 : headFnContent.links;
1653
- match.headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
1654
- match.meta = headFnContent == null ? void 0 : headFnContent.meta;
1655
- match.scripts = (_h = (_g = route.options).scripts) == null ? void 0 : _h.call(_g, assetContext);
1656
- }
1657
1599
  });
1658
1600
  return matches;
1659
1601
  }
@@ -1717,6 +1659,141 @@ function routeNeedsPreload(route) {
1717
1659
  }
1718
1660
  return false;
1719
1661
  }
1662
+ function processRouteTree({
1663
+ routeTree,
1664
+ initRoute
1665
+ }) {
1666
+ const routesById = {};
1667
+ const routesByPath = {};
1668
+ const recurseRoutes = (childRoutes) => {
1669
+ childRoutes.forEach((childRoute, i) => {
1670
+ initRoute == null ? void 0 : initRoute(childRoute, i);
1671
+ const existingRoute = routesById[childRoute.id];
1672
+ invariant(
1673
+ !existingRoute,
1674
+ `Duplicate routes found with id: ${String(childRoute.id)}`
1675
+ );
1676
+ routesById[childRoute.id] = childRoute;
1677
+ if (!childRoute.isRoot && childRoute.path) {
1678
+ const trimmedFullPath = path.trimPathRight(childRoute.fullPath);
1679
+ if (!routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
1680
+ routesByPath[trimmedFullPath] = childRoute;
1681
+ }
1682
+ }
1683
+ const children = childRoute.children;
1684
+ if (children == null ? void 0 : children.length) {
1685
+ recurseRoutes(children);
1686
+ }
1687
+ });
1688
+ };
1689
+ recurseRoutes([routeTree]);
1690
+ const scoredRoutes = [];
1691
+ const routes = Object.values(routesById);
1692
+ routes.forEach((d, i) => {
1693
+ var _a;
1694
+ if (d.isRoot || !d.path) {
1695
+ return;
1696
+ }
1697
+ const trimmed = path.trimPathLeft(d.fullPath);
1698
+ const parsed = path.parsePathname(trimmed);
1699
+ while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
1700
+ parsed.shift();
1701
+ }
1702
+ const scores = parsed.map((segment) => {
1703
+ if (segment.value === "/") {
1704
+ return 0.75;
1705
+ }
1706
+ if (segment.type === "param" && segment.prefixSegment && segment.suffixSegment) {
1707
+ return 0.55;
1708
+ }
1709
+ if (segment.type === "param" && segment.prefixSegment) {
1710
+ return 0.52;
1711
+ }
1712
+ if (segment.type === "param" && segment.suffixSegment) {
1713
+ return 0.51;
1714
+ }
1715
+ if (segment.type === "param") {
1716
+ return 0.5;
1717
+ }
1718
+ if (segment.type === "wildcard" && segment.prefixSegment && segment.suffixSegment) {
1719
+ return 0.3;
1720
+ }
1721
+ if (segment.type === "wildcard" && segment.prefixSegment) {
1722
+ return 0.27;
1723
+ }
1724
+ if (segment.type === "wildcard" && segment.suffixSegment) {
1725
+ return 0.26;
1726
+ }
1727
+ if (segment.type === "wildcard") {
1728
+ return 0.25;
1729
+ }
1730
+ return 1;
1731
+ });
1732
+ scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
1733
+ });
1734
+ const flatRoutes = scoredRoutes.sort((a, b) => {
1735
+ const minLength = Math.min(a.scores.length, b.scores.length);
1736
+ for (let i = 0; i < minLength; i++) {
1737
+ if (a.scores[i] !== b.scores[i]) {
1738
+ return b.scores[i] - a.scores[i];
1739
+ }
1740
+ }
1741
+ if (a.scores.length !== b.scores.length) {
1742
+ return b.scores.length - a.scores.length;
1743
+ }
1744
+ for (let i = 0; i < minLength; i++) {
1745
+ if (a.parsed[i].value !== b.parsed[i].value) {
1746
+ return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
1747
+ }
1748
+ }
1749
+ return a.index - b.index;
1750
+ }).map((d, i) => {
1751
+ d.child.rank = i;
1752
+ return d.child;
1753
+ });
1754
+ return { routesById, routesByPath, flatRoutes };
1755
+ }
1756
+ function getMatchedRoutes({
1757
+ pathname,
1758
+ routePathname,
1759
+ basepath,
1760
+ caseSensitive,
1761
+ routesByPath,
1762
+ routesById,
1763
+ flatRoutes
1764
+ }) {
1765
+ let routeParams = {};
1766
+ const trimmedPath = path.trimPathRight(pathname);
1767
+ const getMatchedParams = (route) => {
1768
+ var _a;
1769
+ const result = path.matchPathname(basepath, trimmedPath, {
1770
+ to: route.fullPath,
1771
+ caseSensitive: ((_a = route.options) == null ? void 0 : _a.caseSensitive) ?? caseSensitive,
1772
+ fuzzy: true
1773
+ });
1774
+ return result;
1775
+ };
1776
+ let foundRoute = routePathname !== void 0 ? routesByPath[routePathname] : void 0;
1777
+ if (foundRoute) {
1778
+ routeParams = getMatchedParams(foundRoute);
1779
+ } else {
1780
+ foundRoute = flatRoutes.find((route) => {
1781
+ const matchedParams = getMatchedParams(route);
1782
+ if (matchedParams) {
1783
+ routeParams = matchedParams;
1784
+ return true;
1785
+ }
1786
+ return false;
1787
+ });
1788
+ }
1789
+ let routeCursor = foundRoute || routesById[root.rootRouteId];
1790
+ const matchedRoutes = [routeCursor];
1791
+ while (routeCursor.parentRoute) {
1792
+ routeCursor = routeCursor.parentRoute;
1793
+ matchedRoutes.unshift(routeCursor);
1794
+ }
1795
+ return { matchedRoutes, routeParams, foundRoute };
1796
+ }
1720
1797
  exports.PathParamError = PathParamError;
1721
1798
  exports.RouterCore = RouterCore;
1722
1799
  exports.SearchParamError = SearchParamError;
@@ -1724,5 +1801,7 @@ exports.componentTypes = componentTypes;
1724
1801
  exports.defaultSerializeError = defaultSerializeError;
1725
1802
  exports.getInitialRouterState = getInitialRouterState;
1726
1803
  exports.getLocationChangeInfo = getLocationChangeInfo;
1804
+ exports.getMatchedRoutes = getMatchedRoutes;
1727
1805
  exports.lazyFn = lazyFn;
1806
+ exports.processRouteTree = processRouteTree;
1728
1807
  //# sourceMappingURL=router.cjs.map