@tanstack/react-router 0.0.1-alpha.1 → 0.0.1-alpha.11

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