@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.
- package/dist/cjs/fileRoute.d.cts +6 -2
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +6 -6
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +18 -1
- package/dist/cjs/path.cjs +130 -16
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +17 -0
- package/dist/cjs/redirect.cjs +17 -14
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/redirect.d.cts +13 -7
- package/dist/cjs/route.cjs +12 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +19 -18
- package/dist/cjs/router.cjs +268 -195
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +46 -3
- package/dist/cjs/typePrimitives.d.cts +2 -2
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +3 -0
- package/dist/esm/fileRoute.d.ts +6 -2
- package/dist/esm/index.d.ts +6 -6
- package/dist/esm/index.js +5 -2
- package/dist/esm/link.d.ts +18 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/path.d.ts +17 -0
- package/dist/esm/path.js +130 -16
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/redirect.d.ts +13 -7
- package/dist/esm/redirect.js +17 -14
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/route.d.ts +19 -18
- package/dist/esm/route.js +12 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +46 -3
- package/dist/esm/router.js +271 -198
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +2 -2
- package/dist/esm/utils.d.ts +3 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/fileRoute.ts +90 -1
- package/src/index.ts +14 -6
- package/src/link.ts +97 -11
- package/src/path.ts +181 -16
- package/src/redirect.ts +37 -22
- package/src/route.ts +109 -39
- package/src/router.ts +373 -250
- package/src/typePrimitives.ts +2 -2
- package/src/utils.ts +15 -0
package/dist/esm/router.js
CHANGED
|
@@ -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,
|
|
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 {
|
|
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 &&
|
|
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
|
-
|
|
110
|
-
|
|
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 = (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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(
|
|
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(
|
|
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.
|
|
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 (
|
|
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.
|
|
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 =
|
|
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, {
|
|
@@ -1070,7 +1005,7 @@ class RouterCore {
|
|
|
1070
1005
|
loaderPromise: createControlledPromise(),
|
|
1071
1006
|
preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
|
|
1072
1007
|
}));
|
|
1073
|
-
const executeHead = () => {
|
|
1008
|
+
const executeHead = async () => {
|
|
1074
1009
|
var _a2, _b2, _c2, _d2, _e, _f;
|
|
1075
1010
|
const match = this.getMatch(matchId);
|
|
1076
1011
|
if (!match) {
|
|
@@ -1082,20 +1017,13 @@ class RouterCore {
|
|
|
1082
1017
|
params: match.params,
|
|
1083
1018
|
loaderData: match.loaderData
|
|
1084
1019
|
};
|
|
1085
|
-
const headFnContent = (_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext);
|
|
1020
|
+
const headFnContent = await ((_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext));
|
|
1086
1021
|
const meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1087
1022
|
const links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1088
1023
|
const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1089
|
-
const scripts = (_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext);
|
|
1090
|
-
const headers = (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext);
|
|
1091
|
-
|
|
1092
|
-
...prev,
|
|
1093
|
-
meta,
|
|
1094
|
-
links,
|
|
1095
|
-
headScripts,
|
|
1096
|
-
headers,
|
|
1097
|
-
scripts
|
|
1098
|
-
}));
|
|
1024
|
+
const scripts = await ((_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext));
|
|
1025
|
+
const headers = await ((_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext));
|
|
1026
|
+
return { meta, links, headScripts, headers, scripts };
|
|
1099
1027
|
};
|
|
1100
1028
|
const runLoader = async () => {
|
|
1101
1029
|
var _a2, _b2, _c2, _d2, _e;
|
|
@@ -1120,17 +1048,19 @@ class RouterCore {
|
|
|
1120
1048
|
await route._lazyPromise;
|
|
1121
1049
|
await potentialPendingMinPromise();
|
|
1122
1050
|
await route._componentsPromise;
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1051
|
+
updateMatch(matchId, (prev) => ({
|
|
1052
|
+
...prev,
|
|
1053
|
+
error: void 0,
|
|
1054
|
+
status: "success",
|
|
1055
|
+
isFetching: false,
|
|
1056
|
+
updatedAt: Date.now(),
|
|
1057
|
+
loaderData
|
|
1058
|
+
}));
|
|
1059
|
+
const head = await executeHead();
|
|
1060
|
+
updateMatch(matchId, (prev) => ({
|
|
1061
|
+
...prev,
|
|
1062
|
+
...head
|
|
1063
|
+
}));
|
|
1134
1064
|
} catch (e) {
|
|
1135
1065
|
let error = e;
|
|
1136
1066
|
await potentialPendingMinPromise();
|
|
@@ -1144,28 +1074,26 @@ class RouterCore {
|
|
|
1144
1074
|
onErrorError
|
|
1145
1075
|
);
|
|
1146
1076
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
});
|
|
1077
|
+
const head = await executeHead();
|
|
1078
|
+
updateMatch(matchId, (prev) => ({
|
|
1079
|
+
...prev,
|
|
1080
|
+
error,
|
|
1081
|
+
status: "error",
|
|
1082
|
+
isFetching: false,
|
|
1083
|
+
...head
|
|
1084
|
+
}));
|
|
1156
1085
|
}
|
|
1157
1086
|
(_e = this.serverSsr) == null ? void 0 : _e.onMatchSettled({
|
|
1158
1087
|
router: this,
|
|
1159
1088
|
match: this.getMatch(matchId)
|
|
1160
1089
|
});
|
|
1161
1090
|
} catch (err) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
});
|
|
1091
|
+
const head = await executeHead();
|
|
1092
|
+
updateMatch(matchId, (prev) => ({
|
|
1093
|
+
...prev,
|
|
1094
|
+
loaderPromise: void 0,
|
|
1095
|
+
...head
|
|
1096
|
+
}));
|
|
1169
1097
|
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
1170
1098
|
}
|
|
1171
1099
|
};
|
|
@@ -1185,15 +1113,19 @@ class RouterCore {
|
|
|
1185
1113
|
loaderPromise: void 0
|
|
1186
1114
|
}));
|
|
1187
1115
|
} catch (err) {
|
|
1188
|
-
if (
|
|
1189
|
-
await this.navigate(err);
|
|
1116
|
+
if (isRedirect(err)) {
|
|
1117
|
+
await this.navigate(err.options);
|
|
1190
1118
|
}
|
|
1191
1119
|
}
|
|
1192
1120
|
})();
|
|
1193
1121
|
} else if (status !== "success" || loaderShouldRunAsync && sync) {
|
|
1194
1122
|
await runLoader();
|
|
1195
1123
|
} else {
|
|
1196
|
-
executeHead();
|
|
1124
|
+
const head = await executeHead();
|
|
1125
|
+
updateMatch(matchId, (prev) => ({
|
|
1126
|
+
...prev,
|
|
1127
|
+
...head
|
|
1128
|
+
}));
|
|
1197
1129
|
}
|
|
1198
1130
|
}
|
|
1199
1131
|
if (!loaderIsRunningAsync) {
|
|
@@ -1252,10 +1184,13 @@ class RouterCore {
|
|
|
1252
1184
|
});
|
|
1253
1185
|
return this.load({ sync: opts == null ? void 0 : opts.sync });
|
|
1254
1186
|
};
|
|
1255
|
-
this.resolveRedirect = (
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
redirect.
|
|
1187
|
+
this.resolveRedirect = (redirect) => {
|
|
1188
|
+
if (!redirect.options.href) {
|
|
1189
|
+
redirect.options.href = this.buildLocation(redirect.options).href;
|
|
1190
|
+
redirect.headers.set("Location", redirect.options.href);
|
|
1191
|
+
}
|
|
1192
|
+
if (!redirect.headers.get("Location")) {
|
|
1193
|
+
redirect.headers.set("Location", redirect.options.href);
|
|
1259
1194
|
}
|
|
1260
1195
|
return redirect;
|
|
1261
1196
|
};
|
|
@@ -1357,11 +1292,11 @@ class RouterCore {
|
|
|
1357
1292
|
return matches;
|
|
1358
1293
|
} catch (err) {
|
|
1359
1294
|
if (isRedirect(err)) {
|
|
1360
|
-
if (err.reloadDocument) {
|
|
1295
|
+
if (err.options.reloadDocument) {
|
|
1361
1296
|
return void 0;
|
|
1362
1297
|
}
|
|
1363
1298
|
return await this.preloadRoute({
|
|
1364
|
-
...err,
|
|
1299
|
+
...err.options,
|
|
1365
1300
|
_fromLocation: next
|
|
1366
1301
|
});
|
|
1367
1302
|
}
|
|
@@ -1465,9 +1400,10 @@ class RouterCore {
|
|
|
1465
1400
|
return this.routesById;
|
|
1466
1401
|
}
|
|
1467
1402
|
matchRoutesInternal(next, opts) {
|
|
1403
|
+
var _a;
|
|
1468
1404
|
const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
|
|
1469
|
-
next,
|
|
1470
|
-
opts == null ? void 0 : opts.dest
|
|
1405
|
+
next.pathname,
|
|
1406
|
+
(_a = opts == null ? void 0 : opts.dest) == null ? void 0 : _a.to
|
|
1471
1407
|
);
|
|
1472
1408
|
let isGlobalNotFound = false;
|
|
1473
1409
|
if (
|
|
@@ -1498,9 +1434,9 @@ class RouterCore {
|
|
|
1498
1434
|
return rootRouteId;
|
|
1499
1435
|
})();
|
|
1500
1436
|
const parseErrors = matchedRoutes.map((route) => {
|
|
1501
|
-
var
|
|
1437
|
+
var _a2;
|
|
1502
1438
|
let parsedParamsError;
|
|
1503
|
-
const parseParams = ((
|
|
1439
|
+
const parseParams = ((_a2 = route.options.params) == null ? void 0 : _a2.parse) ?? route.options.parseParams;
|
|
1504
1440
|
if (parseParams) {
|
|
1505
1441
|
try {
|
|
1506
1442
|
const parsedParams = parseParams(routeParams);
|
|
@@ -1524,7 +1460,7 @@ class RouterCore {
|
|
|
1524
1460
|
return parentContext;
|
|
1525
1461
|
};
|
|
1526
1462
|
matchedRoutes.forEach((route, index) => {
|
|
1527
|
-
var
|
|
1463
|
+
var _a2, _b;
|
|
1528
1464
|
const parentMatch = matches[index - 1];
|
|
1529
1465
|
const [preMatchSearch, strictMatchSearch, searchError] = (() => {
|
|
1530
1466
|
const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
|
|
@@ -1552,7 +1488,7 @@ class RouterCore {
|
|
|
1552
1488
|
return [parentSearch, {}, searchParamError];
|
|
1553
1489
|
}
|
|
1554
1490
|
})();
|
|
1555
|
-
const loaderDeps = ((_b = (
|
|
1491
|
+
const loaderDeps = ((_b = (_a2 = route.options).loaderDeps) == null ? void 0 : _b.call(_a2, {
|
|
1556
1492
|
search: preMatchSearch
|
|
1557
1493
|
})) ?? "";
|
|
1558
1494
|
const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
|
|
@@ -1630,7 +1566,7 @@ class RouterCore {
|
|
|
1630
1566
|
matches.push(match);
|
|
1631
1567
|
});
|
|
1632
1568
|
matches.forEach((match, index) => {
|
|
1633
|
-
var
|
|
1569
|
+
var _a2, _b;
|
|
1634
1570
|
const route = this.looseRoutesById[match.routeId];
|
|
1635
1571
|
const existingMatch = this.getMatch(match.id);
|
|
1636
1572
|
if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
|
|
@@ -1648,7 +1584,7 @@ class RouterCore {
|
|
|
1648
1584
|
preload: !!match.preload,
|
|
1649
1585
|
matches
|
|
1650
1586
|
};
|
|
1651
|
-
match.__routeContext = ((_b = (
|
|
1587
|
+
match.__routeContext = ((_b = (_a2 = route.options).context) == null ? void 0 : _b.call(_a2, contextFnContext)) ?? {};
|
|
1652
1588
|
match.context = {
|
|
1653
1589
|
...parentContext,
|
|
1654
1590
|
...match.__routeContext,
|
|
@@ -1718,6 +1654,141 @@ function routeNeedsPreload(route) {
|
|
|
1718
1654
|
}
|
|
1719
1655
|
return false;
|
|
1720
1656
|
}
|
|
1657
|
+
function processRouteTree({
|
|
1658
|
+
routeTree,
|
|
1659
|
+
initRoute
|
|
1660
|
+
}) {
|
|
1661
|
+
const routesById = {};
|
|
1662
|
+
const routesByPath = {};
|
|
1663
|
+
const recurseRoutes = (childRoutes) => {
|
|
1664
|
+
childRoutes.forEach((childRoute, i) => {
|
|
1665
|
+
initRoute == null ? void 0 : initRoute(childRoute, i);
|
|
1666
|
+
const existingRoute = routesById[childRoute.id];
|
|
1667
|
+
invariant(
|
|
1668
|
+
!existingRoute,
|
|
1669
|
+
`Duplicate routes found with id: ${String(childRoute.id)}`
|
|
1670
|
+
);
|
|
1671
|
+
routesById[childRoute.id] = childRoute;
|
|
1672
|
+
if (!childRoute.isRoot && childRoute.path) {
|
|
1673
|
+
const trimmedFullPath = trimPathRight(childRoute.fullPath);
|
|
1674
|
+
if (!routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith("/")) {
|
|
1675
|
+
routesByPath[trimmedFullPath] = childRoute;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
const children = childRoute.children;
|
|
1679
|
+
if (children == null ? void 0 : children.length) {
|
|
1680
|
+
recurseRoutes(children);
|
|
1681
|
+
}
|
|
1682
|
+
});
|
|
1683
|
+
};
|
|
1684
|
+
recurseRoutes([routeTree]);
|
|
1685
|
+
const scoredRoutes = [];
|
|
1686
|
+
const routes = Object.values(routesById);
|
|
1687
|
+
routes.forEach((d, i) => {
|
|
1688
|
+
var _a;
|
|
1689
|
+
if (d.isRoot || !d.path) {
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
const trimmed = trimPathLeft(d.fullPath);
|
|
1693
|
+
const parsed = parsePathname(trimmed);
|
|
1694
|
+
while (parsed.length > 1 && ((_a = parsed[0]) == null ? void 0 : _a.value) === "/") {
|
|
1695
|
+
parsed.shift();
|
|
1696
|
+
}
|
|
1697
|
+
const scores = parsed.map((segment) => {
|
|
1698
|
+
if (segment.value === "/") {
|
|
1699
|
+
return 0.75;
|
|
1700
|
+
}
|
|
1701
|
+
if (segment.type === "param" && segment.prefixSegment && segment.suffixSegment) {
|
|
1702
|
+
return 0.55;
|
|
1703
|
+
}
|
|
1704
|
+
if (segment.type === "param" && segment.prefixSegment) {
|
|
1705
|
+
return 0.52;
|
|
1706
|
+
}
|
|
1707
|
+
if (segment.type === "param" && segment.suffixSegment) {
|
|
1708
|
+
return 0.51;
|
|
1709
|
+
}
|
|
1710
|
+
if (segment.type === "param") {
|
|
1711
|
+
return 0.5;
|
|
1712
|
+
}
|
|
1713
|
+
if (segment.type === "wildcard" && segment.prefixSegment && segment.suffixSegment) {
|
|
1714
|
+
return 0.3;
|
|
1715
|
+
}
|
|
1716
|
+
if (segment.type === "wildcard" && segment.prefixSegment) {
|
|
1717
|
+
return 0.27;
|
|
1718
|
+
}
|
|
1719
|
+
if (segment.type === "wildcard" && segment.suffixSegment) {
|
|
1720
|
+
return 0.26;
|
|
1721
|
+
}
|
|
1722
|
+
if (segment.type === "wildcard") {
|
|
1723
|
+
return 0.25;
|
|
1724
|
+
}
|
|
1725
|
+
return 1;
|
|
1726
|
+
});
|
|
1727
|
+
scoredRoutes.push({ child: d, trimmed, parsed, index: i, scores });
|
|
1728
|
+
});
|
|
1729
|
+
const flatRoutes = scoredRoutes.sort((a, b) => {
|
|
1730
|
+
const minLength = Math.min(a.scores.length, b.scores.length);
|
|
1731
|
+
for (let i = 0; i < minLength; i++) {
|
|
1732
|
+
if (a.scores[i] !== b.scores[i]) {
|
|
1733
|
+
return b.scores[i] - a.scores[i];
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
if (a.scores.length !== b.scores.length) {
|
|
1737
|
+
return b.scores.length - a.scores.length;
|
|
1738
|
+
}
|
|
1739
|
+
for (let i = 0; i < minLength; i++) {
|
|
1740
|
+
if (a.parsed[i].value !== b.parsed[i].value) {
|
|
1741
|
+
return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
return a.index - b.index;
|
|
1745
|
+
}).map((d, i) => {
|
|
1746
|
+
d.child.rank = i;
|
|
1747
|
+
return d.child;
|
|
1748
|
+
});
|
|
1749
|
+
return { routesById, routesByPath, flatRoutes };
|
|
1750
|
+
}
|
|
1751
|
+
function getMatchedRoutes({
|
|
1752
|
+
pathname,
|
|
1753
|
+
routePathname,
|
|
1754
|
+
basepath,
|
|
1755
|
+
caseSensitive,
|
|
1756
|
+
routesByPath,
|
|
1757
|
+
routesById,
|
|
1758
|
+
flatRoutes
|
|
1759
|
+
}) {
|
|
1760
|
+
let routeParams = {};
|
|
1761
|
+
const trimmedPath = trimPathRight(pathname);
|
|
1762
|
+
const getMatchedParams = (route) => {
|
|
1763
|
+
var _a;
|
|
1764
|
+
const result = matchPathname(basepath, trimmedPath, {
|
|
1765
|
+
to: route.fullPath,
|
|
1766
|
+
caseSensitive: ((_a = route.options) == null ? void 0 : _a.caseSensitive) ?? caseSensitive,
|
|
1767
|
+
fuzzy: true
|
|
1768
|
+
});
|
|
1769
|
+
return result;
|
|
1770
|
+
};
|
|
1771
|
+
let foundRoute = routePathname !== void 0 ? routesByPath[routePathname] : void 0;
|
|
1772
|
+
if (foundRoute) {
|
|
1773
|
+
routeParams = getMatchedParams(foundRoute);
|
|
1774
|
+
} else {
|
|
1775
|
+
foundRoute = flatRoutes.find((route) => {
|
|
1776
|
+
const matchedParams = getMatchedParams(route);
|
|
1777
|
+
if (matchedParams) {
|
|
1778
|
+
routeParams = matchedParams;
|
|
1779
|
+
return true;
|
|
1780
|
+
}
|
|
1781
|
+
return false;
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
let routeCursor = foundRoute || routesById[rootRouteId];
|
|
1785
|
+
const matchedRoutes = [routeCursor];
|
|
1786
|
+
while (routeCursor.parentRoute) {
|
|
1787
|
+
routeCursor = routeCursor.parentRoute;
|
|
1788
|
+
matchedRoutes.unshift(routeCursor);
|
|
1789
|
+
}
|
|
1790
|
+
return { matchedRoutes, routeParams, foundRoute };
|
|
1791
|
+
}
|
|
1721
1792
|
export {
|
|
1722
1793
|
PathParamError,
|
|
1723
1794
|
RouterCore,
|
|
@@ -1726,6 +1797,8 @@ export {
|
|
|
1726
1797
|
defaultSerializeError,
|
|
1727
1798
|
getInitialRouterState,
|
|
1728
1799
|
getLocationChangeInfo,
|
|
1729
|
-
|
|
1800
|
+
getMatchedRoutes,
|
|
1801
|
+
lazyFn,
|
|
1802
|
+
processRouteTree
|
|
1730
1803
|
};
|
|
1731
1804
|
//# sourceMappingURL=router.js.map
|