@tanstack/react-router 0.0.1-beta.219 → 0.0.1-beta.220
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/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +51 -17
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/awaited.js +45 -0
- package/build/cjs/awaited.js.map +1 -0
- package/build/cjs/defer.js +39 -0
- package/build/cjs/defer.js.map +1 -0
- package/build/cjs/index.js +7 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/router.js +0 -43
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/utils.js +6 -0
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +602 -559
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +392 -329
- package/build/types/RouterProvider.d.ts +5 -0
- package/build/types/awaited.d.ts +8 -0
- package/build/types/defer.d.ts +19 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/utils.d.ts +1 -0
- package/build/umd/index.development.js +606 -558
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/Matches.tsx +1 -1
- package/src/RouterProvider.tsx +85 -24
- package/src/awaited.tsx +40 -40
- package/src/defer.ts +48 -48
- package/src/index.tsx +2 -2
- package/src/router.ts +0 -50
- package/src/utils.ts +7 -0
|
@@ -609,6 +609,11 @@
|
|
|
609
609
|
});
|
|
610
610
|
}
|
|
611
611
|
const useLayoutEffect$1 = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
612
|
+
function escapeJSON(jsonString) {
|
|
613
|
+
return jsonString.replace(/\\/g, '\\\\') // Escape backslashes
|
|
614
|
+
.replace(/'/g, "\\'") // Escape single quotes
|
|
615
|
+
.replace(/"/g, '\\"'); // Escape double quotes
|
|
616
|
+
}
|
|
612
617
|
|
|
613
618
|
function joinPaths(paths) {
|
|
614
619
|
return cleanPath(paths.filter(Boolean).join('/'));
|
|
@@ -794,173 +799,480 @@
|
|
|
794
799
|
return isMatch ? params : undefined;
|
|
795
800
|
}
|
|
796
801
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
+
function useParams(opts) {
|
|
803
|
+
return useRouterState({
|
|
804
|
+
select: state => {
|
|
805
|
+
const params = last(state.matches)?.params;
|
|
806
|
+
return opts?.select ? opts.select(params) : params;
|
|
807
|
+
}
|
|
808
|
+
});
|
|
802
809
|
}
|
|
803
|
-
|
|
804
|
-
|
|
810
|
+
|
|
811
|
+
function useSearch(opts) {
|
|
812
|
+
return useMatch({
|
|
813
|
+
...opts,
|
|
814
|
+
select: match => {
|
|
815
|
+
return opts?.select ? opts.select(match.search) : match.search;
|
|
816
|
+
}
|
|
817
|
+
});
|
|
805
818
|
}
|
|
806
819
|
|
|
807
|
-
|
|
820
|
+
const rootRouteId = '__root__';
|
|
808
821
|
|
|
809
|
-
//
|
|
822
|
+
// The parse type here allows a zod schema to be passed directly to the validator
|
|
810
823
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
}
|
|
823
|
-
} else {
|
|
824
|
-
str && (str += '&');
|
|
825
|
-
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
826
|
-
}
|
|
827
|
-
}
|
|
824
|
+
class Route {
|
|
825
|
+
// Set up in this.init()
|
|
826
|
+
|
|
827
|
+
// customId!: TCustomId
|
|
828
|
+
|
|
829
|
+
// Optional
|
|
830
|
+
|
|
831
|
+
constructor(options) {
|
|
832
|
+
this.options = options || {};
|
|
833
|
+
this.isRoot = !options?.getParentRoute;
|
|
834
|
+
Route.__onInit(this);
|
|
828
835
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
return +str * 0 === 0 && +str + '' === str ? +str : str;
|
|
837
|
-
}
|
|
838
|
-
function decode(str) {
|
|
839
|
-
var tmp,
|
|
840
|
-
k,
|
|
841
|
-
out = {},
|
|
842
|
-
arr = str.split('&');
|
|
843
|
-
while (tmp = arr.shift()) {
|
|
844
|
-
tmp = tmp.split('=');
|
|
845
|
-
k = tmp.shift();
|
|
846
|
-
if (out[k] !== void 0) {
|
|
847
|
-
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
836
|
+
init = opts => {
|
|
837
|
+
this.originalIndex = opts.originalIndex;
|
|
838
|
+
const options = this.options;
|
|
839
|
+
const isRoot = !options?.path && !options?.id;
|
|
840
|
+
this.parentRoute = this.options?.getParentRoute?.();
|
|
841
|
+
if (isRoot) {
|
|
842
|
+
this.path = rootRouteId;
|
|
848
843
|
} else {
|
|
849
|
-
|
|
844
|
+
invariant(this.parentRoute, `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`);
|
|
850
845
|
}
|
|
851
|
-
|
|
852
|
-
return out;
|
|
853
|
-
}
|
|
846
|
+
let path = isRoot ? rootRouteId : options.path;
|
|
854
847
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
return searchStr => {
|
|
859
|
-
if (searchStr.substring(0, 1) === '?') {
|
|
860
|
-
searchStr = searchStr.substring(1);
|
|
848
|
+
// If the path is anything other than an index path, trim it up
|
|
849
|
+
if (path && path !== '/') {
|
|
850
|
+
path = trimPath(path);
|
|
861
851
|
}
|
|
862
|
-
|
|
852
|
+
const customId = options?.id || path;
|
|
863
853
|
|
|
864
|
-
//
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
try {
|
|
869
|
-
query[key] = parser(value);
|
|
870
|
-
} catch (err) {
|
|
871
|
-
//
|
|
872
|
-
}
|
|
873
|
-
}
|
|
854
|
+
// Strip the parentId prefix from the first level of children
|
|
855
|
+
let id = isRoot ? rootRouteId : joinPaths([this.parentRoute.id === rootRouteId ? '' : this.parentRoute.id, customId]);
|
|
856
|
+
if (path === rootRouteId) {
|
|
857
|
+
path = '/';
|
|
874
858
|
}
|
|
875
|
-
|
|
859
|
+
if (id !== rootRouteId) {
|
|
860
|
+
id = joinPaths(['/', id]);
|
|
861
|
+
}
|
|
862
|
+
const fullPath = id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path]);
|
|
863
|
+
this.path = path;
|
|
864
|
+
this.id = id;
|
|
865
|
+
// this.customId = customId as TCustomId
|
|
866
|
+
this.fullPath = fullPath;
|
|
867
|
+
this.to = fullPath;
|
|
868
|
+
};
|
|
869
|
+
addChildren = children => {
|
|
870
|
+
this.children = children;
|
|
871
|
+
return this;
|
|
872
|
+
};
|
|
873
|
+
update = options => {
|
|
874
|
+
Object.assign(this.options, options);
|
|
875
|
+
return this;
|
|
876
|
+
};
|
|
877
|
+
static __onInit = route => {
|
|
878
|
+
// This is a dummy static method that should get
|
|
879
|
+
// replaced by a framework specific implementation if necessary
|
|
880
|
+
};
|
|
881
|
+
useMatch = opts => {
|
|
882
|
+
return useMatch({
|
|
883
|
+
...opts,
|
|
884
|
+
from: this.id
|
|
885
|
+
});
|
|
886
|
+
};
|
|
887
|
+
useRouteContext = opts => {
|
|
888
|
+
return useMatch({
|
|
889
|
+
...opts,
|
|
890
|
+
from: this.id,
|
|
891
|
+
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
892
|
+
});
|
|
893
|
+
};
|
|
894
|
+
useSearch = opts => {
|
|
895
|
+
return useSearch({
|
|
896
|
+
...opts,
|
|
897
|
+
from: this.id
|
|
898
|
+
});
|
|
899
|
+
};
|
|
900
|
+
useParams = opts => {
|
|
901
|
+
return useParams({
|
|
902
|
+
...opts,
|
|
903
|
+
from: this.id
|
|
904
|
+
});
|
|
905
|
+
};
|
|
906
|
+
useLoaderData = opts => {
|
|
907
|
+
return useLoaderData({
|
|
908
|
+
...opts,
|
|
909
|
+
from: this.id
|
|
910
|
+
});
|
|
876
911
|
};
|
|
877
912
|
}
|
|
878
|
-
function
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
try {
|
|
882
|
-
return stringify(val);
|
|
883
|
-
} catch (err) {
|
|
884
|
-
// silent
|
|
885
|
-
}
|
|
886
|
-
} else if (typeof val === 'string' && typeof parser === 'function') {
|
|
887
|
-
try {
|
|
888
|
-
// Check if it's a valid parseable string.
|
|
889
|
-
// If it is, then stringify it again.
|
|
890
|
-
parser(val);
|
|
891
|
-
return stringify(val);
|
|
892
|
-
} catch (err) {
|
|
893
|
-
// silent
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
return val;
|
|
897
|
-
}
|
|
898
|
-
return search => {
|
|
899
|
-
search = {
|
|
900
|
-
...search
|
|
901
|
-
};
|
|
902
|
-
if (search) {
|
|
903
|
-
Object.keys(search).forEach(key => {
|
|
904
|
-
const val = search[key];
|
|
905
|
-
if (typeof val === 'undefined' || val === undefined) {
|
|
906
|
-
delete search[key];
|
|
907
|
-
} else {
|
|
908
|
-
search[key] = stringifyValue(val);
|
|
909
|
-
}
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
const searchStr = encode(search).toString();
|
|
913
|
-
return searchStr ? `?${searchStr}` : '';
|
|
913
|
+
function rootRouteWithContext() {
|
|
914
|
+
return options => {
|
|
915
|
+
return new RootRoute(options);
|
|
914
916
|
};
|
|
915
917
|
}
|
|
916
|
-
|
|
917
|
-
//
|
|
918
|
-
|
|
919
|
-
//
|
|
920
|
-
|
|
921
|
-
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
922
|
-
class Router {
|
|
923
|
-
// dehydratedData?: TDehydrated
|
|
924
|
-
// resetNextScroll = false
|
|
925
|
-
// tempLocationKey = `${Math.round(Math.random() * 10000000)}`
|
|
918
|
+
class RootRoute extends Route {
|
|
926
919
|
constructor(options) {
|
|
927
|
-
|
|
928
|
-
defaultPreloadDelay: 50,
|
|
929
|
-
context: undefined,
|
|
930
|
-
...options,
|
|
931
|
-
stringifySearch: options?.stringifySearch ?? defaultStringifySearch,
|
|
932
|
-
parseSearch: options?.parseSearch ?? defaultParseSearch
|
|
933
|
-
};
|
|
934
|
-
this.routeTree = this.options.routeTree;
|
|
920
|
+
super(options);
|
|
935
921
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
fn
|
|
941
|
-
};
|
|
942
|
-
this.subscribers.add(listener);
|
|
943
|
-
return () => {
|
|
944
|
-
this.subscribers.delete(listener);
|
|
945
|
-
};
|
|
946
|
-
};
|
|
947
|
-
emit = routerEvent => {
|
|
948
|
-
this.subscribers.forEach(listener => {
|
|
949
|
-
if (listener.eventType === routerEvent.type) {
|
|
950
|
-
listener.fn(routerEvent);
|
|
951
|
-
}
|
|
952
|
-
});
|
|
953
|
-
};
|
|
922
|
+
}
|
|
923
|
+
function createRouteMask(opts) {
|
|
924
|
+
return opts;
|
|
925
|
+
}
|
|
954
926
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
927
|
+
//
|
|
928
|
+
|
|
929
|
+
function Matches() {
|
|
930
|
+
const {
|
|
931
|
+
routesById,
|
|
932
|
+
state
|
|
933
|
+
} = useRouter();
|
|
934
|
+
const {
|
|
935
|
+
matches
|
|
936
|
+
} = state;
|
|
937
|
+
const locationKey = useRouterState().location.state.key;
|
|
938
|
+
const route = routesById[rootRouteId];
|
|
939
|
+
const errorComponent = React__namespace.useCallback(props => {
|
|
940
|
+
return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
|
|
941
|
+
...props,
|
|
942
|
+
useMatch: route.useMatch,
|
|
943
|
+
useRouteContext: route.useRouteContext,
|
|
944
|
+
useSearch: route.useSearch,
|
|
945
|
+
useParams: route.useParams
|
|
946
|
+
});
|
|
947
|
+
}, [route]);
|
|
948
|
+
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
|
|
949
|
+
value: matches
|
|
950
|
+
}, /*#__PURE__*/React__namespace.createElement(CatchBoundary, {
|
|
951
|
+
resetKey: locationKey,
|
|
952
|
+
errorComponent: errorComponent,
|
|
953
|
+
onCatch: () => {
|
|
954
|
+
warning(false, `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`);
|
|
955
|
+
}
|
|
956
|
+
}, matches.length ? /*#__PURE__*/React__namespace.createElement(Match, {
|
|
957
|
+
matches: matches
|
|
958
|
+
}) : null));
|
|
959
|
+
}
|
|
960
|
+
const defaultPending = () => null;
|
|
961
|
+
function SafeFragment(props) {
|
|
962
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.children);
|
|
963
|
+
}
|
|
964
|
+
function Match({
|
|
965
|
+
matches
|
|
966
|
+
}) {
|
|
967
|
+
const {
|
|
968
|
+
options,
|
|
969
|
+
routesById
|
|
970
|
+
} = useRouter();
|
|
971
|
+
const match = matches[0];
|
|
972
|
+
const routeId = match?.routeId;
|
|
973
|
+
const route = routesById[routeId];
|
|
974
|
+
const locationKey = useRouterState().location.state?.key;
|
|
975
|
+
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent ?? defaultPending;
|
|
976
|
+
const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
|
|
977
|
+
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ? React__namespace.Suspense : SafeFragment;
|
|
978
|
+
const errorComponent = routeErrorComponent ? React__namespace.useCallback(props => {
|
|
979
|
+
return /*#__PURE__*/React__namespace.createElement(routeErrorComponent, {
|
|
980
|
+
...props,
|
|
981
|
+
useMatch: route.useMatch,
|
|
982
|
+
useRouteContext: route.useRouteContext,
|
|
983
|
+
useSearch: route.useSearch,
|
|
984
|
+
useParams: route.useParams
|
|
985
|
+
});
|
|
986
|
+
}, [route]) : undefined;
|
|
987
|
+
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
|
|
988
|
+
value: matches
|
|
989
|
+
}, /*#__PURE__*/React__namespace.createElement(ResolvedSuspenseBoundary, {
|
|
990
|
+
fallback: /*#__PURE__*/React__namespace.createElement(PendingComponent, {
|
|
991
|
+
useMatch: route.useMatch,
|
|
992
|
+
useRouteContext: route.useRouteContext,
|
|
993
|
+
useSearch: route.useSearch,
|
|
994
|
+
useParams: route.useParams
|
|
995
|
+
})
|
|
996
|
+
}, errorComponent ? /*#__PURE__*/React__namespace.createElement(CatchBoundary, {
|
|
997
|
+
resetKey: locationKey,
|
|
998
|
+
errorComponent: errorComponent,
|
|
999
|
+
onCatch: () => {
|
|
1000
|
+
warning(false, `Error in route match: ${match.id}`);
|
|
1001
|
+
}
|
|
1002
|
+
}, /*#__PURE__*/React__namespace.createElement(MatchInner, {
|
|
1003
|
+
match: match
|
|
1004
|
+
})) : /*#__PURE__*/React__namespace.createElement(SafeFragment, null, /*#__PURE__*/React__namespace.createElement(MatchInner, {
|
|
1005
|
+
match: match
|
|
1006
|
+
}))));
|
|
1007
|
+
}
|
|
1008
|
+
function MatchInner({
|
|
1009
|
+
match
|
|
1010
|
+
}) {
|
|
1011
|
+
const {
|
|
1012
|
+
options,
|
|
1013
|
+
routesById
|
|
1014
|
+
} = useRouter();
|
|
1015
|
+
const route = routesById[match.routeId];
|
|
1016
|
+
if (match.status === 'error') {
|
|
1017
|
+
throw match.error;
|
|
1018
|
+
}
|
|
1019
|
+
if (match.status === 'pending') {
|
|
1020
|
+
throw match.loadPromise;
|
|
1021
|
+
}
|
|
1022
|
+
if (match.status === 'success') {
|
|
1023
|
+
let comp = route.options.component ?? options.defaultComponent;
|
|
1024
|
+
if (comp) {
|
|
1025
|
+
return /*#__PURE__*/React__namespace.createElement(comp, {
|
|
1026
|
+
useMatch: route.useMatch,
|
|
1027
|
+
useRouteContext: route.useRouteContext,
|
|
1028
|
+
useSearch: route.useSearch,
|
|
1029
|
+
useParams: route.useParams,
|
|
1030
|
+
useLoaderData: route.useLoaderData
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
return /*#__PURE__*/React__namespace.createElement(Outlet, null);
|
|
1034
|
+
}
|
|
1035
|
+
invariant(false, 'Idle routeMatch status encountered during rendering! You should never see this. File an issue!');
|
|
1036
|
+
}
|
|
1037
|
+
function Outlet() {
|
|
1038
|
+
const matches = React__namespace.useContext(matchesContext).slice(1);
|
|
1039
|
+
if (!matches[0]) {
|
|
1040
|
+
return null;
|
|
1041
|
+
}
|
|
1042
|
+
return /*#__PURE__*/React__namespace.createElement(Match, {
|
|
1043
|
+
matches: matches
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
function useMatchRoute() {
|
|
1047
|
+
const {
|
|
1048
|
+
matchRoute
|
|
1049
|
+
} = useRouter();
|
|
1050
|
+
return React__namespace.useCallback(opts => {
|
|
1051
|
+
const {
|
|
1052
|
+
pending,
|
|
1053
|
+
caseSensitive,
|
|
1054
|
+
...rest
|
|
1055
|
+
} = opts;
|
|
1056
|
+
return matchRoute(rest, {
|
|
1057
|
+
pending,
|
|
1058
|
+
caseSensitive
|
|
1059
|
+
});
|
|
1060
|
+
}, []);
|
|
1061
|
+
}
|
|
1062
|
+
function MatchRoute(props) {
|
|
1063
|
+
const matchRoute = useMatchRoute();
|
|
1064
|
+
const params = matchRoute(props);
|
|
1065
|
+
if (typeof props.children === 'function') {
|
|
1066
|
+
return props.children(params);
|
|
1067
|
+
}
|
|
1068
|
+
return !!params ? props.children : null;
|
|
1069
|
+
}
|
|
1070
|
+
function useMatch(opts) {
|
|
1071
|
+
const nearestMatch = React__namespace.useContext(matchesContext)[0];
|
|
1072
|
+
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
1073
|
+
const matchRouteId = useRouterState({
|
|
1074
|
+
select: state => {
|
|
1075
|
+
const match = opts?.from ? state.matches.find(d => d.routeId === opts?.from) : state.matches.find(d => d.id === nearestMatch.id);
|
|
1076
|
+
return match.routeId;
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
if (opts?.strict ?? true) {
|
|
1080
|
+
invariant(nearestMatchRouteId == matchRouteId, `useMatch("${matchRouteId}") is being called in a component that is meant to render the '${nearestMatchRouteId}' route. Did you mean to 'useMatch("${matchRouteId}", { strict: false })' or 'useRoute("${matchRouteId}")' instead?`);
|
|
1081
|
+
}
|
|
1082
|
+
const matchSelection = useRouterState({
|
|
1083
|
+
select: state => {
|
|
1084
|
+
const match = opts?.from ? state.matches.find(d => d.routeId === opts?.from) : state.matches.find(d => d.id === nearestMatch.id);
|
|
1085
|
+
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
1086
|
+
return opts?.select ? opts.select(match) : match;
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
return matchSelection;
|
|
1090
|
+
}
|
|
1091
|
+
const matchesContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1092
|
+
function useMatches(opts) {
|
|
1093
|
+
const contextMatches = React__namespace.useContext(matchesContext);
|
|
1094
|
+
return useRouterState({
|
|
1095
|
+
select: state => {
|
|
1096
|
+
const matches = state.matches.slice(state.matches.findIndex(d => d.id === contextMatches[0]?.id));
|
|
1097
|
+
return opts?.select ? opts.select(matches) : matches;
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
function useLoaderData(opts) {
|
|
1102
|
+
const match = useMatch({
|
|
1103
|
+
...opts,
|
|
1104
|
+
select: undefined
|
|
1105
|
+
});
|
|
1106
|
+
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// Detect if we're in the DOM
|
|
1110
|
+
|
|
1111
|
+
function redirect(opts) {
|
|
1112
|
+
opts.isRedirect = true;
|
|
1113
|
+
return opts;
|
|
1114
|
+
}
|
|
1115
|
+
function isRedirect(obj) {
|
|
1116
|
+
return !!obj?.isRedirect;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// @ts-nocheck
|
|
1120
|
+
|
|
1121
|
+
// qss has been slightly modified and inlined here for our use cases (and compression's sake). We've included it as a hard dependency for MIT license attribution.
|
|
1122
|
+
|
|
1123
|
+
function encode(obj, pfx) {
|
|
1124
|
+
var k,
|
|
1125
|
+
i,
|
|
1126
|
+
tmp,
|
|
1127
|
+
str = '';
|
|
1128
|
+
for (k in obj) {
|
|
1129
|
+
if ((tmp = obj[k]) !== void 0) {
|
|
1130
|
+
if (Array.isArray(tmp)) {
|
|
1131
|
+
for (i = 0; i < tmp.length; i++) {
|
|
1132
|
+
str && (str += '&');
|
|
1133
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
|
|
1134
|
+
}
|
|
1135
|
+
} else {
|
|
1136
|
+
str && (str += '&');
|
|
1137
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
return (pfx || '') + str;
|
|
1142
|
+
}
|
|
1143
|
+
function toValue(mix) {
|
|
1144
|
+
if (!mix) return '';
|
|
1145
|
+
var str = decodeURIComponent(mix);
|
|
1146
|
+
if (str === 'false') return false;
|
|
1147
|
+
if (str === 'true') return true;
|
|
1148
|
+
return +str * 0 === 0 && +str + '' === str ? +str : str;
|
|
1149
|
+
}
|
|
1150
|
+
function decode(str) {
|
|
1151
|
+
var tmp,
|
|
1152
|
+
k,
|
|
1153
|
+
out = {},
|
|
1154
|
+
arr = str.split('&');
|
|
1155
|
+
while (tmp = arr.shift()) {
|
|
1156
|
+
tmp = tmp.split('=');
|
|
1157
|
+
k = tmp.shift();
|
|
1158
|
+
if (out[k] !== void 0) {
|
|
1159
|
+
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
1160
|
+
} else {
|
|
1161
|
+
out[k] = toValue(tmp.shift());
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return out;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
const defaultParseSearch = parseSearchWith(JSON.parse);
|
|
1168
|
+
const defaultStringifySearch = stringifySearchWith(JSON.stringify, JSON.parse);
|
|
1169
|
+
function parseSearchWith(parser) {
|
|
1170
|
+
return searchStr => {
|
|
1171
|
+
if (searchStr.substring(0, 1) === '?') {
|
|
1172
|
+
searchStr = searchStr.substring(1);
|
|
1173
|
+
}
|
|
1174
|
+
let query = decode(searchStr);
|
|
1175
|
+
|
|
1176
|
+
// Try to parse any query params that might be json
|
|
1177
|
+
for (let key in query) {
|
|
1178
|
+
const value = query[key];
|
|
1179
|
+
if (typeof value === 'string') {
|
|
1180
|
+
try {
|
|
1181
|
+
query[key] = parser(value);
|
|
1182
|
+
} catch (err) {
|
|
1183
|
+
//
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
return query;
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
function stringifySearchWith(stringify, parser) {
|
|
1191
|
+
function stringifyValue(val) {
|
|
1192
|
+
if (typeof val === 'object' && val !== null) {
|
|
1193
|
+
try {
|
|
1194
|
+
return stringify(val);
|
|
1195
|
+
} catch (err) {
|
|
1196
|
+
// silent
|
|
1197
|
+
}
|
|
1198
|
+
} else if (typeof val === 'string' && typeof parser === 'function') {
|
|
1199
|
+
try {
|
|
1200
|
+
// Check if it's a valid parseable string.
|
|
1201
|
+
// If it is, then stringify it again.
|
|
1202
|
+
parser(val);
|
|
1203
|
+
return stringify(val);
|
|
1204
|
+
} catch (err) {
|
|
1205
|
+
// silent
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return val;
|
|
1209
|
+
}
|
|
1210
|
+
return search => {
|
|
1211
|
+
search = {
|
|
1212
|
+
...search
|
|
1213
|
+
};
|
|
1214
|
+
if (search) {
|
|
1215
|
+
Object.keys(search).forEach(key => {
|
|
1216
|
+
const val = search[key];
|
|
1217
|
+
if (typeof val === 'undefined' || val === undefined) {
|
|
1218
|
+
delete search[key];
|
|
1219
|
+
} else {
|
|
1220
|
+
search[key] = stringifyValue(val);
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
const searchStr = encode(search).toString();
|
|
1225
|
+
return searchStr ? `?${searchStr}` : '';
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
//
|
|
1230
|
+
|
|
1231
|
+
//
|
|
1232
|
+
|
|
1233
|
+
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
1234
|
+
class Router {
|
|
1235
|
+
// dehydratedData?: TDehydrated
|
|
1236
|
+
// resetNextScroll = false
|
|
1237
|
+
// tempLocationKey = `${Math.round(Math.random() * 10000000)}`
|
|
1238
|
+
constructor(options) {
|
|
1239
|
+
this.options = {
|
|
1240
|
+
defaultPreloadDelay: 50,
|
|
1241
|
+
context: undefined,
|
|
1242
|
+
...options,
|
|
1243
|
+
stringifySearch: options?.stringifySearch ?? defaultStringifySearch,
|
|
1244
|
+
parseSearch: options?.parseSearch ?? defaultParseSearch
|
|
1245
|
+
};
|
|
1246
|
+
this.routeTree = this.options.routeTree;
|
|
1247
|
+
}
|
|
1248
|
+
subscribers = new Set();
|
|
1249
|
+
subscribe = (eventType, fn) => {
|
|
1250
|
+
const listener = {
|
|
1251
|
+
eventType,
|
|
1252
|
+
fn
|
|
1253
|
+
};
|
|
1254
|
+
this.subscribers.add(listener);
|
|
1255
|
+
return () => {
|
|
1256
|
+
this.subscribers.delete(listener);
|
|
1257
|
+
};
|
|
1258
|
+
};
|
|
1259
|
+
emit = routerEvent => {
|
|
1260
|
+
this.subscribers.forEach(listener => {
|
|
1261
|
+
if (listener.eventType === routerEvent.type) {
|
|
1262
|
+
listener.fn(routerEvent);
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
};
|
|
1266
|
+
|
|
1267
|
+
// dehydrate = (): DehydratedRouter => {
|
|
1268
|
+
// return {
|
|
1269
|
+
// state: {
|
|
1270
|
+
// dehydratedMatches: state.matches.map((d) =>
|
|
1271
|
+
// pick(d, ['fetchedAt', 'invalid', 'id', 'status', 'updatedAt']),
|
|
1272
|
+
// ),
|
|
1273
|
+
// },
|
|
1274
|
+
// }
|
|
1275
|
+
// }
|
|
964
1276
|
|
|
965
1277
|
// hydrate = async (__do_not_use_server_ctx?: HydrationCtx) => {
|
|
966
1278
|
// let _ctx = __do_not_use_server_ctx
|
|
@@ -1009,49 +1321,6 @@
|
|
|
1009
1321
|
// })
|
|
1010
1322
|
// }
|
|
1011
1323
|
|
|
1012
|
-
// TODO:
|
|
1013
|
-
// injectedHtml: (string | (() => Promise<string> | string))[] = []
|
|
1014
|
-
|
|
1015
|
-
// TODO:
|
|
1016
|
-
// injectHtml = async (html: string | (() => Promise<string> | string)) => {
|
|
1017
|
-
// this.injectedHtml.push(html)
|
|
1018
|
-
// }
|
|
1019
|
-
|
|
1020
|
-
// TODO:
|
|
1021
|
-
// dehydrateData = <T>(key: any, getData: T | (() => Promise<T> | T)) => {
|
|
1022
|
-
// if (typeof document === 'undefined') {
|
|
1023
|
-
// const strKey = typeof key === 'string' ? key : JSON.stringify(key)
|
|
1024
|
-
|
|
1025
|
-
// this.injectHtml(async () => {
|
|
1026
|
-
// const id = `__TSR_DEHYDRATED__${strKey}`
|
|
1027
|
-
// const data =
|
|
1028
|
-
// typeof getData === 'function' ? await (getData as any)() : getData
|
|
1029
|
-
// return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(
|
|
1030
|
-
// strKey,
|
|
1031
|
-
// )}"] = ${JSON.stringify(data)}
|
|
1032
|
-
// ;(() => {
|
|
1033
|
-
// var el = document.getElementById('${id}')
|
|
1034
|
-
// el.parentElement.removeChild(el)
|
|
1035
|
-
// })()
|
|
1036
|
-
// </script>`
|
|
1037
|
-
// })
|
|
1038
|
-
|
|
1039
|
-
// return () => this.hydrateData<T>(key)
|
|
1040
|
-
// }
|
|
1041
|
-
|
|
1042
|
-
// return () => undefined
|
|
1043
|
-
// }
|
|
1044
|
-
|
|
1045
|
-
// hydrateData = <T = unknown>(key: any) => {
|
|
1046
|
-
// if (typeof document !== 'undefined') {
|
|
1047
|
-
// const strKey = typeof key === 'string' ? key : JSON.stringify(key)
|
|
1048
|
-
|
|
1049
|
-
// return window[`__TSR_DEHYDRATED__${strKey}` as any] as T
|
|
1050
|
-
// }
|
|
1051
|
-
|
|
1052
|
-
// return undefined
|
|
1053
|
-
// }
|
|
1054
|
-
|
|
1055
1324
|
// resolveMatchPromise = (matchId: string, key: string, value: any) => {
|
|
1056
1325
|
// state.matches
|
|
1057
1326
|
// .find((d) => d.id === matchId)
|
|
@@ -1711,13 +1980,15 @@
|
|
|
1711
1980
|
|
|
1712
1981
|
// Default to reloading the route all the time
|
|
1713
1982
|
let shouldReload = true;
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1983
|
+
if (cause !== 'enter') {
|
|
1984
|
+
let shouldReloadDeps = typeof route.options.shouldReload === 'function' ? route.options.shouldReload?.(loaderContext) : !!(route.options.shouldReload ?? true);
|
|
1985
|
+
if (typeof shouldReloadDeps === 'object') {
|
|
1986
|
+
// compare the deps to see if they've changed
|
|
1987
|
+
shouldReload = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
|
|
1988
|
+
match.shouldReloadDeps = shouldReloadDeps;
|
|
1989
|
+
} else {
|
|
1990
|
+
shouldReload = !!shouldReloadDeps;
|
|
1991
|
+
}
|
|
1721
1992
|
}
|
|
1722
1993
|
|
|
1723
1994
|
// If the user doesn't want the route to reload, just
|
|
@@ -2018,386 +2289,158 @@
|
|
|
2018
2289
|
return () => {
|
|
2019
2290
|
unsub();
|
|
2020
2291
|
};
|
|
2021
|
-
}, [history]);
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
}, []);
|
|
2031
|
-
const matchRoute = useStableCallback((location, opts) => {
|
|
2032
|
-
location = {
|
|
2033
|
-
...location,
|
|
2034
|
-
to: location.to ? resolvePathWithBase(location.from || '', location.to) : undefined
|
|
2035
|
-
};
|
|
2036
|
-
const next = buildLocation(location);
|
|
2037
|
-
if (opts?.pending && state.status !== 'pending') {
|
|
2038
|
-
return false;
|
|
2039
|
-
}
|
|
2040
|
-
const baseLocation = opts?.pending ? latestLocationRef.current : state.resolvedLocation;
|
|
2041
|
-
|
|
2042
|
-
// const baseLocation = state.resolvedLocation
|
|
2043
|
-
|
|
2044
|
-
if (!baseLocation) {
|
|
2045
|
-
return false;
|
|
2046
|
-
}
|
|
2047
|
-
const match = matchPathname(basepath, baseLocation.pathname, {
|
|
2048
|
-
...opts,
|
|
2049
|
-
to: next.pathname
|
|
2050
|
-
});
|
|
2051
|
-
if (!match) {
|
|
2052
|
-
return false;
|
|
2053
|
-
}
|
|
2054
|
-
if (match && (opts?.includeSearch ?? true)) {
|
|
2055
|
-
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
2056
|
-
}
|
|
2057
|
-
return match;
|
|
2058
|
-
});
|
|
2059
|
-
const routerContextValue = {
|
|
2060
|
-
routeTree: router.routeTree,
|
|
2061
|
-
navigate,
|
|
2062
|
-
buildLink,
|
|
2063
|
-
state,
|
|
2064
|
-
matchRoute,
|
|
2065
|
-
routesById,
|
|
2066
|
-
options,
|
|
2067
|
-
history,
|
|
2068
|
-
load,
|
|
2069
|
-
buildLocation,
|
|
2070
|
-
subscribe: router.subscribe,
|
|
2071
|
-
resetNextScrollRef
|
|
2072
|
-
};
|
|
2073
|
-
return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
2074
|
-
value: routerContextValue
|
|
2075
|
-
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
2076
|
-
}
|
|
2077
|
-
function getRouteMatch(state, id) {
|
|
2078
|
-
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
2079
|
-
}
|
|
2080
|
-
function useRouterState(opts) {
|
|
2081
|
-
const {
|
|
2082
|
-
state
|
|
2083
|
-
} = useRouter();
|
|
2084
|
-
// return useStore(router.__store, opts?.select as any)
|
|
2085
|
-
return opts?.select ? opts.select(state) : state;
|
|
2086
|
-
}
|
|
2087
|
-
function useRouter() {
|
|
2088
|
-
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
2089
|
-
const value = React__namespace.useContext(resolvedContext);
|
|
2090
|
-
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
2091
|
-
return value;
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
function Matches() {
|
|
2095
|
-
const {
|
|
2096
|
-
routesById,
|
|
2097
|
-
state
|
|
2098
|
-
} = useRouter();
|
|
2099
|
-
const {
|
|
2100
|
-
matches
|
|
2101
|
-
} = state;
|
|
2102
|
-
const locationKey = useRouterState().location.state.key;
|
|
2103
|
-
const route = routesById[rootRouteId];
|
|
2104
|
-
const errorComponent = React__namespace.useCallback(props => {
|
|
2105
|
-
return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
|
|
2106
|
-
...props,
|
|
2107
|
-
useMatch: route.useMatch,
|
|
2108
|
-
useRouteContext: route.useRouteContext,
|
|
2109
|
-
useSearch: route.useSearch,
|
|
2110
|
-
useParams: route.useParams
|
|
2111
|
-
});
|
|
2112
|
-
}, [route]);
|
|
2113
|
-
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
|
|
2114
|
-
value: matches
|
|
2115
|
-
}, /*#__PURE__*/React__namespace.createElement(CatchBoundary, {
|
|
2116
|
-
resetKey: locationKey,
|
|
2117
|
-
errorComponent: errorComponent,
|
|
2118
|
-
onCatch: () => {
|
|
2119
|
-
warning(false, `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`);
|
|
2120
|
-
}
|
|
2121
|
-
}, matches.length ? /*#__PURE__*/React__namespace.createElement(Match, {
|
|
2122
|
-
matches: matches
|
|
2123
|
-
}) : null));
|
|
2124
|
-
}
|
|
2125
|
-
const defaultPending = () => null;
|
|
2126
|
-
function SafeFragment(props) {
|
|
2127
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.children);
|
|
2128
|
-
}
|
|
2129
|
-
function Match({
|
|
2130
|
-
matches
|
|
2131
|
-
}) {
|
|
2132
|
-
const {
|
|
2133
|
-
options,
|
|
2134
|
-
routesById
|
|
2135
|
-
} = useRouter();
|
|
2136
|
-
const match = matches[0];
|
|
2137
|
-
const routeId = match?.routeId;
|
|
2138
|
-
const route = routesById[routeId];
|
|
2139
|
-
const locationKey = useRouterState().location.state?.key;
|
|
2140
|
-
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent ?? defaultPending;
|
|
2141
|
-
const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
|
|
2142
|
-
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ? React__namespace.Suspense : SafeFragment;
|
|
2143
|
-
const errorComponent = routeErrorComponent ? React__namespace.useCallback(props => {
|
|
2144
|
-
return /*#__PURE__*/React__namespace.createElement(routeErrorComponent, {
|
|
2145
|
-
...props,
|
|
2146
|
-
useMatch: route.useMatch,
|
|
2147
|
-
useRouteContext: route.useRouteContext,
|
|
2148
|
-
useSearch: route.useSearch,
|
|
2149
|
-
useParams: route.useParams
|
|
2150
|
-
});
|
|
2151
|
-
}, [route]) : undefined;
|
|
2152
|
-
return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
|
|
2153
|
-
value: matches
|
|
2154
|
-
}, /*#__PURE__*/React__namespace.createElement(ResolvedSuspenseBoundary, {
|
|
2155
|
-
fallback: /*#__PURE__*/React__namespace.createElement(PendingComponent, {
|
|
2156
|
-
useMatch: route.useMatch,
|
|
2157
|
-
useRouteContext: route.useRouteContext,
|
|
2158
|
-
useSearch: route.useSearch,
|
|
2159
|
-
useParams: route.useParams
|
|
2160
|
-
})
|
|
2161
|
-
}, errorComponent ? /*#__PURE__*/React__namespace.createElement(CatchBoundary, {
|
|
2162
|
-
resetKey: locationKey,
|
|
2163
|
-
errorComponent: errorComponent,
|
|
2164
|
-
onCatch: () => {
|
|
2165
|
-
warning(false, `Error in route match: ${match.id}`);
|
|
2166
|
-
}
|
|
2167
|
-
}, /*#__PURE__*/React__namespace.createElement(MatchInner, {
|
|
2168
|
-
match: match
|
|
2169
|
-
})) : /*#__PURE__*/React__namespace.createElement(SafeFragment, null, /*#__PURE__*/React__namespace.createElement(MatchInner, {
|
|
2170
|
-
match: match
|
|
2171
|
-
}))));
|
|
2172
|
-
}
|
|
2173
|
-
function MatchInner({
|
|
2174
|
-
match
|
|
2175
|
-
}) {
|
|
2176
|
-
const {
|
|
2177
|
-
options,
|
|
2178
|
-
routesById
|
|
2179
|
-
} = useRouter();
|
|
2180
|
-
const route = routesById[match.routeId];
|
|
2181
|
-
if (match.status === 'error') {
|
|
2182
|
-
throw match.error;
|
|
2183
|
-
}
|
|
2184
|
-
if (match.status === 'pending') {
|
|
2185
|
-
throw match.loadPromise;
|
|
2186
|
-
}
|
|
2187
|
-
if (match.status === 'success') {
|
|
2188
|
-
let comp = route.options.component ?? options.defaultComponent;
|
|
2189
|
-
if (comp) {
|
|
2190
|
-
return /*#__PURE__*/React__namespace.createElement(comp, {
|
|
2191
|
-
useMatch: route.useMatch,
|
|
2192
|
-
useRouteContext: route.useRouteContext,
|
|
2193
|
-
useSearch: route.useSearch,
|
|
2194
|
-
useParams: route.useParams,
|
|
2195
|
-
useLoaderData: route.useLoaderData
|
|
2196
|
-
});
|
|
2292
|
+
}, [history]);
|
|
2293
|
+
const matchRoute = useStableCallback((location, opts) => {
|
|
2294
|
+
location = {
|
|
2295
|
+
...location,
|
|
2296
|
+
to: location.to ? resolvePathWithBase(location.from || '', location.to) : undefined
|
|
2297
|
+
};
|
|
2298
|
+
const next = buildLocation(location);
|
|
2299
|
+
if (opts?.pending && state.status !== 'pending') {
|
|
2300
|
+
return false;
|
|
2197
2301
|
}
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
matches: matches
|
|
2209
|
-
});
|
|
2210
|
-
}
|
|
2211
|
-
function useMatchRoute() {
|
|
2212
|
-
const {
|
|
2213
|
-
matchRoute
|
|
2214
|
-
} = useRouter();
|
|
2215
|
-
return React__namespace.useCallback(opts => {
|
|
2216
|
-
const {
|
|
2217
|
-
pending,
|
|
2218
|
-
caseSensitive,
|
|
2219
|
-
...rest
|
|
2220
|
-
} = opts;
|
|
2221
|
-
return matchRoute(rest, {
|
|
2222
|
-
pending,
|
|
2223
|
-
caseSensitive
|
|
2302
|
+
const baseLocation = opts?.pending ? latestLocationRef.current : state.resolvedLocation;
|
|
2303
|
+
|
|
2304
|
+
// const baseLocation = state.resolvedLocation
|
|
2305
|
+
|
|
2306
|
+
if (!baseLocation) {
|
|
2307
|
+
return false;
|
|
2308
|
+
}
|
|
2309
|
+
const match = matchPathname(basepath, baseLocation.pathname, {
|
|
2310
|
+
...opts,
|
|
2311
|
+
to: next.pathname
|
|
2224
2312
|
});
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
function MatchRoute(props) {
|
|
2228
|
-
const matchRoute = useMatchRoute();
|
|
2229
|
-
const params = matchRoute(props);
|
|
2230
|
-
if (typeof props.children === 'function') {
|
|
2231
|
-
return props.children(params);
|
|
2232
|
-
}
|
|
2233
|
-
return !!params ? props.children : null;
|
|
2234
|
-
}
|
|
2235
|
-
function useMatch(opts) {
|
|
2236
|
-
const nearestMatch = React__namespace.useContext(matchesContext)[0];
|
|
2237
|
-
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
2238
|
-
const matchRouteId = useRouterState({
|
|
2239
|
-
select: state => {
|
|
2240
|
-
const match = opts?.from ? state.matches.find(d => d.routeId === opts?.from) : state.matches.find(d => d.id === nearestMatch.id);
|
|
2241
|
-
return match.routeId;
|
|
2313
|
+
if (!match) {
|
|
2314
|
+
return false;
|
|
2242
2315
|
}
|
|
2316
|
+
if (match && (opts?.includeSearch ?? true)) {
|
|
2317
|
+
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
2318
|
+
}
|
|
2319
|
+
return match;
|
|
2243
2320
|
});
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2321
|
+
const injectedHtmlRef = React__namespace.useRef([]);
|
|
2322
|
+
const injectHtml = useStableCallback(async html => {
|
|
2323
|
+
injectedHtmlRef.current.push(html);
|
|
2324
|
+
});
|
|
2325
|
+
const dehydrateData = useStableCallback((key, getData) => {
|
|
2326
|
+
if (typeof document === 'undefined') {
|
|
2327
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2328
|
+
injectHtml(async () => {
|
|
2329
|
+
const id = `__TSR_DEHYDRATED__${strKey}`;
|
|
2330
|
+
const data = typeof getData === 'function' ? await getData() : getData;
|
|
2331
|
+
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}
|
|
2332
|
+
;(() => {
|
|
2333
|
+
var el = document.getElementById('${id}')
|
|
2334
|
+
el.parentElement.removeChild(el)
|
|
2335
|
+
})()
|
|
2336
|
+
</script>`;
|
|
2337
|
+
});
|
|
2338
|
+
return () => hydrateData(key);
|
|
2252
2339
|
}
|
|
2340
|
+
return () => undefined;
|
|
2253
2341
|
});
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
const contextMatches = React__namespace.useContext(matchesContext);
|
|
2259
|
-
return useRouterState({
|
|
2260
|
-
select: state => {
|
|
2261
|
-
const matches = state.matches.slice(state.matches.findIndex(d => d.id === contextMatches[0]?.id));
|
|
2262
|
-
return opts?.select ? opts.select(matches) : matches;
|
|
2342
|
+
const hydrateData = useStableCallback(key => {
|
|
2343
|
+
if (typeof document !== 'undefined') {
|
|
2344
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2345
|
+
return window[`__TSR_DEHYDRATED__${strKey}`];
|
|
2263
2346
|
}
|
|
2347
|
+
return undefined;
|
|
2264
2348
|
});
|
|
2349
|
+
React__namespace.useLayoutEffect(() => {
|
|
2350
|
+
startReactTransition(() => {
|
|
2351
|
+
try {
|
|
2352
|
+
load();
|
|
2353
|
+
} catch (err) {
|
|
2354
|
+
console.error(err);
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
}, []);
|
|
2358
|
+
const routerContextValue = {
|
|
2359
|
+
routeTree: router.routeTree,
|
|
2360
|
+
navigate,
|
|
2361
|
+
buildLink,
|
|
2362
|
+
state,
|
|
2363
|
+
matchRoute,
|
|
2364
|
+
routesById,
|
|
2365
|
+
options,
|
|
2366
|
+
history,
|
|
2367
|
+
load,
|
|
2368
|
+
buildLocation,
|
|
2369
|
+
subscribe: router.subscribe,
|
|
2370
|
+
resetNextScrollRef,
|
|
2371
|
+
injectedHtmlRef,
|
|
2372
|
+
injectHtml,
|
|
2373
|
+
dehydrateData,
|
|
2374
|
+
hydrateData
|
|
2375
|
+
};
|
|
2376
|
+
return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
2377
|
+
value: routerContextValue
|
|
2378
|
+
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
2265
2379
|
}
|
|
2266
|
-
function
|
|
2267
|
-
|
|
2268
|
-
...opts,
|
|
2269
|
-
select: undefined
|
|
2270
|
-
});
|
|
2271
|
-
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
2380
|
+
function getRouteMatch(state, id) {
|
|
2381
|
+
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
2272
2382
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
}
|
|
2280
|
-
});
|
|
2383
|
+
function useRouterState(opts) {
|
|
2384
|
+
const {
|
|
2385
|
+
state
|
|
2386
|
+
} = useRouter();
|
|
2387
|
+
// return useStore(router.__store, opts?.select as any)
|
|
2388
|
+
return opts?.select ? opts.select(state) : state;
|
|
2281
2389
|
}
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
return opts?.select ? opts.select(match.search) : match.search;
|
|
2288
|
-
}
|
|
2289
|
-
});
|
|
2390
|
+
function useRouter() {
|
|
2391
|
+
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
2392
|
+
const value = React__namespace.useContext(resolvedContext);
|
|
2393
|
+
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
2394
|
+
return value;
|
|
2290
2395
|
}
|
|
2291
2396
|
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
Route.__onInit(this);
|
|
2307
|
-
}
|
|
2308
|
-
init = opts => {
|
|
2309
|
-
this.originalIndex = opts.originalIndex;
|
|
2310
|
-
const options = this.options;
|
|
2311
|
-
const isRoot = !options?.path && !options?.id;
|
|
2312
|
-
this.parentRoute = this.options?.getParentRoute?.();
|
|
2313
|
-
if (isRoot) {
|
|
2314
|
-
this.path = rootRouteId;
|
|
2315
|
-
} else {
|
|
2316
|
-
invariant(this.parentRoute, `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`);
|
|
2317
|
-
}
|
|
2318
|
-
let path = isRoot ? rootRouteId : options.path;
|
|
2319
|
-
|
|
2320
|
-
// If the path is anything other than an index path, trim it up
|
|
2321
|
-
if (path && path !== '/') {
|
|
2322
|
-
path = trimPath(path);
|
|
2323
|
-
}
|
|
2324
|
-
const customId = options?.id || path;
|
|
2325
|
-
|
|
2326
|
-
// Strip the parentId prefix from the first level of children
|
|
2327
|
-
let id = isRoot ? rootRouteId : joinPaths([this.parentRoute.id === rootRouteId ? '' : this.parentRoute.id, customId]);
|
|
2328
|
-
if (path === rootRouteId) {
|
|
2329
|
-
path = '/';
|
|
2330
|
-
}
|
|
2331
|
-
if (id !== rootRouteId) {
|
|
2332
|
-
id = joinPaths(['/', id]);
|
|
2333
|
-
}
|
|
2334
|
-
const fullPath = id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path]);
|
|
2335
|
-
this.path = path;
|
|
2336
|
-
this.id = id;
|
|
2337
|
-
// this.customId = customId as TCustomId
|
|
2338
|
-
this.fullPath = fullPath;
|
|
2339
|
-
this.to = fullPath;
|
|
2340
|
-
};
|
|
2341
|
-
addChildren = children => {
|
|
2342
|
-
this.children = children;
|
|
2343
|
-
return this;
|
|
2344
|
-
};
|
|
2345
|
-
update = options => {
|
|
2346
|
-
Object.assign(this.options, options);
|
|
2347
|
-
return this;
|
|
2348
|
-
};
|
|
2349
|
-
static __onInit = route => {
|
|
2350
|
-
// This is a dummy static method that should get
|
|
2351
|
-
// replaced by a framework specific implementation if necessary
|
|
2352
|
-
};
|
|
2353
|
-
useMatch = opts => {
|
|
2354
|
-
return useMatch({
|
|
2355
|
-
...opts,
|
|
2356
|
-
from: this.id
|
|
2357
|
-
});
|
|
2358
|
-
};
|
|
2359
|
-
useRouteContext = opts => {
|
|
2360
|
-
return useMatch({
|
|
2361
|
-
...opts,
|
|
2362
|
-
from: this.id,
|
|
2363
|
-
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
2364
|
-
});
|
|
2365
|
-
};
|
|
2366
|
-
useSearch = opts => {
|
|
2367
|
-
return useSearch({
|
|
2368
|
-
...opts,
|
|
2369
|
-
from: this.id
|
|
2370
|
-
});
|
|
2371
|
-
};
|
|
2372
|
-
useParams = opts => {
|
|
2373
|
-
return useParams({
|
|
2374
|
-
...opts,
|
|
2375
|
-
from: this.id
|
|
2376
|
-
});
|
|
2377
|
-
};
|
|
2378
|
-
useLoaderData = opts => {
|
|
2379
|
-
return useLoaderData({
|
|
2380
|
-
...opts,
|
|
2381
|
-
from: this.id
|
|
2397
|
+
function defer(_promise) {
|
|
2398
|
+
const promise = _promise;
|
|
2399
|
+
if (!promise.__deferredState) {
|
|
2400
|
+
promise.__deferredState = {
|
|
2401
|
+
uid: Math.random().toString(36).slice(2),
|
|
2402
|
+
status: 'pending'
|
|
2403
|
+
};
|
|
2404
|
+
const state = promise.__deferredState;
|
|
2405
|
+
promise.then(data => {
|
|
2406
|
+
state.status = 'success';
|
|
2407
|
+
state.data = data;
|
|
2408
|
+
}).catch(error => {
|
|
2409
|
+
state.status = 'error';
|
|
2410
|
+
state.error = error;
|
|
2382
2411
|
});
|
|
2383
|
-
}
|
|
2412
|
+
}
|
|
2413
|
+
return promise;
|
|
2384
2414
|
}
|
|
2385
|
-
function
|
|
2386
|
-
return
|
|
2387
|
-
return new RootRoute(options);
|
|
2388
|
-
};
|
|
2415
|
+
function isDehydratedDeferred(obj) {
|
|
2416
|
+
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
2389
2417
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2418
|
+
|
|
2419
|
+
function useAwaited({
|
|
2420
|
+
promise
|
|
2421
|
+
}) {
|
|
2422
|
+
const router = useRouter();
|
|
2423
|
+
let state = promise.__deferredState;
|
|
2424
|
+
const key = `__TSR__DEFERRED__${state.uid}`;
|
|
2425
|
+
if (isDehydratedDeferred(promise)) {
|
|
2426
|
+
state = router.hydrateData(key);
|
|
2427
|
+
promise = Promise.resolve(state.data);
|
|
2428
|
+
promise.__deferredState = state;
|
|
2429
|
+
}
|
|
2430
|
+
if (state.status === 'pending') {
|
|
2431
|
+
throw promise;
|
|
2432
|
+
}
|
|
2433
|
+
if (state.status === 'error') {
|
|
2434
|
+
throw state.error;
|
|
2393
2435
|
}
|
|
2436
|
+
router.dehydrateData(key, state);
|
|
2437
|
+
return [state.data];
|
|
2394
2438
|
}
|
|
2395
|
-
function
|
|
2396
|
-
|
|
2439
|
+
function Await(props) {
|
|
2440
|
+
const awaited = useAwaited(props);
|
|
2441
|
+
return props.children(...awaited);
|
|
2397
2442
|
}
|
|
2398
2443
|
|
|
2399
|
-
//
|
|
2400
|
-
|
|
2401
2444
|
class FileRoute {
|
|
2402
2445
|
constructor(path) {
|
|
2403
2446
|
this.path = path;
|
|
@@ -2755,6 +2798,7 @@
|
|
|
2755
2798
|
return null;
|
|
2756
2799
|
}
|
|
2757
2800
|
|
|
2801
|
+
exports.Await = Await;
|
|
2758
2802
|
exports.Block = Block;
|
|
2759
2803
|
exports.CatchBoundary = CatchBoundary;
|
|
2760
2804
|
exports.CatchBoundaryImpl = CatchBoundaryImpl;
|
|
@@ -2783,12 +2827,15 @@
|
|
|
2783
2827
|
exports.deepEqual = deepEqual;
|
|
2784
2828
|
exports.defaultParseSearch = defaultParseSearch;
|
|
2785
2829
|
exports.defaultStringifySearch = defaultStringifySearch;
|
|
2830
|
+
exports.defer = defer;
|
|
2786
2831
|
exports.encode = encode;
|
|
2832
|
+
exports.escapeJSON = escapeJSON;
|
|
2787
2833
|
exports.functionalUpdate = functionalUpdate;
|
|
2788
2834
|
exports.getInitialRouterState = getInitialRouterState;
|
|
2789
2835
|
exports.getRouteMatch = getRouteMatch;
|
|
2790
2836
|
exports.interpolatePath = interpolatePath;
|
|
2791
2837
|
exports.invariant = invariant;
|
|
2838
|
+
exports.isDehydratedDeferred = isDehydratedDeferred;
|
|
2792
2839
|
exports.isPlainObject = isPlainObject;
|
|
2793
2840
|
exports.isRedirect = isRedirect;
|
|
2794
2841
|
exports.isServer = isServer;
|
|
@@ -2814,6 +2861,7 @@
|
|
|
2814
2861
|
exports.trimPathLeft = trimPathLeft;
|
|
2815
2862
|
exports.trimPathRight = trimPathRight;
|
|
2816
2863
|
exports.typedNavigate = typedNavigate;
|
|
2864
|
+
exports.useAwaited = useAwaited;
|
|
2817
2865
|
exports.useBlocker = useBlocker;
|
|
2818
2866
|
exports.useLayoutEffect = useLayoutEffect$1;
|
|
2819
2867
|
exports.useLinkProps = useLinkProps;
|