@tanstack/react-router 0.0.1-alpha.6 → 0.0.1-alpha.7

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.
@@ -93,23 +93,6 @@
93
93
  return _extends$1.apply(this, arguments);
94
94
  }
95
95
 
96
- function _extends() {
97
- _extends = Object.assign ? Object.assign.bind() : function (target) {
98
- for (var i = 1; i < arguments.length; i++) {
99
- var source = arguments[i];
100
-
101
- for (var key in source) {
102
- if (Object.prototype.hasOwnProperty.call(source, key)) {
103
- target[key] = source[key];
104
- }
105
- }
106
- }
107
-
108
- return target;
109
- };
110
- return _extends.apply(this, arguments);
111
- }
112
-
113
96
  /**
114
97
  * Actions represent the type of change to a location value.
115
98
  *
@@ -251,7 +234,7 @@
251
234
 
252
235
  if (index == null) {
253
236
  index = 0;
254
- globalHistory.replaceState(_extends({}, globalHistory.state, {
237
+ globalHistory.replaceState(_extends$1({}, globalHistory.state, {
255
238
  idx: index
256
239
  }), '');
257
240
  }
@@ -266,7 +249,7 @@
266
249
  state = null;
267
250
  }
268
251
 
269
- return readOnly(_extends({
252
+ return readOnly(_extends$1({
270
253
  pathname: location.pathname,
271
254
  hash: '',
272
255
  search: ''
@@ -500,7 +483,7 @@
500
483
 
501
484
  if (index == null) {
502
485
  index = 0;
503
- globalHistory.replaceState(_extends({}, globalHistory.state, {
486
+ globalHistory.replaceState(_extends$1({}, globalHistory.state, {
504
487
  idx: index
505
488
  }), '');
506
489
  }
@@ -527,7 +510,7 @@
527
510
  state = null;
528
511
  }
529
512
 
530
- return readOnly(_extends({
513
+ return readOnly(_extends$1({
531
514
  pathname: location.pathname,
532
515
  hash: '',
533
516
  search: ''
@@ -679,7 +662,7 @@
679
662
  initialEntries = _options3$initialEntr === void 0 ? ['/'] : _options3$initialEntr,
680
663
  initialIndex = _options3.initialIndex;
681
664
  var entries = initialEntries.map(function (entry) {
682
- var location = readOnly(_extends({
665
+ var location = readOnly(_extends$1({
683
666
  pathname: '/',
684
667
  search: '',
685
668
  hash: '',
@@ -704,7 +687,7 @@
704
687
  state = null;
705
688
  }
706
689
 
707
- return readOnly(_extends({
690
+ return readOnly(_extends$1({
708
691
  pathname: location.pathname,
709
692
  search: '',
710
693
  hash: ''
@@ -910,1499 +893,1577 @@
910
893
  throw new Error(value);
911
894
  }
912
895
 
913
- // @ts-nocheck
914
- // We're inlining qss here for compression's sake, but we've included it as a hard dependency for the MIT license it requires.
915
- function encode(obj, pfx) {
916
- var k,
917
- i,
918
- tmp,
919
- str = '';
896
+ // type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
897
+ // k: infer I,
898
+ // ) => any
899
+ // ? I
900
+ // : never
920
901
 
921
- for (k in obj) {
922
- if ((tmp = obj[k]) !== void 0) {
923
- if (Array.isArray(tmp)) {
924
- for (i = 0; i < tmp.length; i++) {
925
- str && (str += '&');
926
- str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
927
- }
928
- } else {
929
- str && (str += '&');
930
- str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
902
+ /**
903
+ * This function returns `a` if `b` is deeply equal.
904
+ * If not, it will replace any deeply equal children of `b` with those of `a`.
905
+ * This can be used for structural sharing between JSON values for example.
906
+ */
907
+ function replaceEqualDeep(prev, next) {
908
+ if (prev === next) {
909
+ return prev;
910
+ }
911
+
912
+ const array = Array.isArray(prev) && Array.isArray(next);
913
+
914
+ if (array || isPlainObject(prev) && isPlainObject(next)) {
915
+ const aSize = array ? prev.length : Object.keys(prev).length;
916
+ const bItems = array ? next : Object.keys(next);
917
+ const bSize = bItems.length;
918
+ const copy = array ? [] : {};
919
+ let equalItems = 0;
920
+
921
+ for (let i = 0; i < bSize; i++) {
922
+ const key = array ? i : bItems[i];
923
+ copy[key] = replaceEqualDeep(prev[key], next[key]);
924
+
925
+ if (copy[key] === prev[key]) {
926
+ equalItems++;
931
927
  }
932
928
  }
929
+
930
+ return aSize === bSize && equalItems === aSize ? prev : copy;
933
931
  }
934
932
 
935
- return (pfx || '') + str;
936
- }
933
+ return next;
934
+ } // Copied from: https://github.com/jonschlinkert/is-plain-object
937
935
 
938
- function toValue(mix) {
939
- if (!mix) return '';
940
- var str = decodeURIComponent(mix);
941
- if (str === 'false') return false;
942
- if (str === 'true') return true;
943
- return +str * 0 === 0 ? +str : str;
944
- }
936
+ function isPlainObject(o) {
937
+ if (!hasObjectPrototype(o)) {
938
+ return false;
939
+ } // If has modified constructor
945
940
 
946
- function decode(str) {
947
- var tmp,
948
- k,
949
- out = {},
950
- arr = str.split('&');
951
941
 
952
- while (tmp = arr.shift()) {
953
- tmp = tmp.split('=');
954
- k = tmp.shift();
942
+ const ctor = o.constructor;
955
943
 
956
- if (out[k] !== void 0) {
957
- out[k] = [].concat(out[k], toValue(tmp.shift()));
958
- } else {
959
- out[k] = toValue(tmp.shift());
960
- }
961
- }
944
+ if (typeof ctor === 'undefined') {
945
+ return true;
946
+ } // If has modified prototype
962
947
 
963
- return out;
948
+
949
+ const prot = ctor.prototype;
950
+
951
+ if (!hasObjectPrototype(prot)) {
952
+ return false;
953
+ } // If constructor does not have an Object-specific method
954
+
955
+
956
+ if (!prot.hasOwnProperty('isPrototypeOf')) {
957
+ return false;
958
+ } // Most likely a plain Object
959
+
960
+
961
+ return true;
964
962
  }
965
963
 
966
- const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
967
- if (options === void 0) {
968
- options = {};
969
- }
964
+ function hasObjectPrototype(o) {
965
+ return Object.prototype.toString.call(o) === '[object Object]';
966
+ }
970
967
 
971
- if (isRoot === void 0) {
972
- isRoot = true;
968
+ function last(arr) {
969
+ return arr[arr.length - 1];
970
+ }
971
+ function warning(cond, message) {
972
+ if (cond) {
973
+ if (typeof console !== 'undefined') console.warn(message);
974
+
975
+ try {
976
+ throw new Error(message);
977
+ } catch (_unused) {}
973
978
  }
974
979
 
975
- if (isRoot) {
976
- options.path = rootRouteId;
977
- } // Strip the root from parentIds
980
+ return true;
981
+ }
978
982
 
983
+ function isFunction(d) {
984
+ return typeof d === 'function';
985
+ }
979
986
 
980
- if (parentId === rootRouteId) {
981
- parentId = '';
987
+ function functionalUpdate(updater, previous) {
988
+ if (isFunction(updater)) {
989
+ return updater(previous);
982
990
  }
983
991
 
984
- let path = isRoot ? rootRouteId : options.path; // If the path is anything other than an index path, trim it up
992
+ return updater;
993
+ }
985
994
 
986
- if (path && path !== '/') {
987
- path = trimPath(path);
988
- }
995
+ function joinPaths(paths) {
996
+ return cleanPath(paths.filter(Boolean).join('/'));
997
+ }
998
+ function cleanPath(path) {
999
+ // remove double slashes
1000
+ return path.replace(/\/{2,}/g, '/');
1001
+ }
1002
+ function trimPathLeft(path) {
1003
+ return path === '/' ? path : path.replace(/^\/{1,}/, '');
1004
+ }
1005
+ function trimPathRight(path) {
1006
+ return path === '/' ? path : path.replace(/\/{1,}$/, '');
1007
+ }
1008
+ function trimPath(path) {
1009
+ return trimPathRight(trimPathLeft(path));
1010
+ }
1011
+ function resolvePath(basepath, base, to) {
1012
+ base = base.replace(new RegExp("^" + basepath), '/');
1013
+ to = to.replace(new RegExp("^" + basepath), '/');
1014
+ let baseSegments = parsePathname(base);
1015
+ const toSegments = parsePathname(to);
1016
+ toSegments.forEach((toSegment, index) => {
1017
+ if (toSegment.value === '/') {
1018
+ if (!index) {
1019
+ // Leading slash
1020
+ baseSegments = [toSegment];
1021
+ } else if (index === toSegments.length - 1) {
1022
+ // Trailing Slash
1023
+ baseSegments.push(toSegment);
1024
+ } else ;
1025
+ } else if (toSegment.value === '..') {
1026
+ var _last;
989
1027
 
990
- const routeId = path || options.id;
991
- let id = joinPaths([parentId, routeId]);
1028
+ // Extra trailing slash? pop it off
1029
+ if (baseSegments.length > 1 && ((_last = last(baseSegments)) == null ? void 0 : _last.value) === '/') {
1030
+ baseSegments.pop();
1031
+ }
992
1032
 
993
- if (path === rootRouteId) {
994
- path = '/';
1033
+ baseSegments.pop();
1034
+ } else if (toSegment.value === '.') {
1035
+ return;
1036
+ } else {
1037
+ baseSegments.push(toSegment);
1038
+ }
1039
+ });
1040
+ const joined = joinPaths([basepath, ...baseSegments.map(d => d.value)]);
1041
+ return cleanPath(joined);
1042
+ }
1043
+ function parsePathname(pathname) {
1044
+ if (!pathname) {
1045
+ return [];
995
1046
  }
996
1047
 
997
- if (id !== rootRouteId) {
998
- id = joinPaths(['/', id]);
1048
+ pathname = cleanPath(pathname);
1049
+ const segments = [];
1050
+
1051
+ if (pathname.slice(0, 1) === '/') {
1052
+ pathname = pathname.substring(1);
1053
+ segments.push({
1054
+ type: 'pathname',
1055
+ value: '/'
1056
+ });
999
1057
  }
1000
1058
 
1001
- const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parentPath, path]));
1002
- return {
1003
- id: id,
1004
- routeId: routeId,
1005
- path: path,
1006
- fullPath: fullPath,
1007
- options: options,
1008
- children,
1009
- addChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)), false, parentId, parentPath)
1010
- };
1011
- };
1012
- const rootRouteId = '__root__';
1013
- // Source
1014
- // Detect if we're in the DOM
1015
- const isDOM$1 = Boolean(typeof window !== 'undefined' && window.document && window.document.createElement); // This is the default history object if none is defined
1059
+ if (!pathname) {
1060
+ return segments;
1061
+ } // Remove empty segments and '.' segments
1016
1062
 
1017
- const createDefaultHistory = () => isDOM$1 ? createBrowserHistory() : createMemoryHistory();
1018
1063
 
1019
- function createRouter(userOptions) {
1020
- var _userOptions$stringif, _userOptions$parseSea;
1064
+ const split = pathname.split('/').filter(Boolean);
1065
+ segments.push(...split.map(part => {
1066
+ if (part.startsWith('*')) {
1067
+ return {
1068
+ type: 'wildcard',
1069
+ value: part
1070
+ };
1071
+ }
1021
1072
 
1022
- const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
1073
+ if (part.charAt(0) === ':') {
1074
+ return {
1075
+ type: 'param',
1076
+ value: part
1077
+ };
1078
+ }
1023
1079
 
1024
- const originalOptions = _extends$1({}, userOptions, {
1025
- stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
1026
- parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
1027
- });
1080
+ return {
1081
+ type: 'pathname',
1082
+ value: part
1083
+ };
1084
+ }));
1028
1085
 
1029
- let router = {
1030
- options: originalOptions,
1031
- listeners: [],
1032
- removeActionQueue: [],
1033
- // Resolved after construction
1034
- basepath: '',
1035
- routeTree: undefined,
1036
- routesById: {},
1037
- location: undefined,
1038
- allRouteInfo: undefined,
1039
- //
1040
- navigationPromise: Promise.resolve(),
1041
- resolveNavigation: () => {},
1042
- preloadCache: {},
1043
- state: {
1044
- status: 'idle',
1045
- location: null,
1046
- matches: [],
1047
- actions: {},
1048
- loaderData: {},
1049
- lastUpdated: Date.now()
1050
- },
1051
- startedLoadingAt: Date.now(),
1052
- subscribe: listener => {
1053
- router.listeners.push(listener);
1054
- return () => {
1055
- router.listeners = router.listeners.filter(x => x !== listener);
1056
- };
1057
- },
1058
- getRoute: id => {
1059
- return router.routesById[id];
1060
- },
1061
- notify: () => {
1062
- router.state = _extends$1({}, router.state);
1063
- router.listeners.forEach(listener => listener());
1064
- },
1065
- mount: () => {
1066
- const next = router.buildLocation({
1067
- to: '.',
1068
- search: true,
1069
- hash: true
1070
- }); // If the current location isn't updated, trigger a navigation
1071
- // to the current location. Otherwise, load the current location.
1072
-
1073
- if (next.href !== router.location.href) {
1074
- return router.commitLocation(next, true);
1075
- } else {
1076
- return router.loadLocation();
1077
- }
1078
- },
1079
- update: opts => {
1080
- Object.assign(router.options, opts);
1081
- const {
1082
- basepath,
1083
- routeConfig
1084
- } = router.options;
1085
- router.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
1086
-
1087
- if (routeConfig) {
1088
- router.routesById = {};
1089
- router.routeTree = router.buildRouteTree(routeConfig);
1090
- }
1091
-
1092
- return router;
1093
- },
1094
- destroy: history.listen(event => {
1095
- router.loadLocation(router.parseLocation(event.location, router.location));
1096
- }),
1097
- buildRouteTree: rootRouteConfig => {
1098
- const recurseRoutes = (routeConfigs, parent) => {
1099
- return routeConfigs.map(routeConfig => {
1100
- const routeOptions = routeConfig.options;
1101
- const route = createRoute(routeConfig, routeOptions, parent, router); // {
1102
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
1103
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
1104
- // }
1105
-
1106
- const existingRoute = router.routesById[route.routeId];
1107
-
1108
- if (existingRoute) {
1109
- {
1110
- console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
1111
- }
1112
-
1113
- throw new Error();
1114
- }
1115
- router.routesById[route.routeId] = route;
1116
- const children = routeConfig.children;
1117
- route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
1118
- return route;
1119
- });
1120
- };
1121
-
1122
- const routes = recurseRoutes([rootRouteConfig]);
1123
- return routes[0];
1124
- },
1125
- parseLocation: (location, previousLocation) => {
1126
- var _location$hash$split$;
1127
-
1128
- const parsedSearch = router.options.parseSearch(location.search);
1129
- return {
1130
- pathname: location.pathname,
1131
- searchStr: location.search,
1132
- search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
1133
- hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
1134
- href: "" + location.pathname + location.search + location.hash,
1135
- state: location.state,
1136
- key: location.key
1137
- };
1138
- },
1139
- buildLocation: function buildLocation(dest) {
1140
- var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
1141
-
1142
- if (dest === void 0) {
1143
- dest = {};
1144
- }
1145
-
1146
- // const resolvedFrom: Location = {
1147
- // ...router.location,
1148
- const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
1149
-
1150
- let pathname = _resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
1151
-
1152
- const fromMatches = router.matchRoutes(router.location.pathname, {
1153
- strictParseParams: true
1154
- });
1155
- const toMatches = router.matchRoutes(pathname);
1156
-
1157
- const prevParams = _extends$1({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
1158
-
1159
- let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
1160
-
1161
- if (nextParams) {
1162
- toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
1163
- Object.assign({}, nextParams, fn(nextParams));
1164
- });
1165
- }
1166
-
1167
- pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
1168
-
1169
- const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), router.location.search) : router.location.search; // Then the link/navigate function
1170
-
1171
- const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
1172
- : dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
1173
- : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
1174
- : {}; // Then post filters
1175
-
1176
- const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
1177
- const search = replaceEqualDeep(router.location.search, postFilteredSearch);
1178
- const searchStr = router.options.stringifySearch(search);
1179
- let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
1180
- hash = hash ? "#" + hash : '';
1181
- return {
1182
- pathname,
1183
- search,
1184
- searchStr,
1185
- state: router.location.state,
1186
- hash,
1187
- href: "" + pathname + searchStr + hash,
1188
- key: dest.key
1189
- };
1190
- },
1191
- commitLocation: (next, replace) => {
1192
- const id = '' + Date.now() + Math.random();
1193
- if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
1194
- let nextAction = 'replace';
1195
-
1196
- if (!replace) {
1197
- nextAction = 'push';
1198
- }
1199
-
1200
- const isSameUrl = router.parseLocation(history.location).href === next.href;
1086
+ if (pathname.slice(-1) === '/') {
1087
+ pathname = pathname.substring(1);
1088
+ segments.push({
1089
+ type: 'pathname',
1090
+ value: '/'
1091
+ });
1092
+ }
1201
1093
 
1202
- if (isSameUrl && !next.key) {
1203
- nextAction = 'replace';
1204
- }
1094
+ return segments;
1095
+ }
1096
+ function interpolatePath(path, params, leaveWildcard) {
1097
+ const interpolatedPathSegments = parsePathname(path);
1098
+ return joinPaths(interpolatedPathSegments.map(segment => {
1099
+ if (segment.value === '*' && !leaveWildcard) {
1100
+ return '';
1101
+ }
1205
1102
 
1206
- if (nextAction === 'replace') {
1207
- history.replace({
1208
- pathname: next.pathname,
1209
- hash: next.hash,
1210
- search: next.searchStr
1211
- }, {
1212
- id
1213
- });
1214
- } else {
1215
- history.push({
1216
- pathname: next.pathname,
1217
- hash: next.hash,
1218
- search: next.searchStr
1219
- }, {
1220
- id
1221
- });
1222
- }
1103
+ if (segment.type === 'param') {
1104
+ var _segment$value$substr;
1223
1105
 
1224
- router.navigationPromise = new Promise(resolve => {
1225
- const previousNavigationResolve = router.resolveNavigation;
1106
+ return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
1107
+ }
1226
1108
 
1227
- router.resolveNavigation = () => {
1228
- previousNavigationResolve();
1229
- resolve();
1230
- };
1231
- });
1232
- return router.navigationPromise;
1233
- },
1234
- buildNext: opts => {
1235
- const next = router.buildLocation(opts);
1236
- const matches = router.matchRoutes(next.pathname);
1109
+ return segment.value;
1110
+ }));
1111
+ }
1112
+ function matchPathname(currentPathname, matchLocation) {
1113
+ const pathParams = matchByPath(currentPathname, matchLocation); // const searchMatched = matchBySearch(currentLocation.search, matchLocation)
1237
1114
 
1238
- const __preSearchFilters = matches.map(match => {
1239
- var _match$options$preSea;
1115
+ if (matchLocation.to && !pathParams) {
1116
+ return;
1117
+ } // if (matchLocation.search && !searchMatched) {
1118
+ // return
1119
+ // }
1240
1120
 
1241
- return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
1242
- }).flat().filter(Boolean);
1243
1121
 
1244
- const __postSearchFilters = matches.map(match => {
1245
- var _match$options$postSe;
1122
+ return pathParams != null ? pathParams : {};
1123
+ }
1124
+ function matchByPath(from, matchLocation) {
1125
+ var _matchLocation$to;
1246
1126
 
1247
- return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
1248
- }).flat().filter(Boolean);
1127
+ const baseSegments = parsePathname(from);
1128
+ const routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
1129
+ const params = {};
1249
1130
 
1250
- return router.buildLocation(_extends$1({}, opts, {
1251
- __preSearchFilters,
1252
- __postSearchFilters
1253
- }));
1254
- },
1255
- cancelMatches: () => {
1256
- var _router$state$pending, _router$state$pending2;
1257
- [...router.state.matches, ...((_router$state$pending = (_router$state$pending2 = router.state.pending) == null ? void 0 : _router$state$pending2.matches) != null ? _router$state$pending : [])].forEach(match => {
1258
- match.cancel();
1259
- });
1260
- },
1261
- loadLocation: async next => {
1262
- const id = Math.random();
1263
- router.startedLoadingAt = id;
1131
+ let isMatch = (() => {
1132
+ for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
1133
+ const baseSegment = baseSegments[i];
1134
+ const routeSegment = routeSegments[i];
1135
+ const isLastRouteSegment = i === routeSegments.length - 1;
1136
+ const isLastBaseSegment = i === baseSegments.length - 1;
1264
1137
 
1265
- if (next) {
1266
- // Ingest the new location
1267
- router.location = next;
1268
- } // Clear out old actions
1138
+ if (routeSegment) {
1139
+ if (routeSegment.type === 'wildcard') {
1140
+ if (baseSegment != null && baseSegment.value) {
1141
+ params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
1142
+ return true;
1143
+ }
1269
1144
 
1145
+ return false;
1146
+ }
1270
1147
 
1271
- router.removeActionQueue.forEach(_ref => {
1272
- let {
1273
- action,
1274
- actionState
1275
- } = _ref;
1148
+ if (routeSegment.type === 'pathname') {
1149
+ if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
1150
+ return true;
1151
+ }
1276
1152
 
1277
- if (router.state.currentAction === actionState) {
1278
- router.state.currentAction = undefined;
1153
+ if (baseSegment) {
1154
+ if (matchLocation.caseSensitive) {
1155
+ if (routeSegment.value !== baseSegment.value) {
1156
+ return false;
1157
+ }
1158
+ } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
1159
+ return false;
1160
+ }
1161
+ }
1279
1162
  }
1280
1163
 
1281
- if (action.current === actionState) {
1282
- action.current = undefined;
1164
+ if (!baseSegment) {
1165
+ return false;
1283
1166
  }
1284
- });
1285
- router.removeActionQueue = []; // Cancel any pending matches
1286
1167
 
1287
- router.cancelMatches(); // Match the routes
1168
+ if (routeSegment.type === 'param') {
1169
+ if ((baseSegment == null ? void 0 : baseSegment.value) === '/') {
1170
+ return false;
1171
+ }
1288
1172
 
1289
- const unloadedMatches = router.matchRoutes(location.pathname, {
1290
- strictParseParams: true
1291
- });
1292
- router.state = _extends$1({}, router.state, {
1293
- pending: {
1294
- matches: unloadedMatches,
1295
- location: router.location
1173
+ if (!baseSegment.value.startsWith(':')) {
1174
+ params[routeSegment.value.substring(1)] = baseSegment.value;
1175
+ }
1296
1176
  }
1297
- });
1298
- router.notify(); // Load the matches
1299
-
1300
- const matches = await router.loadMatches(unloadedMatches, {
1301
- withPending: true
1302
- });
1177
+ }
1303
1178
 
1304
- if (router.startedLoadingAt !== id) {
1305
- // Ignore side-effects of match loading
1306
- return router.navigationPromise;
1179
+ if (isLastRouteSegment && !isLastBaseSegment) {
1180
+ return !!matchLocation.fuzzy;
1307
1181
  }
1182
+ }
1308
1183
 
1309
- const previousMatches = router.state.matches;
1310
- previousMatches.filter(d => {
1311
- return !matches.find(dd => dd.matchId === d.matchId);
1312
- }).forEach(d => {
1313
- d.__.onExit == null ? void 0 : d.__.onExit({
1314
- params: d.params,
1315
- search: d.routeSearch
1316
- });
1317
- });
1318
- previousMatches.filter(d => {
1319
- return matches.find(dd => dd.matchId === d.matchId);
1320
- }).forEach(d => {
1321
- d.options.onTransition == null ? void 0 : d.options.onTransition({
1322
- params: d.params,
1323
- search: d.routeSearch
1324
- });
1325
- });
1326
- matches.filter(d => {
1327
- return !previousMatches.find(dd => dd.matchId === d.matchId);
1328
- }).forEach(d => {
1329
- d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1330
- params: d.params,
1331
- search: d.search
1332
- });
1333
- });
1334
- router.state = _extends$1({}, router.state, {
1335
- location: router.location,
1336
- matches,
1337
- pending: undefined
1338
- });
1184
+ return true;
1185
+ })();
1339
1186
 
1340
- if (matches.some(d => d.status === 'loading')) {
1341
- router.notify();
1342
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
1343
- }
1187
+ return isMatch ? params : undefined;
1188
+ }
1344
1189
 
1345
- if (router.startedLoadingAt !== id) {
1346
- // Ignore side-effects of match loading
1347
- return;
1348
- }
1190
+ // @ts-nocheck
1191
+ // 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.
1192
+ function encode(obj, pfx) {
1193
+ var k,
1194
+ i,
1195
+ tmp,
1196
+ str = '';
1349
1197
 
1350
- router.notify();
1351
- router.resolveNavigation();
1352
- },
1353
- cleanPreloadCache: () => {
1354
- const now = Date.now();
1355
- Object.keys(router.preloadCache).forEach(matchId => {
1356
- const entry = router.preloadCache[matchId]; // Don't remove loading matches
1198
+ for (k in obj) {
1199
+ if ((tmp = obj[k]) !== void 0) {
1200
+ if (Array.isArray(tmp)) {
1201
+ for (i = 0; i < tmp.length; i++) {
1202
+ str && (str += '&');
1203
+ str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
1204
+ }
1205
+ } else {
1206
+ str && (str += '&');
1207
+ str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
1208
+ }
1209
+ }
1210
+ }
1357
1211
 
1358
- if (entry.match.status === 'loading') {
1359
- return;
1360
- } // Do not remove successful matches that are still valid
1212
+ return (pfx || '') + str;
1213
+ }
1361
1214
 
1215
+ function toValue(mix) {
1216
+ if (!mix) return '';
1217
+ var str = decodeURIComponent(mix);
1218
+ if (str === 'false') return false;
1219
+ if (str === 'true') return true;
1220
+ return +str * 0 === 0 ? +str : str;
1221
+ }
1362
1222
 
1363
- if (entry.match.updatedAt && entry.match.updatedAt + entry.maxAge > now) {
1364
- return;
1365
- } // Everything else gets removed
1223
+ function decode(str) {
1224
+ var tmp,
1225
+ k,
1226
+ out = {},
1227
+ arr = str.split('&');
1366
1228
 
1229
+ while (tmp = arr.shift()) {
1230
+ tmp = tmp.split('=');
1231
+ k = tmp.shift();
1367
1232
 
1368
- delete router.preloadCache[matchId];
1369
- });
1370
- },
1371
- loadRoute: async function loadRoute(navigateOpts, loaderOpts) {
1372
- if (navigateOpts === void 0) {
1373
- navigateOpts = router.location;
1374
- }
1233
+ if (out[k] !== void 0) {
1234
+ out[k] = [].concat(out[k], toValue(tmp.shift()));
1235
+ } else {
1236
+ out[k] = toValue(tmp.shift());
1237
+ }
1238
+ }
1375
1239
 
1376
- const next = router.buildNext(navigateOpts);
1377
- const matches = router.matchRoutes(next.pathname, {
1378
- strictParseParams: true
1379
- });
1380
- await router.loadMatches(matches, {
1381
- preload: true,
1382
- maxAge: loaderOpts.maxAge
1383
- });
1384
- return matches;
1385
- },
1386
- matchRoutes: (pathname, opts) => {
1387
- var _router$state$pending3, _router$state$pending4;
1240
+ return out;
1241
+ }
1388
1242
 
1389
- router.cleanPreloadCache();
1390
- const matches = [];
1243
+ function _extends() {
1244
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
1245
+ for (var i = 1; i < arguments.length; i++) {
1246
+ var source = arguments[i];
1391
1247
 
1392
- if (!router.routeTree) {
1393
- return matches;
1248
+ for (var key in source) {
1249
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1250
+ target[key] = source[key];
1251
+ }
1394
1252
  }
1253
+ }
1395
1254
 
1396
- const existingMatches = [...router.state.matches, ...((_router$state$pending3 = (_router$state$pending4 = router.state.pending) == null ? void 0 : _router$state$pending4.matches) != null ? _router$state$pending3 : [])];
1255
+ return target;
1256
+ };
1257
+ return _extends.apply(this, arguments);
1258
+ }
1397
1259
 
1398
- const recurse = async routes => {
1399
- var _parentMatch$params, _router$options$filte, _foundRoute$childRout;
1260
+ function createRoute(routeConfig, options, parent, router) {
1261
+ const {
1262
+ id,
1263
+ routeId,
1264
+ path: routePath,
1265
+ fullPath
1266
+ } = routeConfig;
1400
1267
 
1401
- const parentMatch = last(matches);
1402
- let params = (_parentMatch$params = parentMatch == null ? void 0 : parentMatch.params) != null ? _parentMatch$params : {};
1403
- const filteredRoutes = (_router$options$filte = router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) != null ? _router$options$filte : routes;
1404
- let foundRoutes = [];
1268
+ const action = router.state.actions[id] || (() => {
1269
+ router.state.actions[id] = {
1270
+ pending: [],
1271
+ submit: async (submission, actionOpts) => {
1272
+ var _actionOpts$invalidat;
1405
1273
 
1406
- const findMatchInRoutes = (parentRoutes, routes) => {
1407
- routes.some(route => {
1408
- var _route$childRoutes, _route$childRoutes2, _route$options$caseSe;
1274
+ if (!route) {
1275
+ return;
1276
+ }
1409
1277
 
1410
- if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
1411
- return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
1412
- }
1278
+ const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
1279
+ const actionState = {
1280
+ submittedAt: Date.now(),
1281
+ status: 'pending',
1282
+ submission
1283
+ };
1284
+ action.current = actionState;
1285
+ action.latest = actionState;
1286
+ action.pending.push(actionState);
1287
+ router.state = _extends({}, router.state, {
1288
+ currentAction: actionState,
1289
+ latestAction: actionState
1290
+ });
1291
+ router.notify();
1413
1292
 
1414
- const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length);
1415
- const matchParams = matchPathname(pathname, {
1416
- to: route.fullPath,
1417
- fuzzy,
1418
- caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
1419
- });
1293
+ try {
1294
+ const res = await (route.options.action == null ? void 0 : route.options.action(submission));
1295
+ actionState.data = res;
1420
1296
 
1421
- if (matchParams) {
1422
- let parsedParams;
1297
+ if (invalidate) {
1298
+ router.invalidateRoute({
1299
+ to: '.',
1300
+ fromCurrent: true
1301
+ });
1302
+ await router.reload();
1303
+ }
1423
1304
 
1424
- try {
1425
- var _route$options$parseP;
1305
+ actionState.status = 'success';
1306
+ return res;
1307
+ } catch (err) {
1308
+ console.error(err);
1309
+ actionState.error = err;
1310
+ actionState.status = 'error';
1311
+ } finally {
1312
+ action.pending = action.pending.filter(d => d !== actionState);
1313
+ router.removeActionQueue.push({
1314
+ action,
1315
+ actionState
1316
+ });
1317
+ router.notify();
1318
+ }
1319
+ }
1320
+ };
1321
+ return router.state.actions[id];
1322
+ })();
1426
1323
 
1427
- parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
1428
- } catch (err) {
1429
- if (opts != null && opts.strictParseParams) {
1430
- throw err;
1431
- }
1432
- }
1324
+ let route = {
1325
+ routeId: id,
1326
+ routeRouteId: routeId,
1327
+ routePath,
1328
+ fullPath,
1329
+ options,
1330
+ router,
1331
+ childRoutes: undefined,
1332
+ parentRoute: parent,
1333
+ action,
1334
+ buildLink: options => {
1335
+ return router.buildLink(_extends({}, options, {
1336
+ from: fullPath
1337
+ }));
1338
+ },
1339
+ navigate: options => {
1340
+ return router.navigate(_extends({}, options, {
1341
+ from: fullPath
1342
+ }));
1343
+ },
1344
+ matchRoute: (matchLocation, opts) => {
1345
+ return router.matchRoute(_extends({}, matchLocation, {
1346
+ from: fullPath
1347
+ }), opts);
1348
+ }
1349
+ };
1350
+ router.options.createRoute == null ? void 0 : router.options.createRoute({
1351
+ router,
1352
+ route
1353
+ });
1354
+ return route;
1355
+ }
1356
+ function cascadeLoaderData(matches) {
1357
+ matches.forEach((match, index) => {
1358
+ const parent = matches[index - 1];
1433
1359
 
1434
- params = _extends$1({}, params, parsedParams);
1435
- }
1360
+ if (parent) {
1361
+ match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
1362
+ }
1363
+ });
1364
+ }
1436
1365
 
1437
- if (!!matchParams) {
1438
- foundRoutes = [...parentRoutes, route];
1439
- }
1366
+ const rootRouteId = '__root__';
1367
+ const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
1368
+ if (options === void 0) {
1369
+ options = {};
1370
+ }
1440
1371
 
1441
- return !!foundRoutes.length;
1442
- });
1443
- return !!foundRoutes.length;
1444
- };
1372
+ if (isRoot === void 0) {
1373
+ isRoot = true;
1374
+ }
1445
1375
 
1446
- findMatchInRoutes([], filteredRoutes);
1376
+ if (isRoot) {
1377
+ options.path = rootRouteId;
1378
+ } // Strip the root from parentIds
1447
1379
 
1448
- if (!foundRoutes.length) {
1449
- return;
1450
- }
1451
1380
 
1452
- foundRoutes.forEach(foundRoute => {
1453
- var _router$preloadCache$;
1381
+ if (parentId === rootRouteId) {
1382
+ parentId = '';
1383
+ }
1454
1384
 
1455
- const interpolatedPath = interpolatePath(foundRoute.routePath, params);
1456
- const matchId = interpolatePath(foundRoute.routeId, params, true);
1457
- const match = existingMatches.find(d => d.matchId === matchId) || ((_router$preloadCache$ = router.preloadCache[matchId]) == null ? void 0 : _router$preloadCache$.match) || createRouteMatch(router, foundRoute, {
1458
- matchId,
1459
- params,
1460
- pathname: joinPaths([pathname, interpolatedPath])
1461
- });
1462
- matches.push(match);
1463
- });
1464
- const foundRoute = last(foundRoutes);
1385
+ let path = isRoot ? rootRouteId : options.path; // If the path is anything other than an index path, trim it up
1465
1386
 
1466
- if ((_foundRoute$childRout = foundRoute.childRoutes) != null && _foundRoute$childRout.length) {
1467
- recurse(foundRoute.childRoutes);
1468
- }
1469
- };
1387
+ if (path && path !== '/') {
1388
+ path = trimPath(path);
1389
+ }
1470
1390
 
1471
- recurse([router.routeTree]);
1472
- cascadeLoaderData(matches);
1473
- return matches;
1474
- },
1475
- loadMatches: async (resolvedMatches, loaderOpts) => {
1476
- const matchPromises = resolvedMatches.map(async match => {
1477
- // Validate the match (loads search params etc)
1478
- match.__.validate(); // If this is a preload, add it to the preload cache
1391
+ const routeId = path || options.id;
1392
+ let id = joinPaths([parentId, routeId]);
1479
1393
 
1394
+ if (path === rootRouteId) {
1395
+ path = '/';
1396
+ }
1480
1397
 
1481
- if (loaderOpts != null && loaderOpts.preload) {
1482
- router.preloadCache[match.matchId] = {
1483
- maxAge: loaderOpts == null ? void 0 : loaderOpts.maxAge,
1484
- match
1485
- };
1486
- } // If the match is invalid, errored or idle, trigger it to load
1398
+ if (id !== rootRouteId) {
1399
+ id = joinPaths(['/', id]);
1400
+ }
1487
1401
 
1402
+ const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parentPath, path]));
1403
+ return {
1404
+ id: id,
1405
+ routeId: routeId,
1406
+ path: path,
1407
+ fullPath: fullPath,
1408
+ options: options,
1409
+ children,
1410
+ createChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)), false, parentId, parentPath),
1411
+ addChildren: children => createRouteConfig(options, children, false, parentId, parentPath),
1412
+ createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)
1413
+ };
1414
+ };
1488
1415
 
1489
- if (match.status === 'success' && match.isInvalid || match.status === 'error' || match.status === 'idle') {
1490
- match.load();
1491
- } // If requested, start the pending timers
1416
+ const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1417
+ function createRouteMatch(router, route, opts) {
1418
+ const routeMatch = _extends({}, route, opts, {
1419
+ router,
1420
+ routeSearch: {},
1421
+ search: {},
1422
+ childMatches: [],
1423
+ status: 'idle',
1424
+ routeLoaderData: {},
1425
+ loaderData: {},
1426
+ isPending: false,
1427
+ isFetching: false,
1428
+ isInvalid: false,
1429
+ getIsInvalid: () => {
1430
+ var _ref, _routeMatch$options$l;
1492
1431
 
1432
+ const now = Date.now();
1433
+ const maxAge = (_ref = (_routeMatch$options$l = routeMatch.options.loaderMaxAge) != null ? _routeMatch$options$l : router.options.defaultLoaderMaxAge) != null ? _ref : 0;
1434
+ return routeMatch.isInvalid || routeMatch.updatedAt + maxAge < now;
1435
+ },
1436
+ __: {
1437
+ abortController: new AbortController(),
1438
+ latestId: '',
1439
+ resolve: () => {},
1440
+ notify: () => {
1441
+ routeMatch.__.resolve();
1493
1442
 
1494
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
1495
- // This might be completion, error, or a pending state
1443
+ routeMatch.router.notify();
1444
+ },
1445
+ startPending: () => {
1446
+ var _routeMatch$options$p, _routeMatch$options$p2;
1496
1447
 
1497
- await match.__.loadPromise;
1498
- });
1499
- router.notify();
1500
- await Promise.all(matchPromises);
1501
- return resolvedMatches;
1502
- },
1503
- invalidateRoute: opts => {
1504
- var _router$state$pending5, _router$state$pending6;
1448
+ const pendingMs = (_routeMatch$options$p = routeMatch.options.pendingMs) != null ? _routeMatch$options$p : router.options.defaultPendingMs;
1449
+ const pendingMinMs = (_routeMatch$options$p2 = routeMatch.options.pendingMinMs) != null ? _routeMatch$options$p2 : router.options.defaultPendingMinMs;
1505
1450
 
1506
- const next = router.buildNext(opts);
1507
- const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
1508
- [...router.state.matches, ...((_router$state$pending5 = (_router$state$pending6 = router.state.pending) == null ? void 0 : _router$state$pending6.matches) != null ? _router$state$pending5 : [])].forEach(match => {
1509
- if (unloadedMatchIds.includes(match.matchId)) {
1510
- match.invalidate();
1451
+ if (routeMatch.__.pendingTimeout || routeMatch.status !== 'loading' || typeof pendingMs === 'undefined') {
1452
+ return;
1511
1453
  }
1512
- });
1513
- },
1514
- reload: () => router._navigate({
1515
- fromCurrent: true,
1516
- replace: true,
1517
- search: true
1518
- }),
1519
- resolvePath: (from, path) => {
1520
- return _resolvePath(router.basepath, from, cleanPath(path));
1521
- },
1522
- matchRoute: (location, opts) => {
1523
- var _location$from;
1524
-
1525
- // const location = router.buildNext(opts)
1526
- location = _extends$1({}, location, {
1527
- to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
1528
- });
1529
- const next = router.buildNext(location);
1530
1454
 
1531
- if (opts != null && opts.pending) {
1532
- var _router$state$pending7;
1455
+ routeMatch.__.pendingTimeout = setTimeout(() => {
1456
+ routeMatch.isPending = true;
1533
1457
 
1534
- if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
1535
- return false;
1536
- }
1458
+ routeMatch.__.resolve();
1537
1459
 
1538
- return !!matchPathname(router.state.pending.location.pathname, _extends$1({}, opts, {
1539
- to: next.pathname
1540
- }));
1541
- }
1460
+ if (typeof pendingMinMs !== 'undefined') {
1461
+ routeMatch.__.pendingMinPromise = new Promise(r => routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs));
1462
+ }
1463
+ }, pendingMs);
1464
+ },
1465
+ cancelPending: () => {
1466
+ routeMatch.isPending = false;
1467
+ clearTimeout(routeMatch.__.pendingTimeout);
1468
+ clearTimeout(routeMatch.__.pendingMinTimeout);
1469
+ delete routeMatch.__.pendingMinPromise;
1470
+ },
1471
+ // setParentMatch: (parentMatch?: RouteMatch) => {
1472
+ // routeMatch.parentMatch = parentMatch
1473
+ // },
1474
+ // addChildMatch: (childMatch: RouteMatch) => {
1475
+ // if (
1476
+ // routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
1477
+ // ) {
1478
+ // return
1479
+ // }
1480
+ // routeMatch.childMatches.push(childMatch)
1481
+ // },
1482
+ validate: () => {
1483
+ var _routeMatch$parentMat, _routeMatch$parentMat2;
1542
1484
 
1543
- return !!matchPathname(router.state.location.pathname, _extends$1({}, opts, {
1544
- to: next.pathname
1545
- }));
1546
- },
1547
- _navigate: location => {
1548
- const next = router.buildNext(location);
1549
- return router.commitLocation(next, location.replace);
1550
- },
1551
- navigate: async _ref2 => {
1552
- let {
1553
- from,
1554
- to = '.',
1555
- search,
1556
- hash,
1557
- replace,
1558
- params
1559
- } = _ref2;
1560
- // If this link simply reloads the current route,
1561
- // make sure it has a new key so it will trigger a data refresh
1562
- // If this `to` is a valid external URL, return
1563
- // null for LinkUtils
1564
- const toString = String(to);
1565
- const fromString = String(from);
1566
- let isExternal;
1485
+ // Validate the search params and stabilize them
1486
+ const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
1567
1487
 
1568
- try {
1569
- new URL("" + toString);
1570
- isExternal = true;
1571
- } catch (e) {}
1488
+ try {
1489
+ const prevSearch = routeMatch.routeSearch;
1490
+ const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
1491
+ let nextSearch = replaceEqualDeep(prevSearch, validator == null ? void 0 : validator(parentSearch)); // Invalidate route matches when search param stability changes
1572
1492
 
1573
- invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
1574
- return router._navigate({
1575
- from: fromString,
1576
- to: toString,
1577
- search,
1578
- hash,
1579
- replace,
1580
- params
1581
- });
1582
- },
1583
- buildLink: _ref3 => {
1584
- var _preload, _ref4, _ref5;
1493
+ if (prevSearch !== nextSearch) {
1494
+ routeMatch.isInvalid = true;
1495
+ }
1585
1496
 
1586
- let {
1587
- from,
1588
- to = '.',
1589
- search,
1590
- params,
1591
- hash,
1592
- target,
1593
- replace,
1594
- activeOptions,
1595
- preload,
1596
- preloadMaxAge: userPreloadMaxAge,
1597
- preloadDelay: userPreloadDelay,
1598
- disabled
1599
- } = _ref3;
1497
+ routeMatch.routeSearch = nextSearch;
1498
+ routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
1499
+ } catch (err) {
1500
+ console.error(err);
1501
+ const error = new Error('Invalid search params found', {
1502
+ cause: err
1503
+ });
1504
+ error.code = 'INVALID_SEARCH_PARAMS';
1505
+ routeMatch.status = 'error';
1506
+ routeMatch.error = error; // Do not proceed with loading the route
1600
1507
 
1601
- // If this link simply reloads the current route,
1602
- // make sure it has a new key so it will trigger a data refresh
1603
- // If this `to` is a valid external URL, return
1604
- // null for LinkUtils
1605
- try {
1606
- new URL("" + to);
1607
- return {
1608
- type: 'external',
1609
- href: to
1610
- };
1611
- } catch (e) {}
1508
+ return;
1509
+ }
1510
+ }
1511
+ },
1512
+ cancel: () => {
1513
+ var _routeMatch$__$abortC;
1612
1514
 
1613
- const nextOpts = {
1614
- from,
1615
- to,
1616
- search,
1617
- params,
1618
- hash,
1619
- replace
1620
- };
1621
- const next = router.buildNext(nextOpts);
1622
- preload = (_preload = preload) != null ? _preload : router.options.defaultLinkPreload;
1623
- const preloadMaxAge = (_ref4 = userPreloadMaxAge != null ? userPreloadMaxAge : router.options.defaultLinkPreloadMaxAge) != null ? _ref4 : 2000;
1624
- const preloadDelay = (_ref5 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultLinkPreloadDelay) != null ? _ref5 : 50; // Compare path/hash for matches
1515
+ (_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
1625
1516
 
1626
- const pathIsEqual = router.state.location.pathname === next.pathname;
1627
- const currentPathSplit = router.state.location.pathname.split('/');
1628
- const nextPathSplit = next.pathname.split('/');
1629
- const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
1630
- const hashIsEqual = router.state.location.hash === next.hash; // Combine the matches based on user options
1517
+ routeMatch.__.cancelPending();
1518
+ },
1519
+ invalidate: () => {
1520
+ routeMatch.isInvalid = true;
1521
+ },
1522
+ hasLoaders: () => {
1523
+ return !!(route.options.loader || route.options.import || elementTypes.some(d => typeof route.options[d] === 'function'));
1524
+ },
1525
+ load: async () => {
1526
+ const id = '' + Date.now() + Math.random();
1527
+ routeMatch.__.latestId = id; // If the match was in an error state, set it
1528
+ // to a loading state again. Otherwise, keep it
1529
+ // as loading or resolved
1631
1530
 
1632
- const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
1633
- const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
1531
+ if (routeMatch.status === 'idle') {
1532
+ routeMatch.status = 'loading';
1533
+ } // We started loading the route, so it's no longer invalid
1634
1534
 
1635
- const isActive = pathTest && hashTest; // The click handler
1636
1535
 
1637
- const handleClick = e => {
1638
- if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
1639
- e.preventDefault();
1536
+ routeMatch.isInvalid = false;
1537
+ routeMatch.__.loadPromise = new Promise(async resolve => {
1538
+ // We are now fetching, even if it's in the background of a
1539
+ // resolved state
1540
+ routeMatch.isFetching = true;
1541
+ routeMatch.__.resolve = resolve;
1640
1542
 
1641
- if (pathIsEqual && !search && !hash) {
1642
- router.invalidateRoute(nextOpts);
1643
- } // All is well? Navigate!)
1543
+ const loaderPromise = (async () => {
1544
+ const importer = routeMatch.options.import; // First, run any importers
1644
1545
 
1546
+ if (importer) {
1547
+ routeMatch.__.importPromise = importer({
1548
+ params: routeMatch.params // search: routeMatch.search,
1645
1549
 
1646
- router._navigate(nextOpts);
1647
- }
1648
- }; // The click handler
1550
+ }).then(imported => {
1551
+ routeMatch.__ = _extends({}, routeMatch.__, imported);
1552
+ });
1553
+ } // Wait for the importer to finish before
1554
+ // attempting to load elements and data
1649
1555
 
1650
1556
 
1651
- const handleFocus = e => {
1652
- if (preload && preloadMaxAge > 0) {
1653
- router.loadRoute(nextOpts, {
1654
- maxAge: preloadMaxAge
1655
- });
1656
- }
1657
- };
1557
+ await routeMatch.__.importPromise; // Next, load the elements and data in parallel
1658
1558
 
1659
- const handleEnter = e => {
1660
- const target = e.target || {};
1559
+ routeMatch.__.elementsPromise = (async () => {
1560
+ // then run all element and data loaders in parallel
1561
+ // For each element type, potentially load it asynchronously
1562
+ await Promise.all(elementTypes.map(async type => {
1563
+ const routeElement = routeMatch.options[type];
1661
1564
 
1662
- if (preload && preloadMaxAge > 0) {
1663
- if (target.preloadTimeout) {
1664
- return;
1665
- }
1565
+ if (routeMatch.__[type]) {
1566
+ return;
1567
+ }
1666
1568
 
1667
- target.preloadTimeout = setTimeout(() => {
1668
- target.preloadTimeout = null;
1669
- router.loadRoute(nextOpts, {
1670
- maxAge: preloadMaxAge
1671
- });
1672
- }, preloadDelay);
1673
- }
1674
- };
1569
+ if (typeof routeElement === 'function') {
1570
+ const res = await routeElement(routeMatch);
1571
+ routeMatch.__[type] = res;
1572
+ } else {
1573
+ routeMatch.__[type] = routeMatch.options[type];
1574
+ }
1575
+ }));
1576
+ })();
1675
1577
 
1676
- const handleLeave = e => {
1677
- const target = e.target || {};
1578
+ routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1579
+ try {
1580
+ if (routeMatch.options.loader) {
1581
+ const data = await routeMatch.options.loader({
1582
+ params: routeMatch.params,
1583
+ search: routeMatch.routeSearch,
1584
+ signal: routeMatch.__.abortController.signal
1585
+ });
1586
+
1587
+ if (id !== routeMatch.__.latestId) {
1588
+ return routeMatch.__.loaderPromise;
1589
+ }
1678
1590
 
1679
- if (target.preloadTimeout) {
1680
- clearTimeout(target.preloadTimeout);
1681
- target.preloadTimeout = null;
1682
- }
1683
- };
1591
+ routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1592
+ }
1684
1593
 
1685
- return {
1686
- type: 'internal',
1687
- next,
1688
- handleFocus,
1689
- handleClick,
1690
- handleEnter,
1691
- handleLeave,
1692
- isActive,
1693
- disabled
1694
- };
1695
- },
1696
- __experimental__createSnapshot: () => {
1697
- return _extends$1({}, router.state, {
1698
- matches: router.state.matches.map(_ref6 => {
1699
- let {
1700
- routeLoaderData: loaderData,
1701
- matchId
1702
- } = _ref6;
1703
- return {
1704
- matchId,
1705
- loaderData
1706
- };
1707
- })
1708
- });
1709
- }
1710
- };
1711
- router.location = router.parseLocation(history.location); // router.state.location = __experimental__snapshot?.location ?? router.location
1594
+ routeMatch.error = undefined;
1595
+ routeMatch.status = 'success';
1596
+ routeMatch.updatedAt = Date.now();
1597
+ } catch (err) {
1598
+ if (id !== routeMatch.__.latestId) {
1599
+ return routeMatch.__.loaderPromise;
1600
+ }
1712
1601
 
1713
- router.state.location = router.location;
1714
- router.update(userOptions); // Allow frameworks to hook into the router creation
1602
+ {
1603
+ console.error(err);
1604
+ }
1715
1605
 
1716
- router.options.createRouter == null ? void 0 : router.options.createRouter(router); // router.mount()
1606
+ routeMatch.error = err;
1607
+ routeMatch.status = 'error';
1608
+ routeMatch.updatedAt = Date.now();
1609
+ }
1610
+ });
1717
1611
 
1718
- return router;
1719
- }
1720
- function createRoute(routeConfig, options, parent, router) {
1721
- // const id = (
1722
- // options.path === rootRouteId
1723
- // ? rootRouteId
1724
- // : joinPaths([
1725
- // parent!.id,
1726
- // `${options.path?.replace(/(.)\/$/, '$1')}`,
1727
- // ]).replace(new RegExp(`^${rootRouteId}`), '')
1728
- // ) as TRouteInfo['id']
1729
- const {
1730
- id,
1731
- routeId,
1732
- path: routePath,
1733
- fullPath
1734
- } = routeConfig;
1612
+ try {
1613
+ await Promise.all([routeMatch.__.elementsPromise, routeMatch.__.dataPromise]);
1735
1614
 
1736
- const action = router.state.actions[id] || (() => {
1737
- router.state.actions[id] = {
1738
- pending: [],
1739
- submit: async (submission, actionOpts) => {
1740
- var _actionOpts$invalidat;
1615
+ if (id !== routeMatch.__.latestId) {
1616
+ return routeMatch.__.loaderPromise;
1617
+ }
1741
1618
 
1742
- if (!route) {
1743
- return;
1744
- }
1619
+ if (routeMatch.__.pendingMinPromise) {
1620
+ await routeMatch.__.pendingMinPromise;
1621
+ delete routeMatch.__.pendingMinPromise;
1622
+ }
1623
+ } finally {
1624
+ if (id !== routeMatch.__.latestId) {
1625
+ return routeMatch.__.loaderPromise;
1626
+ }
1745
1627
 
1746
- const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
1747
- const actionState = {
1748
- submittedAt: Date.now(),
1749
- status: 'pending',
1750
- submission
1751
- };
1752
- action.current = actionState;
1753
- action.latest = actionState;
1754
- action.pending.push(actionState);
1755
- router.state = _extends$1({}, router.state, {
1756
- currentAction: actionState,
1757
- latestAction: actionState
1758
- });
1759
- router.notify();
1628
+ routeMatch.__.cancelPending();
1760
1629
 
1761
- try {
1762
- const res = await (route.options.action == null ? void 0 : route.options.action(submission));
1763
- actionState.data = res;
1630
+ routeMatch.isPending = false;
1631
+ routeMatch.isFetching = false;
1764
1632
 
1765
- if (invalidate) {
1766
- router.invalidateRoute({
1767
- to: '.',
1768
- fromCurrent: true
1769
- });
1770
- await router.reload();
1633
+ routeMatch.__.notify();
1771
1634
  }
1635
+ })();
1772
1636
 
1773
- actionState.status = 'success';
1774
- return res;
1775
- } catch (err) {
1776
- console.error(err);
1777
- actionState.error = err;
1778
- actionState.status = 'error';
1779
- } finally {
1780
- action.pending = action.pending.filter(d => d !== actionState);
1781
- router.removeActionQueue.push({
1782
- action,
1783
- actionState
1784
- });
1785
- router.notify();
1637
+ routeMatch.__.loaderPromise = loaderPromise;
1638
+ await loaderPromise;
1639
+
1640
+ if (id !== routeMatch.__.latestId) {
1641
+ return routeMatch.__.loaderPromise;
1786
1642
  }
1787
- }
1788
- };
1789
- return router.state.actions[id];
1790
- })();
1791
1643
 
1792
- let route = {
1793
- routeId: id,
1794
- routeRouteId: routeId,
1795
- routePath,
1796
- fullPath,
1797
- options,
1798
- router,
1799
- childRoutes: undefined,
1800
- parentRoute: parent,
1801
- action,
1802
- buildLink: options => {
1803
- return router.buildLink(_extends$1({}, options, {
1804
- from: fullPath
1805
- }));
1806
- },
1807
- navigate: options => {
1808
- return router.navigate(_extends$1({}, options, {
1809
- from: fullPath
1810
- }));
1811
- },
1812
- matchRoute: (matchLocation, opts) => {
1813
- return router.matchRoute(_extends$1({}, matchLocation, {
1814
- from: fullPath
1815
- }), opts);
1644
+ delete routeMatch.__.loaderPromise;
1645
+ });
1646
+ return await routeMatch.__.loadPromise;
1816
1647
  }
1817
- };
1818
- router.options.createRoute == null ? void 0 : router.options.createRoute({
1819
- router,
1820
- route
1821
1648
  });
1822
- return route;
1649
+
1650
+ if (!routeMatch.hasLoaders()) {
1651
+ routeMatch.status = 'success';
1652
+ }
1653
+
1654
+ return routeMatch;
1823
1655
  }
1824
- function createRouteMatch(router, route, opts) {
1825
- const routeMatch = _extends$1({}, route, opts, {
1826
- router,
1827
- routeSearch: {},
1828
- search: {},
1829
- childMatches: [],
1830
- status: 'idle',
1831
- routeLoaderData: {},
1832
- loaderData: {},
1833
- isPending: false,
1834
- isFetching: false,
1835
- isInvalid: false,
1836
- __: {
1837
- abortController: new AbortController(),
1838
- latestId: '',
1839
- resolve: () => {},
1840
- notify: () => {
1841
- routeMatch.__.resolve();
1842
1656
 
1843
- routeMatch.router.notify();
1844
- },
1845
- startPending: () => {
1846
- var _routeMatch$options$p, _routeMatch$options$p2;
1657
+ const defaultParseSearch = parseSearchWith(JSON.parse);
1658
+ const defaultStringifySearch = stringifySearchWith(JSON.stringify);
1659
+ function parseSearchWith(parser) {
1660
+ return searchStr => {
1661
+ if (searchStr.substring(0, 1) === '?') {
1662
+ searchStr = searchStr.substring(1);
1663
+ }
1847
1664
 
1848
- const pendingMs = (_routeMatch$options$p = routeMatch.options.pendingMs) != null ? _routeMatch$options$p : router.options.defaultPendingMs;
1849
- const pendingMinMs = (_routeMatch$options$p2 = routeMatch.options.pendingMinMs) != null ? _routeMatch$options$p2 : router.options.defaultPendingMinMs;
1665
+ let query = decode(searchStr); // Try to parse any query params that might be json
1850
1666
 
1851
- if (routeMatch.__.pendingTimeout || routeMatch.status !== 'loading' || typeof pendingMs === 'undefined') {
1852
- return;
1667
+ for (let key in query) {
1668
+ const value = query[key];
1669
+
1670
+ if (typeof value === 'string') {
1671
+ try {
1672
+ query[key] = parser(value);
1673
+ } catch (err) {//
1853
1674
  }
1675
+ }
1676
+ }
1854
1677
 
1855
- routeMatch.__.pendingTimeout = setTimeout(() => {
1856
- routeMatch.isPending = true;
1678
+ return query;
1679
+ };
1680
+ }
1681
+ function stringifySearchWith(stringify) {
1682
+ return search => {
1683
+ search = _extends({}, search);
1857
1684
 
1858
- routeMatch.__.resolve();
1685
+ if (search) {
1686
+ Object.keys(search).forEach(key => {
1687
+ const val = search[key];
1859
1688
 
1860
- if (typeof pendingMinMs !== 'undefined') {
1861
- routeMatch.__.pendingMinPromise = new Promise(r => routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs));
1689
+ if (typeof val === 'undefined' || val === undefined) {
1690
+ delete search[key];
1691
+ } else if (val && typeof val === 'object' && val !== null) {
1692
+ try {
1693
+ search[key] = stringify(val);
1694
+ } catch (err) {// silent
1862
1695
  }
1863
- }, pendingMs);
1864
- },
1865
- cancelPending: () => {
1866
- routeMatch.isPending = false;
1867
- clearTimeout(routeMatch.__.pendingTimeout);
1868
- clearTimeout(routeMatch.__.pendingMinTimeout);
1869
- delete routeMatch.__.pendingMinPromise;
1870
- },
1871
- // setParentMatch: (parentMatch?: RouteMatch) => {
1872
- // routeMatch.parentMatch = parentMatch
1873
- // },
1874
- // addChildMatch: (childMatch: RouteMatch) => {
1875
- // if (
1876
- // routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
1877
- // ) {
1878
- // return
1879
- // }
1880
- // routeMatch.childMatches.push(childMatch)
1881
- // },
1882
- validate: () => {
1883
- var _routeMatch$parentMat, _routeMatch$parentMat2;
1696
+ }
1697
+ });
1698
+ }
1884
1699
 
1885
- // Validate the search params and stabilize them
1886
- const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
1700
+ const searchStr = encode(search).toString();
1701
+ return searchStr ? "?" + searchStr : '';
1702
+ };
1703
+ }
1887
1704
 
1888
- try {
1889
- const prevSearch = routeMatch.routeSearch;
1890
- let nextSearch = replaceEqualDeep(prevSearch, routeMatch.options.validateSearch == null ? void 0 : routeMatch.options.validateSearch(parentSearch)); // Invalidate route matches when search param stability changes
1705
+ var _window$document;
1706
+ // Detect if we're in the DOM
1707
+ const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
1891
1708
 
1892
- if (prevSearch !== nextSearch) {
1893
- routeMatch.isInvalid = true;
1894
- }
1709
+ const createDefaultHistory = () => !isServer ? createBrowserHistory() : createMemoryHistory();
1895
1710
 
1896
- routeMatch.routeSearch = nextSearch;
1897
- routeMatch.search = replaceEqualDeep(parentSearch, _extends$1({}, parentSearch, nextSearch));
1898
- } catch (err) {
1899
- console.error(err);
1900
- const error = new Error('Invalid search params found', {
1901
- cause: err
1902
- });
1903
- error.code = 'INVALID_SEARCH_PARAMS';
1904
- routeMatch.status = 'error';
1905
- routeMatch.error = error; // Do not proceed with loading the route
1711
+ function createRouter(userOptions) {
1712
+ var _userOptions$stringif, _userOptions$parseSea;
1906
1713
 
1907
- return;
1908
- }
1909
- }
1714
+ const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
1715
+
1716
+ const originalOptions = _extends({
1717
+ defaultLoaderGcMaxAge: 5 * 60 * 1000,
1718
+ defaultLoaderMaxAge: 0,
1719
+ defaultLinkPreloadDelay: 50
1720
+ }, userOptions, {
1721
+ stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
1722
+ parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
1723
+ });
1724
+
1725
+ let router = {
1726
+ options: originalOptions,
1727
+ listeners: [],
1728
+ removeActionQueue: [],
1729
+ // Resolved after construction
1730
+ basepath: '',
1731
+ routeTree: undefined,
1732
+ routesById: {},
1733
+ location: undefined,
1734
+ allRouteInfo: undefined,
1735
+ //
1736
+ navigationPromise: Promise.resolve(),
1737
+ resolveNavigation: () => {},
1738
+ matchCache: {},
1739
+ state: {
1740
+ status: 'idle',
1741
+ location: null,
1742
+ matches: [],
1743
+ actions: {},
1744
+ loaderData: {},
1745
+ lastUpdated: Date.now(),
1746
+ isFetching: false,
1747
+ isPreloading: false
1910
1748
  },
1911
- cancel: () => {
1912
- var _routeMatch$__$abortC;
1749
+ startedLoadingAt: Date.now(),
1750
+ subscribe: listener => {
1751
+ router.listeners.push(listener);
1752
+ return () => {
1753
+ router.listeners = router.listeners.filter(x => x !== listener);
1754
+ };
1755
+ },
1756
+ getRoute: id => {
1757
+ return router.routesById[id];
1758
+ },
1759
+ notify: () => {
1760
+ router.state = _extends({}, router.state, {
1761
+ isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
1762
+ isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
1763
+ });
1764
+ cascadeLoaderData(router.state.matches);
1765
+ router.listeners.forEach(listener => listener());
1766
+ },
1767
+ mount: () => {
1768
+ const next = router.buildLocation({
1769
+ to: '.',
1770
+ search: true,
1771
+ hash: true
1772
+ }); // If the current location isn't updated, trigger a navigation
1773
+ // to the current location. Otherwise, load the current location.
1913
1774
 
1914
- (_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
1775
+ if (next.href !== router.location.href) {
1776
+ router.commitLocation(next, true);
1777
+ } else {
1778
+ router.loadLocation();
1779
+ }
1915
1780
 
1916
- routeMatch.__.cancelPending();
1781
+ const unsub = history.listen(event => {
1782
+ router.loadLocation(router.parseLocation(event.location, router.location));
1783
+ }); // addEventListener does not exist in React Native, but window does
1784
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1785
+
1786
+ if (!isServer && window.addEventListener) {
1787
+ // Listen to visibillitychange and focus
1788
+ window.addEventListener('visibilitychange', router.onFocus, false);
1789
+ window.addEventListener('focus', router.onFocus, false);
1790
+ }
1791
+
1792
+ return () => {
1793
+ unsub(); // Be sure to unsubscribe if a new handler is set
1794
+
1795
+ window.removeEventListener('visibilitychange', router.onFocus);
1796
+ window.removeEventListener('focus', router.onFocus);
1797
+ };
1917
1798
  },
1918
- invalidate: () => {
1919
- routeMatch.isInvalid = true;
1799
+ onFocus: () => {
1800
+ router.loadLocation();
1920
1801
  },
1921
- load: async () => {
1922
- const id = '' + Date.now() + Math.random();
1923
- routeMatch.__.latestId = id; // If the match was in an error state, set it
1924
- // to a loading state again. Otherwise, keep it
1925
- // as loading or resolved
1802
+ update: opts => {
1803
+ Object.assign(router.options, opts);
1804
+ const {
1805
+ basepath,
1806
+ routeConfig
1807
+ } = router.options;
1808
+ router.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
1926
1809
 
1927
- if (routeMatch.status === 'error' || routeMatch.status === 'idle') {
1928
- routeMatch.status = 'loading';
1929
- } // We started loading the route, so it's no longer invalid
1810
+ if (routeConfig) {
1811
+ router.routesById = {};
1812
+ router.routeTree = router.buildRouteTree(routeConfig);
1813
+ }
1814
+
1815
+ return router;
1816
+ },
1817
+ buildRouteTree: rootRouteConfig => {
1818
+ const recurseRoutes = (routeConfigs, parent) => {
1819
+ return routeConfigs.map(routeConfig => {
1820
+ const routeOptions = routeConfig.options;
1821
+ const route = createRoute(routeConfig, routeOptions, parent, router); // {
1822
+ // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
1823
+ // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
1824
+ // }
1930
1825
 
1826
+ const existingRoute = router.routesById[route.routeId];
1931
1827
 
1932
- routeMatch.isInvalid = false;
1933
- routeMatch.__.loadPromise = new Promise(async resolve => {
1934
- // We are now fetching, even if it's in the background of a
1935
- // resolved state
1936
- routeMatch.isFetching = true;
1937
- routeMatch.__.resolve = resolve;
1828
+ if (existingRoute) {
1829
+ {
1830
+ console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
1831
+ }
1938
1832
 
1939
- const loaderPromise = (async () => {
1940
- const importer = routeMatch.options.import; // First, run any importers
1833
+ throw new Error();
1834
+ }
1835
+ router.routesById[route.routeId] = route;
1836
+ const children = routeConfig.children;
1837
+ route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
1838
+ return route;
1839
+ });
1840
+ };
1941
1841
 
1942
- if (importer) {
1943
- routeMatch.__.importPromise = importer({
1944
- params: routeMatch.params // search: routeMatch.search,
1842
+ const routes = recurseRoutes([rootRouteConfig]);
1843
+ return routes[0];
1844
+ },
1845
+ parseLocation: (location, previousLocation) => {
1846
+ var _location$hash$split$;
1945
1847
 
1946
- }).then(imported => {
1947
- routeMatch.__ = _extends$1({}, routeMatch.__, imported);
1948
- });
1949
- } // Wait for the importer to finish before
1950
- // attempting to load elements and data
1848
+ const parsedSearch = router.options.parseSearch(location.search);
1849
+ return {
1850
+ pathname: location.pathname,
1851
+ searchStr: location.search,
1852
+ search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
1853
+ hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
1854
+ href: "" + location.pathname + location.search + location.hash,
1855
+ state: location.state,
1856
+ key: location.key
1857
+ };
1858
+ },
1859
+ buildLocation: function buildLocation(dest) {
1860
+ var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
1861
+
1862
+ if (dest === void 0) {
1863
+ dest = {};
1864
+ }
1865
+
1866
+ // const resolvedFrom: Location = {
1867
+ // ...router.location,
1868
+ const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
1869
+
1870
+ let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
1951
1871
 
1872
+ const fromMatches = router.matchRoutes(router.location.pathname, {
1873
+ strictParseParams: true
1874
+ });
1875
+ const toMatches = router.matchRoutes(pathname);
1952
1876
 
1953
- await routeMatch.__.importPromise; // Next, load the elements and data in parallel
1877
+ const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
1954
1878
 
1955
- routeMatch.__.elementsPromise = (async () => {
1956
- // then run all element and data loaders in parallel
1957
- // For each element type, potentially load it asynchronously
1958
- const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1959
- await Promise.all(elementTypes.map(async type => {
1960
- const routeElement = routeMatch.options[type];
1879
+ let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
1961
1880
 
1962
- if (routeMatch.__[type]) {
1963
- return;
1964
- }
1881
+ if (nextParams) {
1882
+ toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
1883
+ Object.assign({}, nextParams, fn(nextParams));
1884
+ });
1885
+ }
1965
1886
 
1966
- if (typeof routeElement === 'function') {
1967
- const res = await routeElement(routeMatch);
1968
- routeMatch.__[type] = res;
1969
- } else {
1970
- routeMatch.__[type] = routeMatch.options[type];
1971
- }
1972
- }));
1973
- })();
1887
+ pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
1974
1888
 
1975
- routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1976
- try {
1977
- const data = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
1978
- params: routeMatch.params,
1979
- search: routeMatch.routeSearch,
1980
- signal: routeMatch.__.abortController.signal
1981
- }));
1889
+ const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), router.location.search) : router.location.search; // Then the link/navigate function
1982
1890
 
1983
- if (id !== routeMatch.__.latestId) {
1984
- return routeMatch.__.loaderPromise;
1985
- }
1891
+ const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
1892
+ : dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
1893
+ : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
1894
+ : {}; // Then post filters
1986
1895
 
1987
- routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1988
- routeMatch.error = undefined;
1989
- routeMatch.status = 'success';
1990
- routeMatch.updatedAt = Date.now();
1991
- } catch (err) {
1992
- if (id !== routeMatch.__.latestId) {
1993
- return routeMatch.__.loaderPromise;
1994
- }
1896
+ const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
1897
+ const search = replaceEqualDeep(router.location.search, postFilteredSearch);
1898
+ const searchStr = router.options.stringifySearch(search);
1899
+ let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
1900
+ hash = hash ? "#" + hash : '';
1901
+ return {
1902
+ pathname,
1903
+ search,
1904
+ searchStr,
1905
+ state: router.location.state,
1906
+ hash,
1907
+ href: "" + pathname + searchStr + hash,
1908
+ key: dest.key
1909
+ };
1910
+ },
1911
+ commitLocation: (next, replace) => {
1912
+ const id = '' + Date.now() + Math.random();
1913
+ if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
1914
+ let nextAction = 'replace';
1995
1915
 
1996
- {
1997
- console.error(err);
1998
- }
1916
+ if (!replace) {
1917
+ nextAction = 'push';
1918
+ }
1999
1919
 
2000
- routeMatch.error = err;
2001
- routeMatch.status = 'error';
2002
- routeMatch.updatedAt = Date.now();
2003
- }
2004
- });
1920
+ const isSameUrl = router.parseLocation(history.location).href === next.href;
2005
1921
 
2006
- try {
2007
- await Promise.all([routeMatch.__.elementsPromise, routeMatch.__.dataPromise]);
1922
+ if (isSameUrl && !next.key) {
1923
+ nextAction = 'replace';
1924
+ }
2008
1925
 
2009
- if (id !== routeMatch.__.latestId) {
2010
- return routeMatch.__.loaderPromise;
2011
- }
1926
+ if (nextAction === 'replace') {
1927
+ history.replace({
1928
+ pathname: next.pathname,
1929
+ hash: next.hash,
1930
+ search: next.searchStr
1931
+ }, {
1932
+ id
1933
+ });
1934
+ } else {
1935
+ history.push({
1936
+ pathname: next.pathname,
1937
+ hash: next.hash,
1938
+ search: next.searchStr
1939
+ }, {
1940
+ id
1941
+ });
1942
+ }
2012
1943
 
2013
- if (routeMatch.__.pendingMinPromise) {
2014
- await routeMatch.__.pendingMinPromise;
2015
- delete routeMatch.__.pendingMinPromise;
2016
- }
2017
- } finally {
2018
- if (id !== routeMatch.__.latestId) {
2019
- return routeMatch.__.loaderPromise;
2020
- }
1944
+ router.navigationPromise = new Promise(resolve => {
1945
+ const previousNavigationResolve = router.resolveNavigation;
2021
1946
 
2022
- routeMatch.__.cancelPending();
1947
+ router.resolveNavigation = () => {
1948
+ previousNavigationResolve();
1949
+ resolve();
1950
+ };
1951
+ });
1952
+ return router.navigationPromise;
1953
+ },
1954
+ buildNext: opts => {
1955
+ const next = router.buildLocation(opts);
1956
+ const matches = router.matchRoutes(next.pathname);
2023
1957
 
2024
- routeMatch.isPending = false;
2025
- routeMatch.isFetching = false;
1958
+ const __preSearchFilters = matches.map(match => {
1959
+ var _match$options$preSea;
2026
1960
 
2027
- routeMatch.__.notify();
2028
- }
2029
- })();
1961
+ return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
1962
+ }).flat().filter(Boolean);
2030
1963
 
2031
- routeMatch.__.loaderPromise = loaderPromise;
2032
- await loaderPromise;
1964
+ const __postSearchFilters = matches.map(match => {
1965
+ var _match$options$postSe;
2033
1966
 
2034
- if (id !== routeMatch.__.latestId) {
2035
- return routeMatch.__.loaderPromise;
2036
- }
1967
+ return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
1968
+ }).flat().filter(Boolean);
2037
1969
 
2038
- delete routeMatch.__.loaderPromise;
1970
+ return router.buildLocation(_extends({}, opts, {
1971
+ __preSearchFilters,
1972
+ __postSearchFilters
1973
+ }));
1974
+ },
1975
+ cancelMatches: () => {
1976
+ var _router$state$pending, _router$state$pending2;
1977
+ [...router.state.matches, ...((_router$state$pending = (_router$state$pending2 = router.state.pending) == null ? void 0 : _router$state$pending2.matches) != null ? _router$state$pending : [])].forEach(match => {
1978
+ match.cancel();
2039
1979
  });
2040
- return await routeMatch.__.loadPromise;
2041
- }
2042
- });
1980
+ },
1981
+ loadLocation: async next => {
1982
+ const id = Math.random();
1983
+ router.startedLoadingAt = id;
2043
1984
 
2044
- return routeMatch;
2045
- }
1985
+ if (next) {
1986
+ // Ingest the new location
1987
+ router.location = next;
1988
+ } // Clear out old actions
2046
1989
 
2047
- function cascadeLoaderData(matches) {
2048
- matches.forEach((match, index) => {
2049
- const parent = matches[index - 1];
2050
1990
 
2051
- if (parent) {
2052
- match.loaderData = replaceEqualDeep(match.loaderData, _extends$1({}, parent.loaderData, match.routeLoaderData));
2053
- }
2054
- });
2055
- }
1991
+ router.removeActionQueue.forEach(_ref => {
1992
+ let {
1993
+ action,
1994
+ actionState
1995
+ } = _ref;
2056
1996
 
2057
- function matchPathname(currentPathname, matchLocation) {
2058
- const pathParams = matchByPath(currentPathname, matchLocation); // const searchMatched = matchBySearch(currentLocation.search, matchLocation)
1997
+ if (router.state.currentAction === actionState) {
1998
+ router.state.currentAction = undefined;
1999
+ }
2059
2000
 
2060
- if (matchLocation.to && !pathParams) {
2061
- return;
2062
- } // if (matchLocation.search && !searchMatched) {
2063
- // return
2064
- // }
2001
+ if (action.current === actionState) {
2002
+ action.current = undefined;
2003
+ }
2004
+ });
2005
+ router.removeActionQueue = []; // Cancel any pending matches
2065
2006
 
2007
+ router.cancelMatches(); // Match the routes
2066
2008
 
2067
- return pathParams != null ? pathParams : {};
2068
- }
2009
+ const matches = router.matchRoutes(location.pathname, {
2010
+ strictParseParams: true
2011
+ });
2012
+ router.state = _extends({}, router.state, {
2013
+ pending: {
2014
+ matches: matches,
2015
+ location: router.location
2016
+ },
2017
+ status: 'loading'
2018
+ });
2019
+ router.notify(); // Load the matches
2069
2020
 
2070
- function interpolatePath(path, params, leaveWildcard) {
2071
- const interpolatedPathSegments = parsePathname(path);
2072
- return joinPaths(interpolatedPathSegments.map(segment => {
2073
- if (segment.value === '*' && !leaveWildcard) {
2074
- return '';
2075
- }
2021
+ await router.loadMatches(matches, {
2022
+ withPending: true
2023
+ });
2076
2024
 
2077
- if (segment.type === 'param') {
2078
- var _segment$value$substr;
2025
+ if (router.startedLoadingAt !== id) {
2026
+ // Ignore side-effects of match loading
2027
+ return router.navigationPromise;
2028
+ }
2079
2029
 
2080
- return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
2081
- }
2030
+ const previousMatches = router.state.matches;
2031
+ const exiting = [],
2032
+ staying = [];
2033
+ previousMatches.forEach(d => {
2034
+ if (matches.find(dd => dd.matchId === d.matchId)) {
2035
+ staying.push(d);
2036
+ } else {
2037
+ exiting.push(d);
2038
+ }
2039
+ });
2040
+ const now = Date.now();
2041
+ exiting.forEach(d => {
2042
+ var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
2082
2043
 
2083
- return segment.value;
2084
- }));
2085
- }
2044
+ d.__.onExit == null ? void 0 : d.__.onExit({
2045
+ params: d.params,
2046
+ search: d.routeSearch
2047
+ }); // Clear idle error states when match leaves
2086
2048
 
2087
- function warning(cond, message) {
2088
- if (cond) {
2089
- if (typeof console !== 'undefined') console.warn(message);
2049
+ if (d.status === 'error' && !d.isFetching) {
2050
+ d.status = 'idle';
2051
+ d.error = undefined;
2052
+ }
2090
2053
 
2091
- try {
2092
- throw new Error(message);
2093
- } catch (_unused) {}
2094
- }
2054
+ const gc = Math.max((_ref2 = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref2 : 0, (_ref3 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0);
2095
2055
 
2096
- return true;
2097
- }
2056
+ if (gc > 0) {
2057
+ router.matchCache[d.matchId] = {
2058
+ gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
2059
+ match: d
2060
+ };
2061
+ }
2062
+ });
2063
+ staying.forEach(d => {
2064
+ d.options.onTransition == null ? void 0 : d.options.onTransition({
2065
+ params: d.params,
2066
+ search: d.routeSearch
2067
+ });
2068
+ });
2069
+ const entering = matches.filter(d => {
2070
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
2071
+ });
2072
+ entering.forEach(d => {
2073
+ d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
2074
+ params: d.params,
2075
+ search: d.search
2076
+ });
2077
+ });
2078
+
2079
+ if (matches.some(d => d.status === 'loading')) {
2080
+ router.notify();
2081
+ await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
2082
+ }
2098
2083
 
2099
- function isFunction(d) {
2100
- return typeof d === 'function';
2101
- }
2084
+ if (router.startedLoadingAt !== id) {
2085
+ // Ignore side-effects of match loading
2086
+ return;
2087
+ }
2102
2088
 
2103
- function functionalUpdate(updater, previous) {
2104
- if (isFunction(updater)) {
2105
- return updater(previous);
2106
- }
2089
+ router.state = _extends({}, router.state, {
2090
+ location: router.location,
2091
+ matches,
2092
+ pending: undefined,
2093
+ status: 'idle'
2094
+ });
2095
+ router.notify();
2096
+ router.resolveNavigation();
2097
+ },
2098
+ cleanMatchCache: () => {
2099
+ const now = Date.now();
2100
+ Object.keys(router.matchCache).forEach(matchId => {
2101
+ const entry = router.matchCache[matchId]; // Don't remove loading matches
2107
2102
 
2108
- return updater;
2109
- }
2103
+ if (entry.match.status === 'loading') {
2104
+ return;
2105
+ } // Do not remove successful matches that are still valid
2110
2106
 
2111
- function joinPaths(paths) {
2112
- return cleanPath(paths.filter(Boolean).join('/'));
2113
- }
2114
2107
 
2115
- function cleanPath(path) {
2116
- // remove double slashes
2117
- return path.replace(/\/{2,}/g, '/');
2118
- }
2108
+ if (entry.gc > 0 && entry.gc > now) {
2109
+ return;
2110
+ } // Everything else gets removed
2119
2111
 
2120
- function trimPathLeft(path) {
2121
- return path === '/' ? path : path.replace(/^\/{1,}/, '');
2122
- }
2123
2112
 
2124
- function trimPathRight(path) {
2125
- return path === '/' ? path : path.replace(/\/{1,}$/, '');
2126
- }
2113
+ delete router.matchCache[matchId];
2114
+ });
2115
+ },
2116
+ loadRoute: async function loadRoute(navigateOpts, loaderOpts) {
2117
+ if (navigateOpts === void 0) {
2118
+ navigateOpts = router.location;
2119
+ }
2127
2120
 
2128
- function trimPath(path) {
2129
- return trimPathRight(trimPathLeft(path));
2130
- }
2121
+ const next = router.buildNext(navigateOpts);
2122
+ const matches = router.matchRoutes(next.pathname, {
2123
+ strictParseParams: true
2124
+ });
2125
+ await router.loadMatches(matches, {
2126
+ preload: true,
2127
+ maxAge: loaderOpts.maxAge
2128
+ });
2129
+ return matches;
2130
+ },
2131
+ matchRoutes: (pathname, opts) => {
2132
+ var _router$state$pending3, _router$state$pending4;
2131
2133
 
2132
- function matchByPath(from, matchLocation) {
2133
- var _matchLocation$to;
2134
+ router.cleanMatchCache();
2135
+ const matches = [];
2134
2136
 
2135
- const baseSegments = parsePathname(from);
2136
- const routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
2137
- const params = {};
2137
+ if (!router.routeTree) {
2138
+ return matches;
2139
+ }
2138
2140
 
2139
- let isMatch = (() => {
2140
- for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
2141
- const baseSegment = baseSegments[i];
2142
- const routeSegment = routeSegments[i];
2143
- const isLastRouteSegment = i === routeSegments.length - 1;
2144
- const isLastBaseSegment = i === baseSegments.length - 1;
2141
+ const existingMatches = [...router.state.matches, ...((_router$state$pending3 = (_router$state$pending4 = router.state.pending) == null ? void 0 : _router$state$pending4.matches) != null ? _router$state$pending3 : [])];
2145
2142
 
2146
- if (routeSegment) {
2147
- if (routeSegment.type === 'wildcard') {
2148
- if (baseSegment != null && baseSegment.value) {
2149
- params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
2150
- return true;
2151
- }
2143
+ const recurse = async routes => {
2144
+ var _parentMatch$params, _router$options$filte, _foundRoute$childRout;
2152
2145
 
2153
- return false;
2154
- }
2146
+ const parentMatch = last(matches);
2147
+ let params = (_parentMatch$params = parentMatch == null ? void 0 : parentMatch.params) != null ? _parentMatch$params : {};
2148
+ const filteredRoutes = (_router$options$filte = router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) != null ? _router$options$filte : routes;
2149
+ let foundRoutes = [];
2155
2150
 
2156
- if (routeSegment.type === 'pathname') {
2157
- if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
2158
- return true;
2159
- }
2151
+ const findMatchInRoutes = (parentRoutes, routes) => {
2152
+ routes.some(route => {
2153
+ var _route$childRoutes, _route$childRoutes2, _route$options$caseSe;
2160
2154
 
2161
- if (baseSegment) {
2162
- if (matchLocation.caseSensitive) {
2163
- if (routeSegment.value !== baseSegment.value) {
2164
- return false;
2165
- }
2166
- } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
2167
- return false;
2155
+ if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
2156
+ return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
2168
2157
  }
2169
- }
2170
- }
2171
-
2172
- if (!baseSegment) {
2173
- return false;
2174
- }
2175
2158
 
2176
- if (routeSegment.type === 'param') {
2177
- if ((baseSegment == null ? void 0 : baseSegment.value) === '/') {
2178
- return false;
2179
- }
2159
+ const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length);
2160
+ const matchParams = matchPathname(pathname, {
2161
+ to: route.fullPath,
2162
+ fuzzy,
2163
+ caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
2164
+ });
2180
2165
 
2181
- if (!baseSegment.value.startsWith(':')) {
2182
- params[routeSegment.value.substring(1)] = baseSegment.value;
2183
- }
2184
- }
2185
- }
2166
+ if (matchParams) {
2167
+ let parsedParams;
2186
2168
 
2187
- if (isLastRouteSegment && !isLastBaseSegment) {
2188
- return !!matchLocation.fuzzy;
2189
- }
2190
- }
2169
+ try {
2170
+ var _route$options$parseP;
2191
2171
 
2192
- return true;
2193
- })();
2172
+ parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
2173
+ } catch (err) {
2174
+ if (opts != null && opts.strictParseParams) {
2175
+ throw err;
2176
+ }
2177
+ }
2194
2178
 
2195
- return isMatch ? params : undefined;
2196
- } // function matchBySearch(
2197
- // search: SearchSchema,
2198
- // matchLocation: MatchLocation,
2199
- // ) {
2200
- // return !!(matchLocation.search && matchLocation.search(search))
2201
- // }
2179
+ params = _extends({}, params, parsedParams);
2180
+ }
2202
2181
 
2203
- function parsePathname(pathname) {
2204
- if (!pathname) {
2205
- return [];
2206
- }
2182
+ if (!!matchParams) {
2183
+ foundRoutes = [...parentRoutes, route];
2184
+ }
2207
2185
 
2208
- pathname = cleanPath(pathname);
2209
- const segments = [];
2186
+ return !!foundRoutes.length;
2187
+ });
2188
+ return !!foundRoutes.length;
2189
+ };
2210
2190
 
2211
- if (pathname.slice(0, 1) === '/') {
2212
- pathname = pathname.substring(1);
2213
- segments.push({
2214
- type: 'pathname',
2215
- value: '/'
2216
- });
2217
- }
2191
+ findMatchInRoutes([], filteredRoutes);
2218
2192
 
2219
- if (!pathname) {
2220
- return segments;
2221
- } // Remove empty segments and '.' segments
2193
+ if (!foundRoutes.length) {
2194
+ return;
2195
+ }
2222
2196
 
2197
+ foundRoutes.forEach(foundRoute => {
2198
+ var _router$matchCache$ma;
2223
2199
 
2224
- const split = pathname.split('/').filter(Boolean);
2225
- segments.push(...split.map(part => {
2226
- if (part.startsWith('*')) {
2227
- return {
2228
- type: 'wildcard',
2229
- value: part
2230
- };
2231
- }
2200
+ const interpolatedPath = interpolatePath(foundRoute.routePath, params);
2201
+ const matchId = interpolatePath(foundRoute.routeId, params, true);
2202
+ const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
2203
+ matchId,
2204
+ params,
2205
+ pathname: joinPaths([pathname, interpolatedPath])
2206
+ });
2207
+ matches.push(match);
2208
+ });
2209
+ const foundRoute = last(foundRoutes);
2232
2210
 
2233
- if (part.charAt(0) === ':') {
2234
- return {
2235
- type: 'param',
2236
- value: part
2211
+ if ((_foundRoute$childRout = foundRoute.childRoutes) != null && _foundRoute$childRout.length) {
2212
+ recurse(foundRoute.childRoutes);
2213
+ }
2237
2214
  };
2238
- }
2239
2215
 
2240
- return {
2241
- type: 'pathname',
2242
- value: part
2243
- };
2244
- }));
2216
+ recurse([router.routeTree]);
2217
+ cascadeLoaderData(matches);
2218
+ return matches;
2219
+ },
2220
+ loadMatches: async (resolvedMatches, loaderOpts) => {
2221
+ const now = Date.now();
2222
+ const matchPromises = resolvedMatches.map(async match => {
2223
+ // Validate the match (loads search params etc)
2224
+ match.__.validate(); // If the match doesn't have a loader, don't attempt to load it
2245
2225
 
2246
- if (pathname.slice(-1) === '/') {
2247
- pathname = pathname.substring(1);
2248
- segments.push({
2249
- type: 'pathname',
2250
- value: '/'
2251
- });
2252
- }
2253
2226
 
2254
- return segments;
2255
- }
2227
+ if (!match.hasLoaders()) {
2228
+ return;
2229
+ } // If this is a preload, add it to the preload cache
2256
2230
 
2257
- function _resolvePath(basepath, base, to) {
2258
- base = base.replace(new RegExp("^" + basepath), '/');
2259
- to = to.replace(new RegExp("^" + basepath), '/');
2260
- let baseSegments = parsePathname(base);
2261
- const toSegments = parsePathname(to);
2262
- toSegments.forEach((toSegment, index) => {
2263
- if (toSegment.value === '/') {
2264
- if (!index) {
2265
- // Leading slash
2266
- baseSegments = [toSegment];
2267
- } else if (index === toSegments.length - 1) {
2268
- // Trailing Slash
2269
- baseSegments.push(toSegment);
2270
- } else ;
2271
- } else if (toSegment.value === '..') {
2272
- var _last2;
2273
2231
 
2274
- // Extra trailing slash? pop it off
2275
- if (baseSegments.length > 1 && ((_last2 = last(baseSegments)) == null ? void 0 : _last2.value) === '/') {
2276
- baseSegments.pop();
2277
- }
2232
+ if (loaderOpts != null && loaderOpts.preload && (loaderOpts == null ? void 0 : loaderOpts.maxAge) > 0) {
2233
+ // If the match is currently active, don't preload it
2234
+ if (router.state.matches.find(d => d.matchId === match.matchId)) {
2235
+ return;
2236
+ }
2278
2237
 
2279
- baseSegments.pop();
2280
- } else if (toSegment.value === '.') {
2281
- return;
2282
- } else {
2283
- baseSegments.push(toSegment);
2284
- }
2285
- });
2286
- const joined = joinPaths([basepath, ...baseSegments.map(d => d.value)]);
2287
- return cleanPath(joined);
2288
- }
2289
- function replaceEqualDeep(prev, next) {
2290
- if (prev === next) {
2291
- return prev;
2292
- }
2238
+ router.matchCache[match.matchId] = {
2239
+ gc: now + loaderOpts.maxAge,
2240
+ // TODO: Should this use the route's maxAge?
2241
+ match
2242
+ };
2243
+ } // If the match is invalid, errored or idle, trigger it to load
2293
2244
 
2294
- const array = Array.isArray(prev) && Array.isArray(next);
2295
2245
 
2296
- if (array || isPlainObject(prev) && isPlainObject(next)) {
2297
- const aSize = array ? prev.length : Object.keys(prev).length;
2298
- const bItems = array ? next : Object.keys(next);
2299
- const bSize = bItems.length;
2300
- const copy = array ? [] : {};
2301
- let equalItems = 0;
2246
+ if (match.status === 'success' && match.getIsInvalid() || match.status === 'error' || match.status === 'idle') {
2247
+ match.load();
2248
+ }
2302
2249
 
2303
- for (let i = 0; i < bSize; i++) {
2304
- const key = array ? i : bItems[i];
2305
- copy[key] = replaceEqualDeep(prev[key], next[key]);
2250
+ if (match.status === 'loading') {
2251
+ // If requested, start the pending timers
2252
+ if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
2253
+ // This might be completion, error, or a pending state
2306
2254
 
2307
- if (copy[key] === prev[key]) {
2308
- equalItems++;
2309
- }
2310
- }
2255
+ await match.__.loadPromise;
2256
+ }
2257
+ });
2258
+ router.notify();
2259
+ await Promise.all(matchPromises);
2260
+ },
2261
+ invalidateRoute: opts => {
2262
+ var _router$state$pending5, _router$state$pending6;
2311
2263
 
2312
- return aSize === bSize && equalItems === aSize ? prev : copy;
2313
- }
2264
+ const next = router.buildNext(opts);
2265
+ const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
2266
+ [...router.state.matches, ...((_router$state$pending5 = (_router$state$pending6 = router.state.pending) == null ? void 0 : _router$state$pending6.matches) != null ? _router$state$pending5 : [])].forEach(match => {
2267
+ if (unloadedMatchIds.includes(match.matchId)) {
2268
+ match.invalidate();
2269
+ }
2270
+ });
2271
+ },
2272
+ reload: () => router._navigate({
2273
+ fromCurrent: true,
2274
+ replace: true,
2275
+ search: true
2276
+ }),
2277
+ resolvePath: (from, path) => {
2278
+ return resolvePath(router.basepath, from, cleanPath(path));
2279
+ },
2280
+ matchRoute: (location, opts) => {
2281
+ var _location$from;
2314
2282
 
2315
- return next;
2316
- } // Copied from: https://github.com/jonschlinkert/is-plain-object
2283
+ // const location = router.buildNext(opts)
2284
+ location = _extends({}, location, {
2285
+ to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
2286
+ });
2287
+ const next = router.buildNext(location);
2317
2288
 
2318
- function isPlainObject(o) {
2319
- if (!hasObjectPrototype(o)) {
2320
- return false;
2321
- } // If has modified constructor
2289
+ if (opts != null && opts.pending) {
2290
+ var _router$state$pending7;
2322
2291
 
2292
+ if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
2293
+ return false;
2294
+ }
2323
2295
 
2324
- const ctor = o.constructor;
2296
+ return !!matchPathname(router.state.pending.location.pathname, _extends({}, opts, {
2297
+ to: next.pathname
2298
+ }));
2299
+ }
2325
2300
 
2326
- if (typeof ctor === 'undefined') {
2327
- return true;
2328
- } // If has modified prototype
2301
+ return !!matchPathname(router.state.location.pathname, _extends({}, opts, {
2302
+ to: next.pathname
2303
+ }));
2304
+ },
2305
+ _navigate: location => {
2306
+ const next = router.buildNext(location);
2307
+ return router.commitLocation(next, location.replace);
2308
+ },
2309
+ navigate: async _ref4 => {
2310
+ let {
2311
+ from,
2312
+ to = '.',
2313
+ search,
2314
+ hash,
2315
+ replace,
2316
+ params
2317
+ } = _ref4;
2318
+ // If this link simply reloads the current route,
2319
+ // make sure it has a new key so it will trigger a data refresh
2320
+ // If this `to` is a valid external URL, return
2321
+ // null for LinkUtils
2322
+ const toString = String(to);
2323
+ const fromString = String(from);
2324
+ let isExternal;
2329
2325
 
2326
+ try {
2327
+ new URL("" + toString);
2328
+ isExternal = true;
2329
+ } catch (e) {}
2330
2330
 
2331
- const prot = ctor.prototype;
2331
+ invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
2332
+ return router._navigate({
2333
+ from: fromString,
2334
+ to: toString,
2335
+ search,
2336
+ hash,
2337
+ replace,
2338
+ params
2339
+ });
2340
+ },
2341
+ buildLink: _ref5 => {
2342
+ var _preload, _ref6, _ref7, _ref8;
2332
2343
 
2333
- if (!hasObjectPrototype(prot)) {
2334
- return false;
2335
- } // If constructor does not have an Object-specific method
2344
+ let {
2345
+ from,
2346
+ to = '.',
2347
+ search,
2348
+ params,
2349
+ hash,
2350
+ target,
2351
+ replace,
2352
+ activeOptions,
2353
+ preload,
2354
+ preloadMaxAge: userPreloadMaxAge,
2355
+ preloadDelay: userPreloadDelay,
2356
+ disabled
2357
+ } = _ref5;
2336
2358
 
2359
+ // If this link simply reloads the current route,
2360
+ // make sure it has a new key so it will trigger a data refresh
2361
+ // If this `to` is a valid external URL, return
2362
+ // null for LinkUtils
2363
+ try {
2364
+ new URL("" + to);
2365
+ return {
2366
+ type: 'external',
2367
+ href: to
2368
+ };
2369
+ } catch (e) {}
2337
2370
 
2338
- if (!prot.hasOwnProperty('isPrototypeOf')) {
2339
- return false;
2340
- } // Most likely a plain Object
2371
+ const nextOpts = {
2372
+ from,
2373
+ to,
2374
+ search,
2375
+ params,
2376
+ hash,
2377
+ replace
2378
+ };
2379
+ const next = router.buildNext(nextOpts);
2380
+ preload = (_preload = preload) != null ? _preload : router.options.defaultLinkPreload;
2381
+ const preloadMaxAge = (_ref6 = (_ref7 = userPreloadMaxAge != null ? userPreloadMaxAge : router.options.defaultLinkPreloadMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0;
2382
+ const preloadDelay = (_ref8 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultLinkPreloadDelay) != null ? _ref8 : 0; // Compare path/hash for matches
2341
2383
 
2384
+ const pathIsEqual = router.state.location.pathname === next.pathname;
2385
+ const currentPathSplit = router.state.location.pathname.split('/');
2386
+ const nextPathSplit = next.pathname.split('/');
2387
+ const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
2388
+ const hashIsEqual = router.state.location.hash === next.hash; // Combine the matches based on user options
2342
2389
 
2343
- return true;
2344
- }
2390
+ const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
2391
+ const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
2345
2392
 
2346
- function hasObjectPrototype(o) {
2347
- return Object.prototype.toString.call(o) === '[object Object]';
2348
- }
2393
+ const isActive = pathTest && hashTest; // The click handler
2349
2394
 
2350
- const defaultParseSearch = parseSearchWith(JSON.parse);
2351
- const defaultStringifySearch = stringifySearchWith(JSON.stringify);
2352
- function parseSearchWith(parser) {
2353
- return searchStr => {
2354
- if (searchStr.substring(0, 1) === '?') {
2355
- searchStr = searchStr.substring(1);
2356
- }
2395
+ const handleClick = e => {
2396
+ if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
2397
+ e.preventDefault();
2357
2398
 
2358
- let query = decode(searchStr); // Try to parse any query params that might be json
2399
+ if (pathIsEqual && !search && !hash) {
2400
+ router.invalidateRoute(nextOpts);
2401
+ } // All is well? Navigate!)
2359
2402
 
2360
- for (let key in query) {
2361
- const value = query[key];
2362
2403
 
2363
- if (typeof value === 'string') {
2364
- try {
2365
- query[key] = parser(value);
2366
- } catch (err) {//
2404
+ router._navigate(nextOpts);
2367
2405
  }
2368
- }
2369
- }
2406
+ }; // The click handler
2370
2407
 
2371
- return query;
2372
- };
2373
- }
2374
- function stringifySearchWith(stringify) {
2375
- return search => {
2376
- search = _extends$1({}, search);
2377
2408
 
2378
- if (search) {
2379
- Object.keys(search).forEach(key => {
2380
- const val = search[key];
2409
+ const handleFocus = e => {
2410
+ if (preload && preloadMaxAge > 0) {
2411
+ router.loadRoute(nextOpts, {
2412
+ maxAge: preloadMaxAge
2413
+ });
2414
+ }
2415
+ };
2381
2416
 
2382
- if (typeof val === 'undefined' || val === undefined) {
2383
- delete search[key];
2384
- } else if (val && typeof val === 'object' && val !== null) {
2385
- try {
2386
- search[key] = stringify(val);
2387
- } catch (err) {// silent
2417
+ const handleEnter = e => {
2418
+ const target = e.target || {};
2419
+
2420
+ if (preload && preloadMaxAge > 0) {
2421
+ if (target.preloadTimeout) {
2422
+ return;
2388
2423
  }
2424
+
2425
+ target.preloadTimeout = setTimeout(() => {
2426
+ target.preloadTimeout = null;
2427
+ router.loadRoute(nextOpts, {
2428
+ maxAge: preloadMaxAge
2429
+ });
2430
+ }, preloadDelay);
2389
2431
  }
2390
- });
2391
- }
2432
+ };
2392
2433
 
2393
- const searchStr = encode(search).toString();
2394
- return searchStr ? "?" + searchStr : '';
2434
+ const handleLeave = e => {
2435
+ const target = e.target || {};
2436
+
2437
+ if (target.preloadTimeout) {
2438
+ clearTimeout(target.preloadTimeout);
2439
+ target.preloadTimeout = null;
2440
+ }
2441
+ };
2442
+
2443
+ return {
2444
+ type: 'internal',
2445
+ next,
2446
+ handleFocus,
2447
+ handleClick,
2448
+ handleEnter,
2449
+ handleLeave,
2450
+ isActive,
2451
+ disabled
2452
+ };
2453
+ }
2395
2454
  };
2455
+ router.location = router.parseLocation(history.location);
2456
+ router.state.location = router.location;
2457
+ router.update(userOptions); // Allow frameworks to hook into the router creation
2458
+
2459
+ router.options.createRouter == null ? void 0 : router.options.createRouter(router);
2460
+ return router;
2396
2461
  }
2397
2462
 
2398
2463
  function isCtrlEvent(e) {
2399
2464
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
2400
2465
  }
2401
2466
 
2402
- function last(arr) {
2403
- return arr[arr.length - 1];
2404
- }
2405
-
2406
2467
  const _excluded = ["type", "children", "target", "activeProps", "inactiveProps", "activeOptions", "disabled", "hash", "search", "params", "to", "preload", "preloadDelay", "preloadMaxAge", "replace", "style", "className", "onClick", "onFocus", "onMouseEnter", "onMouseLeave", "onTouchStart", "onTouchEnd"],
2407
2468
  _excluded2 = ["pending", "caseSensitive", "children"],
2408
2469
  _excluded3 = ["children", "router"];
@@ -2472,9 +2533,9 @@
2472
2533
  }; // Get the active props
2473
2534
 
2474
2535
 
2475
- const resolvedActiveProps = isActive ? (_functionalUpdate = functionalUpdate(activeProps)) != null ? _functionalUpdate : {} : {}; // Get the inactive props
2536
+ const resolvedActiveProps = isActive ? (_functionalUpdate = functionalUpdate(activeProps, {})) != null ? _functionalUpdate : {} : {}; // Get the inactive props
2476
2537
 
2477
- const resolvedInactiveProps = isActive ? {} : (_functionalUpdate2 = functionalUpdate(inactiveProps)) != null ? _functionalUpdate2 : {};
2538
+ const resolvedInactiveProps = isActive ? {} : (_functionalUpdate2 = functionalUpdate(inactiveProps, {})) != null ? _functionalUpdate2 : {};
2478
2539
  return _extends$2({}, resolvedActiveProps, resolvedInactiveProps, rest, {
2479
2540
  href: disabled ? undefined : next.href,
2480
2541
  onClick: composeHandlers([handleClick, onClick]),
@@ -2512,7 +2573,7 @@
2512
2573
  const params = route.matchRoute(rest, {
2513
2574
  pending,
2514
2575
  caseSensitive
2515
- }); // useRouterSubscription(router)
2576
+ });
2516
2577
 
2517
2578
  if (!params) {
2518
2579
  return null;
@@ -2526,6 +2587,10 @@
2526
2587
  const coreRouter = createRouter(_extends$2({}, opts, {
2527
2588
  createRouter: router => {
2528
2589
  const routerExt = {
2590
+ useState: () => {
2591
+ useRouterSubscription(router);
2592
+ return router.state;
2593
+ },
2529
2594
  useRoute: routeId => {
2530
2595
  const route = router.getRoute(routeId);
2531
2596
  useRouterSubscription(router);
@@ -2533,6 +2598,7 @@
2533
2598
  return route;
2534
2599
  },
2535
2600
  useMatch: routeId => {
2601
+ useRouterSubscription(router);
2536
2602
  invariant(routeId !== rootRouteId, "\"" + rootRouteId + "\" cannot be used with useMatch! Did you mean to useRoute(\"" + rootRouteId + "\")?");
2537
2603
 
2538
2604
  const runtimeMatch = _useMatch();
@@ -2540,7 +2606,6 @@
2540
2606
  const match = router.state.matches.find(d => d.routeId === routeId);
2541
2607
  invariant(match, "Could not find a match for route \"" + routeId + "\" being rendered in this component!");
2542
2608
  invariant(runtimeMatch.routeId == (match == null ? void 0 : match.routeId), "useMatch('" + (match == null ? void 0 : match.routeId) + "') is being called in a component that is meant to render the '" + runtimeMatch.routeId + "' route. Did you mean to 'useRoute(" + (match == null ? void 0 : match.routeId) + ")' instead?");
2543
- useRouterSubscription(router);
2544
2609
 
2545
2610
  if (!match) {
2546
2611
  invariant('Match not found!');
@@ -2571,10 +2636,10 @@
2571
2636
  rest = _objectWithoutPropertiesLoose(_ref2, _excluded3);
2572
2637
 
2573
2638
  router.update(rest);
2574
- shim.useSyncExternalStore(cb => router.subscribe(() => cb()), () => router.state);
2639
+ useRouterSubscription(router);
2575
2640
  useLayoutEffect(() => {
2576
- router.mount();
2577
- }, []);
2641
+ return router.mount();
2642
+ }, [router]);
2578
2643
  return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
2579
2644
  value: {
2580
2645
  router
@@ -2611,14 +2676,15 @@
2611
2676
  }
2612
2677
 
2613
2678
  function Outlet() {
2614
- var _ref3, _childMatch$options$c;
2679
+ var _childMatch$options$c;
2615
2680
 
2616
2681
  const router = useRouter();
2617
2682
  const [, ...matches] = useMatches();
2618
2683
  const childMatch = matches[0];
2619
2684
  if (!childMatch) return null;
2620
- const element = (_ref3 = (() => {
2621
- var _childMatch$__$errorE, _ref5;
2685
+
2686
+ const element = (() => {
2687
+ var _childMatch$__$errorE, _ref4;
2622
2688
 
2623
2689
  if (!childMatch) {
2624
2690
  return null;
@@ -2635,7 +2701,7 @@
2635
2701
  throw childMatch.error;
2636
2702
  }
2637
2703
 
2638
- return /*#__PURE__*/React__namespace.createElement(DefaultCatchBoundary, {
2704
+ return /*#__PURE__*/React__namespace.createElement(DefaultErrorBoundary, {
2639
2705
  error: childMatch.error
2640
2706
  });
2641
2707
  }
@@ -2647,17 +2713,18 @@
2647
2713
  const pendingElement = (_childMatch$__$pendin = childMatch.__.pendingElement) != null ? _childMatch$__$pendin : router.options.defaultPendingElement;
2648
2714
 
2649
2715
  if (childMatch.options.pendingMs || pendingElement) {
2650
- var _ref4;
2716
+ var _ref3;
2651
2717
 
2652
- return (_ref4 = pendingElement) != null ? _ref4 : null;
2718
+ return (_ref3 = pendingElement) != null ? _ref3 : null;
2653
2719
  }
2654
2720
  }
2655
2721
 
2656
2722
  return null;
2657
2723
  }
2658
2724
 
2659
- return (_ref5 = childMatch.__.element) != null ? _ref5 : router.options.defaultElement;
2660
- })()) != null ? _ref3 : /*#__PURE__*/React__namespace.createElement(Outlet, null);
2725
+ return (_ref4 = childMatch.__.element) != null ? _ref4 : router.options.defaultElement;
2726
+ })();
2727
+
2661
2728
  const catchElement = (_childMatch$options$c = childMatch == null ? void 0 : childMatch.options.catchElement) != null ? _childMatch$options$c : router.options.defaultCatchElement;
2662
2729
  return /*#__PURE__*/React__namespace.createElement(MatchesProvider, {
2663
2730
  value: matches,
@@ -2693,7 +2760,7 @@
2693
2760
  render() {
2694
2761
  var _this$props$catchElem;
2695
2762
 
2696
- const catchElement = (_this$props$catchElem = this.props.catchElement) != null ? _this$props$catchElem : DefaultCatchBoundary;
2763
+ const catchElement = (_this$props$catchElem = this.props.catchElement) != null ? _this$props$catchElem : DefaultErrorBoundary;
2697
2764
 
2698
2765
  if (this.state.error) {
2699
2766
  return typeof catchElement === 'function' ? catchElement(this.state) : catchElement;
@@ -2704,10 +2771,10 @@
2704
2771
 
2705
2772
  }
2706
2773
 
2707
- function DefaultCatchBoundary(_ref6) {
2774
+ function DefaultErrorBoundary(_ref5) {
2708
2775
  let {
2709
2776
  error
2710
- } = _ref6;
2777
+ } = _ref5;
2711
2778
  return /*#__PURE__*/React__namespace.createElement("div", {
2712
2779
  style: {
2713
2780
  padding: '.5rem',
@@ -2741,12 +2808,14 @@
2741
2808
  opacity: 0.5
2742
2809
  }
2743
2810
  }, "If you are the owner of this website, it's highly recommended that you configure your own custom Catch/Error boundaries for the router. You can optionally configure a boundary for each route."));
2744
- }
2811
+ } // TODO: Add prompt
2745
2812
 
2746
- exports.DefaultCatchBoundary = DefaultCatchBoundary;
2813
+ exports.DefaultErrorBoundary = DefaultErrorBoundary;
2747
2814
  exports.MatchesProvider = MatchesProvider;
2748
2815
  exports.Outlet = Outlet;
2749
2816
  exports.RouterProvider = RouterProvider;
2817
+ exports.cascadeLoaderData = cascadeLoaderData;
2818
+ exports.cleanPath = cleanPath;
2750
2819
  exports.createBrowserHistory = createBrowserHistory;
2751
2820
  exports.createHashHistory = createHashHistory;
2752
2821
  exports.createMemoryHistory = createMemoryHistory;
@@ -2755,19 +2824,26 @@
2755
2824
  exports.createRouteConfig = createRouteConfig;
2756
2825
  exports.createRouteMatch = createRouteMatch;
2757
2826
  exports.createRouter = createRouter;
2827
+ exports.decode = decode;
2758
2828
  exports.defaultParseSearch = defaultParseSearch;
2759
2829
  exports.defaultStringifySearch = defaultStringifySearch;
2830
+ exports.encode = encode;
2760
2831
  exports.functionalUpdate = functionalUpdate;
2832
+ exports.interpolatePath = interpolatePath;
2761
2833
  exports.invariant = invariant;
2834
+ exports.joinPaths = joinPaths;
2762
2835
  exports.last = last;
2763
2836
  exports.matchByPath = matchByPath;
2764
2837
  exports.matchPathname = matchPathname;
2765
2838
  exports.parsePathname = parsePathname;
2766
2839
  exports.parseSearchWith = parseSearchWith;
2767
2840
  exports.replaceEqualDeep = replaceEqualDeep;
2768
- exports.resolvePath = _resolvePath;
2841
+ exports.resolvePath = resolvePath;
2769
2842
  exports.rootRouteId = rootRouteId;
2770
2843
  exports.stringifySearchWith = stringifySearchWith;
2844
+ exports.trimPath = trimPath;
2845
+ exports.trimPathLeft = trimPathLeft;
2846
+ exports.trimPathRight = trimPathRight;
2771
2847
  exports.warning = warning;
2772
2848
 
2773
2849
  Object.defineProperty(exports, '__esModule', { value: true });