@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.
- 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 +17 -18
- package/dist/cjs/router.cjs +290 -211
- 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 +2 -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 +17 -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 +293 -214
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +2 -2
- package/dist/esm/utils.d.ts +2 -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 +119 -39
- package/src/router.ts +393 -269
- package/src/typePrimitives.ts +2 -2
- package/src/utils.ts +14 -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,8 +1005,35 @@ class RouterCore {
|
|
|
1070
1005
|
loaderPromise: createControlledPromise(),
|
|
1071
1006
|
preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
|
|
1072
1007
|
}));
|
|
1008
|
+
const executeHead = () => {
|
|
1009
|
+
var _a2, _b2, _c2, _d2, _e, _f;
|
|
1010
|
+
const match = this.getMatch(matchId);
|
|
1011
|
+
if (!match) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
const assetContext = {
|
|
1015
|
+
matches,
|
|
1016
|
+
match,
|
|
1017
|
+
params: match.params,
|
|
1018
|
+
loaderData: match.loaderData
|
|
1019
|
+
};
|
|
1020
|
+
const headFnContent = (_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext);
|
|
1021
|
+
const meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1022
|
+
const links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1023
|
+
const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1024
|
+
const scripts = (_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext);
|
|
1025
|
+
const headers = (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext);
|
|
1026
|
+
updateMatch(matchId, (prev) => ({
|
|
1027
|
+
...prev,
|
|
1028
|
+
meta,
|
|
1029
|
+
links,
|
|
1030
|
+
headScripts,
|
|
1031
|
+
headers,
|
|
1032
|
+
scripts
|
|
1033
|
+
}));
|
|
1034
|
+
};
|
|
1073
1035
|
const runLoader = async () => {
|
|
1074
|
-
var _a2, _b2, _c2, _d2, _e
|
|
1036
|
+
var _a2, _b2, _c2, _d2, _e;
|
|
1075
1037
|
try {
|
|
1076
1038
|
const potentialPendingMinPromise = async () => {
|
|
1077
1039
|
const latestMatch = this.getMatch(matchId);
|
|
@@ -1092,40 +1054,24 @@ class RouterCore {
|
|
|
1092
1054
|
);
|
|
1093
1055
|
await route._lazyPromise;
|
|
1094
1056
|
await potentialPendingMinPromise();
|
|
1095
|
-
const assetContext = {
|
|
1096
|
-
matches,
|
|
1097
|
-
match: this.getMatch(matchId),
|
|
1098
|
-
params: this.getMatch(matchId).params,
|
|
1099
|
-
loaderData
|
|
1100
|
-
};
|
|
1101
|
-
const headFnContent = (_d2 = (_c2 = route.options).head) == null ? void 0 : _d2.call(_c2, assetContext);
|
|
1102
|
-
const meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1103
|
-
const links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1104
|
-
const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1105
|
-
const scripts = (_f = (_e = route.options).scripts) == null ? void 0 : _f.call(_e, assetContext);
|
|
1106
|
-
const headers = (_h = (_g = route.options).headers) == null ? void 0 : _h.call(_g, {
|
|
1107
|
-
loaderData
|
|
1108
|
-
});
|
|
1109
1057
|
await route._componentsPromise;
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
scripts
|
|
1122
|
-
}));
|
|
1058
|
+
batch(() => {
|
|
1059
|
+
updateMatch(matchId, (prev) => ({
|
|
1060
|
+
...prev,
|
|
1061
|
+
error: void 0,
|
|
1062
|
+
status: "success",
|
|
1063
|
+
isFetching: false,
|
|
1064
|
+
updatedAt: Date.now(),
|
|
1065
|
+
loaderData
|
|
1066
|
+
}));
|
|
1067
|
+
executeHead();
|
|
1068
|
+
});
|
|
1123
1069
|
} catch (e) {
|
|
1124
1070
|
let error = e;
|
|
1125
1071
|
await potentialPendingMinPromise();
|
|
1126
1072
|
handleRedirectAndNotFound(this.getMatch(matchId), e);
|
|
1127
1073
|
try {
|
|
1128
|
-
(
|
|
1074
|
+
(_d2 = (_c2 = route.options).onError) == null ? void 0 : _d2.call(_c2, e);
|
|
1129
1075
|
} catch (onErrorError) {
|
|
1130
1076
|
error = onErrorError;
|
|
1131
1077
|
handleRedirectAndNotFound(
|
|
@@ -1133,22 +1079,28 @@ class RouterCore {
|
|
|
1133
1079
|
onErrorError
|
|
1134
1080
|
);
|
|
1135
1081
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1082
|
+
batch(() => {
|
|
1083
|
+
updateMatch(matchId, (prev) => ({
|
|
1084
|
+
...prev,
|
|
1085
|
+
error,
|
|
1086
|
+
status: "error",
|
|
1087
|
+
isFetching: false
|
|
1088
|
+
}));
|
|
1089
|
+
executeHead();
|
|
1090
|
+
});
|
|
1142
1091
|
}
|
|
1143
|
-
(
|
|
1092
|
+
(_e = this.serverSsr) == null ? void 0 : _e.onMatchSettled({
|
|
1144
1093
|
router: this,
|
|
1145
1094
|
match: this.getMatch(matchId)
|
|
1146
1095
|
});
|
|
1147
1096
|
} catch (err) {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1097
|
+
batch(() => {
|
|
1098
|
+
updateMatch(matchId, (prev) => ({
|
|
1099
|
+
...prev,
|
|
1100
|
+
loaderPromise: void 0
|
|
1101
|
+
}));
|
|
1102
|
+
executeHead();
|
|
1103
|
+
});
|
|
1152
1104
|
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
1153
1105
|
}
|
|
1154
1106
|
};
|
|
@@ -1168,13 +1120,15 @@ class RouterCore {
|
|
|
1168
1120
|
loaderPromise: void 0
|
|
1169
1121
|
}));
|
|
1170
1122
|
} catch (err) {
|
|
1171
|
-
if (
|
|
1172
|
-
await this.navigate(err);
|
|
1123
|
+
if (isRedirect(err)) {
|
|
1124
|
+
await this.navigate(err.options);
|
|
1173
1125
|
}
|
|
1174
1126
|
}
|
|
1175
1127
|
})();
|
|
1176
1128
|
} else if (status !== "success" || loaderShouldRunAsync && sync) {
|
|
1177
1129
|
await runLoader();
|
|
1130
|
+
} else {
|
|
1131
|
+
executeHead();
|
|
1178
1132
|
}
|
|
1179
1133
|
}
|
|
1180
1134
|
if (!loaderIsRunningAsync) {
|
|
@@ -1233,10 +1187,13 @@ class RouterCore {
|
|
|
1233
1187
|
});
|
|
1234
1188
|
return this.load({ sync: opts == null ? void 0 : opts.sync });
|
|
1235
1189
|
};
|
|
1236
|
-
this.resolveRedirect = (
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
redirect.
|
|
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);
|
|
1240
1197
|
}
|
|
1241
1198
|
return redirect;
|
|
1242
1199
|
};
|
|
@@ -1338,11 +1295,11 @@ class RouterCore {
|
|
|
1338
1295
|
return matches;
|
|
1339
1296
|
} catch (err) {
|
|
1340
1297
|
if (isRedirect(err)) {
|
|
1341
|
-
if (err.reloadDocument) {
|
|
1298
|
+
if (err.options.reloadDocument) {
|
|
1342
1299
|
return void 0;
|
|
1343
1300
|
}
|
|
1344
1301
|
return await this.preloadRoute({
|
|
1345
|
-
...err,
|
|
1302
|
+
...err.options,
|
|
1346
1303
|
_fromLocation: next
|
|
1347
1304
|
});
|
|
1348
1305
|
}
|
|
@@ -1446,9 +1403,10 @@ class RouterCore {
|
|
|
1446
1403
|
return this.routesById;
|
|
1447
1404
|
}
|
|
1448
1405
|
matchRoutesInternal(next, opts) {
|
|
1406
|
+
var _a;
|
|
1449
1407
|
const { foundRoute, matchedRoutes, routeParams } = this.getMatchedRoutes(
|
|
1450
|
-
next,
|
|
1451
|
-
opts == null ? void 0 : opts.dest
|
|
1408
|
+
next.pathname,
|
|
1409
|
+
(_a = opts == null ? void 0 : opts.dest) == null ? void 0 : _a.to
|
|
1452
1410
|
);
|
|
1453
1411
|
let isGlobalNotFound = false;
|
|
1454
1412
|
if (
|
|
@@ -1479,9 +1437,9 @@ class RouterCore {
|
|
|
1479
1437
|
return rootRouteId;
|
|
1480
1438
|
})();
|
|
1481
1439
|
const parseErrors = matchedRoutes.map((route) => {
|
|
1482
|
-
var
|
|
1440
|
+
var _a2;
|
|
1483
1441
|
let parsedParamsError;
|
|
1484
|
-
const parseParams = ((
|
|
1442
|
+
const parseParams = ((_a2 = route.options.params) == null ? void 0 : _a2.parse) ?? route.options.parseParams;
|
|
1485
1443
|
if (parseParams) {
|
|
1486
1444
|
try {
|
|
1487
1445
|
const parsedParams = parseParams(routeParams);
|
|
@@ -1505,7 +1463,7 @@ class RouterCore {
|
|
|
1505
1463
|
return parentContext;
|
|
1506
1464
|
};
|
|
1507
1465
|
matchedRoutes.forEach((route, index) => {
|
|
1508
|
-
var
|
|
1466
|
+
var _a2, _b;
|
|
1509
1467
|
const parentMatch = matches[index - 1];
|
|
1510
1468
|
const [preMatchSearch, strictMatchSearch, searchError] = (() => {
|
|
1511
1469
|
const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
|
|
@@ -1533,7 +1491,7 @@ class RouterCore {
|
|
|
1533
1491
|
return [parentSearch, {}, searchParamError];
|
|
1534
1492
|
}
|
|
1535
1493
|
})();
|
|
1536
|
-
const loaderDeps = ((_b = (
|
|
1494
|
+
const loaderDeps = ((_b = (_a2 = route.options).loaderDeps) == null ? void 0 : _b.call(_a2, {
|
|
1537
1495
|
search: preMatchSearch
|
|
1538
1496
|
})) ?? "";
|
|
1539
1497
|
const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
|
|
@@ -1611,7 +1569,7 @@ class RouterCore {
|
|
|
1611
1569
|
matches.push(match);
|
|
1612
1570
|
});
|
|
1613
1571
|
matches.forEach((match, index) => {
|
|
1614
|
-
var
|
|
1572
|
+
var _a2, _b;
|
|
1615
1573
|
const route = this.looseRoutesById[match.routeId];
|
|
1616
1574
|
const existingMatch = this.getMatch(match.id);
|
|
1617
1575
|
if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
|
|
@@ -1629,29 +1587,13 @@ class RouterCore {
|
|
|
1629
1587
|
preload: !!match.preload,
|
|
1630
1588
|
matches
|
|
1631
1589
|
};
|
|
1632
|
-
match.__routeContext = ((_b = (
|
|
1590
|
+
match.__routeContext = ((_b = (_a2 = route.options).context) == null ? void 0 : _b.call(_a2, contextFnContext)) ?? {};
|
|
1633
1591
|
match.context = {
|
|
1634
1592
|
...parentContext,
|
|
1635
1593
|
...match.__routeContext,
|
|
1636
1594
|
...match.__beforeLoadContext
|
|
1637
1595
|
};
|
|
1638
1596
|
}
|
|
1639
|
-
if (match.status === "success") {
|
|
1640
|
-
match.headers = (_d = (_c = route.options).headers) == null ? void 0 : _d.call(_c, {
|
|
1641
|
-
loaderData: match.loaderData
|
|
1642
|
-
});
|
|
1643
|
-
const assetContext = {
|
|
1644
|
-
matches,
|
|
1645
|
-
match,
|
|
1646
|
-
params: match.params,
|
|
1647
|
-
loaderData: match.loaderData
|
|
1648
|
-
};
|
|
1649
|
-
const headFnContent = (_f = (_e = route.options).head) == null ? void 0 : _f.call(_e, assetContext);
|
|
1650
|
-
match.links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1651
|
-
match.headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1652
|
-
match.meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1653
|
-
match.scripts = (_h = (_g = route.options).scripts) == null ? void 0 : _h.call(_g, assetContext);
|
|
1654
|
-
}
|
|
1655
1597
|
});
|
|
1656
1598
|
return matches;
|
|
1657
1599
|
}
|
|
@@ -1715,6 +1657,141 @@ function routeNeedsPreload(route) {
|
|
|
1715
1657
|
}
|
|
1716
1658
|
return false;
|
|
1717
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
|
+
}
|
|
1718
1795
|
export {
|
|
1719
1796
|
PathParamError,
|
|
1720
1797
|
RouterCore,
|
|
@@ -1723,6 +1800,8 @@ export {
|
|
|
1723
1800
|
defaultSerializeError,
|
|
1724
1801
|
getInitialRouterState,
|
|
1725
1802
|
getLocationChangeInfo,
|
|
1726
|
-
|
|
1803
|
+
getMatchedRoutes,
|
|
1804
|
+
lazyFn,
|
|
1805
|
+
processRouteTree
|
|
1727
1806
|
};
|
|
1728
1807
|
//# sourceMappingURL=router.js.map
|