@tanstack/react-router 1.16.2 → 1.16.5
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.cjs.map +1 -1
- package/dist/cjs/fileRoute.d.cts +4 -2
- package/dist/cjs/link.cjs +16 -16
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/not-found.d.cts +1 -1
- package/dist/cjs/redirects.cjs.map +1 -1
- package/dist/cjs/redirects.d.cts +1 -0
- package/dist/cjs/route.cjs +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +4 -3
- package/dist/cjs/router.cjs +142 -149
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +4 -2
- package/dist/esm/fileRoute.d.ts +4 -2
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/link.js +16 -16
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/not-found.d.ts +1 -1
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/redirects.d.ts +1 -0
- package/dist/esm/redirects.js.map +1 -1
- package/dist/esm/route.d.ts +4 -3
- package/dist/esm/route.js +1 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +4 -2
- package/dist/esm/router.js +143 -150
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/fileRoute.ts +2 -2
- package/src/link.tsx +18 -18
- package/src/not-found.tsx +1 -1
- package/src/redirects.ts +1 -0
- package/src/route.ts +11 -3
- package/src/router.ts +168 -179
package/dist/cjs/router.cjs
CHANGED
|
@@ -554,111 +554,94 @@ class Router {
|
|
|
554
554
|
};
|
|
555
555
|
});
|
|
556
556
|
};
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
try {
|
|
573
|
-
(_b2 = (_a2 = route2.options).onError) == null ? void 0 : _b2.call(_a2, err);
|
|
574
|
-
} catch (errorHandlerErr) {
|
|
575
|
-
err = errorHandlerErr;
|
|
576
|
-
if (redirects.isRedirect(errorHandlerErr)) {
|
|
577
|
-
throw errorHandlerErr;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
matches[index] = match = {
|
|
581
|
-
...match,
|
|
582
|
-
error: err,
|
|
583
|
-
status: "error",
|
|
584
|
-
updatedAt: Date.now(),
|
|
585
|
-
abortController: new AbortController()
|
|
586
|
-
};
|
|
587
|
-
};
|
|
557
|
+
for (let [index, match] of matches.entries()) {
|
|
558
|
+
const parentMatch = matches[index - 1];
|
|
559
|
+
const route2 = this.looseRoutesById[match.routeId];
|
|
560
|
+
const abortController = new AbortController();
|
|
561
|
+
const handleError = (err, code) => {
|
|
562
|
+
var _a2, _b2;
|
|
563
|
+
err.routerCode = code;
|
|
564
|
+
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
565
|
+
if (redirects.isRedirect(err)) {
|
|
566
|
+
throw err;
|
|
567
|
+
}
|
|
568
|
+
if (notFound.isNotFound(err)) {
|
|
569
|
+
err.routeId = match.routeId;
|
|
570
|
+
throw err;
|
|
571
|
+
}
|
|
588
572
|
try {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
-
const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
596
|
-
const pendingMs = route2.options.pendingMs ?? this.options.defaultPendingMs;
|
|
597
|
-
const pendingPromise = typeof pendingMs === "number" && pendingMs <= 0 ? Promise.resolve() : new Promise((r) => setTimeout(r, pendingMs));
|
|
598
|
-
const beforeLoadContext = await ((_b = (_a = route2.options).beforeLoad) == null ? void 0 : _b.call(_a, {
|
|
599
|
-
search: match.search,
|
|
600
|
-
abortController,
|
|
601
|
-
params: match.params,
|
|
602
|
-
preload: !!preload,
|
|
603
|
-
context: parentContext,
|
|
604
|
-
location: this.state.location,
|
|
605
|
-
// TOOD: just expose state and router, etc
|
|
606
|
-
navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
|
|
607
|
-
buildLocation: this.buildLocation,
|
|
608
|
-
cause: preload ? "preload" : match.cause
|
|
609
|
-
})) ?? {};
|
|
610
|
-
if (redirects.isRedirect(beforeLoadContext)) {
|
|
611
|
-
throw beforeLoadContext;
|
|
573
|
+
(_b2 = (_a2 = route2.options).onError) == null ? void 0 : _b2.call(_a2, err);
|
|
574
|
+
} catch (errorHandlerErr) {
|
|
575
|
+
err = errorHandlerErr;
|
|
576
|
+
if (redirects.isRedirect(errorHandlerErr)) {
|
|
577
|
+
throw errorHandlerErr;
|
|
612
578
|
}
|
|
613
|
-
const context = {
|
|
614
|
-
...parentContext,
|
|
615
|
-
...beforeLoadContext
|
|
616
|
-
};
|
|
617
|
-
matches[index] = match = {
|
|
618
|
-
...match,
|
|
619
|
-
routeContext: utils.replaceEqualDeep(
|
|
620
|
-
match.routeContext,
|
|
621
|
-
beforeLoadContext
|
|
622
|
-
),
|
|
623
|
-
context: utils.replaceEqualDeep(match.context, context),
|
|
624
|
-
abortController,
|
|
625
|
-
pendingPromise
|
|
626
|
-
};
|
|
627
|
-
} catch (err) {
|
|
628
|
-
handleErrorAndRedirect(err, "BEFORE_LOAD");
|
|
629
|
-
break;
|
|
630
579
|
}
|
|
580
|
+
matches[index] = match = {
|
|
581
|
+
...match,
|
|
582
|
+
error: err,
|
|
583
|
+
status: "error",
|
|
584
|
+
updatedAt: Date.now(),
|
|
585
|
+
abortController: new AbortController()
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
try {
|
|
589
|
+
if (match.paramsError) {
|
|
590
|
+
handleError(match.paramsError, "PARSE_PARAMS");
|
|
591
|
+
}
|
|
592
|
+
if (match.searchError) {
|
|
593
|
+
handleError(match.searchError, "VALIDATE_SEARCH");
|
|
594
|
+
}
|
|
595
|
+
const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
596
|
+
const pendingMs = route2.options.pendingMs ?? this.options.defaultPendingMs;
|
|
597
|
+
const pendingPromise = typeof pendingMs === "number" && pendingMs <= 0 ? Promise.resolve() : new Promise((r) => setTimeout(r, pendingMs));
|
|
598
|
+
const beforeLoadContext = await ((_b = (_a = route2.options).beforeLoad) == null ? void 0 : _b.call(_a, {
|
|
599
|
+
search: match.search,
|
|
600
|
+
abortController,
|
|
601
|
+
params: match.params,
|
|
602
|
+
preload: !!preload,
|
|
603
|
+
context: parentContext,
|
|
604
|
+
location: this.state.location,
|
|
605
|
+
// TOOD: just expose state and router, etc
|
|
606
|
+
navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
|
|
607
|
+
buildLocation: this.buildLocation,
|
|
608
|
+
cause: preload ? "preload" : match.cause
|
|
609
|
+
})) ?? {};
|
|
610
|
+
if (redirects.isRedirect(beforeLoadContext)) {
|
|
611
|
+
throw beforeLoadContext;
|
|
612
|
+
}
|
|
613
|
+
const context = {
|
|
614
|
+
...parentContext,
|
|
615
|
+
...beforeLoadContext
|
|
616
|
+
};
|
|
617
|
+
matches[index] = match = {
|
|
618
|
+
...match,
|
|
619
|
+
routeContext: utils.replaceEqualDeep(match.routeContext, beforeLoadContext),
|
|
620
|
+
context: utils.replaceEqualDeep(match.context, context),
|
|
621
|
+
abortController,
|
|
622
|
+
pendingPromise
|
|
623
|
+
};
|
|
624
|
+
} catch (err) {
|
|
625
|
+
handleError(err, "BEFORE_LOAD");
|
|
626
|
+
break;
|
|
631
627
|
}
|
|
632
|
-
} catch (err) {
|
|
633
|
-
if (redirects.isRedirect(err)) {
|
|
634
|
-
if (!preload)
|
|
635
|
-
this.navigate(err);
|
|
636
|
-
return matches;
|
|
637
|
-
}
|
|
638
|
-
throw err;
|
|
639
628
|
}
|
|
640
629
|
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
641
630
|
const matchPromises = [];
|
|
642
631
|
validResolvedMatches.forEach((match, index) => {
|
|
643
632
|
matchPromises.push(
|
|
644
|
-
new Promise(async (resolve) => {
|
|
633
|
+
new Promise(async (resolve, reject) => {
|
|
645
634
|
var _a2;
|
|
646
635
|
const parentMatchPromise = matchPromises[index - 1];
|
|
647
636
|
const route2 = this.looseRoutesById[match.routeId];
|
|
648
|
-
const
|
|
637
|
+
const handleError = (err) => {
|
|
649
638
|
if (redirects.isRedirect(err)) {
|
|
650
|
-
|
|
651
|
-
this.navigate(err);
|
|
652
|
-
}
|
|
653
|
-
return true;
|
|
639
|
+
throw err;
|
|
654
640
|
}
|
|
655
641
|
if (notFound.isNotFound(err)) {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
return true;
|
|
642
|
+
err.routeId = match.routeId;
|
|
643
|
+
throw err;
|
|
660
644
|
}
|
|
661
|
-
return false;
|
|
662
645
|
};
|
|
663
646
|
let loadPromise;
|
|
664
647
|
matches[index] = match = {
|
|
@@ -726,10 +709,7 @@ class Router {
|
|
|
726
709
|
const loaderData = await loadPromise;
|
|
727
710
|
if (latestPromise = checkLatest())
|
|
728
711
|
return await latestPromise;
|
|
729
|
-
|
|
730
|
-
if (handleErrorAndRedirect(loaderData))
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
712
|
+
handleError(loaderData);
|
|
733
713
|
if (didShowPending && pendingMinMs) {
|
|
734
714
|
await new Promise((r) => setTimeout(r, pendingMinMs));
|
|
735
715
|
}
|
|
@@ -737,6 +717,7 @@ class Router {
|
|
|
737
717
|
return await latestPromise;
|
|
738
718
|
const [meta, headers] = await Promise.all([
|
|
739
719
|
(_d = (_c = route2.options).meta) == null ? void 0 : _d.call(_c, {
|
|
720
|
+
params: match.params,
|
|
740
721
|
loaderData
|
|
741
722
|
}),
|
|
742
723
|
(_f = (_e = route2.options).headers) == null ? void 0 : _f.call(_e, {
|
|
@@ -757,14 +738,12 @@ class Router {
|
|
|
757
738
|
} catch (error) {
|
|
758
739
|
if (latestPromise = checkLatest())
|
|
759
740
|
return await latestPromise;
|
|
760
|
-
|
|
761
|
-
return;
|
|
741
|
+
handleError(error);
|
|
762
742
|
try {
|
|
763
743
|
(_h = (_g = route2.options).onError) == null ? void 0 : _h.call(_g, error);
|
|
764
744
|
} catch (onErrorError) {
|
|
765
745
|
error = onErrorError;
|
|
766
|
-
|
|
767
|
-
return;
|
|
746
|
+
handleError(onErrorError);
|
|
768
747
|
}
|
|
769
748
|
matches[index] = match = {
|
|
770
749
|
...match,
|
|
@@ -784,23 +763,27 @@ class Router {
|
|
|
784
763
|
...match,
|
|
785
764
|
preload: !!preload && !this.state.matches.find((d) => d.id === match.id)
|
|
786
765
|
};
|
|
787
|
-
|
|
788
|
-
if (
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
766
|
+
try {
|
|
767
|
+
if (match.status !== "success") {
|
|
768
|
+
if (shouldPending) {
|
|
769
|
+
(_a2 = match.pendingPromise) == null ? void 0 : _a2.then(async () => {
|
|
770
|
+
if (latestPromise = checkLatest())
|
|
771
|
+
return latestPromise;
|
|
772
|
+
didShowPending = true;
|
|
773
|
+
matches[index] = match = {
|
|
774
|
+
...match,
|
|
775
|
+
showPending: true
|
|
776
|
+
};
|
|
777
|
+
updateMatch(match);
|
|
778
|
+
resolve();
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
await fetch();
|
|
782
|
+
} else if (match.invalid || (shouldReload ?? age > staleAge)) {
|
|
783
|
+
fetch();
|
|
800
784
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
fetch();
|
|
785
|
+
} catch (err) {
|
|
786
|
+
reject(err);
|
|
804
787
|
}
|
|
805
788
|
resolve();
|
|
806
789
|
})
|
|
@@ -810,20 +793,6 @@ class Router {
|
|
|
810
793
|
return matches;
|
|
811
794
|
};
|
|
812
795
|
this.invalidate = () => {
|
|
813
|
-
const invalidate = (d) => ({
|
|
814
|
-
...d,
|
|
815
|
-
invalid: true
|
|
816
|
-
});
|
|
817
|
-
this.__store.setState((s) => {
|
|
818
|
-
var _a;
|
|
819
|
-
return {
|
|
820
|
-
...s,
|
|
821
|
-
matches: s.matches.map(invalidate),
|
|
822
|
-
cachedMatches: s.cachedMatches.map(invalidate),
|
|
823
|
-
pendingMatches: (_a = s.pendingMatches) == null ? void 0 : _a.map(invalidate)
|
|
824
|
-
};
|
|
825
|
-
});
|
|
826
|
-
this.load();
|
|
827
796
|
};
|
|
828
797
|
this.load = async () => {
|
|
829
798
|
const promise = new Promise(async (resolve, reject) => {
|
|
@@ -862,6 +831,11 @@ class Router {
|
|
|
862
831
|
checkLatest: () => this.checkLatest(promise)
|
|
863
832
|
});
|
|
864
833
|
} catch (err) {
|
|
834
|
+
if (redirects.isRedirect(err)) {
|
|
835
|
+
this.handleRedirect(err);
|
|
836
|
+
} else if (notFound.isNotFound(err)) {
|
|
837
|
+
this.handleNotFound(pendingMatches, err);
|
|
838
|
+
}
|
|
865
839
|
}
|
|
866
840
|
if (latestPromise = this.checkLatest(promise)) {
|
|
867
841
|
return latestPromise;
|
|
@@ -915,6 +889,15 @@ class Router {
|
|
|
915
889
|
this.latestLoadPromise = promise;
|
|
916
890
|
return this.latestLoadPromise;
|
|
917
891
|
};
|
|
892
|
+
this.handleRedirect = (err) => {
|
|
893
|
+
if (!err.href) {
|
|
894
|
+
err.href = this.buildLocation(err).href;
|
|
895
|
+
}
|
|
896
|
+
if (utils.isServer) {
|
|
897
|
+
throw err;
|
|
898
|
+
}
|
|
899
|
+
this.navigate(err);
|
|
900
|
+
};
|
|
918
901
|
this.cleanCache = () => {
|
|
919
902
|
this.__store.setState((s) => {
|
|
920
903
|
return {
|
|
@@ -953,12 +936,19 @@ class Router {
|
|
|
953
936
|
}
|
|
954
937
|
});
|
|
955
938
|
});
|
|
956
|
-
|
|
957
|
-
matches
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
939
|
+
try {
|
|
940
|
+
matches = await this.loadMatches({
|
|
941
|
+
matches,
|
|
942
|
+
preload: true,
|
|
943
|
+
checkLatest: () => void 0
|
|
944
|
+
});
|
|
945
|
+
return matches;
|
|
946
|
+
} catch (err) {
|
|
947
|
+
if (!redirects.isRedirect(err) && !notFound.isNotFound(err)) {
|
|
948
|
+
console.error(err);
|
|
949
|
+
}
|
|
950
|
+
return void 0;
|
|
951
|
+
}
|
|
962
952
|
};
|
|
963
953
|
this.matchRoute = (location, opts) => {
|
|
964
954
|
const matchLocation = {
|
|
@@ -1094,6 +1084,7 @@ class Router {
|
|
|
1094
1084
|
...match,
|
|
1095
1085
|
...dehydratedMatch,
|
|
1096
1086
|
meta: (_b2 = (_a2 = route2.options).meta) == null ? void 0 : _b2.call(_a2, {
|
|
1087
|
+
params: match.params,
|
|
1097
1088
|
loaderData: dehydratedMatch.loaderData
|
|
1098
1089
|
}),
|
|
1099
1090
|
links: (_d = (_c2 = route2.options).links) == null ? void 0 : _d.call(_c2),
|
|
@@ -1110,27 +1101,29 @@ class Router {
|
|
|
1110
1101
|
};
|
|
1111
1102
|
});
|
|
1112
1103
|
};
|
|
1113
|
-
this.
|
|
1104
|
+
this.handleNotFound = (matches, err) => {
|
|
1114
1105
|
const matchesByRouteId = Object.fromEntries(
|
|
1115
1106
|
matches.map((match) => [match.routeId, match])
|
|
1116
1107
|
);
|
|
1117
|
-
if (err.global) {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1108
|
+
if (!err.global && err.routeId) {
|
|
1109
|
+
let currentRoute = this.looseRoutesById[err.routeId];
|
|
1110
|
+
if (currentRoute) {
|
|
1111
|
+
while (!currentRoute.options.notFoundComponent) {
|
|
1112
|
+
currentRoute = currentRoute == null ? void 0 : currentRoute.parentRoute;
|
|
1113
|
+
invariant(
|
|
1114
|
+
currentRoute,
|
|
1115
|
+
"Found invalid route tree while trying to find not-found handler."
|
|
1116
|
+
);
|
|
1117
|
+
if (currentRoute.id === route.rootRouteId)
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
const match = matchesByRouteId[currentRoute.id];
|
|
1121
|
+
invariant(match, "Could not find match for route: " + currentRoute.id);
|
|
1122
|
+
match.notFoundError = err;
|
|
1123
|
+
return;
|
|
1129
1124
|
}
|
|
1130
|
-
const match = matchesByRouteId[currentRoute.id];
|
|
1131
|
-
invariant(match, "Could not find match for route: " + currentRoute.id);
|
|
1132
|
-
match.notFoundError = err;
|
|
1133
1125
|
}
|
|
1126
|
+
matchesByRouteId[route.rootRouteId].notFoundError = err;
|
|
1134
1127
|
};
|
|
1135
1128
|
this.hasNotFoundMatch = () => {
|
|
1136
1129
|
return this.__store.state.matches.some((d) => d.notFoundError);
|