@tanstack/router-core 1.124.0 → 1.125.0
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.map +1 -1
- package/dist/cjs/Matches.d.cts +29 -0
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/route.cjs +0 -5
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +20 -6
- package/dist/cjs/router.cjs +178 -56
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +6 -1
- package/dist/cjs/ssr/ssr-client.cjs +38 -2
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.d.cts +1 -0
- package/dist/cjs/ssr/ssr-server.cjs +2 -1
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/utils.cjs +5 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -0
- package/dist/esm/Matches.d.ts +29 -0
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/route.d.ts +20 -6
- package/dist/esm/route.js +0 -5
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +6 -1
- package/dist/esm/router.js +178 -56
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/ssr/ssr-client.d.ts +1 -0
- package/dist/esm/ssr/ssr-client.js +38 -2
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.js +2 -1
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +5 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.ts +38 -0
- package/src/index.ts +1 -0
- package/src/route.ts +32 -10
- package/src/router.ts +225 -66
- package/src/ssr/ssr-client.ts +49 -3
- package/src/ssr/ssr-server.ts +1 -0
- package/src/utils.ts +12 -0
package/dist/cjs/router.cjs
CHANGED
|
@@ -112,8 +112,7 @@ class RouterCore {
|
|
|
112
112
|
routeTree: this.routeTree,
|
|
113
113
|
initRoute: (route, i) => {
|
|
114
114
|
route.init({
|
|
115
|
-
originalIndex: i
|
|
116
|
-
defaultSsr: this.options.defaultSsr
|
|
115
|
+
originalIndex: i
|
|
117
116
|
});
|
|
118
117
|
}
|
|
119
118
|
});
|
|
@@ -123,8 +122,7 @@ class RouterCore {
|
|
|
123
122
|
const notFoundRoute = this.options.notFoundRoute;
|
|
124
123
|
if (notFoundRoute) {
|
|
125
124
|
notFoundRoute.init({
|
|
126
|
-
originalIndex: 99999999999
|
|
127
|
-
defaultSsr: this.options.defaultSsr
|
|
125
|
+
originalIndex: 99999999999
|
|
128
126
|
});
|
|
129
127
|
this.routesById[notFoundRoute.id] = notFoundRoute;
|
|
130
128
|
}
|
|
@@ -232,9 +230,10 @@ class RouterCore {
|
|
|
232
230
|
});
|
|
233
231
|
const lastMatch = utils.last(allFromMatches);
|
|
234
232
|
let fromPath = lastMatch.fullPath;
|
|
233
|
+
const routeIsChanging = !!dest.to && dest.to !== fromPath && this.resolvePathWithBase(fromPath, `${dest.to}`) !== fromPath;
|
|
235
234
|
if (dest.unsafeRelative === "path") {
|
|
236
235
|
fromPath = currentLocation.pathname;
|
|
237
|
-
} else if (
|
|
236
|
+
} else if (routeIsChanging && dest.from) {
|
|
238
237
|
fromPath = dest.from;
|
|
239
238
|
const existingFrom = [...allFromMatches].reverse().find((d) => {
|
|
240
239
|
return d.fullPath === fromPath || d.fullPath === path.joinPaths([fromPath, "/"]);
|
|
@@ -497,7 +496,10 @@ class RouterCore {
|
|
|
497
496
|
throw redirect.redirect({ href: nextLocation.href });
|
|
498
497
|
}
|
|
499
498
|
}
|
|
500
|
-
|
|
499
|
+
let pendingMatches = this.matchRoutes(this.latestLocation);
|
|
500
|
+
if (this.isShell) {
|
|
501
|
+
pendingMatches = pendingMatches.slice(0, 1);
|
|
502
|
+
}
|
|
501
503
|
this.__store.setState((s) => ({
|
|
502
504
|
...s,
|
|
503
505
|
status: "pending",
|
|
@@ -692,12 +694,41 @@ class RouterCore {
|
|
|
692
694
|
const triggerOnReady = async () => {
|
|
693
695
|
if (!rendered) {
|
|
694
696
|
rendered = true;
|
|
697
|
+
if (!allPreload && !this.isServer) {
|
|
698
|
+
matches.forEach((match) => {
|
|
699
|
+
const {
|
|
700
|
+
id: matchId,
|
|
701
|
+
routeId,
|
|
702
|
+
_forcePending,
|
|
703
|
+
minPendingPromise
|
|
704
|
+
} = match;
|
|
705
|
+
const route = this.looseRoutesById[routeId];
|
|
706
|
+
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
707
|
+
if (_forcePending && pendingMinMs && !minPendingPromise) {
|
|
708
|
+
const minPendingPromise2 = utils.createControlledPromise();
|
|
709
|
+
updateMatch(matchId, (prev) => ({
|
|
710
|
+
...prev,
|
|
711
|
+
minPendingPromise: minPendingPromise2
|
|
712
|
+
}));
|
|
713
|
+
setTimeout(() => {
|
|
714
|
+
minPendingPromise2.resolve();
|
|
715
|
+
updateMatch(matchId, (prev) => ({
|
|
716
|
+
...prev,
|
|
717
|
+
minPendingPromise: void 0
|
|
718
|
+
}));
|
|
719
|
+
}, pendingMinMs);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
}
|
|
695
723
|
await (onReady == null ? void 0 : onReady());
|
|
696
724
|
}
|
|
697
725
|
};
|
|
698
726
|
const resolvePreload = (matchId) => {
|
|
699
727
|
return !!(allPreload && !this.state.matches.find((d) => d.id === matchId));
|
|
700
728
|
};
|
|
729
|
+
if (!this.isServer && this.state.matches.find((d) => d._forcePending)) {
|
|
730
|
+
triggerOnReady();
|
|
731
|
+
}
|
|
701
732
|
const handleRedirectAndNotFound = (match, err) => {
|
|
702
733
|
var _a, _b, _c, _d;
|
|
703
734
|
if (redirect.isRedirect(err) || notFound.isNotFound(err)) {
|
|
@@ -740,6 +771,18 @@ class RouterCore {
|
|
|
740
771
|
}
|
|
741
772
|
}
|
|
742
773
|
};
|
|
774
|
+
const shouldSkipLoader = (matchId) => {
|
|
775
|
+
const match = this.getMatch(matchId);
|
|
776
|
+
if (!this.isServer && match._dehydrated) {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
if (this.isServer) {
|
|
780
|
+
if (match.ssr === false) {
|
|
781
|
+
return true;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return false;
|
|
785
|
+
};
|
|
743
786
|
try {
|
|
744
787
|
await new Promise((resolveAll, rejectAll) => {
|
|
745
788
|
;
|
|
@@ -780,8 +823,60 @@ class RouterCore {
|
|
|
780
823
|
for (const [index, { id: matchId, routeId }] of matches.entries()) {
|
|
781
824
|
const existingMatch = this.getMatch(matchId);
|
|
782
825
|
const parentMatchId = (_a = matches[index - 1]) == null ? void 0 : _a.id;
|
|
826
|
+
const parentMatch = parentMatchId ? this.getMatch(parentMatchId) : void 0;
|
|
783
827
|
const route = this.looseRoutesById[routeId];
|
|
784
828
|
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
829
|
+
if (this.isServer) {
|
|
830
|
+
const defaultSsr = this.options.defaultSsr ?? true;
|
|
831
|
+
let ssr;
|
|
832
|
+
if ((parentMatch == null ? void 0 : parentMatch.ssr) === false) {
|
|
833
|
+
ssr = false;
|
|
834
|
+
} else {
|
|
835
|
+
let tempSsr;
|
|
836
|
+
if (route.options.ssr === void 0) {
|
|
837
|
+
tempSsr = defaultSsr;
|
|
838
|
+
} else if (typeof route.options.ssr === "function") {
|
|
839
|
+
let makeMaybe = function(value, error) {
|
|
840
|
+
if (error) {
|
|
841
|
+
return { status: "error", error };
|
|
842
|
+
}
|
|
843
|
+
return { status: "success", value };
|
|
844
|
+
};
|
|
845
|
+
const { search, params } = this.getMatch(matchId);
|
|
846
|
+
const ssrFnContext = {
|
|
847
|
+
search: makeMaybe(search, existingMatch.searchError),
|
|
848
|
+
params: makeMaybe(params, existingMatch.paramsError),
|
|
849
|
+
location,
|
|
850
|
+
matches: matches.map((match) => ({
|
|
851
|
+
index: match.index,
|
|
852
|
+
pathname: match.pathname,
|
|
853
|
+
fullPath: match.fullPath,
|
|
854
|
+
staticData: match.staticData,
|
|
855
|
+
id: match.id,
|
|
856
|
+
routeId: match.routeId,
|
|
857
|
+
search: makeMaybe(match.search, match.searchError),
|
|
858
|
+
params: makeMaybe(match.params, match.paramsError),
|
|
859
|
+
ssr: match.ssr
|
|
860
|
+
}))
|
|
861
|
+
};
|
|
862
|
+
tempSsr = await route.options.ssr(ssrFnContext) ?? defaultSsr;
|
|
863
|
+
} else {
|
|
864
|
+
tempSsr = route.options.ssr;
|
|
865
|
+
}
|
|
866
|
+
if (tempSsr === true && (parentMatch == null ? void 0 : parentMatch.ssr) === "data-only") {
|
|
867
|
+
ssr = "data-only";
|
|
868
|
+
} else {
|
|
869
|
+
ssr = tempSsr;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
updateMatch(matchId, (prev) => ({
|
|
873
|
+
...prev,
|
|
874
|
+
ssr
|
|
875
|
+
}));
|
|
876
|
+
}
|
|
877
|
+
if (shouldSkipLoader(matchId)) {
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
785
880
|
const shouldPending = !!(onReady && !this.isServer && !resolvePreload(matchId) && (route.options.loader || route.options.beforeLoad || routeNeedsPreload(route)) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? ((_b = this.options) == null ? void 0 : _b.defaultPendingComponent)));
|
|
786
881
|
let executeBeforeLoad = true;
|
|
787
882
|
if (
|
|
@@ -834,7 +929,7 @@ class RouterCore {
|
|
|
834
929
|
if (searchError) {
|
|
835
930
|
handleSerialError(index, searchError, "VALIDATE_SEARCH");
|
|
836
931
|
}
|
|
837
|
-
const
|
|
932
|
+
const parentMatchContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
|
|
838
933
|
updateMatch(matchId, (prev) => ({
|
|
839
934
|
...prev,
|
|
840
935
|
isFetching: "beforeLoad",
|
|
@@ -842,7 +937,7 @@ class RouterCore {
|
|
|
842
937
|
abortController,
|
|
843
938
|
pendingTimeout,
|
|
844
939
|
context: {
|
|
845
|
-
...
|
|
940
|
+
...parentMatchContext,
|
|
846
941
|
...prev.__routeContext
|
|
847
942
|
}
|
|
848
943
|
}));
|
|
@@ -869,7 +964,7 @@ class RouterCore {
|
|
|
869
964
|
...prev,
|
|
870
965
|
__beforeLoadContext: beforeLoadContext,
|
|
871
966
|
context: {
|
|
872
|
-
...
|
|
967
|
+
...parentMatchContext,
|
|
873
968
|
...prev.__routeContext,
|
|
874
969
|
...beforeLoadContext
|
|
875
970
|
},
|
|
@@ -895,10 +990,61 @@ class RouterCore {
|
|
|
895
990
|
validResolvedMatches.forEach(({ id: matchId, routeId }, index) => {
|
|
896
991
|
matchPromises.push(
|
|
897
992
|
(async () => {
|
|
993
|
+
var _a2, _b2;
|
|
898
994
|
let loaderShouldRunAsync = false;
|
|
899
995
|
let loaderIsRunningAsync = false;
|
|
996
|
+
const route = this.looseRoutesById[routeId];
|
|
997
|
+
const executeHead = async () => {
|
|
998
|
+
var _a3, _b3, _c2, _d2, _e, _f;
|
|
999
|
+
const match = this.getMatch(matchId);
|
|
1000
|
+
if (!match) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const assetContext = {
|
|
1004
|
+
matches,
|
|
1005
|
+
match,
|
|
1006
|
+
params: match.params,
|
|
1007
|
+
loaderData: match.loaderData
|
|
1008
|
+
};
|
|
1009
|
+
const headFnContent = await ((_b3 = (_a3 = route.options).head) == null ? void 0 : _b3.call(_a3, assetContext));
|
|
1010
|
+
const meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1011
|
+
const links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1012
|
+
const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1013
|
+
const styles = headFnContent == null ? void 0 : headFnContent.styles;
|
|
1014
|
+
const scripts = await ((_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext));
|
|
1015
|
+
const headers = await ((_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext));
|
|
1016
|
+
return {
|
|
1017
|
+
meta,
|
|
1018
|
+
links,
|
|
1019
|
+
headScripts,
|
|
1020
|
+
headers,
|
|
1021
|
+
scripts,
|
|
1022
|
+
styles
|
|
1023
|
+
};
|
|
1024
|
+
};
|
|
1025
|
+
const potentialPendingMinPromise = async () => {
|
|
1026
|
+
const latestMatch = this.getMatch(matchId);
|
|
1027
|
+
if (latestMatch.minPendingPromise) {
|
|
1028
|
+
await latestMatch.minPendingPromise;
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
900
1031
|
const prevMatch = this.getMatch(matchId);
|
|
901
|
-
if (
|
|
1032
|
+
if (shouldSkipLoader(matchId)) {
|
|
1033
|
+
if (this.isServer) {
|
|
1034
|
+
const head = await executeHead();
|
|
1035
|
+
updateMatch(matchId, (prev) => ({
|
|
1036
|
+
...prev,
|
|
1037
|
+
...head
|
|
1038
|
+
}));
|
|
1039
|
+
(_a2 = this.serverSsr) == null ? void 0 : _a2.onMatchSettled({
|
|
1040
|
+
router: this,
|
|
1041
|
+
match: this.getMatch(matchId)
|
|
1042
|
+
});
|
|
1043
|
+
return this.getMatch(matchId);
|
|
1044
|
+
} else {
|
|
1045
|
+
await potentialPendingMinPromise();
|
|
1046
|
+
}
|
|
1047
|
+
} else if (prevMatch.loaderPromise) {
|
|
902
1048
|
if (prevMatch.status === "success" && !sync && !prevMatch.preload) {
|
|
903
1049
|
return this.getMatch(matchId);
|
|
904
1050
|
}
|
|
@@ -909,7 +1055,6 @@ class RouterCore {
|
|
|
909
1055
|
}
|
|
910
1056
|
} else {
|
|
911
1057
|
const parentMatchPromise = matchPromises[index - 1];
|
|
912
|
-
const route = this.looseRoutesById[routeId];
|
|
913
1058
|
const getLoaderContext = () => {
|
|
914
1059
|
const {
|
|
915
1060
|
params,
|
|
@@ -942,55 +1087,28 @@ class RouterCore {
|
|
|
942
1087
|
loaderPromise: utils.createControlledPromise(),
|
|
943
1088
|
preload: !!preload && !this.state.matches.find((d) => d.id === matchId)
|
|
944
1089
|
}));
|
|
945
|
-
const executeHead = async () => {
|
|
946
|
-
var _a2, _b2, _c2, _d2, _e, _f;
|
|
947
|
-
const match = this.getMatch(matchId);
|
|
948
|
-
if (!match) {
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
const assetContext = {
|
|
952
|
-
matches,
|
|
953
|
-
match,
|
|
954
|
-
params: match.params,
|
|
955
|
-
loaderData: match.loaderData
|
|
956
|
-
};
|
|
957
|
-
const headFnContent = await ((_b2 = (_a2 = route.options).head) == null ? void 0 : _b2.call(_a2, assetContext));
|
|
958
|
-
const meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
959
|
-
const links = headFnContent == null ? void 0 : headFnContent.links;
|
|
960
|
-
const headScripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
961
|
-
const styles = headFnContent == null ? void 0 : headFnContent.styles;
|
|
962
|
-
const scripts = await ((_d2 = (_c2 = route.options).scripts) == null ? void 0 : _d2.call(_c2, assetContext));
|
|
963
|
-
const headers = await ((_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, assetContext));
|
|
964
|
-
return {
|
|
965
|
-
meta,
|
|
966
|
-
links,
|
|
967
|
-
headScripts,
|
|
968
|
-
headers,
|
|
969
|
-
scripts,
|
|
970
|
-
styles
|
|
971
|
-
};
|
|
972
|
-
};
|
|
973
1090
|
const runLoader = async () => {
|
|
974
|
-
var
|
|
1091
|
+
var _a3, _b3, _c2, _d2, _e;
|
|
975
1092
|
try {
|
|
976
|
-
const potentialPendingMinPromise = async () => {
|
|
977
|
-
const latestMatch = this.getMatch(matchId);
|
|
978
|
-
if (latestMatch.minPendingPromise) {
|
|
979
|
-
await latestMatch.minPendingPromise;
|
|
980
|
-
}
|
|
981
|
-
};
|
|
982
1093
|
try {
|
|
983
|
-
this.
|
|
1094
|
+
if (!this.isServer || this.isServer && this.getMatch(matchId).ssr === true) {
|
|
1095
|
+
this.loadRouteChunk(route);
|
|
1096
|
+
}
|
|
984
1097
|
updateMatch(matchId, (prev) => ({
|
|
985
1098
|
...prev,
|
|
986
1099
|
isFetching: "loader"
|
|
987
1100
|
}));
|
|
988
|
-
const loaderData = await ((
|
|
1101
|
+
const loaderData = await ((_b3 = (_a3 = route.options).loader) == null ? void 0 : _b3.call(_a3, getLoaderContext()));
|
|
989
1102
|
handleRedirectAndNotFound(
|
|
990
1103
|
this.getMatch(matchId),
|
|
991
1104
|
loaderData
|
|
992
1105
|
);
|
|
1106
|
+
updateMatch(matchId, (prev) => ({
|
|
1107
|
+
...prev,
|
|
1108
|
+
loaderData
|
|
1109
|
+
}));
|
|
993
1110
|
await route._lazyPromise;
|
|
1111
|
+
const head = await executeHead();
|
|
994
1112
|
await potentialPendingMinPromise();
|
|
995
1113
|
await route._componentsPromise;
|
|
996
1114
|
updateMatch(matchId, (prev) => ({
|
|
@@ -999,11 +1117,6 @@ class RouterCore {
|
|
|
999
1117
|
status: "success",
|
|
1000
1118
|
isFetching: false,
|
|
1001
1119
|
updatedAt: Date.now(),
|
|
1002
|
-
loaderData
|
|
1003
|
-
}));
|
|
1004
|
-
const head = await executeHead();
|
|
1005
|
-
updateMatch(matchId, (prev) => ({
|
|
1006
|
-
...prev,
|
|
1007
1120
|
...head
|
|
1008
1121
|
}));
|
|
1009
1122
|
} catch (e) {
|
|
@@ -1042,10 +1155,10 @@ class RouterCore {
|
|
|
1042
1155
|
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
1043
1156
|
}
|
|
1044
1157
|
};
|
|
1045
|
-
const { status, invalid } = this.getMatch(matchId);
|
|
1158
|
+
const { status, invalid, _forcePending } = this.getMatch(matchId);
|
|
1046
1159
|
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
1047
1160
|
if (preload && route.options.preload === false) {
|
|
1048
|
-
} else if (loaderShouldRunAsync && !sync) {
|
|
1161
|
+
} else if (loaderShouldRunAsync && !sync && !_forcePending) {
|
|
1049
1162
|
loaderIsRunningAsync = true;
|
|
1050
1163
|
(async () => {
|
|
1051
1164
|
try {
|
|
@@ -1066,11 +1179,18 @@ class RouterCore {
|
|
|
1066
1179
|
} else if (status !== "success" || loaderShouldRunAsync && sync) {
|
|
1067
1180
|
await runLoader();
|
|
1068
1181
|
} else {
|
|
1182
|
+
if (_forcePending) {
|
|
1183
|
+
await potentialPendingMinPromise();
|
|
1184
|
+
}
|
|
1069
1185
|
const head = await executeHead();
|
|
1070
1186
|
updateMatch(matchId, (prev) => ({
|
|
1071
1187
|
...prev,
|
|
1072
1188
|
...head
|
|
1073
1189
|
}));
|
|
1190
|
+
(_b2 = this.serverSsr) == null ? void 0 : _b2.onMatchSettled({
|
|
1191
|
+
router: this,
|
|
1192
|
+
match: this.getMatch(matchId)
|
|
1193
|
+
});
|
|
1074
1194
|
}
|
|
1075
1195
|
}
|
|
1076
1196
|
if (!loaderIsRunningAsync) {
|
|
@@ -1082,7 +1202,9 @@ class RouterCore {
|
|
|
1082
1202
|
...prev,
|
|
1083
1203
|
isFetching: loaderIsRunningAsync ? prev.isFetching : false,
|
|
1084
1204
|
loaderPromise: loaderIsRunningAsync ? prev.loaderPromise : void 0,
|
|
1085
|
-
invalid: false
|
|
1205
|
+
invalid: false,
|
|
1206
|
+
_dehydrated: void 0,
|
|
1207
|
+
_forcePending: void 0
|
|
1086
1208
|
}));
|
|
1087
1209
|
return this.getMatch(matchId);
|
|
1088
1210
|
})()
|