@tanstack/react-router 1.31.0 → 1.31.2
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/Matches.cjs +1 -5
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +1 -1
- package/dist/cjs/RouterProvider.cjs +2 -2
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/redirects.cjs +4 -0
- package/dist/cjs/redirects.cjs.map +1 -1
- package/dist/cjs/redirects.d.cts +1 -0
- package/dist/cjs/router.cjs +209 -201
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +8 -7
- package/dist/esm/Matches.d.ts +1 -1
- package/dist/esm/Matches.js +1 -5
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.js +2 -2
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/redirects.d.ts +1 -0
- package/dist/esm/redirects.js +4 -0
- package/dist/esm/redirects.js.map +1 -1
- package/dist/esm/router.d.ts +8 -7
- package/dist/esm/router.js +210 -202
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.tsx +6 -6
- package/src/RouterProvider.tsx +2 -2
- package/src/redirects.ts +4 -0
- package/src/router.ts +288 -294
package/dist/esm/router.js
CHANGED
|
@@ -7,7 +7,7 @@ import { defaultStringifySearch, defaultParseSearch } from "./searchParams.js";
|
|
|
7
7
|
import { createControlledPromise, replaceEqualDeep, pick, last, deepEqual, escapeJSON, functionalUpdate } from "./utils.js";
|
|
8
8
|
import { getRouteMatch } from "./RouterProvider.js";
|
|
9
9
|
import { trimPath, trimPathLeft, parsePathname, resolvePath, cleanPath, matchPathname, trimPathRight, interpolatePath, joinPaths } from "./path.js";
|
|
10
|
-
import { isRedirect } from "./redirects.js";
|
|
10
|
+
import { isResolvedRedirect, isRedirect } from "./redirects.js";
|
|
11
11
|
import { isNotFound } from "./not-found.js";
|
|
12
12
|
const componentTypes = [
|
|
13
13
|
"component",
|
|
@@ -28,7 +28,6 @@ class Router {
|
|
|
28
28
|
)}`;
|
|
29
29
|
this.resetNextScroll = true;
|
|
30
30
|
this.shouldViewTransition = void 0;
|
|
31
|
-
this.navigateTimeout = null;
|
|
32
31
|
this.latestLoadPromise = Promise.resolve();
|
|
33
32
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
34
33
|
this.injectedHtml = [];
|
|
@@ -173,7 +172,9 @@ class Router {
|
|
|
173
172
|
});
|
|
174
173
|
};
|
|
175
174
|
this.checkLatest = (promise) => {
|
|
176
|
-
|
|
175
|
+
if (this.latestLoadPromise !== promise) {
|
|
176
|
+
throw this.latestLoadPromise;
|
|
177
|
+
}
|
|
177
178
|
};
|
|
178
179
|
this.parseLocation = (previousLocation) => {
|
|
179
180
|
const parse = ({
|
|
@@ -396,20 +397,20 @@ class Router {
|
|
|
396
397
|
};
|
|
397
398
|
this.buildLocation = (opts) => {
|
|
398
399
|
const build = (dest = {}, matches) => {
|
|
399
|
-
var _a, _b, _c
|
|
400
|
-
|
|
401
|
-
let fromSearch =
|
|
402
|
-
const fromMatches = this.matchRoutes(
|
|
400
|
+
var _a, _b, _c;
|
|
401
|
+
let fromPath = this.latestLocation.pathname;
|
|
402
|
+
let fromSearch = dest.fromSearch || this.latestLocation.search;
|
|
403
|
+
const fromMatches = this.matchRoutes(
|
|
404
|
+
this.latestLocation.pathname,
|
|
405
|
+
fromSearch
|
|
406
|
+
);
|
|
407
|
+
fromPath = ((_a = fromMatches.find((d) => d.id === dest.from)) == null ? void 0 : _a.pathname) || fromPath;
|
|
403
408
|
fromSearch = ((_b = last(fromMatches)) == null ? void 0 : _b.search) || this.latestLocation.search;
|
|
404
409
|
const stayingMatches = matches == null ? void 0 : matches.filter(
|
|
405
410
|
(d) => fromMatches.find((e) => e.routeId === d.routeId)
|
|
406
411
|
);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
dest.from ?? this.latestLocation.pathname,
|
|
410
|
-
`${dest.to}`
|
|
411
|
-
) : this.resolvePathWithBase(fromRoute == null ? void 0 : fromRoute.fullPath, fromRoute == null ? void 0 : fromRoute.fullPath);
|
|
412
|
-
const prevParams = { ...(_d = last(fromMatches)) == null ? void 0 : _d.params };
|
|
412
|
+
let pathname = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, fromPath);
|
|
413
|
+
const prevParams = { ...(_c = last(fromMatches)) == null ? void 0 : _c.params };
|
|
413
414
|
let nextParams = (dest.params ?? true) === true ? prevParams : { ...prevParams, ...functionalUpdate(dest.params, prevParams) };
|
|
414
415
|
if (Object.keys(nextParams).length > 0) {
|
|
415
416
|
matches == null ? void 0 : matches.map((d) => this.looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach((fn) => {
|
|
@@ -503,8 +504,6 @@ class Router {
|
|
|
503
504
|
viewTransition,
|
|
504
505
|
...next
|
|
505
506
|
}) => {
|
|
506
|
-
if (this.navigateTimeout)
|
|
507
|
-
clearTimeout(this.navigateTimeout);
|
|
508
507
|
const isSameUrl = this.latestLocation.href === next.href;
|
|
509
508
|
if (!isSameUrl) {
|
|
510
509
|
let { maskedLocation, ...nextHistory } = next;
|
|
@@ -574,14 +573,131 @@ class Router {
|
|
|
574
573
|
// to: toString,
|
|
575
574
|
});
|
|
576
575
|
};
|
|
576
|
+
this.load = async () => {
|
|
577
|
+
const promise = createControlledPromise();
|
|
578
|
+
this.latestLoadPromise = promise;
|
|
579
|
+
let redirect;
|
|
580
|
+
let notFound;
|
|
581
|
+
this.startReactTransition(async () => {
|
|
582
|
+
try {
|
|
583
|
+
const next = this.latestLocation;
|
|
584
|
+
const prevLocation = this.state.resolvedLocation;
|
|
585
|
+
const pathDidChange = prevLocation.href !== next.href;
|
|
586
|
+
this.cancelMatches();
|
|
587
|
+
this.emit({
|
|
588
|
+
type: "onBeforeLoad",
|
|
589
|
+
fromLocation: prevLocation,
|
|
590
|
+
toLocation: next,
|
|
591
|
+
pathChanged: pathDidChange
|
|
592
|
+
});
|
|
593
|
+
let pendingMatches;
|
|
594
|
+
this.__store.batch(() => {
|
|
595
|
+
this.cleanCache();
|
|
596
|
+
pendingMatches = this.matchRoutes(next.pathname, next.search);
|
|
597
|
+
this.__store.setState((s) => ({
|
|
598
|
+
...s,
|
|
599
|
+
status: "pending",
|
|
600
|
+
isLoading: true,
|
|
601
|
+
location: next,
|
|
602
|
+
pendingMatches,
|
|
603
|
+
// If a cached moved to pendingMatches, remove it from cachedMatches
|
|
604
|
+
cachedMatches: s.cachedMatches.filter((d) => {
|
|
605
|
+
return !pendingMatches.find((e) => e.id === d.id);
|
|
606
|
+
})
|
|
607
|
+
}));
|
|
608
|
+
});
|
|
609
|
+
await this.loadMatches({
|
|
610
|
+
matches: pendingMatches,
|
|
611
|
+
location: next,
|
|
612
|
+
checkLatest: () => this.checkLatest(promise),
|
|
613
|
+
onReady: async () => {
|
|
614
|
+
await this.startViewTransition(async () => {
|
|
615
|
+
let exitingMatches;
|
|
616
|
+
let enteringMatches;
|
|
617
|
+
let stayingMatches;
|
|
618
|
+
this.__store.batch(() => {
|
|
619
|
+
this.__store.setState((s) => {
|
|
620
|
+
const previousMatches = s.matches;
|
|
621
|
+
const newMatches = s.pendingMatches || s.matches;
|
|
622
|
+
exitingMatches = previousMatches.filter(
|
|
623
|
+
(match) => !newMatches.find((d) => d.id === match.id)
|
|
624
|
+
);
|
|
625
|
+
enteringMatches = newMatches.filter(
|
|
626
|
+
(match) => !previousMatches.find((d) => d.id === match.id)
|
|
627
|
+
);
|
|
628
|
+
stayingMatches = previousMatches.filter(
|
|
629
|
+
(match) => newMatches.find((d) => d.id === match.id)
|
|
630
|
+
);
|
|
631
|
+
return {
|
|
632
|
+
...s,
|
|
633
|
+
isLoading: false,
|
|
634
|
+
matches: newMatches,
|
|
635
|
+
pendingMatches: void 0,
|
|
636
|
+
cachedMatches: [
|
|
637
|
+
...s.cachedMatches,
|
|
638
|
+
...exitingMatches.filter((d) => d.status !== "error")
|
|
639
|
+
]
|
|
640
|
+
};
|
|
641
|
+
});
|
|
642
|
+
this.cleanCache();
|
|
643
|
+
});
|
|
644
|
+
[
|
|
645
|
+
[exitingMatches, "onLeave"],
|
|
646
|
+
[enteringMatches, "onEnter"],
|
|
647
|
+
[stayingMatches, "onStay"]
|
|
648
|
+
].forEach(([matches, hook]) => {
|
|
649
|
+
matches.forEach((match) => {
|
|
650
|
+
var _a, _b;
|
|
651
|
+
(_b = (_a = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b.call(_a, match);
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
} catch (err) {
|
|
658
|
+
if (isResolvedRedirect(err)) {
|
|
659
|
+
redirect = err;
|
|
660
|
+
if (!this.isServer) {
|
|
661
|
+
this.navigate({ ...err, replace: true });
|
|
662
|
+
this.load();
|
|
663
|
+
}
|
|
664
|
+
} else if (isNotFound(err)) {
|
|
665
|
+
notFound = err;
|
|
666
|
+
}
|
|
667
|
+
this.__store.setState((s) => ({
|
|
668
|
+
...s,
|
|
669
|
+
statusCode: (redirect == null ? void 0 : redirect.statusCode) || notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
|
|
670
|
+
redirect
|
|
671
|
+
}));
|
|
672
|
+
}
|
|
673
|
+
promise.resolve();
|
|
674
|
+
});
|
|
675
|
+
return this.latestLoadPromise;
|
|
676
|
+
};
|
|
677
|
+
this.startViewTransition = async (fn) => {
|
|
678
|
+
var _a, _b;
|
|
679
|
+
const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
|
|
680
|
+
delete this.shouldViewTransition;
|
|
681
|
+
((_b = (_a = shouldViewTransition && typeof document !== "undefined" ? document : void 0) == null ? void 0 : _a.startViewTransition) == null ? void 0 : _b.call(_a, fn)) || fn();
|
|
682
|
+
};
|
|
577
683
|
this.loadMatches = async ({
|
|
578
684
|
checkLatest,
|
|
579
685
|
location,
|
|
580
686
|
matches,
|
|
581
|
-
preload
|
|
687
|
+
preload,
|
|
688
|
+
onReady
|
|
582
689
|
}) => {
|
|
583
|
-
let latestPromise;
|
|
584
690
|
let firstBadMatchIndex;
|
|
691
|
+
let rendered = false;
|
|
692
|
+
const triggerOnReady = async () => {
|
|
693
|
+
if (!rendered) {
|
|
694
|
+
rendered = true;
|
|
695
|
+
await (onReady == null ? void 0 : onReady());
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
if (!this.isServer && !this.state.matches.length) {
|
|
699
|
+
triggerOnReady();
|
|
700
|
+
}
|
|
585
701
|
const updateMatch = (id, updater, opts) => {
|
|
586
702
|
var _a;
|
|
587
703
|
let updated;
|
|
@@ -599,41 +715,64 @@ class Router {
|
|
|
599
715
|
});
|
|
600
716
|
return updated;
|
|
601
717
|
};
|
|
718
|
+
const handleRedirectAndNotFound = (match, err) => {
|
|
719
|
+
if (isResolvedRedirect(err))
|
|
720
|
+
throw err;
|
|
721
|
+
if (isRedirect(err) || isNotFound(err)) {
|
|
722
|
+
updateMatch(match.id, (prev) => ({
|
|
723
|
+
...prev,
|
|
724
|
+
status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : "error",
|
|
725
|
+
isFetching: false,
|
|
726
|
+
error: err
|
|
727
|
+
}));
|
|
728
|
+
rendered = true;
|
|
729
|
+
if (!err.routeId) {
|
|
730
|
+
err.routeId = match.routeId;
|
|
731
|
+
}
|
|
732
|
+
if (isRedirect(err)) {
|
|
733
|
+
err = this.resolveRedirect(err);
|
|
734
|
+
throw err;
|
|
735
|
+
} else if (isNotFound(err)) {
|
|
736
|
+
this.handleNotFound(matches, err);
|
|
737
|
+
throw err;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
};
|
|
602
741
|
try {
|
|
603
742
|
await new Promise((resolveAll, rejectAll) => {
|
|
604
743
|
;
|
|
605
744
|
(async () => {
|
|
606
745
|
var _a, _b;
|
|
607
746
|
try {
|
|
608
|
-
const handleRedirectAndNotFound = (match, err) => {
|
|
609
|
-
if (isRedirect(err) || isNotFound(err)) {
|
|
610
|
-
updateMatch(match.id, (prev) => ({
|
|
611
|
-
...prev,
|
|
612
|
-
status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : "error",
|
|
613
|
-
isFetching: false,
|
|
614
|
-
error: err
|
|
615
|
-
}));
|
|
616
|
-
if (!err.routeId) {
|
|
617
|
-
;
|
|
618
|
-
err.routeId = match.routeId;
|
|
619
|
-
}
|
|
620
|
-
if (isRedirect(err)) {
|
|
621
|
-
const redirect = this.resolveRedirect(err);
|
|
622
|
-
if (!preload && !this.isServer) {
|
|
623
|
-
this.navigate({ ...redirect, replace: true });
|
|
624
|
-
}
|
|
625
|
-
throw redirect;
|
|
626
|
-
} else if (isNotFound(err)) {
|
|
627
|
-
if (!preload)
|
|
628
|
-
this.handleNotFound(matches, err);
|
|
629
|
-
throw err;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
};
|
|
633
747
|
for (let [index, match] of matches.entries()) {
|
|
634
748
|
const parentMatch = matches[index - 1];
|
|
635
749
|
const route = this.looseRoutesById[match.routeId];
|
|
636
750
|
const abortController = new AbortController();
|
|
751
|
+
let loadPromise = match.loadPromise;
|
|
752
|
+
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
753
|
+
const shouldPending = !!(onReady && !this.isServer && !preload && (route.options.loader || route.options.beforeLoad) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options.defaultPendingComponent));
|
|
754
|
+
if (shouldPending) {
|
|
755
|
+
setTimeout(() => {
|
|
756
|
+
try {
|
|
757
|
+
checkLatest();
|
|
758
|
+
triggerOnReady();
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
761
|
+
}, pendingMs);
|
|
762
|
+
}
|
|
763
|
+
if (match.isFetching) {
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
const previousResolve = loadPromise.resolve;
|
|
767
|
+
loadPromise = createControlledPromise(
|
|
768
|
+
// Resolve the old when we we resolve the new one
|
|
769
|
+
previousResolve
|
|
770
|
+
);
|
|
771
|
+
matches[index] = match = updateMatch(match.id, (prev) => ({
|
|
772
|
+
...prev,
|
|
773
|
+
isFetching: "beforeLoad",
|
|
774
|
+
loadPromise
|
|
775
|
+
}));
|
|
637
776
|
const handleSerialError = (err, routerCode) => {
|
|
638
777
|
var _a2, _b2;
|
|
639
778
|
err.routerCode = routerCode;
|
|
@@ -661,19 +800,6 @@ class Router {
|
|
|
661
800
|
}
|
|
662
801
|
try {
|
|
663
802
|
const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
664
|
-
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
665
|
-
const pendingPromise = typeof pendingMs !== "number" || pendingMs <= 0 ? Promise.resolve() : new Promise((r) => {
|
|
666
|
-
if (pendingMs !== Infinity)
|
|
667
|
-
setTimeout(r, pendingMs);
|
|
668
|
-
});
|
|
669
|
-
const shouldPending = !this.isServer && !preload && (route.options.loader || route.options.beforeLoad) && typeof pendingMs === "number" && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
|
|
670
|
-
if (shouldPending) {
|
|
671
|
-
pendingPromise.then(async () => {
|
|
672
|
-
if (latestPromise = checkLatest())
|
|
673
|
-
return latestPromise;
|
|
674
|
-
resolveAll();
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
803
|
const beforeLoadContext = await ((_b = (_a = route.options).beforeLoad) == null ? void 0 : _b.call(_a, {
|
|
678
804
|
search: match.search,
|
|
679
805
|
abortController,
|
|
@@ -685,6 +811,7 @@ class Router {
|
|
|
685
811
|
buildLocation: this.buildLocation,
|
|
686
812
|
cause: preload ? "preload" : match.cause
|
|
687
813
|
})) ?? {};
|
|
814
|
+
checkLatest();
|
|
688
815
|
if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
|
|
689
816
|
handleSerialError(beforeLoadContext, "BEFORE_LOAD");
|
|
690
817
|
}
|
|
@@ -708,6 +835,7 @@ class Router {
|
|
|
708
835
|
updateMatch(match.id, () => match);
|
|
709
836
|
}
|
|
710
837
|
}
|
|
838
|
+
checkLatest();
|
|
711
839
|
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
712
840
|
const matchPromises = [];
|
|
713
841
|
await Promise.all(
|
|
@@ -732,13 +860,11 @@ class Router {
|
|
|
732
860
|
let lazyPromise = Promise.resolve();
|
|
733
861
|
let componentsPromise = Promise.resolve();
|
|
734
862
|
let loaderPromise = existing.loaderPromise;
|
|
735
|
-
let loadPromise = existing.loadPromise;
|
|
736
863
|
const potentialPendingMinPromise = async () => {
|
|
737
864
|
const latestMatch = getRouteMatch(this.state, match.id);
|
|
738
865
|
if (latestMatch == null ? void 0 : latestMatch.minPendingPromise) {
|
|
739
866
|
await latestMatch.minPendingPromise;
|
|
740
|
-
|
|
741
|
-
return await latestPromise;
|
|
867
|
+
checkLatest();
|
|
742
868
|
updateMatch(latestMatch.id, (prev) => ({
|
|
743
869
|
...prev,
|
|
744
870
|
minPendingPromise: void 0
|
|
@@ -746,12 +872,15 @@ class Router {
|
|
|
746
872
|
}
|
|
747
873
|
};
|
|
748
874
|
try {
|
|
749
|
-
if (
|
|
750
|
-
matches[index] = match =
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
875
|
+
if (match.isFetching === "beforeLoad") {
|
|
876
|
+
matches[index] = match = updateMatch(
|
|
877
|
+
match.id,
|
|
878
|
+
(prev) => ({
|
|
879
|
+
...prev,
|
|
880
|
+
isFetching: "loader",
|
|
881
|
+
fetchCount: match.fetchCount + 1
|
|
882
|
+
})
|
|
883
|
+
);
|
|
755
884
|
lazyPromise = ((_a2 = route.lazyFn) == null ? void 0 : _a2.call(route).then((lazyRoute) => {
|
|
756
885
|
Object.assign(route.options, lazyRoute.options);
|
|
757
886
|
})) || Promise.resolve();
|
|
@@ -766,29 +895,21 @@ class Router {
|
|
|
766
895
|
)
|
|
767
896
|
);
|
|
768
897
|
await lazyPromise;
|
|
769
|
-
|
|
770
|
-
return await latestPromise;
|
|
898
|
+
checkLatest();
|
|
771
899
|
loaderPromise = (_c = (_b2 = route.options).loader) == null ? void 0 : _c.call(_b2, loaderContext);
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
900
|
+
matches[index] = match = updateMatch(
|
|
901
|
+
match.id,
|
|
902
|
+
(prev) => ({
|
|
903
|
+
...prev,
|
|
904
|
+
loaderPromise
|
|
905
|
+
})
|
|
776
906
|
);
|
|
777
907
|
}
|
|
778
|
-
matches[index] = match = updateMatch(match.id, (prev) => ({
|
|
779
|
-
...prev,
|
|
780
|
-
loaderPromise,
|
|
781
|
-
loadPromise
|
|
782
|
-
}));
|
|
783
908
|
const loaderData = await loaderPromise;
|
|
784
|
-
|
|
785
|
-
return await latestPromise;
|
|
909
|
+
checkLatest();
|
|
786
910
|
handleRedirectAndNotFound(match, loaderData);
|
|
787
|
-
if (latestPromise = checkLatest())
|
|
788
|
-
return await latestPromise;
|
|
789
911
|
await potentialPendingMinPromise();
|
|
790
|
-
|
|
791
|
-
return await latestPromise;
|
|
912
|
+
checkLatest();
|
|
792
913
|
const meta = (_e = (_d = route.options).meta) == null ? void 0 : _e.call(_d, {
|
|
793
914
|
params: match.params,
|
|
794
915
|
loaderData
|
|
@@ -807,12 +928,10 @@ class Router {
|
|
|
807
928
|
headers
|
|
808
929
|
}));
|
|
809
930
|
} catch (e) {
|
|
931
|
+
checkLatest();
|
|
810
932
|
let error = e;
|
|
811
|
-
if (latestPromise = checkLatest())
|
|
812
|
-
return await latestPromise;
|
|
813
933
|
await potentialPendingMinPromise();
|
|
814
|
-
|
|
815
|
-
return await latestPromise;
|
|
934
|
+
checkLatest();
|
|
816
935
|
handleRedirectAndNotFound(match, e);
|
|
817
936
|
try {
|
|
818
937
|
(_i = (_h = route.options).onError) == null ? void 0 : _i.call(_h, e);
|
|
@@ -828,9 +947,8 @@ class Router {
|
|
|
828
947
|
}));
|
|
829
948
|
}
|
|
830
949
|
await componentsPromise;
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
loadPromise.resolve();
|
|
950
|
+
checkLatest();
|
|
951
|
+
match.loadPromise.resolve();
|
|
834
952
|
};
|
|
835
953
|
const age = Date.now() - match.updatedAt;
|
|
836
954
|
const staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
|
|
@@ -844,8 +962,7 @@ class Router {
|
|
|
844
962
|
try {
|
|
845
963
|
await fetch();
|
|
846
964
|
} catch (err) {
|
|
847
|
-
|
|
848
|
-
return await latestPromise;
|
|
965
|
+
checkLatest();
|
|
849
966
|
handleRedirectAndNotFound(match, err);
|
|
850
967
|
}
|
|
851
968
|
};
|
|
@@ -858,14 +975,14 @@ class Router {
|
|
|
858
975
|
}
|
|
859
976
|
})
|
|
860
977
|
);
|
|
861
|
-
|
|
862
|
-
return await latestPromise;
|
|
978
|
+
checkLatest();
|
|
863
979
|
resolveAll();
|
|
864
980
|
} catch (err) {
|
|
865
981
|
rejectAll(err);
|
|
866
982
|
}
|
|
867
983
|
})();
|
|
868
984
|
});
|
|
985
|
+
await triggerOnReady();
|
|
869
986
|
} catch (err) {
|
|
870
987
|
if (isRedirect(err) || isNotFound(err)) {
|
|
871
988
|
throw err;
|
|
@@ -890,115 +1007,6 @@ class Router {
|
|
|
890
1007
|
});
|
|
891
1008
|
return this.load();
|
|
892
1009
|
};
|
|
893
|
-
this.load = async () => {
|
|
894
|
-
let resolveLoad;
|
|
895
|
-
let rejectLoad;
|
|
896
|
-
const promise = new Promise((resolve, reject) => {
|
|
897
|
-
resolveLoad = resolve;
|
|
898
|
-
rejectLoad = reject;
|
|
899
|
-
});
|
|
900
|
-
this.latestLoadPromise = promise;
|
|
901
|
-
let latestPromise;
|
|
902
|
-
this.startReactTransition(async () => {
|
|
903
|
-
var _a, _b;
|
|
904
|
-
try {
|
|
905
|
-
const next = this.latestLocation;
|
|
906
|
-
const prevLocation = this.state.resolvedLocation;
|
|
907
|
-
const pathDidChange = prevLocation.href !== next.href;
|
|
908
|
-
this.cancelMatches();
|
|
909
|
-
this.emit({
|
|
910
|
-
type: "onBeforeLoad",
|
|
911
|
-
fromLocation: prevLocation,
|
|
912
|
-
toLocation: next,
|
|
913
|
-
pathChanged: pathDidChange
|
|
914
|
-
});
|
|
915
|
-
let pendingMatches;
|
|
916
|
-
const previousMatches = this.state.matches;
|
|
917
|
-
this.__store.batch(() => {
|
|
918
|
-
this.cleanCache();
|
|
919
|
-
pendingMatches = this.matchRoutes(next.pathname, next.search);
|
|
920
|
-
this.__store.setState((s) => ({
|
|
921
|
-
...s,
|
|
922
|
-
status: "pending",
|
|
923
|
-
isLoading: true,
|
|
924
|
-
location: next,
|
|
925
|
-
pendingMatches,
|
|
926
|
-
cachedMatches: s.cachedMatches.filter((d) => {
|
|
927
|
-
return !pendingMatches.find((e) => e.id === d.id);
|
|
928
|
-
})
|
|
929
|
-
}));
|
|
930
|
-
});
|
|
931
|
-
let redirect;
|
|
932
|
-
let notFound;
|
|
933
|
-
try {
|
|
934
|
-
const loadMatchesPromise = this.loadMatches({
|
|
935
|
-
matches: pendingMatches,
|
|
936
|
-
location: next,
|
|
937
|
-
checkLatest: () => this.checkLatest(promise)
|
|
938
|
-
});
|
|
939
|
-
if (previousMatches.length || this.isServer) {
|
|
940
|
-
await loadMatchesPromise;
|
|
941
|
-
}
|
|
942
|
-
} catch (err) {
|
|
943
|
-
if (isRedirect(err)) {
|
|
944
|
-
redirect = err;
|
|
945
|
-
} else if (isNotFound(err)) {
|
|
946
|
-
notFound = err;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
if (latestPromise = this.checkLatest(promise)) {
|
|
950
|
-
return latestPromise;
|
|
951
|
-
}
|
|
952
|
-
const exitingMatches = previousMatches.filter(
|
|
953
|
-
(match) => !pendingMatches.find((d) => d.id === match.id)
|
|
954
|
-
);
|
|
955
|
-
const enteringMatches = pendingMatches.filter(
|
|
956
|
-
(match) => !previousMatches.find((d) => d.id === match.id)
|
|
957
|
-
);
|
|
958
|
-
const stayingMatches = previousMatches.filter(
|
|
959
|
-
(match) => pendingMatches.find((d) => d.id === match.id)
|
|
960
|
-
);
|
|
961
|
-
const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
|
|
962
|
-
delete this.shouldViewTransition;
|
|
963
|
-
const apply = () => {
|
|
964
|
-
this.__store.batch(() => {
|
|
965
|
-
this.__store.setState((s) => ({
|
|
966
|
-
...s,
|
|
967
|
-
isLoading: false,
|
|
968
|
-
matches: s.pendingMatches,
|
|
969
|
-
pendingMatches: void 0,
|
|
970
|
-
cachedMatches: [
|
|
971
|
-
...s.cachedMatches,
|
|
972
|
-
...exitingMatches.filter((d) => d.status !== "error")
|
|
973
|
-
],
|
|
974
|
-
statusCode: (redirect == null ? void 0 : redirect.statusCode) || notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
|
|
975
|
-
redirect
|
|
976
|
-
}));
|
|
977
|
-
this.cleanCache();
|
|
978
|
-
});
|
|
979
|
-
[
|
|
980
|
-
[exitingMatches, "onLeave"],
|
|
981
|
-
[enteringMatches, "onEnter"],
|
|
982
|
-
[stayingMatches, "onStay"]
|
|
983
|
-
].forEach(([matches, hook]) => {
|
|
984
|
-
matches.forEach((match) => {
|
|
985
|
-
var _a2, _b2;
|
|
986
|
-
(_b2 = (_a2 = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b2.call(_a2, match);
|
|
987
|
-
});
|
|
988
|
-
});
|
|
989
|
-
resolveLoad();
|
|
990
|
-
};
|
|
991
|
-
((_b = (_a = shouldViewTransition && typeof document !== "undefined" ? document : void 0) == null ? void 0 : _a.startViewTransition) == null ? void 0 : _b.call(_a, apply)) || apply();
|
|
992
|
-
} catch (err) {
|
|
993
|
-
if (latestPromise = this.checkLatest(promise)) {
|
|
994
|
-
return latestPromise;
|
|
995
|
-
}
|
|
996
|
-
console.error("Load Error", err);
|
|
997
|
-
rejectLoad(err);
|
|
998
|
-
}
|
|
999
|
-
});
|
|
1000
|
-
return this.latestLoadPromise;
|
|
1001
|
-
};
|
|
1002
1010
|
this.resolveRedirect = (err) => {
|
|
1003
1011
|
const redirect = err;
|
|
1004
1012
|
if (!redirect.href) {
|
|
@@ -1061,7 +1069,7 @@ class Router {
|
|
|
1061
1069
|
} catch (err) {
|
|
1062
1070
|
if (isRedirect(err)) {
|
|
1063
1071
|
return await this.preloadRoute({
|
|
1064
|
-
|
|
1072
|
+
fromSearch: next.search,
|
|
1065
1073
|
from: next.pathname,
|
|
1066
1074
|
...err
|
|
1067
1075
|
});
|