@tanstack/router-core 1.120.5 → 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 +15 -14
  16. package/dist/cjs/router.cjs +231 -155
  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 +15 -14
  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 +234 -158
  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 +104 -35
  49. package/src/router.ts +332 -209
  50. package/src/typePrimitives.ts +2 -2
  51. package/src/utils.ts +14 -0
@@ -2,12 +2,12 @@ import { Store, batch } from "@tanstack/store";
2
2
  import { createMemoryHistory, createBrowserHistory, parseHref } from "@tanstack/history";
3
3
  import invariant from "tiny-invariant";
4
4
  import { pick, createControlledPromise, deepEqual, replaceEqualDeep, last, functionalUpdate } from "./utils.js";
5
- import { trimPath, trimPathLeft, parsePathname, resolvePath, cleanPath, trimPathRight, matchPathname, interpolatePath, joinPaths } from "./path.js";
5
+ import { trimPath, resolvePath, cleanPath, matchPathname, trimPathRight, interpolatePath, joinPaths, trimPathLeft, parsePathname } from "./path.js";
6
6
  import { isNotFound } from "./not-found.js";
7
7
  import { setupScrollRestoration } from "./scroll-restoration.js";
8
8
  import { defaultParseSearch, defaultStringifySearch } from "./searchParams.js";
9
9
  import { rootRouteId } from "./root.js";
10
- import { isResolvedRedirect, isRedirect } from "./redirect.js";
10
+ import { isRedirect } from "./redirect.js";
11
11
  function defaultSerializeError(err) {
12
12
  if (err instanceof Error) {
13
13
  const obj = {
@@ -46,6 +46,7 @@ class RouterCore {
46
46
  this.isScrollRestoring = false;
47
47
  this.isScrollRestorationSetup = false;
48
48
  this.startTransition = (fn) => fn();
49
+ this.isShell = false;
49
50
  this.update = (newOptions) => {
50
51
  var _a;
51
52
  if (newOptions.notFoundRoute) {
@@ -72,10 +73,7 @@ class RouterCore {
72
73
  this.basepath = `/${trimPath(newOptions.basepath)}`;
73
74
  }
74
75
  }
75
- if (
76
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
77
- !this.history || this.options.history && this.options.history !== this.history
78
- ) {
76
+ if (!this.history || this.options.history && this.options.history !== this.history) {
79
77
  this.history = this.options.history ?? (this.isServer ? createMemoryHistory({
80
78
  initialEntries: [this.basepath || "/"]
81
79
  }) : createBrowserHistory());
@@ -98,16 +96,28 @@ class RouterCore {
98
96
  });
99
97
  setupScrollRestoration(this);
100
98
  }
101
- if (typeof window !== "undefined" && "CSS" in window && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
102
- typeof ((_a = window.CSS) == null ? void 0 : _a.supports) === "function") {
99
+ if (typeof window !== "undefined" && "CSS" in window && typeof ((_a = window.CSS) == null ? void 0 : _a.supports) === "function") {
103
100
  this.isViewTransitionTypesSupported = window.CSS.supports(
104
101
  "selector(:active-view-transition-type(a)"
105
102
  );
106
103
  }
104
+ if (this.latestLocation.search.__TSS_SHELL) {
105
+ this.isShell = true;
106
+ }
107
107
  };
108
108
  this.buildRouteTree = () => {
109
- this.routesById = {};
110
- this.routesByPath = {};
109
+ const { routesById, routesByPath, flatRoutes } = processRouteTree({
110
+ routeTree: this.routeTree,
111
+ initRoute: (route, i) => {
112
+ route.init({
113
+ originalIndex: i,
114
+ defaultSsr: this.options.defaultSsr
115
+ });
116
+ }
117
+ });
118
+ this.routesById = routesById;
119
+ this.routesByPath = routesByPath;
120
+ this.flatRoutes = flatRoutes;
111
121
  const notFoundRoute = this.options.notFoundRoute;
112
122
  if (notFoundRoute) {
113
123
  notFoundRoute.init({
@@ -116,77 +126,6 @@ class RouterCore {
116
126
  });
117
127
  this.routesById[notFoundRoute.id] = notFoundRoute;
118
128
  }
119
- const recurseRoutes = (childRoutes) => {
120
- childRoutes.forEach((childRoute, i) => {
121
- childRoute.init({
122
- originalIndex: i,
123
- defaultSsr: this.options.defaultSsr
124
- });
125
- const existingRoute = this.routesById[childRoute.id];
126
- invariant(
127
- !existingRoute,
128
- `Duplicate routes found with id: ${String(childRoute.id)}`
129
- );
130
- this.routesById[childRoute.id] = childRoute;
131
- if (!childRoute.isRoot && childRoute.path) {
132
- const trimmedFullPath = trimPathRight(childRoute.fullPath);
133
- if (!this.routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
134
- this.routesByPath[trimmedFullPath] = childRoute;
135
- }
136
- }
137
- const children = childRoute.children;
138
- if (children == null ? void 0 : children.length) {
139
- recurseRoutes(children);
140
- }
141
- });
142
- };
143
- recurseRoutes([this.routeTree]);
144
- const scoredRoutes = [];
145
- const routes = Object.values(this.routesById);
146
- routes.forEach((d, i) => {
147
- var _a;
148
- if (d.isRoot || !d.path) {
149
- return;
150
- }
151
- const trimmed = trimPathLeft(d.fullPath);
152
- const parsed = parsePathname(trimmed);
153
- while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
154
- parsed.shift();
155
- }
156
- const scores = parsed.map((segment) => {
157
- if (segment.value === "/") {
158
- return 0.75;
159
- }
160
- if (segment.type === "param") {
161
- return 0.5;
162
- }
163
- if (segment.type === "wildcard") {
164
- return 0.25;
165
- }
166
- return 1;
167
- });
168
- scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
169
- });
170
- this.flatRoutes = scoredRoutes.sort((a, b) => {
171
- const minLength = Math.min(a.scores.length, b.scores.length);
172
- for (let i = 0; i < minLength; i++) {
173
- if (a.scores[i] !== b.scores[i]) {
174
- return b.scores[i] - a.scores[i];
175
- }
176
- }
177
- if (a.scores.length !== b.scores.length) {
178
- return b.scores.length - a.scores.length;
179
- }
180
- for (let i = 0; i < minLength; i++) {
181
- if (a.parsed[i].value !== b.parsed[i].value) {
182
- return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
183
- }
184
- }
185
- return a.index - b.index;
186
- }).map((d, i) => {
187
- d.child.rank = i;
188
- return d.child;
189
- });
190
129
  };
191
130
  this.subscribe = (eventType, fn) => {
192
131
  const listener = {
@@ -259,37 +198,16 @@ class RouterCore {
259
198
  return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
260
199
  }
261
200
  };
262
- this.getMatchedRoutes = (next, dest) => {
263
- let routeParams = {};
264
- const trimmedPath = trimPathRight(next.pathname);
265
- const getMatchedParams = (route) => {
266
- const result = matchPathname(this.basepath, trimmedPath, {
267
- to: route.fullPath,
268
- caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive,
269
- fuzzy: true
270
- });
271
- return result;
272
- };
273
- let foundRoute = (dest == null ? void 0 : dest.to) !== void 0 ? this.routesByPath[dest.to] : void 0;
274
- if (foundRoute) {
275
- routeParams = getMatchedParams(foundRoute);
276
- } else {
277
- foundRoute = this.flatRoutes.find((route) => {
278
- const matchedParams = getMatchedParams(route);
279
- if (matchedParams) {
280
- routeParams = matchedParams;
281
- return true;
282
- }
283
- return false;
284
- });
285
- }
286
- let routeCursor = foundRoute || this.routesById[rootRouteId];
287
- const matchedRoutes = [routeCursor];
288
- while (routeCursor.parentRoute) {
289
- routeCursor = routeCursor.parentRoute;
290
- matchedRoutes.unshift(routeCursor);
291
- }
292
- return { matchedRoutes, routeParams, foundRoute };
201
+ this.getMatchedRoutes = (pathname, routePathname) => {
202
+ return getMatchedRoutes({
203
+ pathname,
204
+ routePathname,
205
+ basepath: this.basepath,
206
+ caseSensitive: this.options.caseSensitive,
207
+ routesByPath: this.routesByPath,
208
+ routesById: this.routesById,
209
+ flatRoutes: this.flatRoutes
210
+ });
293
211
  };
294
212
  this.cancelMatch = (id) => {
295
213
  const match = this.getMatch(id);
@@ -502,10 +420,16 @@ class RouterCore {
502
420
  maskedNext = build(maskedDest);
503
421
  }
504
422
  }
505
- const nextMatches = this.getMatchedRoutes(next, dest);
423
+ const nextMatches = this.getMatchedRoutes(
424
+ next.pathname,
425
+ dest.to
426
+ );
506
427
  const final = build(dest, nextMatches);
507
428
  if (maskedNext) {
508
- const maskedMatches = this.getMatchedRoutes(maskedNext, maskedDest);
429
+ const maskedMatches = this.getMatchedRoutes(
430
+ maskedNext.pathname,
431
+ maskedDest == null ? void 0 : maskedDest.to
432
+ );
509
433
  const maskedFinal = build(maskedDest, maskedMatches);
510
434
  final.maskedLocation = maskedFinal;
511
435
  }
@@ -616,6 +540,13 @@ class RouterCore {
616
540
  });
617
541
  };
618
542
  this.navigate = ({ to, reloadDocument, href, ...rest }) => {
543
+ if (!reloadDocument && href) {
544
+ try {
545
+ new URL(`${href}`);
546
+ reloadDocument = true;
547
+ } catch {
548
+ }
549
+ }
619
550
  if (reloadDocument) {
620
551
  if (!href) {
621
552
  const location = this.buildLocation({ to, ...rest });
@@ -634,8 +565,23 @@ class RouterCore {
634
565
  to
635
566
  });
636
567
  };
637
- this.load = async (opts) => {
568
+ this.beforeLoad = () => {
569
+ this.cancelMatches();
638
570
  this.latestLocation = this.parseLocation(this.latestLocation);
571
+ const pendingMatches = this.matchRoutes(this.latestLocation);
572
+ this.__store.setState((s) => ({
573
+ ...s,
574
+ status: "pending",
575
+ isLoading: true,
576
+ location: this.latestLocation,
577
+ pendingMatches,
578
+ // If a cached moved to pendingMatches, remove it from cachedMatches
579
+ cachedMatches: s.cachedMatches.filter((d) => {
580
+ return !pendingMatches.find((e) => e.id === d.id);
581
+ })
582
+ }));
583
+ };
584
+ this.load = async (opts) => {
639
585
  let redirect;
640
586
  let notFound;
641
587
  let loadPromise;
@@ -643,24 +589,9 @@ class RouterCore {
643
589
  this.startTransition(async () => {
644
590
  var _a;
645
591
  try {
592
+ this.beforeLoad();
646
593
  const next = this.latestLocation;
647
594
  const prevLocation = this.state.resolvedLocation;
648
- this.cancelMatches();
649
- let pendingMatches;
650
- batch(() => {
651
- pendingMatches = this.matchRoutes(next);
652
- this.__store.setState((s) => ({
653
- ...s,
654
- status: "pending",
655
- isLoading: true,
656
- location: next,
657
- pendingMatches,
658
- // If a cached moved to pendingMatches, remove it from cachedMatches
659
- cachedMatches: s.cachedMatches.filter((d) => {
660
- return !pendingMatches.find((e) => e.id === d.id);
661
- })
662
- }));
663
- });
664
595
  if (!this.state.redirect) {
665
596
  this.emit({
666
597
  type: "onBeforeNavigate",
@@ -679,7 +610,7 @@ class RouterCore {
679
610
  });
680
611
  await this.loadMatches({
681
612
  sync: opts == null ? void 0 : opts.sync,
682
- matches: pendingMatches,
613
+ matches: this.state.pendingMatches,
683
614
  location: next,
684
615
  // eslint-disable-next-line @typescript-eslint/require-await
685
616
  onReady: async () => {
@@ -728,11 +659,11 @@ class RouterCore {
728
659
  }
729
660
  });
730
661
  } catch (err) {
731
- if (isResolvedRedirect(err)) {
662
+ if (isRedirect(err)) {
732
663
  redirect = err;
733
664
  if (!this.isServer) {
734
665
  this.navigate({
735
- ...redirect,
666
+ ...redirect.options,
736
667
  replace: true,
737
668
  ignoreBlocker: true
738
669
  });
@@ -742,7 +673,7 @@ class RouterCore {
742
673
  }
743
674
  this.__store.setState((s) => ({
744
675
  ...s,
745
- statusCode: redirect ? redirect.statusCode : notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
676
+ statusCode: redirect ? redirect.status : notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
746
677
  redirect
747
678
  }));
748
679
  }
@@ -840,12 +771,14 @@ class RouterCore {
840
771
  };
841
772
  const handleRedirectAndNotFound = (match, err) => {
842
773
  var _a, _b, _c, _d;
843
- if (isResolvedRedirect(err)) {
844
- if (!err.reloadDocument) {
845
- throw err;
846
- }
847
- }
848
774
  if (isRedirect(err) || isNotFound(err)) {
775
+ if (isRedirect(err)) {
776
+ if (err.redirectHandled) {
777
+ if (!err.options.reloadDocument) {
778
+ throw err;
779
+ }
780
+ }
781
+ }
849
782
  updateMatch(match.id, (prev) => ({
850
783
  ...prev,
851
784
  status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : "error",
@@ -862,7 +795,9 @@ class RouterCore {
862
795
  (_c = match.loadPromise) == null ? void 0 : _c.resolve();
863
796
  if (isRedirect(err)) {
864
797
  rendered = true;
865
- err = this.resolveRedirect({ ...err, _fromLocation: location });
798
+ err.options._fromLocation = location;
799
+ err.redirectHandled = true;
800
+ err = this.resolveRedirect(err);
866
801
  throw err;
867
802
  } else if (isNotFound(err)) {
868
803
  this._handleNotFound(matches, err, {
@@ -1185,8 +1120,8 @@ class RouterCore {
1185
1120
  loaderPromise: void 0
1186
1121
  }));
1187
1122
  } catch (err) {
1188
- if (isResolvedRedirect(err)) {
1189
- await this.navigate(err);
1123
+ if (isRedirect(err)) {
1124
+ await this.navigate(err.options);
1190
1125
  }
1191
1126
  }
1192
1127
  })();
@@ -1252,10 +1187,13 @@ class RouterCore {
1252
1187
  });
1253
1188
  return this.load({ sync: opts == null ? void 0 : opts.sync });
1254
1189
  };
1255
- this.resolveRedirect = (err) => {
1256
- const redirect = err;
1257
- if (!redirect.href) {
1258
- redirect.href = this.buildLocation(redirect).href;
1190
+ this.resolveRedirect = (redirect) => {
1191
+ if (!redirect.options.href) {
1192
+ redirect.options.href = this.buildLocation(redirect.options).href;
1193
+ redirect.headers.set("Location", redirect.options.href);
1194
+ }
1195
+ if (!redirect.headers.get("Location")) {
1196
+ redirect.headers.set("Location", redirect.options.href);
1259
1197
  }
1260
1198
  return redirect;
1261
1199
  };
@@ -1357,11 +1295,11 @@ class RouterCore {
1357
1295
  return matches;
1358
1296
  } catch (err) {
1359
1297
  if (isRedirect(err)) {
1360
- if (err.reloadDocument) {
1298
+ if (err.options.reloadDocument) {
1361
1299
  return void 0;
1362
1300
  }
1363
1301
  return await this.preloadRoute({
1364
- ...err,
1302
+ ...err.options,
1365
1303
  _fromLocation: next
1366
1304
  });
1367
1305
  }
@@ -1465,9 +1403,10 @@ class RouterCore {
1465
1403
  return this.routesById;
1466
1404
  }
1467
1405
  matchRoutesInternal(next, opts) {
1406
+ var _a;
1468
1407
  const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
1469
- next,
1470
- opts == null ? void 0 : opts.dest
1408
+ next.pathname,
1409
+ (_a = opts == null ? void 0 : opts.dest) == null ? void 0 : _a.to
1471
1410
  );
1472
1411
  let isGlobalNotFound = false;
1473
1412
  if (
@@ -1498,9 +1437,9 @@ class RouterCore {
1498
1437
  return rootRouteId;
1499
1438
  })();
1500
1439
  const parseErrors = matchedRoutes.map((route) => {
1501
- var _a;
1440
+ var _a2;
1502
1441
  let parsedParamsError;
1503
- const parseParams = ((_a = route.options.params) == null ? void 0 : _a.parse) ?? route.options.parseParams;
1442
+ const parseParams = ((_a2 = route.options.params) == null ? void 0 : _a2.parse) ?? route.options.parseParams;
1504
1443
  if (parseParams) {
1505
1444
  try {
1506
1445
  const parsedParams = parseParams(routeParams);
@@ -1524,7 +1463,7 @@ class RouterCore {
1524
1463
  return parentContext;
1525
1464
  };
1526
1465
  matchedRoutes.forEach((route, index) => {
1527
- var _a, _b;
1466
+ var _a2, _b;
1528
1467
  const parentMatch = matches[index - 1];
1529
1468
  const [preMatchSearch, strictMatchSearch, searchError] = (() => {
1530
1469
  const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
@@ -1552,7 +1491,7 @@ class RouterCore {
1552
1491
  return [parentSearch, {}, searchParamError];
1553
1492
  }
1554
1493
  })();
1555
- const loaderDeps = ((_b = (_a = route.options).loaderDeps) == null ? void 0 : _b.call(_a, {
1494
+ const loaderDeps = ((_b = (_a2 = route.options).loaderDeps) == null ? void 0 : _b.call(_a2, {
1556
1495
  search: preMatchSearch
1557
1496
  })) ?? "";
1558
1497
  const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
@@ -1630,7 +1569,7 @@ class RouterCore {
1630
1569
  matches.push(match);
1631
1570
  });
1632
1571
  matches.forEach((match, index) => {
1633
- var _a, _b;
1572
+ var _a2, _b;
1634
1573
  const route = this.looseRoutesById[match.routeId];
1635
1574
  const existingMatch = this.getMatch(match.id);
1636
1575
  if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
@@ -1648,7 +1587,7 @@ class RouterCore {
1648
1587
  preload: !!match.preload,
1649
1588
  matches
1650
1589
  };
1651
- match.__routeContext = ((_b = (_a = route.options).context) == null ? void 0 : _b.call(_a, contextFnContext)) ?? {};
1590
+ match.__routeContext = ((_b = (_a2 = route.options).context) == null ? void 0 : _b.call(_a2, contextFnContext)) ?? {};
1652
1591
  match.context = {
1653
1592
  ...parentContext,
1654
1593
  ...match.__routeContext,
@@ -1718,6 +1657,141 @@ function routeNeedsPreload(route) {
1718
1657
  }
1719
1658
  return false;
1720
1659
  }
1660
+ function processRouteTree({
1661
+ routeTree,
1662
+ initRoute
1663
+ }) {
1664
+ const routesById = {};
1665
+ const routesByPath = {};
1666
+ const recurseRoutes = (childRoutes) => {
1667
+ childRoutes.forEach((childRoute, i) => {
1668
+ initRoute == null ? void 0 : initRoute(childRoute, i);
1669
+ const existingRoute = routesById[childRoute.id];
1670
+ invariant(
1671
+ !existingRoute,
1672
+ `Duplicate routes found with id: ${String(childRoute.id)}`
1673
+ );
1674
+ routesById[childRoute.id] = childRoute;
1675
+ if (!childRoute.isRoot && childRoute.path) {
1676
+ const trimmedFullPath = trimPathRight(childRoute.fullPath);
1677
+ if (!routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
1678
+ routesByPath[trimmedFullPath] = childRoute;
1679
+ }
1680
+ }
1681
+ const children = childRoute.children;
1682
+ if (children == null ? void 0 : children.length) {
1683
+ recurseRoutes(children);
1684
+ }
1685
+ });
1686
+ };
1687
+ recurseRoutes([routeTree]);
1688
+ const scoredRoutes = [];
1689
+ const routes = Object.values(routesById);
1690
+ routes.forEach((d, i) => {
1691
+ var _a;
1692
+ if (d.isRoot || !d.path) {
1693
+ return;
1694
+ }
1695
+ const trimmed = trimPathLeft(d.fullPath);
1696
+ const parsed = parsePathname(trimmed);
1697
+ while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
1698
+ parsed.shift();
1699
+ }
1700
+ const scores = parsed.map((segment) => {
1701
+ if (segment.value === "/") {
1702
+ return 0.75;
1703
+ }
1704
+ if (segment.type === "param" && segment.prefixSegment && segment.suffixSegment) {
1705
+ return 0.55;
1706
+ }
1707
+ if (segment.type === "param" && segment.prefixSegment) {
1708
+ return 0.52;
1709
+ }
1710
+ if (segment.type === "param" && segment.suffixSegment) {
1711
+ return 0.51;
1712
+ }
1713
+ if (segment.type === "param") {
1714
+ return 0.5;
1715
+ }
1716
+ if (segment.type === "wildcard" && segment.prefixSegment && segment.suffixSegment) {
1717
+ return 0.3;
1718
+ }
1719
+ if (segment.type === "wildcard" && segment.prefixSegment) {
1720
+ return 0.27;
1721
+ }
1722
+ if (segment.type === "wildcard" && segment.suffixSegment) {
1723
+ return 0.26;
1724
+ }
1725
+ if (segment.type === "wildcard") {
1726
+ return 0.25;
1727
+ }
1728
+ return 1;
1729
+ });
1730
+ scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
1731
+ });
1732
+ const flatRoutes = scoredRoutes.sort((a, b) => {
1733
+ const minLength = Math.min(a.scores.length, b.scores.length);
1734
+ for (let i = 0; i < minLength; i++) {
1735
+ if (a.scores[i] !== b.scores[i]) {
1736
+ return b.scores[i] - a.scores[i];
1737
+ }
1738
+ }
1739
+ if (a.scores.length !== b.scores.length) {
1740
+ return b.scores.length - a.scores.length;
1741
+ }
1742
+ for (let i = 0; i < minLength; i++) {
1743
+ if (a.parsed[i].value !== b.parsed[i].value) {
1744
+ return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
1745
+ }
1746
+ }
1747
+ return a.index - b.index;
1748
+ }).map((d, i) => {
1749
+ d.child.rank = i;
1750
+ return d.child;
1751
+ });
1752
+ return { routesById, routesByPath, flatRoutes };
1753
+ }
1754
+ function getMatchedRoutes({
1755
+ pathname,
1756
+ routePathname,
1757
+ basepath,
1758
+ caseSensitive,
1759
+ routesByPath,
1760
+ routesById,
1761
+ flatRoutes
1762
+ }) {
1763
+ let routeParams = {};
1764
+ const trimmedPath = trimPathRight(pathname);
1765
+ const getMatchedParams = (route) => {
1766
+ var _a;
1767
+ const result = matchPathname(basepath, trimmedPath, {
1768
+ to: route.fullPath,
1769
+ caseSensitive: ((_a = route.options) == null ? void 0 : _a.caseSensitive) ?? caseSensitive,
1770
+ fuzzy: true
1771
+ });
1772
+ return result;
1773
+ };
1774
+ let foundRoute = routePathname !== void 0 ? routesByPath[routePathname] : void 0;
1775
+ if (foundRoute) {
1776
+ routeParams = getMatchedParams(foundRoute);
1777
+ } else {
1778
+ foundRoute = flatRoutes.find((route) => {
1779
+ const matchedParams = getMatchedParams(route);
1780
+ if (matchedParams) {
1781
+ routeParams = matchedParams;
1782
+ return true;
1783
+ }
1784
+ return false;
1785
+ });
1786
+ }
1787
+ let routeCursor = foundRoute || routesById[rootRouteId];
1788
+ const matchedRoutes = [routeCursor];
1789
+ while (routeCursor.parentRoute) {
1790
+ routeCursor = routeCursor.parentRoute;
1791
+ matchedRoutes.unshift(routeCursor);
1792
+ }
1793
+ return { matchedRoutes, routeParams, foundRoute };
1794
+ }
1721
1795
  export {
1722
1796
  PathParamError,
1723
1797
  RouterCore,
@@ -1726,6 +1800,8 @@ export {
1726
1800
  defaultSerializeError,
1727
1801
  getInitialRouterState,
1728
1802
  getLocationChangeInfo,
1729
- lazyFn
1803
+ getMatchedRoutes,
1804
+ lazyFn,
1805
+ processRouteTree
1730
1806
  };
1731
1807
  //# sourceMappingURL=router.js.map