@tanstack/router-core 1.132.0-alpha.0 → 1.132.0-alpha.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.map +1 -1
- package/dist/cjs/Matches.d.cts +7 -9
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +0 -4
- package/dist/cjs/router.cjs +629 -528
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +19 -8
- package/dist/cjs/scroll-restoration.d.cts +0 -9
- package/dist/cjs/ssr/ssr-client.cjs +38 -39
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/typePrimitives.d.cts +6 -6
- package/dist/cjs/utils.cjs +6 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -0
- package/dist/esm/Matches.d.ts +7 -9
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/route.d.ts +0 -4
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +19 -8
- package/dist/esm/router.js +630 -529
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.d.ts +0 -9
- package/dist/esm/ssr/ssr-client.js +38 -39
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +6 -6
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +6 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/Matches.ts +16 -8
- package/src/route.ts +10 -2
- package/src/router.ts +909 -717
- package/src/ssr/ssr-client.ts +42 -41
- package/src/typePrimitives.ts +6 -6
- package/src/utils.ts +10 -0
package/dist/esm/router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Store, batch } from "@tanstack/store";
|
|
2
2
|
import { createMemoryHistory, createBrowserHistory, parseHref } from "@tanstack/history";
|
|
3
3
|
import invariant from "tiny-invariant";
|
|
4
|
-
import { pick, createControlledPromise, deepEqual, replaceEqualDeep, last, functionalUpdate } from "./utils.js";
|
|
4
|
+
import { pick, createControlledPromise, isPromise, deepEqual, replaceEqualDeep, last, functionalUpdate } from "./utils.js";
|
|
5
5
|
import { trimPath, resolvePath, cleanPath, matchPathname, trimPathRight, interpolatePath, joinPaths, trimPathLeft, parsePathname, SEGMENT_TYPE_PARAM, SEGMENT_TYPE_OPTIONAL_PARAM, SEGMENT_TYPE_WILDCARD, SEGMENT_TYPE_PATHNAME } from "./path.js";
|
|
6
6
|
import { isNotFound } from "./not-found.js";
|
|
7
7
|
import { setupScrollRestoration } from "./scroll-restoration.js";
|
|
@@ -210,13 +210,8 @@ class RouterCore {
|
|
|
210
210
|
const match = this.getMatch(id);
|
|
211
211
|
if (!match) return;
|
|
212
212
|
match.abortController.abort();
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
...prev,
|
|
217
|
-
pendingTimeout: void 0
|
|
218
|
-
};
|
|
219
|
-
});
|
|
213
|
+
clearTimeout(match._nonReactive.pendingTimeout);
|
|
214
|
+
match._nonReactive.pendingTimeout = void 0;
|
|
220
215
|
};
|
|
221
216
|
this.cancelMatches = () => {
|
|
222
217
|
this.state.pendingMatches?.forEach((match) => {
|
|
@@ -230,7 +225,7 @@ class RouterCore {
|
|
|
230
225
|
_buildLocation: true
|
|
231
226
|
});
|
|
232
227
|
const lastMatch = last(allCurrentLocationMatches);
|
|
233
|
-
let fromPath = lastMatch.fullPath;
|
|
228
|
+
let fromPath = this.resolvePathWithBase(lastMatch.fullPath, ".");
|
|
234
229
|
const toPath = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
|
|
235
230
|
const routeIsChanging = !!dest.to && !comparePaths(dest.to.toString(), fromPath) && !comparePaths(toPath, fromPath);
|
|
236
231
|
if (dest.unsafeRelative === "path") {
|
|
@@ -253,6 +248,7 @@ class RouterCore {
|
|
|
253
248
|
}
|
|
254
249
|
}
|
|
255
250
|
}
|
|
251
|
+
fromPath = this.resolvePathWithBase(fromPath, ".");
|
|
256
252
|
const fromSearch = lastMatch.search;
|
|
257
253
|
const fromParams = { ...lastMatch.params };
|
|
258
254
|
const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
|
|
@@ -265,13 +261,9 @@ class RouterCore {
|
|
|
265
261
|
params: nextParams ?? {},
|
|
266
262
|
parseCache: this.parsePathnameCache
|
|
267
263
|
}).interpolatedPath;
|
|
268
|
-
const destRoutes = this.matchRoutes(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
{
|
|
272
|
-
_buildLocation: true
|
|
273
|
-
}
|
|
274
|
-
).map((d) => this.looseRoutesById[d.routeId]);
|
|
264
|
+
const destRoutes = this.matchRoutes(interpolatedNextTo, void 0, {
|
|
265
|
+
_buildLocation: true
|
|
266
|
+
}).map((d) => this.looseRoutesById[d.routeId]);
|
|
275
267
|
if (Object.keys(nextParams).length > 0) {
|
|
276
268
|
destRoutes.map((route) => {
|
|
277
269
|
return route.options.params?.stringify ?? route.options.stringifyParams;
|
|
@@ -693,502 +685,597 @@ class RouterCore {
|
|
|
693
685
|
const findFn = (d) => d.id === matchId;
|
|
694
686
|
return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
|
|
695
687
|
};
|
|
696
|
-
this.
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
688
|
+
this.triggerOnReady = (innerLoadContext) => {
|
|
689
|
+
if (!innerLoadContext.rendered) {
|
|
690
|
+
innerLoadContext.rendered = true;
|
|
691
|
+
return innerLoadContext.onReady?.();
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
this.resolvePreload = (innerLoadContext, matchId) => {
|
|
695
|
+
return !!(innerLoadContext.preload && !this.state.matches.some((d) => d.id === matchId));
|
|
696
|
+
};
|
|
697
|
+
this.handleRedirectAndNotFound = (innerLoadContext, match, err) => {
|
|
698
|
+
if (!isRedirect(err) && !isNotFound(err)) return;
|
|
699
|
+
if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {
|
|
700
|
+
throw err;
|
|
701
|
+
}
|
|
702
|
+
if (match) {
|
|
703
|
+
match._nonReactive.beforeLoadPromise?.resolve();
|
|
704
|
+
match._nonReactive.loaderPromise?.resolve();
|
|
705
|
+
match._nonReactive.beforeLoadPromise = void 0;
|
|
706
|
+
match._nonReactive.loaderPromise = void 0;
|
|
707
|
+
const status = isRedirect(err) ? "redirected" : "notFound";
|
|
708
|
+
innerLoadContext.updateMatch(match.id, (prev) => ({
|
|
709
|
+
...prev,
|
|
710
|
+
status,
|
|
711
|
+
isFetching: false,
|
|
712
|
+
error: err
|
|
713
|
+
}));
|
|
714
|
+
if (isNotFound(err) && !err.routeId) {
|
|
715
|
+
err.routeId = match.routeId;
|
|
716
|
+
}
|
|
717
|
+
match._nonReactive.loadPromise?.resolve();
|
|
718
|
+
}
|
|
719
|
+
if (isRedirect(err)) {
|
|
720
|
+
innerLoadContext.rendered = true;
|
|
721
|
+
err.options._fromLocation = innerLoadContext.location;
|
|
722
|
+
err.redirectHandled = true;
|
|
723
|
+
err = this.resolveRedirect(err);
|
|
724
|
+
throw err;
|
|
725
|
+
} else {
|
|
726
|
+
this._handleNotFound(innerLoadContext, err);
|
|
727
|
+
throw err;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
this.shouldSkipLoader = (matchId) => {
|
|
731
|
+
const match = this.getMatch(matchId);
|
|
732
|
+
if (!this.isServer && match._nonReactive.dehydrated) {
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
if (this.isServer) {
|
|
736
|
+
if (match.ssr === false) {
|
|
737
|
+
return true;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return false;
|
|
741
|
+
};
|
|
742
|
+
this.handleSerialError = (innerLoadContext, index, err, routerCode) => {
|
|
743
|
+
const { id: matchId, routeId } = innerLoadContext.matches[index];
|
|
744
|
+
const route = this.looseRoutesById[routeId];
|
|
745
|
+
if (err instanceof Promise) {
|
|
746
|
+
throw err;
|
|
747
|
+
}
|
|
748
|
+
err.routerCode = routerCode;
|
|
749
|
+
innerLoadContext.firstBadMatchIndex ??= index;
|
|
750
|
+
this.handleRedirectAndNotFound(
|
|
751
|
+
innerLoadContext,
|
|
752
|
+
this.getMatch(matchId),
|
|
753
|
+
err
|
|
754
|
+
);
|
|
755
|
+
try {
|
|
756
|
+
route.options.onError?.(err);
|
|
757
|
+
} catch (errorHandlerErr) {
|
|
758
|
+
err = errorHandlerErr;
|
|
759
|
+
this.handleRedirectAndNotFound(
|
|
760
|
+
innerLoadContext,
|
|
761
|
+
this.getMatch(matchId),
|
|
762
|
+
err
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
innerLoadContext.updateMatch(matchId, (prev) => {
|
|
766
|
+
prev._nonReactive.beforeLoadPromise?.resolve();
|
|
767
|
+
prev._nonReactive.beforeLoadPromise = void 0;
|
|
768
|
+
prev._nonReactive.loadPromise?.resolve();
|
|
769
|
+
return {
|
|
770
|
+
...prev,
|
|
771
|
+
error: err,
|
|
772
|
+
status: "error",
|
|
773
|
+
isFetching: false,
|
|
774
|
+
updatedAt: Date.now(),
|
|
775
|
+
abortController: new AbortController()
|
|
776
|
+
};
|
|
777
|
+
});
|
|
778
|
+
};
|
|
779
|
+
this.isBeforeLoadSsr = (innerLoadContext, matchId, index, route) => {
|
|
780
|
+
const existingMatch = this.getMatch(matchId);
|
|
781
|
+
const parentMatchId = innerLoadContext.matches[index - 1]?.id;
|
|
782
|
+
const parentMatch = parentMatchId ? this.getMatch(parentMatchId) : void 0;
|
|
783
|
+
if (this.isShell()) {
|
|
784
|
+
existingMatch.ssr = matchId === rootRouteId;
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
if (parentMatch?.ssr === false) {
|
|
788
|
+
existingMatch.ssr = false;
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const parentOverride = (tempSsr2) => {
|
|
792
|
+
if (tempSsr2 === true && parentMatch?.ssr === "data-only") {
|
|
793
|
+
return "data-only";
|
|
710
794
|
}
|
|
795
|
+
return tempSsr2;
|
|
711
796
|
};
|
|
712
|
-
const
|
|
713
|
-
|
|
797
|
+
const defaultSsr = this.options.defaultSsr ?? true;
|
|
798
|
+
if (route.options.ssr === void 0) {
|
|
799
|
+
existingMatch.ssr = parentOverride(defaultSsr);
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
if (typeof route.options.ssr !== "function") {
|
|
803
|
+
existingMatch.ssr = parentOverride(route.options.ssr);
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
const { search, params } = this.getMatch(matchId);
|
|
807
|
+
const ssrFnContext = {
|
|
808
|
+
search: makeMaybe(search, existingMatch.searchError),
|
|
809
|
+
params: makeMaybe(params, existingMatch.paramsError),
|
|
810
|
+
location: innerLoadContext.location,
|
|
811
|
+
matches: innerLoadContext.matches.map((match) => ({
|
|
812
|
+
index: match.index,
|
|
813
|
+
pathname: match.pathname,
|
|
814
|
+
fullPath: match.fullPath,
|
|
815
|
+
staticData: match.staticData,
|
|
816
|
+
id: match.id,
|
|
817
|
+
routeId: match.routeId,
|
|
818
|
+
search: makeMaybe(match.search, match.searchError),
|
|
819
|
+
params: makeMaybe(match.params, match.paramsError),
|
|
820
|
+
ssr: match.ssr
|
|
821
|
+
}))
|
|
714
822
|
};
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
823
|
+
const tempSsr = route.options.ssr(ssrFnContext);
|
|
824
|
+
if (isPromise(tempSsr)) {
|
|
825
|
+
return tempSsr.then((ssr) => {
|
|
826
|
+
existingMatch.ssr = parentOverride(ssr ?? defaultSsr);
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr);
|
|
830
|
+
return;
|
|
831
|
+
};
|
|
832
|
+
this.setupPendingTimeout = (innerLoadContext, matchId, route) => {
|
|
833
|
+
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
834
|
+
const shouldPending = !!(innerLoadContext.onReady && !this.isServer && !this.resolvePreload(innerLoadContext, matchId) && (route.options.loader || route.options.beforeLoad || routeNeedsPreload(route)) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options?.defaultPendingComponent));
|
|
835
|
+
const match = this.getMatch(matchId);
|
|
836
|
+
if (shouldPending && match._nonReactive.pendingTimeout === void 0) {
|
|
837
|
+
const pendingTimeout = setTimeout(() => {
|
|
838
|
+
this.triggerOnReady(innerLoadContext);
|
|
839
|
+
}, pendingMs);
|
|
840
|
+
match._nonReactive.pendingTimeout = pendingTimeout;
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
this.shouldExecuteBeforeLoad = (innerLoadContext, matchId, route) => {
|
|
844
|
+
const existingMatch = this.getMatch(matchId);
|
|
845
|
+
if (!existingMatch._nonReactive.beforeLoadPromise && !existingMatch._nonReactive.loaderPromise)
|
|
846
|
+
return true;
|
|
847
|
+
this.setupPendingTimeout(innerLoadContext, matchId, route);
|
|
848
|
+
const then = () => {
|
|
849
|
+
let shouldExecuteBeforeLoad = true;
|
|
850
|
+
const match = this.getMatch(matchId);
|
|
851
|
+
if (match.status === "error") {
|
|
852
|
+
shouldExecuteBeforeLoad = true;
|
|
853
|
+
} else if (match.preload && (match.status === "redirected" || match.status === "notFound")) {
|
|
854
|
+
this.handleRedirectAndNotFound(innerLoadContext, match, match.error);
|
|
855
|
+
}
|
|
856
|
+
return shouldExecuteBeforeLoad;
|
|
857
|
+
};
|
|
858
|
+
return existingMatch._nonReactive.beforeLoadPromise ? existingMatch._nonReactive.beforeLoadPromise.then(then) : then();
|
|
859
|
+
};
|
|
860
|
+
this.executeBeforeLoad = (innerLoadContext, matchId, index, route) => {
|
|
861
|
+
const match = this.getMatch(matchId);
|
|
862
|
+
match._nonReactive.beforeLoadPromise = createControlledPromise();
|
|
863
|
+
const prevLoadPromise = match._nonReactive.loadPromise;
|
|
864
|
+
match._nonReactive.loadPromise = createControlledPromise(() => {
|
|
865
|
+
prevLoadPromise?.resolve();
|
|
866
|
+
});
|
|
867
|
+
const { paramsError, searchError } = match;
|
|
868
|
+
if (paramsError) {
|
|
869
|
+
this.handleSerialError(
|
|
870
|
+
innerLoadContext,
|
|
871
|
+
index,
|
|
872
|
+
paramsError,
|
|
873
|
+
"PARSE_PARAMS"
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
if (searchError) {
|
|
877
|
+
this.handleSerialError(
|
|
878
|
+
innerLoadContext,
|
|
879
|
+
index,
|
|
880
|
+
searchError,
|
|
881
|
+
"VALIDATE_SEARCH"
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
this.setupPendingTimeout(innerLoadContext, matchId, route);
|
|
885
|
+
const abortController = new AbortController();
|
|
886
|
+
const parentMatchId = innerLoadContext.matches[index - 1]?.id;
|
|
887
|
+
const parentMatch = parentMatchId ? this.getMatch(parentMatchId) : void 0;
|
|
888
|
+
const parentMatchContext = parentMatch?.context ?? this.options.context ?? void 0;
|
|
889
|
+
const context = { ...parentMatchContext, ...match.__routeContext };
|
|
890
|
+
let isPending = false;
|
|
891
|
+
const pending = () => {
|
|
892
|
+
if (isPending) return;
|
|
893
|
+
isPending = true;
|
|
894
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
895
|
+
...prev,
|
|
896
|
+
isFetching: "beforeLoad",
|
|
897
|
+
fetchCount: prev.fetchCount + 1,
|
|
898
|
+
abortController,
|
|
899
|
+
context
|
|
900
|
+
}));
|
|
901
|
+
};
|
|
902
|
+
const resolve = () => {
|
|
903
|
+
match._nonReactive.beforeLoadPromise?.resolve();
|
|
904
|
+
match._nonReactive.beforeLoadPromise = void 0;
|
|
905
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
906
|
+
...prev,
|
|
907
|
+
isFetching: false
|
|
908
|
+
}));
|
|
909
|
+
};
|
|
910
|
+
if (!route.options.beforeLoad) {
|
|
911
|
+
batch(() => {
|
|
912
|
+
pending();
|
|
913
|
+
resolve();
|
|
914
|
+
});
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
const { search, params, cause } = match;
|
|
918
|
+
const preload = this.resolvePreload(innerLoadContext, matchId);
|
|
919
|
+
const beforeLoadFnContext = {
|
|
920
|
+
search,
|
|
921
|
+
abortController,
|
|
922
|
+
params,
|
|
923
|
+
preload,
|
|
924
|
+
context,
|
|
925
|
+
location: innerLoadContext.location,
|
|
926
|
+
navigate: (opts) => this.navigate({ ...opts, _fromLocation: innerLoadContext.location }),
|
|
927
|
+
buildLocation: this.buildLocation,
|
|
928
|
+
cause: preload ? "preload" : cause,
|
|
929
|
+
matches: innerLoadContext.matches
|
|
930
|
+
};
|
|
931
|
+
const updateContext = (beforeLoadContext2) => {
|
|
932
|
+
if (beforeLoadContext2 === void 0) {
|
|
933
|
+
batch(() => {
|
|
934
|
+
pending();
|
|
935
|
+
resolve();
|
|
936
|
+
});
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
if (isRedirect(beforeLoadContext2) || isNotFound(beforeLoadContext2)) {
|
|
940
|
+
pending();
|
|
941
|
+
this.handleSerialError(
|
|
942
|
+
innerLoadContext,
|
|
943
|
+
index,
|
|
944
|
+
beforeLoadContext2,
|
|
945
|
+
"BEFORE_LOAD"
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
batch(() => {
|
|
949
|
+
pending();
|
|
950
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
951
|
+
...prev,
|
|
952
|
+
__beforeLoadContext: beforeLoadContext2,
|
|
953
|
+
context: {
|
|
954
|
+
...prev.context,
|
|
955
|
+
...beforeLoadContext2
|
|
956
|
+
}
|
|
957
|
+
}));
|
|
958
|
+
resolve();
|
|
959
|
+
});
|
|
960
|
+
};
|
|
961
|
+
let beforeLoadContext;
|
|
962
|
+
try {
|
|
963
|
+
beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext);
|
|
964
|
+
if (isPromise(beforeLoadContext)) {
|
|
965
|
+
pending();
|
|
966
|
+
return beforeLoadContext.catch((err) => {
|
|
967
|
+
this.handleSerialError(innerLoadContext, index, err, "BEFORE_LOAD");
|
|
968
|
+
}).then(updateContext);
|
|
969
|
+
}
|
|
970
|
+
} catch (err) {
|
|
971
|
+
pending();
|
|
972
|
+
this.handleSerialError(innerLoadContext, index, err, "BEFORE_LOAD");
|
|
973
|
+
}
|
|
974
|
+
updateContext(beforeLoadContext);
|
|
975
|
+
return;
|
|
976
|
+
};
|
|
977
|
+
this.handleBeforeLoad = (innerLoadContext, index) => {
|
|
978
|
+
const { id: matchId, routeId } = innerLoadContext.matches[index];
|
|
979
|
+
const route = this.looseRoutesById[routeId];
|
|
980
|
+
const serverSsr = () => {
|
|
981
|
+
if (this.isServer) {
|
|
982
|
+
const maybePromise = this.isBeforeLoadSsr(
|
|
983
|
+
innerLoadContext,
|
|
984
|
+
matchId,
|
|
985
|
+
index,
|
|
986
|
+
route
|
|
987
|
+
);
|
|
988
|
+
if (isPromise(maybePromise)) return maybePromise.then(queueExecution);
|
|
989
|
+
}
|
|
990
|
+
return queueExecution();
|
|
991
|
+
};
|
|
992
|
+
const queueExecution = () => {
|
|
993
|
+
if (this.shouldSkipLoader(matchId)) return;
|
|
994
|
+
const shouldExecuteBeforeLoadResult = this.shouldExecuteBeforeLoad(
|
|
995
|
+
innerLoadContext,
|
|
996
|
+
matchId,
|
|
997
|
+
route
|
|
998
|
+
);
|
|
999
|
+
return isPromise(shouldExecuteBeforeLoadResult) ? shouldExecuteBeforeLoadResult.then(execute) : execute(shouldExecuteBeforeLoadResult);
|
|
1000
|
+
};
|
|
1001
|
+
const execute = (shouldExecuteBeforeLoad) => {
|
|
1002
|
+
if (shouldExecuteBeforeLoad) {
|
|
1003
|
+
return this.executeBeforeLoad(innerLoadContext, matchId, index, route);
|
|
1004
|
+
}
|
|
1005
|
+
return;
|
|
1006
|
+
};
|
|
1007
|
+
return serverSsr();
|
|
1008
|
+
};
|
|
1009
|
+
this.executeHead = (innerLoadContext, matchId, route) => {
|
|
1010
|
+
const match = this.getMatch(matchId);
|
|
1011
|
+
if (!match) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
if (!route.options.head && !route.options.scripts && !route.options.headers) {
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
const assetContext = {
|
|
1018
|
+
matches: innerLoadContext.matches,
|
|
1019
|
+
match,
|
|
1020
|
+
params: match.params,
|
|
1021
|
+
loaderData: match.loaderData
|
|
1022
|
+
};
|
|
1023
|
+
return Promise.all([
|
|
1024
|
+
route.options.head?.(assetContext),
|
|
1025
|
+
route.options.scripts?.(assetContext),
|
|
1026
|
+
route.options.headers?.(assetContext)
|
|
1027
|
+
]).then(([headFnContent, scripts, headers]) => {
|
|
1028
|
+
const meta = headFnContent?.meta;
|
|
1029
|
+
const links = headFnContent?.links;
|
|
1030
|
+
const headScripts = headFnContent?.scripts;
|
|
1031
|
+
const styles = headFnContent?.styles;
|
|
1032
|
+
return {
|
|
1033
|
+
meta,
|
|
1034
|
+
links,
|
|
1035
|
+
headScripts,
|
|
1036
|
+
headers,
|
|
1037
|
+
scripts,
|
|
1038
|
+
styles
|
|
1039
|
+
};
|
|
1040
|
+
});
|
|
1041
|
+
};
|
|
1042
|
+
this.potentialPendingMinPromise = (matchId) => {
|
|
1043
|
+
const latestMatch = this.getMatch(matchId);
|
|
1044
|
+
return latestMatch._nonReactive.minPendingPromise;
|
|
1045
|
+
};
|
|
1046
|
+
this.getLoaderContext = (innerLoadContext, matchId, index, route) => {
|
|
1047
|
+
const parentMatchPromise = innerLoadContext.matchPromises[index - 1];
|
|
1048
|
+
const { params, loaderDeps, abortController, context, cause } = this.getMatch(matchId);
|
|
1049
|
+
const preload = this.resolvePreload(innerLoadContext, matchId);
|
|
1050
|
+
return {
|
|
1051
|
+
params,
|
|
1052
|
+
deps: loaderDeps,
|
|
1053
|
+
preload: !!preload,
|
|
1054
|
+
parentMatchPromise,
|
|
1055
|
+
abortController,
|
|
1056
|
+
context,
|
|
1057
|
+
location: innerLoadContext.location,
|
|
1058
|
+
navigate: (opts) => this.navigate({ ...opts, _fromLocation: innerLoadContext.location }),
|
|
1059
|
+
cause: preload ? "preload" : cause,
|
|
1060
|
+
route
|
|
1061
|
+
};
|
|
1062
|
+
};
|
|
1063
|
+
this.runLoader = async (innerLoadContext, matchId, index, route) => {
|
|
1064
|
+
try {
|
|
1065
|
+
try {
|
|
1066
|
+
if (!this.isServer || this.getMatch(matchId).ssr === true) {
|
|
1067
|
+
this.loadRouteChunk(route);
|
|
1068
|
+
}
|
|
1069
|
+
const loaderResult = route.options.loader?.(
|
|
1070
|
+
this.getLoaderContext(innerLoadContext, matchId, index, route)
|
|
1071
|
+
);
|
|
1072
|
+
const loaderResultIsPromise = route.options.loader && isPromise(loaderResult);
|
|
1073
|
+
const willLoadSomething = !!(loaderResultIsPromise || route._lazyPromise || route._componentsPromise || route.options.head || route.options.scripts || route.options.headers || this.getMatch(matchId)._nonReactive.minPendingPromise);
|
|
1074
|
+
if (willLoadSomething) {
|
|
1075
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1076
|
+
...prev,
|
|
1077
|
+
isFetching: "loader"
|
|
1078
|
+
}));
|
|
1079
|
+
}
|
|
1080
|
+
if (route.options.loader) {
|
|
1081
|
+
const loaderData = loaderResultIsPromise ? await loaderResult : loaderResult;
|
|
1082
|
+
this.handleRedirectAndNotFound(
|
|
1083
|
+
innerLoadContext,
|
|
1084
|
+
this.getMatch(matchId),
|
|
1085
|
+
loaderData
|
|
1086
|
+
);
|
|
1087
|
+
if (loaderData !== void 0) {
|
|
1088
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1089
|
+
...prev,
|
|
1090
|
+
loaderData
|
|
1091
|
+
}));
|
|
725
1092
|
}
|
|
726
1093
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
1094
|
+
if (route._lazyPromise) await route._lazyPromise;
|
|
1095
|
+
const headResult = this.executeHead(innerLoadContext, matchId, route);
|
|
1096
|
+
const head = headResult ? await headResult : void 0;
|
|
1097
|
+
const pendingPromise = this.potentialPendingMinPromise(matchId);
|
|
1098
|
+
if (pendingPromise) await pendingPromise;
|
|
1099
|
+
if (route._componentsPromise) await route._componentsPromise;
|
|
1100
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
730
1101
|
...prev,
|
|
731
|
-
|
|
1102
|
+
error: void 0,
|
|
1103
|
+
status: "success",
|
|
732
1104
|
isFetching: false,
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
loaderPromise: void 0
|
|
1105
|
+
updatedAt: Date.now(),
|
|
1106
|
+
...head
|
|
736
1107
|
}));
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1108
|
+
} catch (e) {
|
|
1109
|
+
let error = e;
|
|
1110
|
+
const pendingPromise = this.potentialPendingMinPromise(matchId);
|
|
1111
|
+
if (pendingPromise) await pendingPromise;
|
|
1112
|
+
this.handleRedirectAndNotFound(
|
|
1113
|
+
innerLoadContext,
|
|
1114
|
+
this.getMatch(matchId),
|
|
1115
|
+
e
|
|
1116
|
+
);
|
|
1117
|
+
try {
|
|
1118
|
+
route.options.onError?.(e);
|
|
1119
|
+
} catch (onErrorError) {
|
|
1120
|
+
error = onErrorError;
|
|
1121
|
+
this.handleRedirectAndNotFound(
|
|
1122
|
+
innerLoadContext,
|
|
1123
|
+
this.getMatch(matchId),
|
|
1124
|
+
onErrorError
|
|
1125
|
+
);
|
|
752
1126
|
}
|
|
1127
|
+
const headResult = this.executeHead(innerLoadContext, matchId, route);
|
|
1128
|
+
const head = headResult ? await headResult : void 0;
|
|
1129
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1130
|
+
...prev,
|
|
1131
|
+
error,
|
|
1132
|
+
status: "error",
|
|
1133
|
+
isFetching: false,
|
|
1134
|
+
...head
|
|
1135
|
+
}));
|
|
753
1136
|
}
|
|
754
|
-
}
|
|
755
|
-
const shouldSkipLoader = (matchId) => {
|
|
1137
|
+
} catch (err) {
|
|
756
1138
|
const match = this.getMatch(matchId);
|
|
757
|
-
if (
|
|
758
|
-
|
|
1139
|
+
if (match) {
|
|
1140
|
+
const headResult = this.executeHead(innerLoadContext, matchId, route);
|
|
1141
|
+
if (headResult) {
|
|
1142
|
+
const head = await headResult;
|
|
1143
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1144
|
+
...prev,
|
|
1145
|
+
...head
|
|
1146
|
+
}));
|
|
1147
|
+
}
|
|
1148
|
+
match._nonReactive.loaderPromise = void 0;
|
|
759
1149
|
}
|
|
1150
|
+
this.handleRedirectAndNotFound(innerLoadContext, match, err);
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
this.loadRouteMatch = async (innerLoadContext, index) => {
|
|
1154
|
+
const { id: matchId, routeId } = innerLoadContext.matches[index];
|
|
1155
|
+
let loaderShouldRunAsync = false;
|
|
1156
|
+
let loaderIsRunningAsync = false;
|
|
1157
|
+
const route = this.looseRoutesById[routeId];
|
|
1158
|
+
const prevMatch = this.getMatch(matchId);
|
|
1159
|
+
if (this.shouldSkipLoader(matchId)) {
|
|
760
1160
|
if (this.isServer) {
|
|
761
|
-
|
|
762
|
-
|
|
1161
|
+
const headResult = this.executeHead(innerLoadContext, matchId, route);
|
|
1162
|
+
if (headResult) {
|
|
1163
|
+
const head = await headResult;
|
|
1164
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1165
|
+
...prev,
|
|
1166
|
+
...head
|
|
1167
|
+
}));
|
|
763
1168
|
}
|
|
1169
|
+
return this.getMatch(matchId);
|
|
764
1170
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
1171
|
+
} else if (prevMatch._nonReactive.loaderPromise) {
|
|
1172
|
+
if (prevMatch.status === "success" && !innerLoadContext.sync && !prevMatch.preload) {
|
|
1173
|
+
return this.getMatch(matchId);
|
|
1174
|
+
}
|
|
1175
|
+
await prevMatch._nonReactive.loaderPromise;
|
|
1176
|
+
const match2 = this.getMatch(matchId);
|
|
1177
|
+
if (match2.error) {
|
|
1178
|
+
this.handleRedirectAndNotFound(innerLoadContext, match2, match2.error);
|
|
1179
|
+
}
|
|
1180
|
+
} else {
|
|
1181
|
+
const age = Date.now() - this.getMatch(matchId).updatedAt;
|
|
1182
|
+
const preload = this.resolvePreload(innerLoadContext, matchId);
|
|
1183
|
+
const staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
|
|
1184
|
+
const shouldReloadOption = route.options.shouldReload;
|
|
1185
|
+
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(
|
|
1186
|
+
this.getLoaderContext(innerLoadContext, matchId, index, route)
|
|
1187
|
+
) : shouldReloadOption;
|
|
1188
|
+
const nextPreload = !!preload && !this.state.matches.some((d) => d.id === matchId);
|
|
1189
|
+
const match2 = this.getMatch(matchId);
|
|
1190
|
+
match2._nonReactive.loaderPromise = createControlledPromise();
|
|
1191
|
+
if (nextPreload !== match2.preload) {
|
|
1192
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1193
|
+
...prev,
|
|
1194
|
+
preload: nextPreload
|
|
1195
|
+
}));
|
|
1196
|
+
}
|
|
1197
|
+
const { status, invalid } = this.getMatch(matchId);
|
|
1198
|
+
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
1199
|
+
if (preload && route.options.preload === false) ;
|
|
1200
|
+
else if (loaderShouldRunAsync && !innerLoadContext.sync) {
|
|
1201
|
+
loaderIsRunningAsync = true;
|
|
770
1202
|
(async () => {
|
|
771
1203
|
try {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
778
|
-
err.routerCode = routerCode;
|
|
779
|
-
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
780
|
-
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
781
|
-
try {
|
|
782
|
-
route.options.onError?.(err);
|
|
783
|
-
} catch (errorHandlerErr) {
|
|
784
|
-
err = errorHandlerErr;
|
|
785
|
-
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
786
|
-
}
|
|
787
|
-
updateMatch(matchId, (prev) => {
|
|
788
|
-
prev.beforeLoadPromise?.resolve();
|
|
789
|
-
prev.loadPromise?.resolve();
|
|
790
|
-
return {
|
|
791
|
-
...prev,
|
|
792
|
-
error: err,
|
|
793
|
-
status: "error",
|
|
794
|
-
isFetching: false,
|
|
795
|
-
updatedAt: Date.now(),
|
|
796
|
-
abortController: new AbortController(),
|
|
797
|
-
beforeLoadPromise: void 0
|
|
798
|
-
};
|
|
799
|
-
});
|
|
800
|
-
};
|
|
801
|
-
for (const [index, { id: matchId, routeId }] of matches.entries()) {
|
|
802
|
-
const existingMatch = this.getMatch(matchId);
|
|
803
|
-
const parentMatchId = matches[index - 1]?.id;
|
|
804
|
-
const parentMatch = parentMatchId ? this.getMatch(parentMatchId) : void 0;
|
|
805
|
-
const route = this.looseRoutesById[routeId];
|
|
806
|
-
const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
|
|
807
|
-
if (this.isServer) {
|
|
808
|
-
let ssr;
|
|
809
|
-
if (this.isShell()) {
|
|
810
|
-
ssr = matchId === rootRouteId;
|
|
811
|
-
} else {
|
|
812
|
-
const defaultSsr = this.options.defaultSsr ?? true;
|
|
813
|
-
if (parentMatch?.ssr === false) {
|
|
814
|
-
ssr = false;
|
|
815
|
-
} else {
|
|
816
|
-
let tempSsr;
|
|
817
|
-
if (route.options.ssr === void 0) {
|
|
818
|
-
tempSsr = defaultSsr;
|
|
819
|
-
} else if (typeof route.options.ssr === "function") {
|
|
820
|
-
let makeMaybe = function(value, error) {
|
|
821
|
-
if (error) {
|
|
822
|
-
return { status: "error", error };
|
|
823
|
-
}
|
|
824
|
-
return { status: "success", value };
|
|
825
|
-
};
|
|
826
|
-
const { search, params } = this.getMatch(matchId);
|
|
827
|
-
const ssrFnContext = {
|
|
828
|
-
search: makeMaybe(search, existingMatch.searchError),
|
|
829
|
-
params: makeMaybe(params, existingMatch.paramsError),
|
|
830
|
-
location,
|
|
831
|
-
matches: matches.map((match) => ({
|
|
832
|
-
index: match.index,
|
|
833
|
-
pathname: match.pathname,
|
|
834
|
-
fullPath: match.fullPath,
|
|
835
|
-
staticData: match.staticData,
|
|
836
|
-
id: match.id,
|
|
837
|
-
routeId: match.routeId,
|
|
838
|
-
search: makeMaybe(match.search, match.searchError),
|
|
839
|
-
params: makeMaybe(match.params, match.paramsError),
|
|
840
|
-
ssr: match.ssr
|
|
841
|
-
}))
|
|
842
|
-
};
|
|
843
|
-
tempSsr = await route.options.ssr(ssrFnContext) ?? defaultSsr;
|
|
844
|
-
} else {
|
|
845
|
-
tempSsr = route.options.ssr;
|
|
846
|
-
}
|
|
847
|
-
if (tempSsr === true && parentMatch?.ssr === "data-only") {
|
|
848
|
-
ssr = "data-only";
|
|
849
|
-
} else {
|
|
850
|
-
ssr = tempSsr;
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
updateMatch(matchId, (prev) => ({
|
|
855
|
-
...prev,
|
|
856
|
-
ssr
|
|
857
|
-
}));
|
|
858
|
-
}
|
|
859
|
-
if (shouldSkipLoader(matchId)) {
|
|
860
|
-
continue;
|
|
861
|
-
}
|
|
862
|
-
const shouldPending = !!(onReady && !this.isServer && !resolvePreload(matchId) && (route.options.loader || route.options.beforeLoad || routeNeedsPreload(route)) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options?.defaultPendingComponent));
|
|
863
|
-
let executeBeforeLoad = true;
|
|
864
|
-
const setupPendingTimeout = () => {
|
|
865
|
-
if (shouldPending && this.getMatch(matchId).pendingTimeout === void 0) {
|
|
866
|
-
const pendingTimeout = setTimeout(() => {
|
|
867
|
-
try {
|
|
868
|
-
triggerOnReady();
|
|
869
|
-
} catch {
|
|
870
|
-
}
|
|
871
|
-
}, pendingMs);
|
|
872
|
-
updateMatch(matchId, (prev) => ({
|
|
873
|
-
...prev,
|
|
874
|
-
pendingTimeout
|
|
875
|
-
}));
|
|
876
|
-
}
|
|
877
|
-
};
|
|
878
|
-
if (
|
|
879
|
-
// If we are in the middle of a load, either of these will be present
|
|
880
|
-
// (not to be confused with `loadPromise`, which is always defined)
|
|
881
|
-
existingMatch.beforeLoadPromise || existingMatch.loaderPromise
|
|
882
|
-
) {
|
|
883
|
-
setupPendingTimeout();
|
|
884
|
-
await existingMatch.beforeLoadPromise;
|
|
885
|
-
const match = this.getMatch(matchId);
|
|
886
|
-
if (match.status === "error") {
|
|
887
|
-
executeBeforeLoad = true;
|
|
888
|
-
} else if (match.preload && (match.status === "redirected" || match.status === "notFound")) {
|
|
889
|
-
handleRedirectAndNotFound(match, match.error);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
if (executeBeforeLoad) {
|
|
893
|
-
try {
|
|
894
|
-
updateMatch(matchId, (prev) => {
|
|
895
|
-
const prevLoadPromise = prev.loadPromise;
|
|
896
|
-
return {
|
|
897
|
-
...prev,
|
|
898
|
-
loadPromise: createControlledPromise(() => {
|
|
899
|
-
prevLoadPromise?.resolve();
|
|
900
|
-
}),
|
|
901
|
-
beforeLoadPromise: createControlledPromise()
|
|
902
|
-
};
|
|
903
|
-
});
|
|
904
|
-
const { paramsError, searchError } = this.getMatch(matchId);
|
|
905
|
-
if (paramsError) {
|
|
906
|
-
handleSerialError(index, paramsError, "PARSE_PARAMS");
|
|
907
|
-
}
|
|
908
|
-
if (searchError) {
|
|
909
|
-
handleSerialError(index, searchError, "VALIDATE_SEARCH");
|
|
910
|
-
}
|
|
911
|
-
setupPendingTimeout();
|
|
912
|
-
const abortController = new AbortController();
|
|
913
|
-
const parentMatchContext = parentMatch?.context ?? this.options.context ?? {};
|
|
914
|
-
updateMatch(matchId, (prev) => ({
|
|
915
|
-
...prev,
|
|
916
|
-
isFetching: "beforeLoad",
|
|
917
|
-
fetchCount: prev.fetchCount + 1,
|
|
918
|
-
abortController,
|
|
919
|
-
context: {
|
|
920
|
-
...parentMatchContext,
|
|
921
|
-
...prev.__routeContext
|
|
922
|
-
}
|
|
923
|
-
}));
|
|
924
|
-
const { search, params, context, cause } = this.getMatch(matchId);
|
|
925
|
-
const preload = resolvePreload(matchId);
|
|
926
|
-
const beforeLoadFnContext = {
|
|
927
|
-
search,
|
|
928
|
-
abortController,
|
|
929
|
-
params,
|
|
930
|
-
preload,
|
|
931
|
-
context,
|
|
932
|
-
location,
|
|
933
|
-
navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
|
|
934
|
-
buildLocation: this.buildLocation,
|
|
935
|
-
cause: preload ? "preload" : cause,
|
|
936
|
-
matches
|
|
937
|
-
};
|
|
938
|
-
const beforeLoadContext = await route.options.beforeLoad?.(beforeLoadFnContext);
|
|
939
|
-
if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
|
|
940
|
-
handleSerialError(index, beforeLoadContext, "BEFORE_LOAD");
|
|
941
|
-
}
|
|
942
|
-
updateMatch(matchId, (prev) => {
|
|
943
|
-
return {
|
|
944
|
-
...prev,
|
|
945
|
-
__beforeLoadContext: beforeLoadContext,
|
|
946
|
-
context: {
|
|
947
|
-
...parentMatchContext,
|
|
948
|
-
...prev.__routeContext,
|
|
949
|
-
...beforeLoadContext
|
|
950
|
-
},
|
|
951
|
-
abortController
|
|
952
|
-
};
|
|
953
|
-
});
|
|
954
|
-
} catch (err) {
|
|
955
|
-
handleSerialError(index, err, "BEFORE_LOAD");
|
|
956
|
-
}
|
|
957
|
-
updateMatch(matchId, (prev) => {
|
|
958
|
-
prev.beforeLoadPromise?.resolve();
|
|
959
|
-
return {
|
|
960
|
-
...prev,
|
|
961
|
-
beforeLoadPromise: void 0,
|
|
962
|
-
isFetching: false
|
|
963
|
-
};
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
968
|
-
const matchPromises = [];
|
|
969
|
-
validResolvedMatches.forEach(({ id: matchId, routeId }, index) => {
|
|
970
|
-
matchPromises.push(
|
|
971
|
-
(async () => {
|
|
972
|
-
let loaderShouldRunAsync = false;
|
|
973
|
-
let loaderIsRunningAsync = false;
|
|
974
|
-
const route = this.looseRoutesById[routeId];
|
|
975
|
-
const executeHead = async () => {
|
|
976
|
-
const match = this.getMatch(matchId);
|
|
977
|
-
if (!match) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
const assetContext = {
|
|
981
|
-
matches,
|
|
982
|
-
match,
|
|
983
|
-
params: match.params,
|
|
984
|
-
loaderData: match.loaderData
|
|
985
|
-
};
|
|
986
|
-
const headFnContent = await route.options.head?.(assetContext);
|
|
987
|
-
const meta = headFnContent?.meta;
|
|
988
|
-
const links = headFnContent?.links;
|
|
989
|
-
const headScripts = headFnContent?.scripts;
|
|
990
|
-
const styles = headFnContent?.styles;
|
|
991
|
-
const scripts = await route.options.scripts?.(assetContext);
|
|
992
|
-
const headers = await route.options.headers?.(assetContext);
|
|
993
|
-
return {
|
|
994
|
-
meta,
|
|
995
|
-
links,
|
|
996
|
-
headScripts,
|
|
997
|
-
headers,
|
|
998
|
-
scripts,
|
|
999
|
-
styles
|
|
1000
|
-
};
|
|
1001
|
-
};
|
|
1002
|
-
const potentialPendingMinPromise = async () => {
|
|
1003
|
-
const latestMatch = this.getMatch(matchId);
|
|
1004
|
-
if (latestMatch.minPendingPromise) {
|
|
1005
|
-
await latestMatch.minPendingPromise;
|
|
1006
|
-
}
|
|
1007
|
-
};
|
|
1008
|
-
const prevMatch = this.getMatch(matchId);
|
|
1009
|
-
if (shouldSkipLoader(matchId)) {
|
|
1010
|
-
if (this.isServer) {
|
|
1011
|
-
const head = await executeHead();
|
|
1012
|
-
updateMatch(matchId, (prev) => ({
|
|
1013
|
-
...prev,
|
|
1014
|
-
...head
|
|
1015
|
-
}));
|
|
1016
|
-
return this.getMatch(matchId);
|
|
1017
|
-
}
|
|
1018
|
-
} else if (prevMatch.loaderPromise) {
|
|
1019
|
-
if (prevMatch.status === "success" && !sync && !prevMatch.preload) {
|
|
1020
|
-
return this.getMatch(matchId);
|
|
1021
|
-
}
|
|
1022
|
-
await prevMatch.loaderPromise;
|
|
1023
|
-
const match = this.getMatch(matchId);
|
|
1024
|
-
if (match.error) {
|
|
1025
|
-
handleRedirectAndNotFound(match, match.error);
|
|
1026
|
-
}
|
|
1027
|
-
} else {
|
|
1028
|
-
const parentMatchPromise = matchPromises[index - 1];
|
|
1029
|
-
const getLoaderContext = () => {
|
|
1030
|
-
const {
|
|
1031
|
-
params,
|
|
1032
|
-
loaderDeps,
|
|
1033
|
-
abortController,
|
|
1034
|
-
context,
|
|
1035
|
-
cause
|
|
1036
|
-
} = this.getMatch(matchId);
|
|
1037
|
-
const preload2 = resolvePreload(matchId);
|
|
1038
|
-
return {
|
|
1039
|
-
params,
|
|
1040
|
-
deps: loaderDeps,
|
|
1041
|
-
preload: !!preload2,
|
|
1042
|
-
parentMatchPromise,
|
|
1043
|
-
abortController,
|
|
1044
|
-
context,
|
|
1045
|
-
location,
|
|
1046
|
-
navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
|
|
1047
|
-
cause: preload2 ? "preload" : cause,
|
|
1048
|
-
route
|
|
1049
|
-
};
|
|
1050
|
-
};
|
|
1051
|
-
const age = Date.now() - this.getMatch(matchId).updatedAt;
|
|
1052
|
-
const preload = resolvePreload(matchId);
|
|
1053
|
-
const staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
|
|
1054
|
-
const shouldReloadOption = route.options.shouldReload;
|
|
1055
|
-
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext()) : shouldReloadOption;
|
|
1056
|
-
updateMatch(matchId, (prev) => ({
|
|
1057
|
-
...prev,
|
|
1058
|
-
loaderPromise: createControlledPromise(),
|
|
1059
|
-
preload: !!preload && !this.state.matches.some((d) => d.id === matchId)
|
|
1060
|
-
}));
|
|
1061
|
-
const runLoader = async () => {
|
|
1062
|
-
try {
|
|
1063
|
-
try {
|
|
1064
|
-
if (!this.isServer || this.isServer && this.getMatch(matchId).ssr === true) {
|
|
1065
|
-
this.loadRouteChunk(route);
|
|
1066
|
-
}
|
|
1067
|
-
updateMatch(matchId, (prev) => ({
|
|
1068
|
-
...prev,
|
|
1069
|
-
isFetching: "loader"
|
|
1070
|
-
}));
|
|
1071
|
-
const loaderData = await route.options.loader?.(getLoaderContext());
|
|
1072
|
-
handleRedirectAndNotFound(
|
|
1073
|
-
this.getMatch(matchId),
|
|
1074
|
-
loaderData
|
|
1075
|
-
);
|
|
1076
|
-
updateMatch(matchId, (prev) => ({
|
|
1077
|
-
...prev,
|
|
1078
|
-
loaderData
|
|
1079
|
-
}));
|
|
1080
|
-
await route._lazyPromise;
|
|
1081
|
-
const head = await executeHead();
|
|
1082
|
-
await potentialPendingMinPromise();
|
|
1083
|
-
await route._componentsPromise;
|
|
1084
|
-
updateMatch(matchId, (prev) => ({
|
|
1085
|
-
...prev,
|
|
1086
|
-
error: void 0,
|
|
1087
|
-
status: "success",
|
|
1088
|
-
isFetching: false,
|
|
1089
|
-
updatedAt: Date.now(),
|
|
1090
|
-
...head
|
|
1091
|
-
}));
|
|
1092
|
-
} catch (e) {
|
|
1093
|
-
let error = e;
|
|
1094
|
-
await potentialPendingMinPromise();
|
|
1095
|
-
handleRedirectAndNotFound(this.getMatch(matchId), e);
|
|
1096
|
-
try {
|
|
1097
|
-
route.options.onError?.(e);
|
|
1098
|
-
} catch (onErrorError) {
|
|
1099
|
-
error = onErrorError;
|
|
1100
|
-
handleRedirectAndNotFound(
|
|
1101
|
-
this.getMatch(matchId),
|
|
1102
|
-
onErrorError
|
|
1103
|
-
);
|
|
1104
|
-
}
|
|
1105
|
-
const head = await executeHead();
|
|
1106
|
-
updateMatch(matchId, (prev) => ({
|
|
1107
|
-
...prev,
|
|
1108
|
-
error,
|
|
1109
|
-
status: "error",
|
|
1110
|
-
isFetching: false,
|
|
1111
|
-
...head
|
|
1112
|
-
}));
|
|
1113
|
-
}
|
|
1114
|
-
} catch (err) {
|
|
1115
|
-
const head = await executeHead();
|
|
1116
|
-
updateMatch(matchId, (prev) => ({
|
|
1117
|
-
...prev,
|
|
1118
|
-
loaderPromise: void 0,
|
|
1119
|
-
...head
|
|
1120
|
-
}));
|
|
1121
|
-
handleRedirectAndNotFound(this.getMatch(matchId), err);
|
|
1122
|
-
}
|
|
1123
|
-
};
|
|
1124
|
-
const { status, invalid } = this.getMatch(matchId);
|
|
1125
|
-
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
1126
|
-
if (preload && route.options.preload === false) {
|
|
1127
|
-
} else if (loaderShouldRunAsync && !sync) {
|
|
1128
|
-
loaderIsRunningAsync = true;
|
|
1129
|
-
(async () => {
|
|
1130
|
-
try {
|
|
1131
|
-
await runLoader();
|
|
1132
|
-
const { loaderPromise, loadPromise } = this.getMatch(matchId);
|
|
1133
|
-
loaderPromise?.resolve();
|
|
1134
|
-
loadPromise?.resolve();
|
|
1135
|
-
updateMatch(matchId, (prev) => ({
|
|
1136
|
-
...prev,
|
|
1137
|
-
loaderPromise: void 0
|
|
1138
|
-
}));
|
|
1139
|
-
} catch (err) {
|
|
1140
|
-
if (isRedirect(err)) {
|
|
1141
|
-
await this.navigate(err.options);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
})();
|
|
1145
|
-
} else if (status !== "success" || loaderShouldRunAsync && sync) {
|
|
1146
|
-
await runLoader();
|
|
1147
|
-
} else {
|
|
1148
|
-
const head = await executeHead();
|
|
1149
|
-
updateMatch(matchId, (prev) => ({
|
|
1150
|
-
...prev,
|
|
1151
|
-
...head
|
|
1152
|
-
}));
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
if (!loaderIsRunningAsync) {
|
|
1156
|
-
const { loaderPromise, loadPromise } = this.getMatch(matchId);
|
|
1157
|
-
loaderPromise?.resolve();
|
|
1158
|
-
loadPromise?.resolve();
|
|
1159
|
-
}
|
|
1160
|
-
updateMatch(matchId, (prev) => {
|
|
1161
|
-
clearTimeout(prev.pendingTimeout);
|
|
1162
|
-
return {
|
|
1163
|
-
...prev,
|
|
1164
|
-
isFetching: loaderIsRunningAsync ? prev.isFetching : false,
|
|
1165
|
-
loaderPromise: loaderIsRunningAsync ? prev.loaderPromise : void 0,
|
|
1166
|
-
invalid: false,
|
|
1167
|
-
pendingTimeout: void 0,
|
|
1168
|
-
_dehydrated: void 0
|
|
1169
|
-
};
|
|
1170
|
-
});
|
|
1171
|
-
return this.getMatch(matchId);
|
|
1172
|
-
})()
|
|
1173
|
-
);
|
|
1174
|
-
});
|
|
1175
|
-
await Promise.all(matchPromises);
|
|
1176
|
-
resolveAll();
|
|
1204
|
+
await this.runLoader(innerLoadContext, matchId, index, route);
|
|
1205
|
+
const match3 = this.getMatch(matchId);
|
|
1206
|
+
match3._nonReactive.loaderPromise?.resolve();
|
|
1207
|
+
match3._nonReactive.loadPromise?.resolve();
|
|
1208
|
+
match3._nonReactive.loaderPromise = void 0;
|
|
1177
1209
|
} catch (err) {
|
|
1178
|
-
|
|
1210
|
+
if (isRedirect(err)) {
|
|
1211
|
+
await this.navigate(err.options);
|
|
1212
|
+
}
|
|
1179
1213
|
}
|
|
1180
1214
|
})();
|
|
1181
|
-
})
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
if (
|
|
1186
|
-
await
|
|
1215
|
+
} else if (status !== "success" || loaderShouldRunAsync && innerLoadContext.sync) {
|
|
1216
|
+
await this.runLoader(innerLoadContext, matchId, index, route);
|
|
1217
|
+
} else {
|
|
1218
|
+
const headResult = this.executeHead(innerLoadContext, matchId, route);
|
|
1219
|
+
if (headResult) {
|
|
1220
|
+
const head = await headResult;
|
|
1221
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1222
|
+
...prev,
|
|
1223
|
+
...head
|
|
1224
|
+
}));
|
|
1187
1225
|
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
const match = this.getMatch(matchId);
|
|
1229
|
+
if (!loaderIsRunningAsync) {
|
|
1230
|
+
match._nonReactive.loaderPromise?.resolve();
|
|
1231
|
+
match._nonReactive.loadPromise?.resolve();
|
|
1232
|
+
}
|
|
1233
|
+
clearTimeout(match._nonReactive.pendingTimeout);
|
|
1234
|
+
match._nonReactive.pendingTimeout = void 0;
|
|
1235
|
+
if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = void 0;
|
|
1236
|
+
match._nonReactive.dehydrated = void 0;
|
|
1237
|
+
const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false;
|
|
1238
|
+
if (nextIsFetching !== match.isFetching || match.invalid !== false) {
|
|
1239
|
+
innerLoadContext.updateMatch(matchId, (prev) => ({
|
|
1240
|
+
...prev,
|
|
1241
|
+
isFetching: nextIsFetching,
|
|
1242
|
+
invalid: false
|
|
1243
|
+
}));
|
|
1244
|
+
}
|
|
1245
|
+
return this.getMatch(matchId);
|
|
1246
|
+
};
|
|
1247
|
+
this.loadMatches = async (baseContext) => {
|
|
1248
|
+
const innerLoadContext = baseContext;
|
|
1249
|
+
innerLoadContext.updateMatch ??= this.updateMatch;
|
|
1250
|
+
innerLoadContext.matchPromises = [];
|
|
1251
|
+
if (!this.isServer && this.state.matches.some((d) => d._forcePending)) {
|
|
1252
|
+
this.triggerOnReady(innerLoadContext);
|
|
1253
|
+
}
|
|
1254
|
+
try {
|
|
1255
|
+
for (let i = 0; i < innerLoadContext.matches.length; i++) {
|
|
1256
|
+
const beforeLoad = this.handleBeforeLoad(innerLoadContext, i);
|
|
1257
|
+
if (isPromise(beforeLoad)) await beforeLoad;
|
|
1258
|
+
}
|
|
1259
|
+
const max = innerLoadContext.firstBadMatchIndex ?? innerLoadContext.matches.length;
|
|
1260
|
+
for (let i = 0; i < max; i++) {
|
|
1261
|
+
innerLoadContext.matchPromises.push(
|
|
1262
|
+
this.loadRouteMatch(innerLoadContext, i)
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
await Promise.all(innerLoadContext.matchPromises);
|
|
1266
|
+
const readyPromise = this.triggerOnReady(innerLoadContext);
|
|
1267
|
+
if (isPromise(readyPromise)) await readyPromise;
|
|
1268
|
+
} catch (err) {
|
|
1269
|
+
if (isNotFound(err) && !innerLoadContext.preload) {
|
|
1270
|
+
const readyPromise = this.triggerOnReady(innerLoadContext);
|
|
1271
|
+
if (isPromise(readyPromise)) await readyPromise;
|
|
1272
|
+
throw err;
|
|
1273
|
+
}
|
|
1274
|
+
if (isRedirect(err)) {
|
|
1188
1275
|
throw err;
|
|
1189
1276
|
}
|
|
1190
1277
|
}
|
|
1191
|
-
return matches;
|
|
1278
|
+
return innerLoadContext.matches;
|
|
1192
1279
|
};
|
|
1193
1280
|
this.invalidate = (opts) => {
|
|
1194
1281
|
const invalidate = (d) => {
|
|
@@ -1196,7 +1283,7 @@ class RouterCore {
|
|
|
1196
1283
|
return {
|
|
1197
1284
|
...d,
|
|
1198
1285
|
invalid: true,
|
|
1199
|
-
...opts?.forcePending || d.status === "error" ? { status: "pending", error: void 0 } :
|
|
1286
|
+
...opts?.forcePending || d.status === "error" ? { status: "pending", error: void 0 } : void 0
|
|
1200
1287
|
};
|
|
1201
1288
|
}
|
|
1202
1289
|
return d;
|
|
@@ -1255,27 +1342,35 @@ class RouterCore {
|
|
|
1255
1342
|
this.clearCache({ filter });
|
|
1256
1343
|
};
|
|
1257
1344
|
this.loadRouteChunk = (route) => {
|
|
1258
|
-
if (route._lazyPromise === void 0) {
|
|
1345
|
+
if (!route._lazyLoaded && route._lazyPromise === void 0) {
|
|
1259
1346
|
if (route.lazyFn) {
|
|
1260
1347
|
route._lazyPromise = route.lazyFn().then((lazyRoute) => {
|
|
1261
1348
|
const { id: _id, ...options2 } = lazyRoute.options;
|
|
1262
1349
|
Object.assign(route.options, options2);
|
|
1350
|
+
route._lazyLoaded = true;
|
|
1351
|
+
route._lazyPromise = void 0;
|
|
1263
1352
|
});
|
|
1264
1353
|
} else {
|
|
1265
|
-
route.
|
|
1354
|
+
route._lazyLoaded = true;
|
|
1266
1355
|
}
|
|
1267
1356
|
}
|
|
1268
|
-
if (route._componentsPromise === void 0) {
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1357
|
+
if (!route._componentsLoaded && route._componentsPromise === void 0) {
|
|
1358
|
+
const loadComponents = () => {
|
|
1359
|
+
const preloads = [];
|
|
1360
|
+
for (const type of componentTypes) {
|
|
1361
|
+
const preload = route.options[type]?.preload;
|
|
1362
|
+
if (preload) preloads.push(preload());
|
|
1363
|
+
}
|
|
1364
|
+
if (preloads.length)
|
|
1365
|
+
return Promise.all(preloads).then(() => {
|
|
1366
|
+
route._componentsLoaded = true;
|
|
1367
|
+
route._componentsPromise = void 0;
|
|
1368
|
+
});
|
|
1369
|
+
route._componentsLoaded = true;
|
|
1370
|
+
route._componentsPromise = void 0;
|
|
1371
|
+
return;
|
|
1372
|
+
};
|
|
1373
|
+
route._componentsPromise = route._lazyPromise ? route._lazyPromise.then(loadComponents) : loadComponents();
|
|
1279
1374
|
}
|
|
1280
1375
|
return route._componentsPromise;
|
|
1281
1376
|
};
|
|
@@ -1373,12 +1468,10 @@ class RouterCore {
|
|
|
1373
1468
|
}
|
|
1374
1469
|
return match;
|
|
1375
1470
|
};
|
|
1376
|
-
this._handleNotFound = (
|
|
1377
|
-
updateMatch = this.updateMatch
|
|
1378
|
-
} = {}) => {
|
|
1471
|
+
this._handleNotFound = (innerLoadContext, err) => {
|
|
1379
1472
|
const routeCursor = this.routesById[err.routeId ?? ""] ?? this.routeTree;
|
|
1380
1473
|
const matchesByRouteId = {};
|
|
1381
|
-
for (const match of matches) {
|
|
1474
|
+
for (const match of innerLoadContext.matches) {
|
|
1382
1475
|
matchesByRouteId[match.routeId] = match;
|
|
1383
1476
|
}
|
|
1384
1477
|
if (!routeCursor.options.notFoundComponent && this.options?.defaultNotFoundComponent) {
|
|
@@ -1393,7 +1486,7 @@ class RouterCore {
|
|
|
1393
1486
|
matchForRoute,
|
|
1394
1487
|
"Could not find match for route: " + routeCursor.id
|
|
1395
1488
|
);
|
|
1396
|
-
updateMatch(matchForRoute.id, (prev) => ({
|
|
1489
|
+
innerLoadContext.updateMatch(matchForRoute.id, (prev) => ({
|
|
1397
1490
|
...prev,
|
|
1398
1491
|
status: "notFound",
|
|
1399
1492
|
error: err,
|
|
@@ -1401,9 +1494,7 @@ class RouterCore {
|
|
|
1401
1494
|
}));
|
|
1402
1495
|
if (err.routerCode === "BEFORE_LOAD" && routeCursor.parentRoute) {
|
|
1403
1496
|
err.routeId = routeCursor.parentRoute.id;
|
|
1404
|
-
this._handleNotFound(
|
|
1405
|
-
updateMatch
|
|
1406
|
-
});
|
|
1497
|
+
this._handleNotFound(innerLoadContext, err);
|
|
1407
1498
|
}
|
|
1408
1499
|
};
|
|
1409
1500
|
this.hasNotFoundMatch = () => {
|
|
@@ -1493,16 +1584,16 @@ class RouterCore {
|
|
|
1493
1584
|
const matches = [];
|
|
1494
1585
|
const getParentContext = (parentMatch) => {
|
|
1495
1586
|
const parentMatchId = parentMatch?.id;
|
|
1496
|
-
const parentContext = !parentMatchId ? this.options.context ??
|
|
1587
|
+
const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
|
|
1497
1588
|
return parentContext;
|
|
1498
1589
|
};
|
|
1499
1590
|
matchedRoutes.forEach((route, index) => {
|
|
1500
1591
|
const parentMatch = matches[index - 1];
|
|
1501
1592
|
const [preMatchSearch, strictMatchSearch, searchError] = (() => {
|
|
1502
1593
|
const parentSearch = parentMatch?.search ?? next.search;
|
|
1503
|
-
const parentStrictSearch = parentMatch?._strictSearch ??
|
|
1594
|
+
const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
|
|
1504
1595
|
try {
|
|
1505
|
-
const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ??
|
|
1596
|
+
const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? void 0;
|
|
1506
1597
|
return [
|
|
1507
1598
|
{
|
|
1508
1599
|
...parentSearch,
|
|
@@ -1572,7 +1663,10 @@ class RouterCore {
|
|
|
1572
1663
|
isFetching: false,
|
|
1573
1664
|
error: void 0,
|
|
1574
1665
|
paramsError: parseErrors[index],
|
|
1575
|
-
__routeContext:
|
|
1666
|
+
__routeContext: void 0,
|
|
1667
|
+
_nonReactive: {
|
|
1668
|
+
loadPromise: createControlledPromise()
|
|
1669
|
+
},
|
|
1576
1670
|
__beforeLoadContext: void 0,
|
|
1577
1671
|
context: {},
|
|
1578
1672
|
abortController: new AbortController(),
|
|
@@ -1586,7 +1680,6 @@ class RouterCore {
|
|
|
1586
1680
|
headScripts: void 0,
|
|
1587
1681
|
meta: void 0,
|
|
1588
1682
|
staticData: route.options.staticData || {},
|
|
1589
|
-
loadPromise: createControlledPromise(),
|
|
1590
1683
|
fullPath: route.fullPath
|
|
1591
1684
|
};
|
|
1592
1685
|
}
|
|
@@ -1608,19 +1701,21 @@ class RouterCore {
|
|
|
1608
1701
|
if (!existingMatch && opts?._buildLocation !== true) {
|
|
1609
1702
|
const parentMatch = matches[index - 1];
|
|
1610
1703
|
const parentContext = getParentContext(parentMatch);
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1704
|
+
if (route.options.context) {
|
|
1705
|
+
const contextFnContext = {
|
|
1706
|
+
deps: match.loaderDeps,
|
|
1707
|
+
params: match.params,
|
|
1708
|
+
context: parentContext ?? {},
|
|
1709
|
+
location: next,
|
|
1710
|
+
navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
|
|
1711
|
+
buildLocation: this.buildLocation,
|
|
1712
|
+
cause: match.cause,
|
|
1713
|
+
abortController: match.abortController,
|
|
1714
|
+
preload: !!match.preload,
|
|
1715
|
+
matches
|
|
1716
|
+
};
|
|
1717
|
+
match.__routeContext = route.options.context(contextFnContext) ?? void 0;
|
|
1718
|
+
}
|
|
1624
1719
|
match.context = {
|
|
1625
1720
|
...parentContext,
|
|
1626
1721
|
...match.__routeContext,
|
|
@@ -1635,6 +1730,12 @@ class SearchParamError extends Error {
|
|
|
1635
1730
|
}
|
|
1636
1731
|
class PathParamError extends Error {
|
|
1637
1732
|
}
|
|
1733
|
+
function makeMaybe(value, error) {
|
|
1734
|
+
if (error) {
|
|
1735
|
+
return { status: "error", error };
|
|
1736
|
+
}
|
|
1737
|
+
return { status: "success", value };
|
|
1738
|
+
}
|
|
1638
1739
|
const normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
|
|
1639
1740
|
function comparePaths(a, b) {
|
|
1640
1741
|
return normalize(a) === normalize(b);
|
|
@@ -1923,7 +2024,7 @@ function applySearchMiddleware({
|
|
|
1923
2024
|
try {
|
|
1924
2025
|
const validatedSearch = {
|
|
1925
2026
|
...result,
|
|
1926
|
-
...validateSearch(route.options.validateSearch, result) ??
|
|
2027
|
+
...validateSearch(route.options.validateSearch, result) ?? void 0
|
|
1927
2028
|
};
|
|
1928
2029
|
return validatedSearch;
|
|
1929
2030
|
} catch {
|