@tanstack/router-core 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.
Files changed (43) hide show
  1. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +30 -0
  2. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +1 -0
  3. package/build/cjs/packages/router-core/src/index.js +35 -1421
  4. package/build/cjs/packages/router-core/src/index.js.map +1 -1
  5. package/build/cjs/packages/router-core/src/path.js +222 -0
  6. package/build/cjs/packages/router-core/src/path.js.map +1 -0
  7. package/build/cjs/packages/router-core/src/qss.js +1 -1
  8. package/build/cjs/packages/router-core/src/qss.js.map +1 -1
  9. package/build/cjs/packages/router-core/src/route.js +161 -0
  10. package/build/cjs/packages/router-core/src/route.js.map +1 -0
  11. package/build/cjs/packages/router-core/src/routeConfig.js +69 -0
  12. package/build/cjs/packages/router-core/src/routeConfig.js.map +1 -0
  13. package/build/cjs/packages/router-core/src/routeMatch.js +266 -0
  14. package/build/cjs/packages/router-core/src/routeMatch.js.map +1 -0
  15. package/build/cjs/packages/router-core/src/router.js +789 -0
  16. package/build/cjs/packages/router-core/src/router.js.map +1 -0
  17. package/build/cjs/packages/router-core/src/searchParams.js +70 -0
  18. package/build/cjs/packages/router-core/src/searchParams.js.map +1 -0
  19. package/build/cjs/packages/router-core/src/utils.js +118 -0
  20. package/build/cjs/packages/router-core/src/utils.js.map +1 -0
  21. package/build/esm/index.js +1385 -1232
  22. package/build/esm/index.js.map +1 -1
  23. package/build/stats-html.html +1 -1
  24. package/build/stats-react.json +388 -46
  25. package/build/types/index.d.ts +433 -338
  26. package/build/umd/index.development.js +1226 -1065
  27. package/build/umd/index.development.js.map +1 -1
  28. package/build/umd/index.production.js +1 -1
  29. package/build/umd/index.production.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/frameworks.ts +12 -0
  32. package/src/index.ts +15 -2969
  33. package/src/link.ts +319 -0
  34. package/src/path.ts +236 -0
  35. package/src/qss.ts +1 -1
  36. package/src/route.ts +243 -0
  37. package/src/routeConfig.ts +495 -0
  38. package/src/routeInfo.ts +228 -0
  39. package/src/routeMatch.ts +374 -0
  40. package/src/router.ts +1230 -0
  41. package/src/searchParams.ts +54 -0
  42. package/src/utils.ts +157 -0
  43. package/src/createRoutes.test.ts +0 -328
@@ -31,23 +31,6 @@
31
31
  return _extends$1.apply(this, arguments);
32
32
  }
33
33
 
34
- function _extends() {
35
- _extends = Object.assign ? Object.assign.bind() : function (target) {
36
- for (var i = 1; i < arguments.length; i++) {
37
- var source = arguments[i];
38
-
39
- for (var key in source) {
40
- if (Object.prototype.hasOwnProperty.call(source, key)) {
41
- target[key] = source[key];
42
- }
43
- }
44
- }
45
-
46
- return target;
47
- };
48
- return _extends.apply(this, arguments);
49
- }
50
-
51
34
  /**
52
35
  * Actions represent the type of change to a location value.
53
36
  *
@@ -189,7 +172,7 @@
189
172
 
190
173
  if (index == null) {
191
174
  index = 0;
192
- globalHistory.replaceState(_extends({}, globalHistory.state, {
175
+ globalHistory.replaceState(_extends$1({}, globalHistory.state, {
193
176
  idx: index
194
177
  }), '');
195
178
  }
@@ -204,7 +187,7 @@
204
187
  state = null;
205
188
  }
206
189
 
207
- return readOnly(_extends({
190
+ return readOnly(_extends$1({
208
191
  pathname: location.pathname,
209
192
  hash: '',
210
193
  search: ''
@@ -438,7 +421,7 @@
438
421
 
439
422
  if (index == null) {
440
423
  index = 0;
441
- globalHistory.replaceState(_extends({}, globalHistory.state, {
424
+ globalHistory.replaceState(_extends$1({}, globalHistory.state, {
442
425
  idx: index
443
426
  }), '');
444
427
  }
@@ -465,7 +448,7 @@
465
448
  state = null;
466
449
  }
467
450
 
468
- return readOnly(_extends({
451
+ return readOnly(_extends$1({
469
452
  pathname: location.pathname,
470
453
  hash: '',
471
454
  search: ''
@@ -617,7 +600,7 @@
617
600
  initialEntries = _options3$initialEntr === void 0 ? ['/'] : _options3$initialEntr,
618
601
  initialIndex = _options3.initialIndex;
619
602
  var entries = initialEntries.map(function (entry) {
620
- var location = readOnly(_extends({
603
+ var location = readOnly(_extends$1({
621
604
  pathname: '/',
622
605
  search: '',
623
606
  hash: '',
@@ -642,7 +625,7 @@
642
625
  state = null;
643
626
  }
644
627
 
645
- return readOnly(_extends({
628
+ return readOnly(_extends$1({
646
629
  pathname: location.pathname,
647
630
  search: '',
648
631
  hash: ''
@@ -839,797 +822,390 @@
839
822
  return parsedPath;
840
823
  }
841
824
 
842
- // @ts-nocheck
843
- // We're inlining qss here for compression's sake, but we've included it as a hard dependency for the MIT license it requires.
844
- function encode(obj, pfx) {
845
- var k,
846
- i,
847
- tmp,
848
- str = '';
849
-
850
- for (k in obj) {
851
- if ((tmp = obj[k]) !== void 0) {
852
- if (Array.isArray(tmp)) {
853
- for (i = 0; i < tmp.length; i++) {
854
- str && (str += '&');
855
- str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
856
- }
857
- } else {
858
- str && (str += '&');
859
- str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
860
- }
825
+ var prefix = 'Invariant failed';
826
+ function invariant(condition, message) {
827
+ if (condition) {
828
+ return;
861
829
  }
862
- }
863
-
864
- return (pfx || '') + str;
830
+ var provided = typeof message === 'function' ? message() : message;
831
+ var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
832
+ throw new Error(value);
865
833
  }
866
834
 
867
- function toValue(mix) {
868
- if (!mix) return '';
869
- var str = decodeURIComponent(mix);
870
- if (str === 'false') return false;
871
- if (str === 'true') return true;
872
- return +str * 0 === 0 ? +str : str;
873
- }
835
+ // type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
836
+ // k: infer I,
837
+ // ) => any
838
+ // ? I
839
+ // : never
874
840
 
875
- function decode(str) {
876
- var tmp,
877
- k,
878
- out = {},
879
- arr = str.split('&');
841
+ /**
842
+ * This function returns `a` if `b` is deeply equal.
843
+ * If not, it will replace any deeply equal children of `b` with those of `a`.
844
+ * This can be used for structural sharing between JSON values for example.
845
+ */
846
+ function replaceEqualDeep(prev, next) {
847
+ if (prev === next) {
848
+ return prev;
849
+ }
880
850
 
881
- while (tmp = arr.shift()) {
882
- tmp = tmp.split('=');
883
- k = tmp.shift();
851
+ const array = Array.isArray(prev) && Array.isArray(next);
884
852
 
885
- if (out[k] !== void 0) {
886
- out[k] = [].concat(out[k], toValue(tmp.shift()));
887
- } else {
888
- out[k] = toValue(tmp.shift());
889
- }
890
- }
853
+ if (array || isPlainObject(prev) && isPlainObject(next)) {
854
+ const aSize = array ? prev.length : Object.keys(prev).length;
855
+ const bItems = array ? next : Object.keys(next);
856
+ const bSize = bItems.length;
857
+ const copy = array ? [] : {};
858
+ let equalItems = 0;
891
859
 
892
- return out;
893
- }
860
+ for (let i = 0; i < bSize; i++) {
861
+ const key = array ? i : bItems[i];
862
+ copy[key] = replaceEqualDeep(prev[key], next[key]);
894
863
 
895
- const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId) {
896
- if (options === void 0) {
897
- options = {};
898
- }
864
+ if (copy[key] === prev[key]) {
865
+ equalItems++;
866
+ }
867
+ }
899
868
 
900
- if (isRoot === void 0) {
901
- isRoot = true;
869
+ return aSize === bSize && equalItems === aSize ? prev : copy;
902
870
  }
903
871
 
904
- if (isRoot) {
905
- options.path = rootRouteId;
906
- } else {
907
- warning(!options.path, 'Routes must have a path property.');
908
- } // Strip the root from parentIds
872
+ return next;
873
+ } // Copied from: https://github.com/jonschlinkert/is-plain-object
909
874
 
875
+ function isPlainObject(o) {
876
+ if (!hasObjectPrototype(o)) {
877
+ return false;
878
+ } // If has modified constructor
910
879
 
911
- if (parentId === rootRouteId) {
912
- parentId = '';
913
- }
914
880
 
915
- let path = String(isRoot ? rootRouteId : options.path); // If the path is anything other than an index path, trim it up
881
+ const ctor = o.constructor;
916
882
 
917
- if (path !== '/') {
918
- path = trimPath(path);
919
- }
883
+ if (typeof ctor === 'undefined') {
884
+ return true;
885
+ } // If has modified prototype
920
886
 
921
- let id = joinPaths([parentId, path]);
922
887
 
923
- if (path === rootRouteId) {
924
- path = '/';
925
- }
888
+ const prot = ctor.prototype;
926
889
 
927
- if (id !== rootRouteId) {
928
- id = joinPaths(['/', id]);
929
- }
890
+ if (!hasObjectPrototype(prot)) {
891
+ return false;
892
+ } // If constructor does not have an Object-specific method
930
893
 
931
- const fullPath = id === rootRouteId ? '/' : trimPathRight(id);
932
- return {
933
- id: id,
934
- path: path,
935
- fullPath: fullPath,
936
- options: options,
937
- children,
938
- addChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id)), false, parentId)
939
- };
940
- };
941
- const rootRouteId = '__root__';
942
- // Source
943
- // Detect if we're in the DOM
944
- const isDOM = Boolean(typeof window !== 'undefined' && window.document && window.document.createElement); // This is the default history object if none is defined
945
894
 
946
- const createDefaultHistory = () => isDOM ? createBrowserHistory() : createMemoryHistory();
895
+ if (!prot.hasOwnProperty('isPrototypeOf')) {
896
+ return false;
897
+ } // Most likely a plain Object
947
898
 
948
- function createRouter(userOptions) {
949
- var _userOptions$stringif, _userOptions$parseSea;
950
899
 
951
- const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
900
+ return true;
901
+ }
952
902
 
953
- const originalOptions = _extends$1({}, userOptions, {
954
- stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
955
- parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
956
- });
903
+ function hasObjectPrototype(o) {
904
+ return Object.prototype.toString.call(o) === '[object Object]';
905
+ }
957
906
 
958
- let router = {
959
- options: originalOptions,
960
- listeners: [],
961
- // Resolved after construction
962
- basepath: '',
963
- routeTree: undefined,
964
- routesById: {},
965
- location: undefined,
966
- allRouteInfo: undefined,
967
- //
968
- navigationPromise: Promise.resolve(),
969
- resolveNavigation: () => {},
970
- preloadCache: {},
971
- state: {
972
- status: 'idle',
973
- location: null,
974
- matches: [],
975
- actions: {},
976
- loaderData: {},
977
- lastUpdated: Date.now()
978
- },
979
- startedLoadingAt: Date.now(),
980
- subscribe: listener => {
981
- router.listeners.push(listener);
982
- return () => {
983
- router.listeners = router.listeners.filter(x => x !== listener);
984
- };
985
- },
986
- getRoute: id => {
987
- return router.routesById[id];
988
- },
989
- notify: () => {
990
- router.state = _extends$1({}, router.state);
991
- router.listeners.forEach(listener => listener());
992
- },
993
- mount: () => {
994
- const next = router.buildLocation({
995
- to: '.',
996
- search: true,
997
- hash: true
998
- }); // If the current location isn't updated, trigger a navigation
999
- // to the current location. Otherwise, load the current location.
907
+ function last(arr) {
908
+ return arr[arr.length - 1];
909
+ }
910
+ function warning(cond, message) {
911
+ if (cond) {
912
+ if (typeof console !== 'undefined') console.warn(message);
1000
913
 
1001
- if (next.href !== router.location.href) {
1002
- return router.commitLocation(next, true);
1003
- } else {
1004
- return router.loadLocation();
1005
- }
1006
- },
1007
- update: opts => {
1008
- Object.assign(router.options, opts);
1009
- const {
1010
- basepath,
1011
- routeConfig
1012
- } = router.options;
1013
- router.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
914
+ try {
915
+ throw new Error(message);
916
+ } catch (_unused) {}
917
+ }
1014
918
 
1015
- if (routeConfig) {
1016
- router.routesById = {};
1017
- router.routeTree = router.buildRouteTree(routeConfig);
1018
- }
919
+ return true;
920
+ }
1019
921
 
1020
- return router;
1021
- },
1022
- destroy: history.listen(event => {
1023
- router.loadLocation(router.parseLocation(event.location, router.location));
1024
- }),
1025
- buildRouteTree: rootRouteConfig => {
1026
- const recurseRoutes = (routeConfigs, parent) => {
1027
- return routeConfigs.map(routeConfig => {
1028
- const routeOptions = routeConfig.options;
1029
- const route = createRoute(routeConfig, routeOptions, parent, router); // {
1030
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
1031
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
1032
- // }
1033
-
1034
- const existingRoute = router.routesById[route.routeId];
1035
-
1036
- if (existingRoute) {
1037
- {
1038
- console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
1039
- }
922
+ function isFunction(d) {
923
+ return typeof d === 'function';
924
+ }
1040
925
 
1041
- throw new Error();
1042
- }
1043
- router.routesById[route.routeId] = route;
1044
- const children = routeConfig.children;
1045
- route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
1046
- return route;
1047
- });
1048
- };
926
+ function functionalUpdate(updater, previous) {
927
+ if (isFunction(updater)) {
928
+ return updater(previous);
929
+ }
1049
930
 
1050
- const routes = recurseRoutes([rootRouteConfig]);
1051
- return routes[0];
1052
- },
1053
- parseLocation: (location, previousLocation) => {
1054
- var _location$hash$split$;
931
+ return updater;
932
+ }
1055
933
 
1056
- const parsedSearch = router.options.parseSearch(location.search);
1057
- return {
1058
- pathname: location.pathname,
1059
- searchStr: location.search,
1060
- search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
1061
- hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
1062
- href: "" + location.pathname + location.search + location.hash,
1063
- state: location.state,
1064
- key: location.key
1065
- };
1066
- },
1067
- buildLocation: function buildLocation(dest) {
1068
- var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
934
+ function joinPaths(paths) {
935
+ return cleanPath(paths.filter(Boolean).join('/'));
936
+ }
937
+ function cleanPath(path) {
938
+ // remove double slashes
939
+ return path.replace(/\/{2,}/g, '/');
940
+ }
941
+ function trimPathLeft(path) {
942
+ return path === '/' ? path : path.replace(/^\/{1,}/, '');
943
+ }
944
+ function trimPathRight(path) {
945
+ return path === '/' ? path : path.replace(/\/{1,}$/, '');
946
+ }
947
+ function trimPath(path) {
948
+ return trimPathRight(trimPathLeft(path));
949
+ }
950
+ function resolvePath(basepath, base, to) {
951
+ base = base.replace(new RegExp("^" + basepath), '/');
952
+ to = to.replace(new RegExp("^" + basepath), '/');
953
+ let baseSegments = parsePathname(base);
954
+ const toSegments = parsePathname(to);
955
+ toSegments.forEach((toSegment, index) => {
956
+ if (toSegment.value === '/') {
957
+ if (!index) {
958
+ // Leading slash
959
+ baseSegments = [toSegment];
960
+ } else if (index === toSegments.length - 1) {
961
+ // Trailing Slash
962
+ baseSegments.push(toSegment);
963
+ } else ;
964
+ } else if (toSegment.value === '..') {
965
+ var _last;
1069
966
 
1070
- if (dest === void 0) {
1071
- dest = {};
967
+ // Extra trailing slash? pop it off
968
+ if (baseSegments.length > 1 && ((_last = last(baseSegments)) == null ? void 0 : _last.value) === '/') {
969
+ baseSegments.pop();
1072
970
  }
1073
971
 
1074
- // const resolvedFrom: Location = {
1075
- // ...router.location,
1076
- const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
1077
-
1078
- let pathname = _resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
972
+ baseSegments.pop();
973
+ } else if (toSegment.value === '.') {
974
+ return;
975
+ } else {
976
+ baseSegments.push(toSegment);
977
+ }
978
+ });
979
+ const joined = joinPaths([basepath, ...baseSegments.map(d => d.value)]);
980
+ return cleanPath(joined);
981
+ }
982
+ function parsePathname(pathname) {
983
+ if (!pathname) {
984
+ return [];
985
+ }
1079
986
 
1080
- const fromMatches = router.matchRoutes(router.location.pathname, {
1081
- strictParseParams: true
1082
- });
1083
- const toMatches = router.matchRoutes(pathname);
1084
- const prevParams = (_last = last(fromMatches)) == null ? void 0 : _last.params;
1085
- let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
987
+ pathname = cleanPath(pathname);
988
+ const segments = [];
1086
989
 
1087
- if (nextParams) {
1088
- toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
1089
- Object.assign(nextParams, fn(nextParams));
1090
- });
1091
- }
990
+ if (pathname.slice(0, 1) === '/') {
991
+ pathname = pathname.substring(1);
992
+ segments.push({
993
+ type: 'pathname',
994
+ value: '/'
995
+ });
996
+ }
1092
997
 
1093
- pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
998
+ if (!pathname) {
999
+ return segments;
1000
+ } // Remove empty segments and '.' segments
1094
1001
 
1095
- 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
1096
1002
 
1097
- const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
1098
- : dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
1099
- : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
1100
- : {}; // Then post filters
1003
+ const split = pathname.split('/').filter(Boolean);
1004
+ segments.push(...split.map(part => {
1005
+ if (part.startsWith('*')) {
1006
+ return {
1007
+ type: 'wildcard',
1008
+ value: part
1009
+ };
1010
+ }
1101
1011
 
1102
- const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
1103
- const search = replaceEqualDeep(router.location.search, postFilteredSearch);
1104
- const searchStr = router.options.stringifySearch(search);
1105
- let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
1106
- hash = hash ? "#" + hash : '';
1012
+ if (part.charAt(0) === ':') {
1107
1013
  return {
1108
- pathname,
1109
- search,
1110
- searchStr,
1111
- state: router.location.state,
1112
- hash,
1113
- href: "" + pathname + searchStr + hash,
1114
- key: dest.key
1014
+ type: 'param',
1015
+ value: part
1115
1016
  };
1116
- },
1117
- commitLocation: (next, replace) => {
1118
- const id = '' + Date.now() + Math.random();
1119
- if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
1120
- let nextAction = 'replace';
1017
+ }
1121
1018
 
1122
- if (!replace) {
1123
- nextAction = 'push';
1124
- }
1019
+ return {
1020
+ type: 'pathname',
1021
+ value: part
1022
+ };
1023
+ }));
1125
1024
 
1126
- const isSameUrl = router.parseLocation(history.location).href === next.href;
1025
+ if (pathname.slice(-1) === '/') {
1026
+ pathname = pathname.substring(1);
1027
+ segments.push({
1028
+ type: 'pathname',
1029
+ value: '/'
1030
+ });
1031
+ }
1127
1032
 
1128
- if (isSameUrl && !next.key) {
1129
- nextAction = 'replace';
1130
- }
1033
+ return segments;
1034
+ }
1035
+ function interpolatePath(path, params, leaveWildcard) {
1036
+ const interpolatedPathSegments = parsePathname(path);
1037
+ return joinPaths(interpolatedPathSegments.map(segment => {
1038
+ if (segment.value === '*' && !leaveWildcard) {
1039
+ return '';
1040
+ }
1131
1041
 
1132
- if (nextAction === 'replace') {
1133
- history.replace({
1134
- pathname: next.pathname,
1135
- hash: next.hash,
1136
- search: next.searchStr
1137
- }, {
1138
- id
1139
- });
1140
- } else {
1141
- history.push({
1142
- pathname: next.pathname,
1143
- hash: next.hash,
1144
- search: next.searchStr
1145
- }, {
1146
- id
1147
- });
1148
- }
1042
+ if (segment.type === 'param') {
1043
+ var _segment$value$substr;
1149
1044
 
1150
- router.navigationPromise = new Promise(resolve => {
1151
- const previousNavigationResolve = router.resolveNavigation;
1045
+ return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
1046
+ }
1152
1047
 
1153
- router.resolveNavigation = () => {
1154
- previousNavigationResolve();
1155
- resolve();
1156
- };
1157
- });
1158
- return router.navigationPromise;
1159
- },
1160
- buildNext: opts => {
1161
- const next = router.buildLocation(opts);
1162
- const matches = router.matchRoutes(next.pathname);
1048
+ return segment.value;
1049
+ }));
1050
+ }
1051
+ function matchPathname(currentPathname, matchLocation) {
1052
+ const pathParams = matchByPath(currentPathname, matchLocation); // const searchMatched = matchBySearch(currentLocation.search, matchLocation)
1163
1053
 
1164
- const __preSearchFilters = matches.map(match => {
1165
- var _match$options$preSea;
1054
+ if (matchLocation.to && !pathParams) {
1055
+ return;
1056
+ } // if (matchLocation.search && !searchMatched) {
1057
+ // return
1058
+ // }
1166
1059
 
1167
- return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
1168
- }).flat().filter(Boolean);
1169
1060
 
1170
- const __postSearchFilters = matches.map(match => {
1171
- var _match$options$postSe;
1061
+ return pathParams != null ? pathParams : {};
1062
+ }
1063
+ function matchByPath(from, matchLocation) {
1064
+ var _matchLocation$to;
1172
1065
 
1173
- return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
1174
- }).flat().filter(Boolean);
1066
+ const baseSegments = parsePathname(from);
1067
+ const routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
1068
+ const params = {};
1175
1069
 
1176
- return router.buildLocation(_extends$1({}, opts, {
1177
- __preSearchFilters,
1178
- __postSearchFilters
1179
- }));
1180
- },
1181
- cancelMatches: () => {
1182
- var _router$state$pending, _router$state$pending2;
1183
- [...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 => {
1184
- match.cancel();
1185
- });
1186
- },
1187
- loadLocation: async next => {
1188
- const id = Math.random();
1189
- router.startedLoadingAt = id;
1070
+ let isMatch = (() => {
1071
+ for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
1072
+ const baseSegment = baseSegments[i];
1073
+ const routeSegment = routeSegments[i];
1074
+ const isLastRouteSegment = i === routeSegments.length - 1;
1075
+ const isLastBaseSegment = i === baseSegments.length - 1;
1190
1076
 
1191
- if (next) {
1192
- // Ingest the new location
1193
- router.location = next;
1194
- } // Cancel any pending matches
1077
+ if (routeSegment) {
1078
+ if (routeSegment.type === 'wildcard') {
1079
+ if (baseSegment != null && baseSegment.value) {
1080
+ params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
1081
+ return true;
1082
+ }
1195
1083
 
1084
+ return false;
1085
+ }
1196
1086
 
1197
- router.cancelMatches(); // Match the routes
1087
+ if (routeSegment.type === 'pathname') {
1088
+ if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
1089
+ return true;
1090
+ }
1198
1091
 
1199
- const unloadedMatches = router.matchRoutes(location.pathname, {
1200
- strictParseParams: true
1201
- });
1202
- unloadedMatches.forEach((match, index) => {
1203
- const parent = unloadedMatches[index - 1];
1204
- const child = unloadedMatches[index + 1];
1205
- if (parent) match.__.setParentMatch(parent);
1206
- if (child) match.__.addChildMatch(child);
1207
- });
1208
- router.state = _extends$1({}, router.state, {
1209
- pending: {
1210
- matches: unloadedMatches,
1211
- location: router.location
1092
+ if (baseSegment) {
1093
+ if (matchLocation.caseSensitive) {
1094
+ if (routeSegment.value !== baseSegment.value) {
1095
+ return false;
1096
+ }
1097
+ } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
1098
+ return false;
1099
+ }
1100
+ }
1212
1101
  }
1213
- });
1214
- router.notify(); // Load the matches
1215
-
1216
- const matches = await router.loadMatches(unloadedMatches, {
1217
- withPending: true
1218
- });
1219
1102
 
1220
- if (router.startedLoadingAt !== id) {
1221
- // Ignore side-effects of match loading
1222
- return router.navigationPromise;
1223
- }
1103
+ if (!baseSegment) {
1104
+ return false;
1105
+ }
1224
1106
 
1225
- const previousMatches = router.state.matches;
1226
- previousMatches.filter(d => {
1227
- return !matches.find(dd => dd.matchId === d.matchId);
1228
- }).forEach(d => {
1229
- d.__.onExit == null ? void 0 : d.__.onExit({
1230
- params: d.params,
1231
- search: d.routeSearch
1232
- });
1233
- });
1234
- previousMatches.filter(d => {
1235
- return matches.find(dd => dd.matchId === d.matchId);
1236
- }).forEach(d => {
1237
- d.options.onTransition == null ? void 0 : d.options.onTransition({
1238
- params: d.params,
1239
- search: d.routeSearch
1240
- });
1241
- });
1242
- matches.filter(d => {
1243
- return !previousMatches.find(dd => dd.matchId === d.matchId);
1244
- }).forEach(d => {
1245
- d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1246
- params: d.params,
1247
- search: d.search
1248
- });
1249
- });
1250
- router.state = _extends$1({}, router.state, {
1251
- location: router.location,
1252
- matches,
1253
- pending: undefined
1254
- });
1107
+ if (routeSegment.type === 'param') {
1108
+ if ((baseSegment == null ? void 0 : baseSegment.value) === '/') {
1109
+ return false;
1110
+ }
1255
1111
 
1256
- if (matches.some(d => d.status === 'loading')) {
1257
- router.notify();
1258
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
1112
+ if (!baseSegment.value.startsWith(':')) {
1113
+ params[routeSegment.value.substring(1)] = baseSegment.value;
1114
+ }
1115
+ }
1259
1116
  }
1260
1117
 
1261
- if (router.startedLoadingAt !== id) {
1262
- // Ignore side-effects of match loading
1263
- return;
1118
+ if (isLastRouteSegment && !isLastBaseSegment) {
1119
+ return !!matchLocation.fuzzy;
1264
1120
  }
1121
+ }
1265
1122
 
1266
- router.notify();
1267
- router.resolveNavigation();
1268
- },
1269
- cleanPreloadCache: () => {
1270
- const now = Date.now();
1271
- Object.keys(router.preloadCache).forEach(matchId => {
1272
- const entry = router.preloadCache[matchId]; // Don't remove loading matches
1273
-
1274
- if (entry.match.status === 'loading') {
1275
- return;
1276
- } // Do not remove successful matches that are still valid
1277
-
1123
+ return true;
1124
+ })();
1278
1125
 
1279
- if (entry.match.updatedAt && entry.match.updatedAt + entry.maxAge > now) {
1280
- return;
1281
- } // Everything else gets removed
1126
+ return isMatch ? params : undefined;
1127
+ }
1282
1128
 
1129
+ // @ts-nocheck
1130
+ // 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.
1131
+ function encode(obj, pfx) {
1132
+ var k,
1133
+ i,
1134
+ tmp,
1135
+ str = '';
1283
1136
 
1284
- delete router.preloadCache[matchId];
1285
- });
1286
- },
1287
- loadRoute: async function loadRoute(navigateOpts, loaderOpts) {
1288
- if (navigateOpts === void 0) {
1289
- navigateOpts = router.location;
1137
+ for (k in obj) {
1138
+ if ((tmp = obj[k]) !== void 0) {
1139
+ if (Array.isArray(tmp)) {
1140
+ for (i = 0; i < tmp.length; i++) {
1141
+ str && (str += '&');
1142
+ str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
1143
+ }
1144
+ } else {
1145
+ str && (str += '&');
1146
+ str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
1290
1147
  }
1148
+ }
1149
+ }
1291
1150
 
1292
- const next = router.buildNext(navigateOpts);
1293
- const matches = router.matchRoutes(next.pathname, {
1294
- strictParseParams: true
1295
- });
1296
- await router.loadMatches(matches, {
1297
- preload: true,
1298
- maxAge: loaderOpts.maxAge
1299
- });
1300
- return matches;
1301
- },
1302
- matchRoutes: (pathname, opts) => {
1303
- var _router$state$pending3, _router$state$pending4;
1304
-
1305
- router.cleanPreloadCache();
1306
- const matches = [];
1151
+ return (pfx || '') + str;
1152
+ }
1307
1153
 
1308
- if (!router.routeTree) {
1309
- return matches;
1310
- }
1311
-
1312
- 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 : [])];
1313
-
1314
- const recurse = async (routes, parentMatch) => {
1315
- var _parentMatch$params, _router$options$filte, _router$preloadCache$, _route$childRoutes2;
1316
-
1317
- let params = (_parentMatch$params = parentMatch == null ? void 0 : parentMatch.params) != null ? _parentMatch$params : {};
1318
- const filteredRoutes = (_router$options$filte = router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) != null ? _router$options$filte : routes;
1319
- const route = filteredRoutes == null ? void 0 : filteredRoutes.find(route => {
1320
- var _route$childRoutes, _route$options$caseSe;
1321
-
1322
- const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length);
1323
- const matchParams = matchPathname(pathname, {
1324
- to: route.fullPath,
1325
- fuzzy,
1326
- caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
1327
- });
1328
-
1329
- if (matchParams) {
1330
- let parsedParams;
1331
-
1332
- try {
1333
- var _route$options$parseP;
1334
-
1335
- parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
1336
- } catch (err) {
1337
- if (opts != null && opts.strictParseParams) {
1338
- throw err;
1339
- }
1340
- }
1341
-
1342
- params = _extends$1({}, params, parsedParams);
1343
- }
1344
-
1345
- return !!matchParams;
1346
- });
1347
-
1348
- if (!route) {
1349
- return;
1350
- }
1351
-
1352
- const interpolatedPath = interpolatePath(route.routePath, params);
1353
- const matchId = interpolatePath(route.routeId, params, true);
1354
- const match = existingMatches.find(d => d.matchId === matchId) || ((_router$preloadCache$ = router.preloadCache[matchId]) == null ? void 0 : _router$preloadCache$.match) || createRouteMatch(router, route, {
1355
- matchId,
1356
- params,
1357
- pathname: joinPaths([pathname, interpolatedPath])
1358
- });
1359
- matches.push(match);
1360
-
1361
- if ((_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length) {
1362
- recurse(route.childRoutes, match);
1363
- }
1364
- };
1365
-
1366
- recurse([router.routeTree]);
1367
- return matches;
1368
- },
1369
- loadMatches: async (resolvedMatches, loaderOpts) => {
1370
- const matchPromises = resolvedMatches.map(async match => {
1371
- // Validate the match (loads search params etc)
1372
- match.__.validate(); // If this is a preload, add it to the preload cache
1373
-
1374
-
1375
- if (loaderOpts != null && loaderOpts.preload) {
1376
- router.preloadCache[match.matchId] = {
1377
- maxAge: loaderOpts == null ? void 0 : loaderOpts.maxAge,
1378
- match
1379
- };
1380
- } // If the match is invalid, errored or idle, trigger it to load
1381
-
1382
-
1383
- if (match.status === 'success' && match.isInvalid || match.status === 'error' || match.status === 'idle') {
1384
- match.load();
1385
- } // If requested, start the pending timers
1386
-
1387
-
1388
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
1389
- // This might be completion, error, or a pending state
1390
-
1391
- await match.__.loadPromise;
1392
- });
1393
- router.notify();
1394
- await Promise.all(matchPromises);
1395
- return resolvedMatches;
1396
- },
1397
- invalidateRoute: opts => {
1398
- var _router$state$pending5, _router$state$pending6;
1399
-
1400
- const next = router.buildNext(opts);
1401
- const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
1402
- [...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 => {
1403
- if (unloadedMatchIds.includes(match.matchId)) {
1404
- match.isInvalid = true;
1405
- }
1406
- });
1407
- },
1408
- reload: () => router._navigate({
1409
- fromCurrent: true,
1410
- replace: true,
1411
- search: true
1412
- }),
1413
- resolvePath: (from, path) => {
1414
- return _resolvePath(router.basepath, from, cleanPath(path));
1415
- },
1416
- matchRoute: (location, opts) => {
1417
- var _location$from;
1418
-
1419
- // const location = router.buildNext(opts)
1420
- location = _extends$1({}, location, {
1421
- to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
1422
- });
1423
- const next = router.buildNext(location);
1154
+ function toValue(mix) {
1155
+ if (!mix) return '';
1156
+ var str = decodeURIComponent(mix);
1157
+ if (str === 'false') return false;
1158
+ if (str === 'true') return true;
1159
+ return +str * 0 === 0 ? +str : str;
1160
+ }
1424
1161
 
1425
- if (opts != null && opts.pending) {
1426
- var _router$state$pending7;
1162
+ function decode(str) {
1163
+ var tmp,
1164
+ k,
1165
+ out = {},
1166
+ arr = str.split('&');
1427
1167
 
1428
- if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
1429
- return false;
1430
- }
1168
+ while (tmp = arr.shift()) {
1169
+ tmp = tmp.split('=');
1170
+ k = tmp.shift();
1431
1171
 
1432
- return !!matchPathname(router.state.pending.location.pathname, _extends$1({}, opts, {
1433
- to: next.pathname
1434
- }));
1435
- }
1172
+ if (out[k] !== void 0) {
1173
+ out[k] = [].concat(out[k], toValue(tmp.shift()));
1174
+ } else {
1175
+ out[k] = toValue(tmp.shift());
1176
+ }
1177
+ }
1436
1178
 
1437
- return !!matchPathname(router.state.location.pathname, _extends$1({}, opts, {
1438
- to: next.pathname
1439
- }));
1440
- },
1441
- _navigate: location => {
1442
- const next = router.buildNext(location);
1443
- return router.commitLocation(next, location.replace);
1444
- },
1445
- navigate: async _ref => {
1446
- let {
1447
- from,
1448
- to = '.',
1449
- search,
1450
- hash,
1451
- replace
1452
- } = _ref;
1453
- // If this link simply reloads the current route,
1454
- // make sure it has a new key so it will trigger a data refresh
1455
- // If this `to` is a valid external URL, return
1456
- // null for LinkUtils
1457
- const toString = String(to);
1458
- const fromString = String(from);
1459
- let isExternal;
1179
+ return out;
1180
+ }
1460
1181
 
1461
- try {
1462
- new URL("" + toString);
1463
- isExternal = true;
1464
- } catch (e) {}
1182
+ function _extends() {
1183
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
1184
+ for (var i = 1; i < arguments.length; i++) {
1185
+ var source = arguments[i];
1465
1186
 
1466
- if (isExternal) {
1467
- {
1468
- throw new Error('Attempting to navigate to external url with router.navigate!');
1187
+ for (var key in source) {
1188
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1189
+ target[key] = source[key];
1469
1190
  }
1470
1191
  }
1471
-
1472
- return router._navigate({
1473
- from: fromString,
1474
- to: toString,
1475
- search,
1476
- hash
1477
- });
1478
- },
1479
- buildLink: _ref2 => {
1480
- var _preload, _ref3, _ref4;
1481
-
1482
- let {
1483
- from,
1484
- to = '.',
1485
- search,
1486
- params,
1487
- hash,
1488
- target,
1489
- replace,
1490
- activeOptions,
1491
- preload,
1492
- preloadMaxAge: userPreloadMaxAge,
1493
- preloadDelay: userPreloadDelay,
1494
- disabled
1495
- } = _ref2;
1496
-
1497
- // If this link simply reloads the current route,
1498
- // make sure it has a new key so it will trigger a data refresh
1499
- // If this `to` is a valid external URL, return
1500
- // null for LinkUtils
1501
- try {
1502
- new URL("" + to);
1503
- return {
1504
- type: 'external',
1505
- href: to
1506
- };
1507
- } catch (e) {}
1508
-
1509
- const nextOpts = {
1510
- from,
1511
- to,
1512
- search,
1513
- params,
1514
- hash,
1515
- replace
1516
- };
1517
- const next = router.buildNext(nextOpts);
1518
- preload = (_preload = preload) != null ? _preload : router.options.defaultLinkPreload;
1519
- const preloadMaxAge = (_ref3 = userPreloadMaxAge != null ? userPreloadMaxAge : router.options.defaultLinkPreloadMaxAge) != null ? _ref3 : 2000;
1520
- const preloadDelay = (_ref4 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultLinkPreloadDelay) != null ? _ref4 : 50; // Compare path/hash for matches
1521
-
1522
- const pathIsEqual = router.state.location.pathname === next.pathname;
1523
- const currentPathSplit = router.state.location.pathname.split('/');
1524
- const nextPathSplit = next.pathname.split('/');
1525
- const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
1526
- const hashIsEqual = router.state.location.hash === next.hash; // Combine the matches based on user options
1527
-
1528
- const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
1529
- const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
1530
-
1531
- const isActive = pathTest && hashTest; // The click handler
1532
-
1533
- const handleClick = e => {
1534
- if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
1535
- e.preventDefault();
1536
-
1537
- if (pathIsEqual && !search && !hash) {
1538
- router.invalidateRoute(nextOpts);
1539
- } // All is well? Navigate!)
1540
-
1541
-
1542
- router._navigate(nextOpts);
1543
- }
1544
- }; // The click handler
1545
-
1546
-
1547
- const handleFocus = e => {
1548
- if (preload && preloadMaxAge > 0) {
1549
- router.loadRoute(nextOpts, {
1550
- maxAge: preloadMaxAge
1551
- });
1552
- }
1553
- };
1554
-
1555
- const handleEnter = e => {
1556
- const target = e.target || {};
1557
-
1558
- if (preload && preloadMaxAge > 0) {
1559
- if (target.preloadTimeout) {
1560
- return;
1561
- }
1562
-
1563
- target.preloadTimeout = setTimeout(() => {
1564
- target.preloadTimeout = null;
1565
- router.loadRoute(nextOpts, {
1566
- maxAge: preloadMaxAge
1567
- });
1568
- }, preloadDelay);
1569
- }
1570
- };
1571
-
1572
- const handleLeave = e => {
1573
- const target = e.target || {};
1574
-
1575
- if (target.preloadTimeout) {
1576
- clearTimeout(target.preloadTimeout);
1577
- target.preloadTimeout = null;
1578
- }
1579
- };
1580
-
1581
- return {
1582
- type: 'internal',
1583
- next,
1584
- handleFocus,
1585
- handleClick,
1586
- handleEnter,
1587
- handleLeave,
1588
- isActive,
1589
- disabled
1590
- };
1591
- },
1592
- __experimental__createSnapshot: () => {
1593
- return _extends$1({}, router.state, {
1594
- matches: router.state.matches.map(_ref5 => {
1595
- let {
1596
- routeLoaderData: loaderData,
1597
- matchId
1598
- } = _ref5;
1599
- return {
1600
- matchId,
1601
- loaderData
1602
- };
1603
- })
1604
- });
1605
1192
  }
1606
- };
1607
- router.location = router.parseLocation(history.location); // router.state.location = __experimental__snapshot?.location ?? router.location
1608
-
1609
- router.state.location = router.location;
1610
- router.update(userOptions); // Allow frameworks to hook into the router creation
1611
-
1612
- router.options.createRouter == null ? void 0 : router.options.createRouter(router); // router.mount()
1613
1193
 
1614
- return router;
1194
+ return target;
1195
+ };
1196
+ return _extends.apply(this, arguments);
1615
1197
  }
1198
+
1616
1199
  function createRoute(routeConfig, options, parent, router) {
1617
- // const id = (
1618
- // options.path === rootRouteId
1619
- // ? rootRouteId
1620
- // : joinPaths([
1621
- // parent!.id,
1622
- // `${options.path?.replace(/(.)\/$/, '$1')}`,
1623
- // ]).replace(new RegExp(`^${rootRouteId}`), '')
1624
- // ) as TRouteInfo['id']
1625
1200
  const {
1626
- id: routeId,
1201
+ id,
1202
+ routeId,
1627
1203
  path: routePath,
1628
1204
  fullPath
1629
1205
  } = routeConfig;
1630
1206
 
1631
- const action = router.state.actions[routeId] || (() => {
1632
- router.state.actions[routeId] = {
1207
+ const action = router.state.actions[id] || (() => {
1208
+ router.state.actions[id] = {
1633
1209
  pending: [],
1634
1210
  submit: async (submission, actionOpts) => {
1635
1211
  var _actionOpts$invalidat;
@@ -1644,10 +1220,12 @@
1644
1220
  status: 'pending',
1645
1221
  submission
1646
1222
  };
1223
+ action.current = actionState;
1647
1224
  action.latest = actionState;
1648
1225
  action.pending.push(actionState);
1649
- router.state = _extends$1({}, router.state, {
1650
- action: actionState
1226
+ router.state = _extends({}, router.state, {
1227
+ currentAction: actionState,
1228
+ latestAction: actionState
1651
1229
  });
1652
1230
  router.notify();
1653
1231
 
@@ -1671,20 +1249,54 @@
1671
1249
  actionState.status = 'error';
1672
1250
  } finally {
1673
1251
  action.pending = action.pending.filter(d => d !== actionState);
1674
-
1675
- if (actionState === router.state.action) {
1676
- router.state.action = undefined;
1677
- }
1678
-
1252
+ router.removeActionQueue.push({
1253
+ action,
1254
+ actionState
1255
+ });
1679
1256
  router.notify();
1680
1257
  }
1681
1258
  }
1682
1259
  };
1683
- return router.state.actions[routeId];
1260
+ return router.state.actions[id];
1261
+ })();
1262
+
1263
+ const loader = router.state.loaders[id] || (() => {
1264
+ router.state.loaders[id] = {
1265
+ pending: [],
1266
+ fetch: async loaderContext => {
1267
+ if (!route) {
1268
+ return;
1269
+ }
1270
+
1271
+ const loaderState = {
1272
+ loadedAt: Date.now(),
1273
+ loaderContext
1274
+ };
1275
+ loader.current = loaderState;
1276
+ loader.latest = loaderState;
1277
+ loader.pending.push(loaderState); // router.state = {
1278
+ // ...router.state,
1279
+ // currentAction: loaderState,
1280
+ // latestAction: loaderState,
1281
+ // }
1282
+
1283
+ router.notify();
1284
+
1285
+ try {
1286
+ return await (route.options.loader == null ? void 0 : route.options.loader(loaderContext));
1287
+ } finally {
1288
+ loader.pending = loader.pending.filter(d => d !== loaderState); // router.removeActionQueue.push({ loader, loaderState })
1289
+
1290
+ router.notify();
1291
+ }
1292
+ }
1293
+ };
1294
+ return router.state.loaders[id];
1684
1295
  })();
1685
1296
 
1686
1297
  let route = {
1687
- routeId,
1298
+ routeId: id,
1299
+ routeRouteId: routeId,
1688
1300
  routePath,
1689
1301
  fullPath,
1690
1302
  options,
@@ -1692,18 +1304,19 @@
1692
1304
  childRoutes: undefined,
1693
1305
  parentRoute: parent,
1694
1306
  action,
1307
+ loader: loader,
1695
1308
  buildLink: options => {
1696
- return router.buildLink(_extends$1({}, options, {
1309
+ return router.buildLink(_extends({}, options, {
1697
1310
  from: fullPath
1698
1311
  }));
1699
1312
  },
1700
1313
  navigate: options => {
1701
- return router.navigate(_extends$1({}, options, {
1314
+ return router.navigate(_extends({}, options, {
1702
1315
  from: fullPath
1703
1316
  }));
1704
1317
  },
1705
1318
  matchRoute: (matchLocation, opts) => {
1706
- return router.matchRoute(_extends$1({}, matchLocation, {
1319
+ return router.matchRoute(_extends({}, matchLocation, {
1707
1320
  from: fullPath
1708
1321
  }), opts);
1709
1322
  }
@@ -1714,8 +1327,69 @@
1714
1327
  });
1715
1328
  return route;
1716
1329
  }
1330
+ function cascadeLoaderData(matches) {
1331
+ matches.forEach((match, index) => {
1332
+ const parent = matches[index - 1];
1333
+
1334
+ if (parent) {
1335
+ match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
1336
+ }
1337
+ });
1338
+ }
1339
+
1340
+ const rootRouteId = '__root__';
1341
+ const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
1342
+ if (options === void 0) {
1343
+ options = {};
1344
+ }
1345
+
1346
+ if (isRoot === void 0) {
1347
+ isRoot = true;
1348
+ }
1349
+
1350
+ if (isRoot) {
1351
+ options.path = rootRouteId;
1352
+ } // Strip the root from parentIds
1353
+
1354
+
1355
+ if (parentId === rootRouteId) {
1356
+ parentId = '';
1357
+ }
1358
+
1359
+ let path = isRoot ? rootRouteId : options.path; // If the path is anything other than an index path, trim it up
1360
+
1361
+ if (path && path !== '/') {
1362
+ path = trimPath(path);
1363
+ }
1364
+
1365
+ const routeId = path || options.id;
1366
+ let id = joinPaths([parentId, routeId]);
1367
+
1368
+ if (path === rootRouteId) {
1369
+ path = '/';
1370
+ }
1371
+
1372
+ if (id !== rootRouteId) {
1373
+ id = joinPaths(['/', id]);
1374
+ }
1375
+
1376
+ const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parentPath, path]));
1377
+ return {
1378
+ id: id,
1379
+ routeId: routeId,
1380
+ path: path,
1381
+ fullPath: fullPath,
1382
+ options: options,
1383
+ children,
1384
+ createChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)), false, parentId, parentPath),
1385
+ addChildren: children => createRouteConfig(options, children, false, parentId, parentPath),
1386
+ createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)
1387
+ };
1388
+ };
1389
+
1390
+ const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1717
1391
  function createRouteMatch(router, route, opts) {
1718
- const routeMatch = _extends$1({}, route, opts, {
1392
+ const routeMatch = _extends({}, route, opts, {
1719
1393
  router,
1720
1394
  routeSearch: {},
1721
1395
  search: {},
@@ -1726,6 +1400,11 @@
1726
1400
  isPending: false,
1727
1401
  isFetching: false,
1728
1402
  isInvalid: false,
1403
+ invalidAt: Infinity,
1404
+ getIsInvalid: () => {
1405
+ const now = Date.now();
1406
+ return routeMatch.isInvalid || routeMatch.invalidAt < now;
1407
+ },
1729
1408
  __: {
1730
1409
  abortController: new AbortController(),
1731
1410
  latestId: '',
@@ -1761,16 +1440,17 @@
1761
1440
  clearTimeout(routeMatch.__.pendingMinTimeout);
1762
1441
  delete routeMatch.__.pendingMinPromise;
1763
1442
  },
1764
- setParentMatch: parentMatch => {
1765
- routeMatch.parentMatch = parentMatch;
1766
- },
1767
- addChildMatch: childMatch => {
1768
- if (routeMatch.childMatches.find(d => d.matchId === childMatch.matchId)) {
1769
- return;
1770
- }
1771
-
1772
- routeMatch.childMatches.push(childMatch);
1773
- },
1443
+ // setParentMatch: (parentMatch?: RouteMatch) => {
1444
+ // routeMatch.parentMatch = parentMatch
1445
+ // },
1446
+ // addChildMatch: (childMatch: RouteMatch) => {
1447
+ // if (
1448
+ // routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
1449
+ // ) {
1450
+ // return
1451
+ // }
1452
+ // routeMatch.childMatches.push(childMatch)
1453
+ // },
1774
1454
  validate: () => {
1775
1455
  var _routeMatch$parentMat, _routeMatch$parentMat2;
1776
1456
 
@@ -1779,14 +1459,15 @@
1779
1459
 
1780
1460
  try {
1781
1461
  const prevSearch = routeMatch.routeSearch;
1782
- let nextSearch = replaceEqualDeep(prevSearch, routeMatch.options.validateSearch == null ? void 0 : routeMatch.options.validateSearch(parentSearch)); // Invalidate route matches when search param stability changes
1462
+ const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
1463
+ let nextSearch = replaceEqualDeep(prevSearch, validator == null ? void 0 : validator(parentSearch)); // Invalidate route matches when search param stability changes
1783
1464
 
1784
1465
  if (prevSearch !== nextSearch) {
1785
1466
  routeMatch.isInvalid = true;
1786
1467
  }
1787
1468
 
1788
1469
  routeMatch.routeSearch = nextSearch;
1789
- routeMatch.search = replaceEqualDeep(parentSearch, _extends$1({}, parentSearch, nextSearch));
1470
+ routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
1790
1471
  } catch (err) {
1791
1472
  console.error(err);
1792
1473
  const error = new Error('Invalid search params found', {
@@ -1807,13 +1488,43 @@
1807
1488
 
1808
1489
  routeMatch.__.cancelPending();
1809
1490
  },
1810
- load: async () => {
1491
+ invalidate: () => {
1492
+ routeMatch.isInvalid = true;
1493
+ },
1494
+ hasLoaders: () => {
1495
+ return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
1496
+ },
1497
+ load: async loaderOpts => {
1498
+ const now = Date.now();
1499
+ 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
1500
+
1501
+ if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
1502
+ // If the match is currently active, don't preload it
1503
+ if (router.state.matches.find(d => d.matchId === routeMatch.matchId)) {
1504
+ return;
1505
+ }
1506
+
1507
+ router.matchCache[routeMatch.matchId] = {
1508
+ gc: now + loaderOpts.gcMaxAge,
1509
+ match: routeMatch
1510
+ };
1511
+ } // If the match is invalid, errored or idle, trigger it to load
1512
+
1513
+
1514
+ if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
1515
+ const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
1516
+ routeMatch.fetch({
1517
+ maxAge
1518
+ });
1519
+ }
1520
+ },
1521
+ fetch: async opts => {
1811
1522
  const id = '' + Date.now() + Math.random();
1812
1523
  routeMatch.__.latestId = id; // If the match was in an error state, set it
1813
1524
  // to a loading state again. Otherwise, keep it
1814
1525
  // as loading or resolved
1815
1526
 
1816
- if (routeMatch.status === 'error' || routeMatch.status === 'idle') {
1527
+ if (routeMatch.status === 'idle') {
1817
1528
  routeMatch.status = 'loading';
1818
1529
  } // We started loading the route, so it's no longer invalid
1819
1530
 
@@ -1826,25 +1537,10 @@
1826
1537
  routeMatch.__.resolve = resolve;
1827
1538
 
1828
1539
  const loaderPromise = (async () => {
1829
- const importer = routeMatch.options.import; // First, run any importers
1830
-
1831
- if (importer) {
1832
- routeMatch.__.importPromise = importer({
1833
- params: routeMatch.params // search: routeMatch.search,
1834
-
1835
- }).then(imported => {
1836
- routeMatch.__ = _extends$1({}, routeMatch.__, imported);
1837
- });
1838
- } // Wait for the importer to finish before
1839
- // attempting to load elements and data
1840
-
1841
-
1842
- await routeMatch.__.importPromise; // Next, load the elements and data in parallel
1843
-
1540
+ // Load the elements and data in parallel
1844
1541
  routeMatch.__.elementsPromise = (async () => {
1845
1542
  // then run all element and data loaders in parallel
1846
1543
  // For each element type, potentially load it asynchronously
1847
- const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1848
1544
  await Promise.all(elementTypes.map(async type => {
1849
1545
  const routeElement = routeMatch.options[type];
1850
1546
 
@@ -1852,32 +1548,32 @@
1852
1548
  return;
1853
1549
  }
1854
1550
 
1855
- if (typeof routeElement === 'function') {
1856
- const res = await routeElement(routeMatch);
1857
- routeMatch.__[type] = res;
1858
- } else {
1859
- routeMatch.__[type] = routeMatch.options[type];
1860
- }
1551
+ routeMatch.__[type] = await router.options.createElement(routeElement);
1861
1552
  }));
1862
1553
  })();
1863
1554
 
1864
1555
  routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1865
1556
  try {
1866
- const data = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
1867
- params: routeMatch.params,
1868
- search: routeMatch.routeSearch,
1869
- signal: routeMatch.__.abortController.signal
1870
- }));
1557
+ var _ref, _ref2, _opts$maxAge;
1871
1558
 
1872
- if (id !== routeMatch.__.latestId) {
1873
- return routeMatch.__.loaderPromise;
1559
+ if (routeMatch.options.loader) {
1560
+ const data = await routeMatch.options.loader({
1561
+ params: routeMatch.params,
1562
+ search: routeMatch.routeSearch,
1563
+ signal: routeMatch.__.abortController.signal
1564
+ });
1565
+
1566
+ if (id !== routeMatch.__.latestId) {
1567
+ return routeMatch.__.loaderPromise;
1568
+ }
1569
+
1570
+ routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1874
1571
  }
1875
1572
 
1876
- routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1877
- cascadeLoaderData(routeMatch);
1878
1573
  routeMatch.error = undefined;
1879
1574
  routeMatch.status = 'success';
1880
1575
  routeMatch.updatedAt = Date.now();
1576
+ 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);
1881
1577
  } catch (err) {
1882
1578
  if (id !== routeMatch.__.latestId) {
1883
1579
  return routeMatch.__.loaderPromise;
@@ -1931,370 +1627,827 @@
1931
1627
  }
1932
1628
  });
1933
1629
 
1934
- return routeMatch;
1935
- }
1936
-
1937
- function cascadeLoaderData(routeMatch) {
1938
- if (routeMatch.parentMatch) {
1939
- routeMatch.loaderData = replaceEqualDeep(routeMatch.loaderData, _extends$1({}, routeMatch.parentMatch.loaderData, routeMatch.routeLoaderData));
1940
- }
1941
-
1942
- if (routeMatch.childMatches.length) {
1943
- routeMatch.childMatches.forEach(childMatch => {
1944
- cascadeLoaderData(childMatch);
1945
- });
1630
+ if (!routeMatch.hasLoaders()) {
1631
+ routeMatch.status = 'success';
1946
1632
  }
1947
- }
1948
-
1949
- function matchPathname(currentPathname, matchLocation) {
1950
- const pathParams = matchByPath(currentPathname, matchLocation); // const searchMatched = matchBySearch(currentLocation.search, matchLocation)
1951
-
1952
- if (matchLocation.to && !pathParams) {
1953
- return;
1954
- } // if (matchLocation.search && !searchMatched) {
1955
- // return
1956
- // }
1957
-
1958
1633
 
1959
- return pathParams != null ? pathParams : {};
1634
+ return routeMatch;
1960
1635
  }
1961
1636
 
1962
- function interpolatePath(path, params, leaveWildcard) {
1963
- const interpolatedPathSegments = parsePathname(path);
1964
- return joinPaths(interpolatedPathSegments.map(segment => {
1965
- if (segment.value === '*' && !leaveWildcard) {
1966
- return '';
1637
+ const defaultParseSearch = parseSearchWith(JSON.parse);
1638
+ const defaultStringifySearch = stringifySearchWith(JSON.stringify);
1639
+ function parseSearchWith(parser) {
1640
+ return searchStr => {
1641
+ if (searchStr.substring(0, 1) === '?') {
1642
+ searchStr = searchStr.substring(1);
1967
1643
  }
1968
1644
 
1969
- if (segment.type === 'param') {
1970
- var _segment$value$substr;
1645
+ let query = decode(searchStr); // Try to parse any query params that might be json
1971
1646
 
1972
- return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
1647
+ for (let key in query) {
1648
+ const value = query[key];
1649
+
1650
+ if (typeof value === 'string') {
1651
+ try {
1652
+ query[key] = parser(value);
1653
+ } catch (err) {//
1654
+ }
1655
+ }
1973
1656
  }
1974
1657
 
1975
- return segment.value;
1976
- }));
1658
+ return query;
1659
+ };
1977
1660
  }
1661
+ function stringifySearchWith(stringify) {
1662
+ return search => {
1663
+ search = _extends({}, search);
1978
1664
 
1979
- function warning(cond, message) {
1980
- if (cond) {
1981
- if (typeof console !== 'undefined') console.warn(message);
1665
+ if (search) {
1666
+ Object.keys(search).forEach(key => {
1667
+ const val = search[key];
1982
1668
 
1983
- try {
1984
- throw new Error(message);
1985
- } catch (_unused) {}
1986
- }
1669
+ if (typeof val === 'undefined' || val === undefined) {
1670
+ delete search[key];
1671
+ } else if (val && typeof val === 'object' && val !== null) {
1672
+ try {
1673
+ search[key] = stringify(val);
1674
+ } catch (err) {// silent
1675
+ }
1676
+ }
1677
+ });
1678
+ }
1987
1679
 
1988
- return true;
1680
+ const searchStr = encode(search).toString();
1681
+ return searchStr ? "?" + searchStr : '';
1682
+ };
1989
1683
  }
1990
1684
 
1991
- function isFunction(d) {
1992
- return typeof d === 'function';
1993
- }
1685
+ var _window$document;
1686
+ // Detect if we're in the DOM
1687
+ const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
1994
1688
 
1995
- function functionalUpdate(updater, previous) {
1996
- if (isFunction(updater)) {
1997
- return updater(previous);
1998
- }
1689
+ const createDefaultHistory = () => !isServer ? createBrowserHistory() : createMemoryHistory();
1999
1690
 
2000
- return updater;
2001
- }
1691
+ function createRouter(userOptions) {
1692
+ var _userOptions$stringif, _userOptions$parseSea;
2002
1693
 
2003
- function joinPaths(paths) {
2004
- return cleanPath(paths.filter(Boolean).join('/'));
2005
- }
1694
+ const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
2006
1695
 
2007
- function cleanPath(path) {
2008
- // remove double slashes
2009
- return path.replace(/\/{2,}/g, '/');
2010
- }
1696
+ const originalOptions = _extends({
1697
+ defaultLoaderGcMaxAge: 5 * 60 * 1000,
1698
+ defaultLoaderMaxAge: 0,
1699
+ defaultPreloadMaxAge: 2000,
1700
+ defaultPreloadDelay: 50
1701
+ }, userOptions, {
1702
+ stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
1703
+ parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
1704
+ });
2011
1705
 
2012
- function trimPathLeft(path) {
2013
- return path === '/' ? path : path.replace(/^\/{1,}/, '');
2014
- }
1706
+ let router = {
1707
+ history,
1708
+ options: originalOptions,
1709
+ listeners: [],
1710
+ removeActionQueue: [],
1711
+ // Resolved after construction
1712
+ basepath: '',
1713
+ routeTree: undefined,
1714
+ routesById: {},
1715
+ location: undefined,
1716
+ allRouteInfo: undefined,
1717
+ //
1718
+ navigationPromise: Promise.resolve(),
1719
+ resolveNavigation: () => {},
1720
+ matchCache: {},
1721
+ state: {
1722
+ status: 'idle',
1723
+ location: null,
1724
+ matches: [],
1725
+ actions: {},
1726
+ loaders: {},
1727
+ loaderData: {},
1728
+ lastUpdated: Date.now(),
1729
+ isFetching: false,
1730
+ isPreloading: false
1731
+ },
1732
+ startedLoadingAt: Date.now(),
1733
+ subscribe: listener => {
1734
+ router.listeners.push(listener);
1735
+ return () => {
1736
+ router.listeners = router.listeners.filter(x => x !== listener);
1737
+ };
1738
+ },
1739
+ getRoute: id => {
1740
+ return router.routesById[id];
1741
+ },
1742
+ notify: () => {
1743
+ router.state = _extends({}, router.state, {
1744
+ isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
1745
+ isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
1746
+ });
1747
+ cascadeLoaderData(router.state.matches);
1748
+ router.listeners.forEach(listener => listener());
1749
+ },
1750
+ mount: () => {
1751
+ const next = router.__.buildLocation({
1752
+ to: '.',
1753
+ search: true,
1754
+ hash: true
1755
+ }); // If the current location isn't updated, trigger a navigation
1756
+ // to the current location. Otherwise, load the current location.
2015
1757
 
2016
- function trimPathRight(path) {
2017
- return path === '/' ? path : path.replace(/\/{1,}$/, '');
2018
- }
2019
1758
 
2020
- function trimPath(path) {
2021
- return trimPathRight(trimPathLeft(path));
2022
- }
1759
+ if (next.href !== router.location.href) {
1760
+ router.__.commitLocation(next, true);
1761
+ } else {
1762
+ router.loadLocation();
1763
+ }
2023
1764
 
2024
- function matchByPath(from, matchLocation) {
2025
- var _matchLocation$to;
1765
+ const unsub = history.listen(event => {
1766
+ router.loadLocation(router.__.parseLocation(event.location, router.location));
1767
+ }); // addEventListener does not exist in React Native, but window does
1768
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2026
1769
 
2027
- const baseSegments = parsePathname(from);
2028
- const routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
2029
- const params = {};
1770
+ if (!isServer && window.addEventListener) {
1771
+ // Listen to visibillitychange and focus
1772
+ window.addEventListener('visibilitychange', router.onFocus, false);
1773
+ window.addEventListener('focus', router.onFocus, false);
1774
+ }
2030
1775
 
2031
- let isMatch = (() => {
2032
- for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
2033
- const baseSegment = baseSegments[i];
2034
- const routeSegment = routeSegments[i];
2035
- const isLastRouteSegment = i === routeSegments.length - 1;
2036
- const isLastBaseSegment = i === baseSegments.length - 1;
1776
+ return () => {
1777
+ unsub(); // Be sure to unsubscribe if a new handler is set
2037
1778
 
2038
- if (routeSegment) {
2039
- if (routeSegment.type === 'wildcard') {
2040
- if (baseSegment != null && baseSegment.value) {
2041
- params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
2042
- return true;
2043
- }
1779
+ window.removeEventListener('visibilitychange', router.onFocus);
1780
+ window.removeEventListener('focus', router.onFocus);
1781
+ };
1782
+ },
1783
+ onFocus: () => {
1784
+ router.loadLocation();
1785
+ },
1786
+ update: opts => {
1787
+ Object.assign(router.options, opts);
1788
+ const {
1789
+ basepath,
1790
+ routeConfig
1791
+ } = router.options;
1792
+ router.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
2044
1793
 
2045
- return false;
1794
+ if (routeConfig) {
1795
+ router.routesById = {};
1796
+ router.routeTree = router.__.buildRouteTree(routeConfig);
1797
+ }
1798
+
1799
+ return router;
1800
+ },
1801
+ cancelMatches: () => {
1802
+ var _router$state$pending, _router$state$pending2;
1803
+ [...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 => {
1804
+ match.cancel();
1805
+ });
1806
+ },
1807
+ loadLocation: async next => {
1808
+ const id = Math.random();
1809
+ router.startedLoadingAt = id;
1810
+
1811
+ if (next) {
1812
+ // Ingest the new location
1813
+ router.location = next;
1814
+ } // Clear out old actions
1815
+
1816
+
1817
+ router.removeActionQueue.forEach(_ref => {
1818
+ let {
1819
+ action,
1820
+ actionState
1821
+ } = _ref;
1822
+
1823
+ if (router.state.currentAction === actionState) {
1824
+ router.state.currentAction = undefined;
2046
1825
  }
2047
1826
 
2048
- if (routeSegment.type === 'pathname') {
2049
- if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
2050
- return true;
2051
- }
1827
+ if (action.current === actionState) {
1828
+ action.current = undefined;
1829
+ }
1830
+ });
1831
+ router.removeActionQueue = []; // Cancel any pending matches
2052
1832
 
2053
- if (baseSegment) {
2054
- if (matchLocation.caseSensitive) {
2055
- if (routeSegment.value !== baseSegment.value) {
2056
- return false;
1833
+ router.cancelMatches(); // Match the routes
1834
+
1835
+ const matches = router.matchRoutes(location.pathname, {
1836
+ strictParseParams: true
1837
+ });
1838
+ router.state = _extends({}, router.state, {
1839
+ pending: {
1840
+ matches: matches,
1841
+ location: router.location
1842
+ },
1843
+ status: 'loading'
1844
+ });
1845
+ router.notify(); // Load the matches
1846
+
1847
+ await router.loadMatches(matches, {
1848
+ withPending: true
1849
+ });
1850
+
1851
+ if (router.startedLoadingAt !== id) {
1852
+ // Ignore side-effects of match loading
1853
+ return router.navigationPromise;
1854
+ }
1855
+
1856
+ const previousMatches = router.state.matches;
1857
+ const exiting = [],
1858
+ staying = [];
1859
+ previousMatches.forEach(d => {
1860
+ if (matches.find(dd => dd.matchId === d.matchId)) {
1861
+ staying.push(d);
1862
+ } else {
1863
+ exiting.push(d);
1864
+ }
1865
+ });
1866
+ const now = Date.now();
1867
+ exiting.forEach(d => {
1868
+ var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
1869
+
1870
+ d.__.onExit == null ? void 0 : d.__.onExit({
1871
+ params: d.params,
1872
+ search: d.routeSearch
1873
+ }); // Clear idle error states when match leaves
1874
+
1875
+ if (d.status === 'error' && !d.isFetching) {
1876
+ d.status = 'idle';
1877
+ d.error = undefined;
1878
+ }
1879
+
1880
+ 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);
1881
+
1882
+ if (gc > 0) {
1883
+ router.matchCache[d.matchId] = {
1884
+ gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
1885
+ match: d
1886
+ };
1887
+ }
1888
+ });
1889
+ staying.forEach(d => {
1890
+ d.options.onTransition == null ? void 0 : d.options.onTransition({
1891
+ params: d.params,
1892
+ search: d.routeSearch
1893
+ });
1894
+ });
1895
+ const entering = matches.filter(d => {
1896
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
1897
+ });
1898
+ entering.forEach(d => {
1899
+ d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1900
+ params: d.params,
1901
+ search: d.search
1902
+ });
1903
+ delete router.matchCache[d.matchId];
1904
+ });
1905
+
1906
+ if (matches.some(d => d.status === 'loading')) {
1907
+ router.notify();
1908
+ await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
1909
+ }
1910
+
1911
+ if (router.startedLoadingAt !== id) {
1912
+ // Ignore side-effects of match loading
1913
+ return;
1914
+ }
1915
+
1916
+ router.state = _extends({}, router.state, {
1917
+ location: router.location,
1918
+ matches,
1919
+ pending: undefined,
1920
+ status: 'idle'
1921
+ });
1922
+ router.notify();
1923
+ router.resolveNavigation();
1924
+ },
1925
+ cleanMatchCache: () => {
1926
+ const now = Date.now();
1927
+ Object.keys(router.matchCache).forEach(matchId => {
1928
+ const entry = router.matchCache[matchId]; // Don't remove loading matches
1929
+
1930
+ if (entry.match.status === 'loading') {
1931
+ return;
1932
+ } // Do not remove successful matches that are still valid
1933
+
1934
+
1935
+ if (entry.gc > 0 && entry.gc > now) {
1936
+ return;
1937
+ } // Everything else gets removed
1938
+
1939
+
1940
+ delete router.matchCache[matchId];
1941
+ });
1942
+ },
1943
+ loadRoute: async function loadRoute(navigateOpts) {
1944
+ if (navigateOpts === void 0) {
1945
+ navigateOpts = router.location;
1946
+ }
1947
+
1948
+ const next = router.buildNext(navigateOpts);
1949
+ const matches = router.matchRoutes(next.pathname, {
1950
+ strictParseParams: true
1951
+ });
1952
+ await router.loadMatches(matches);
1953
+ return matches;
1954
+ },
1955
+ preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
1956
+ var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
1957
+
1958
+ if (navigateOpts === void 0) {
1959
+ navigateOpts = router.location;
1960
+ }
1961
+
1962
+ const next = router.buildNext(navigateOpts);
1963
+ const matches = router.matchRoutes(next.pathname, {
1964
+ strictParseParams: true
1965
+ });
1966
+ await router.loadMatches(matches, {
1967
+ preload: true,
1968
+ maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
1969
+ gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
1970
+ });
1971
+ return matches;
1972
+ },
1973
+ matchRoutes: (pathname, opts) => {
1974
+ var _router$state$pending3, _router$state$pending4;
1975
+
1976
+ router.cleanMatchCache();
1977
+ const matches = [];
1978
+
1979
+ if (!router.routeTree) {
1980
+ return matches;
1981
+ }
1982
+
1983
+ 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 : [])];
1984
+
1985
+ const recurse = async routes => {
1986
+ var _parentMatch$params, _router$options$filte, _foundRoute$childRout;
1987
+
1988
+ const parentMatch = last(matches);
1989
+ let params = (_parentMatch$params = parentMatch == null ? void 0 : parentMatch.params) != null ? _parentMatch$params : {};
1990
+ const filteredRoutes = (_router$options$filte = router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) != null ? _router$options$filte : routes;
1991
+ let foundRoutes = [];
1992
+
1993
+ const findMatchInRoutes = (parentRoutes, routes) => {
1994
+ routes.some(route => {
1995
+ var _route$childRoutes, _route$childRoutes2, _route$options$caseSe;
1996
+
1997
+ if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
1998
+ return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
1999
+ }
2000
+
2001
+ const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length);
2002
+ const matchParams = matchPathname(pathname, {
2003
+ to: route.fullPath,
2004
+ fuzzy,
2005
+ caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
2006
+ });
2007
+
2008
+ if (matchParams) {
2009
+ let parsedParams;
2010
+
2011
+ try {
2012
+ var _route$options$parseP;
2013
+
2014
+ parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
2015
+ } catch (err) {
2016
+ if (opts != null && opts.strictParseParams) {
2017
+ throw err;
2018
+ }
2057
2019
  }
2058
- } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
2059
- return false;
2020
+
2021
+ params = _extends({}, params, parsedParams);
2060
2022
  }
2061
- }
2023
+
2024
+ if (!!matchParams) {
2025
+ foundRoutes = [...parentRoutes, route];
2026
+ }
2027
+
2028
+ return !!foundRoutes.length;
2029
+ });
2030
+ return !!foundRoutes.length;
2031
+ };
2032
+
2033
+ findMatchInRoutes([], filteredRoutes);
2034
+
2035
+ if (!foundRoutes.length) {
2036
+ return;
2037
+ }
2038
+
2039
+ foundRoutes.forEach(foundRoute => {
2040
+ var _router$matchCache$ma;
2041
+
2042
+ const interpolatedPath = interpolatePath(foundRoute.routePath, params);
2043
+ const matchId = interpolatePath(foundRoute.routeId, params, true);
2044
+ const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
2045
+ matchId,
2046
+ params,
2047
+ pathname: joinPaths([pathname, interpolatedPath])
2048
+ });
2049
+ matches.push(match);
2050
+ });
2051
+ const foundRoute = last(foundRoutes);
2052
+
2053
+ if ((_foundRoute$childRout = foundRoute.childRoutes) != null && _foundRoute$childRout.length) {
2054
+ recurse(foundRoute.childRoutes);
2062
2055
  }
2056
+ };
2057
+
2058
+ recurse([router.routeTree]);
2059
+ cascadeLoaderData(matches);
2060
+ return matches;
2061
+ },
2062
+ loadMatches: async (resolvedMatches, loaderOpts) => {
2063
+ const matchPromises = resolvedMatches.map(async match => {
2064
+ // Validate the match (loads search params etc)
2065
+ match.__.validate();
2066
+
2067
+ match.load(loaderOpts);
2068
+
2069
+ if (match.status === 'loading') {
2070
+ // If requested, start the pending timers
2071
+ if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
2072
+ // This might be completion, error, or a pending state
2073
+
2074
+ await match.__.loadPromise;
2075
+ }
2076
+ });
2077
+ router.notify();
2078
+ await Promise.all(matchPromises);
2079
+ },
2080
+ invalidateRoute: opts => {
2081
+ var _router$state$pending5, _router$state$pending6;
2082
+
2083
+ const next = router.buildNext(opts);
2084
+ const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
2085
+ [...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 => {
2086
+ if (unloadedMatchIds.includes(match.matchId)) {
2087
+ match.invalidate();
2088
+ }
2089
+ });
2090
+ },
2091
+ reload: () => router.__.navigate({
2092
+ fromCurrent: true,
2093
+ replace: true,
2094
+ search: true
2095
+ }),
2096
+ resolvePath: (from, path) => {
2097
+ return resolvePath(router.basepath, from, cleanPath(path));
2098
+ },
2099
+ matchRoute: (location, opts) => {
2100
+ var _location$from;
2101
+
2102
+ // const location = router.buildNext(opts)
2103
+ location = _extends({}, location, {
2104
+ to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
2105
+ });
2106
+ const next = router.buildNext(location);
2107
+
2108
+ if (opts != null && opts.pending) {
2109
+ var _router$state$pending7;
2110
+
2111
+ if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
2112
+ return false;
2113
+ }
2114
+
2115
+ return !!matchPathname(router.state.pending.location.pathname, _extends({}, opts, {
2116
+ to: next.pathname
2117
+ }));
2118
+ }
2119
+
2120
+ return !!matchPathname(router.state.location.pathname, _extends({}, opts, {
2121
+ to: next.pathname
2122
+ }));
2123
+ },
2124
+ navigate: async _ref8 => {
2125
+ let {
2126
+ from,
2127
+ to = '.',
2128
+ search,
2129
+ hash,
2130
+ replace,
2131
+ params
2132
+ } = _ref8;
2133
+ // If this link simply reloads the current route,
2134
+ // make sure it has a new key so it will trigger a data refresh
2135
+ // If this `to` is a valid external URL, return
2136
+ // null for LinkUtils
2137
+ const toString = String(to);
2138
+ const fromString = String(from);
2139
+ let isExternal;
2140
+
2141
+ try {
2142
+ new URL("" + toString);
2143
+ isExternal = true;
2144
+ } catch (e) {}
2145
+
2146
+ invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
2147
+ return router.__.navigate({
2148
+ from: fromString,
2149
+ to: toString,
2150
+ search,
2151
+ hash,
2152
+ replace,
2153
+ params
2154
+ });
2155
+ },
2156
+ buildLink: _ref9 => {
2157
+ var _preload, _ref10;
2158
+
2159
+ let {
2160
+ from,
2161
+ to = '.',
2162
+ search,
2163
+ params,
2164
+ hash,
2165
+ target,
2166
+ replace,
2167
+ activeOptions,
2168
+ preload,
2169
+ preloadMaxAge: userPreloadMaxAge,
2170
+ preloadGcMaxAge: userPreloadGcMaxAge,
2171
+ preloadDelay: userPreloadDelay,
2172
+ disabled
2173
+ } = _ref9;
2174
+
2175
+ // If this link simply reloads the current route,
2176
+ // make sure it has a new key so it will trigger a data refresh
2177
+ // If this `to` is a valid external URL, return
2178
+ // null for LinkUtils
2179
+ try {
2180
+ new URL("" + to);
2181
+ return {
2182
+ type: 'external',
2183
+ href: to
2184
+ };
2185
+ } catch (e) {}
2186
+
2187
+ const nextOpts = {
2188
+ from,
2189
+ to,
2190
+ search,
2191
+ params,
2192
+ hash,
2193
+ replace
2194
+ };
2195
+ const next = router.buildNext(nextOpts);
2196
+ preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
2197
+ const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
2198
+
2199
+ const pathIsEqual = router.state.location.pathname === next.pathname;
2200
+ const currentPathSplit = router.state.location.pathname.split('/');
2201
+ const nextPathSplit = next.pathname.split('/');
2202
+ const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
2203
+ const hashIsEqual = router.state.location.hash === next.hash; // Combine the matches based on user options
2204
+
2205
+ const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
2206
+ const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
2063
2207
 
2064
- if (!baseSegment) {
2065
- return false;
2066
- }
2208
+ const isActive = pathTest && hashTest; // The click handler
2067
2209
 
2068
- if (routeSegment.type === 'param') {
2069
- if ((baseSegment == null ? void 0 : baseSegment.value) === '/') {
2070
- return false;
2071
- }
2210
+ const handleClick = e => {
2211
+ if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
2212
+ e.preventDefault();
2072
2213
 
2073
- if (!baseSegment.value.startsWith(':')) {
2074
- params[routeSegment.value.substring(1)] = baseSegment.value;
2075
- }
2076
- }
2077
- }
2214
+ if (pathIsEqual && !search && !hash) {
2215
+ router.invalidateRoute(nextOpts);
2216
+ } // All is well? Navigate!)
2078
2217
 
2079
- if (isLastRouteSegment && !isLastBaseSegment) {
2080
- return !!matchLocation.fuzzy;
2081
- }
2082
- }
2083
2218
 
2084
- return true;
2085
- })();
2219
+ router.__.navigate(nextOpts);
2220
+ }
2221
+ }; // The click handler
2086
2222
 
2087
- return isMatch ? params : undefined;
2088
- } // function matchBySearch(
2089
- // search: SearchSchema,
2090
- // matchLocation: MatchLocation,
2091
- // ) {
2092
- // return !!(matchLocation.search && matchLocation.search(search))
2093
- // }
2094
2223
 
2095
- function parsePathname(pathname) {
2096
- if (!pathname) {
2097
- return [];
2098
- }
2224
+ const handleFocus = e => {
2225
+ if (preload) {
2226
+ router.preloadRoute(nextOpts, {
2227
+ maxAge: userPreloadMaxAge,
2228
+ gcMaxAge: userPreloadGcMaxAge
2229
+ });
2230
+ }
2231
+ };
2099
2232
 
2100
- pathname = cleanPath(pathname);
2101
- const segments = [];
2233
+ const handleEnter = e => {
2234
+ const target = e.target || {};
2102
2235
 
2103
- if (pathname.slice(0, 1) === '/') {
2104
- pathname = pathname.substring(1);
2105
- segments.push({
2106
- type: 'pathname',
2107
- value: '/'
2108
- });
2109
- }
2236
+ if (preload) {
2237
+ if (target.preloadTimeout) {
2238
+ return;
2239
+ }
2110
2240
 
2111
- if (!pathname) {
2112
- return segments;
2113
- } // Remove empty segments and '.' segments
2241
+ target.preloadTimeout = setTimeout(() => {
2242
+ target.preloadTimeout = null;
2243
+ router.preloadRoute(nextOpts, {
2244
+ maxAge: userPreloadMaxAge,
2245
+ gcMaxAge: userPreloadGcMaxAge
2246
+ });
2247
+ }, preloadDelay);
2248
+ }
2249
+ };
2114
2250
 
2251
+ const handleLeave = e => {
2252
+ const target = e.target || {};
2115
2253
 
2116
- const split = pathname.split('/').filter(Boolean);
2117
- segments.push(...split.map(part => {
2118
- if (part.startsWith('*')) {
2119
- return {
2120
- type: 'wildcard',
2121
- value: part
2254
+ if (target.preloadTimeout) {
2255
+ clearTimeout(target.preloadTimeout);
2256
+ target.preloadTimeout = null;
2257
+ }
2122
2258
  };
2123
- }
2124
2259
 
2125
- if (part.charAt(0) === ':') {
2126
2260
  return {
2127
- type: 'param',
2128
- value: part
2261
+ type: 'internal',
2262
+ next,
2263
+ handleFocus,
2264
+ handleClick,
2265
+ handleEnter,
2266
+ handleLeave,
2267
+ isActive,
2268
+ disabled
2129
2269
  };
2130
- }
2131
-
2132
- return {
2133
- type: 'pathname',
2134
- value: part
2135
- };
2136
- }));
2137
-
2138
- if (pathname.slice(-1) === '/') {
2139
- pathname = pathname.substring(1);
2140
- segments.push({
2141
- type: 'pathname',
2142
- value: '/'
2143
- });
2144
- }
2270
+ },
2271
+ buildNext: opts => {
2272
+ const next = router.__.buildLocation(opts);
2145
2273
 
2146
- return segments;
2147
- }
2274
+ const matches = router.matchRoutes(next.pathname);
2148
2275
 
2149
- function _resolvePath(basepath, base, to) {
2150
- base = base.replace(new RegExp("^" + basepath), '/');
2151
- to = to.replace(new RegExp("^" + basepath), '/');
2152
- let baseSegments = parsePathname(base);
2153
- const toSegments = parsePathname(to);
2154
- toSegments.forEach((toSegment, index) => {
2155
- if (toSegment.value === '/') {
2156
- if (!index) {
2157
- // Leading slash
2158
- baseSegments = [toSegment];
2159
- } else if (index === toSegments.length - 1) {
2160
- // Trailing Slash
2161
- baseSegments.push(toSegment);
2162
- } else ;
2163
- } else if (toSegment.value === '..') {
2164
- var _last2;
2276
+ const __preSearchFilters = matches.map(match => {
2277
+ var _match$options$preSea;
2165
2278
 
2166
- // Extra trailing slash? pop it off
2167
- if (baseSegments.length > 1 && ((_last2 = last(baseSegments)) == null ? void 0 : _last2.value) === '/') {
2168
- baseSegments.pop();
2169
- }
2279
+ return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
2280
+ }).flat().filter(Boolean);
2170
2281
 
2171
- baseSegments.pop();
2172
- } else if (toSegment.value === '.') {
2173
- return;
2174
- } else {
2175
- baseSegments.push(toSegment);
2176
- }
2177
- });
2178
- const joined = joinPaths([basepath, ...baseSegments.map(d => d.value)]);
2179
- return cleanPath(joined);
2180
- }
2181
- function replaceEqualDeep(prev, next) {
2182
- if (prev === next) {
2183
- return prev;
2184
- }
2282
+ const __postSearchFilters = matches.map(match => {
2283
+ var _match$options$postSe;
2185
2284
 
2186
- const array = Array.isArray(prev) && Array.isArray(next);
2285
+ return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
2286
+ }).flat().filter(Boolean);
2187
2287
 
2188
- if (array || isPlainObject(prev) && isPlainObject(next)) {
2189
- const aSize = array ? prev.length : Object.keys(prev).length;
2190
- const bItems = array ? next : Object.keys(next);
2191
- const bSize = bItems.length;
2192
- const copy = array ? [] : {};
2193
- let equalItems = 0;
2288
+ return router.__.buildLocation(_extends({}, opts, {
2289
+ __preSearchFilters,
2290
+ __postSearchFilters
2291
+ }));
2292
+ },
2293
+ __: {
2294
+ buildRouteTree: rootRouteConfig => {
2295
+ const recurseRoutes = (routeConfigs, parent) => {
2296
+ return routeConfigs.map(routeConfig => {
2297
+ const routeOptions = routeConfig.options;
2298
+ const route = createRoute(routeConfig, routeOptions, parent, router); // {
2299
+ // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
2300
+ // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
2301
+ // }
2302
+
2303
+ const existingRoute = router.routesById[route.routeId];
2304
+
2305
+ if (existingRoute) {
2306
+ {
2307
+ console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
2308
+ }
2194
2309
 
2195
- for (let i = 0; i < bSize; i++) {
2196
- const key = array ? i : bItems[i];
2197
- copy[key] = replaceEqualDeep(prev[key], next[key]);
2310
+ throw new Error();
2311
+ }
2312
+ router.routesById[route.routeId] = route;
2313
+ const children = routeConfig.children;
2314
+ route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
2315
+ return route;
2316
+ });
2317
+ };
2198
2318
 
2199
- if (copy[key] === prev[key]) {
2200
- equalItems++;
2201
- }
2202
- }
2319
+ const routes = recurseRoutes([rootRouteConfig]);
2320
+ return routes[0];
2321
+ },
2322
+ parseLocation: (location, previousLocation) => {
2323
+ var _location$hash$split$;
2203
2324
 
2204
- return aSize === bSize && equalItems === aSize ? prev : copy;
2205
- }
2325
+ const parsedSearch = router.options.parseSearch(location.search);
2326
+ return {
2327
+ pathname: location.pathname,
2328
+ searchStr: location.search,
2329
+ search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
2330
+ hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
2331
+ href: "" + location.pathname + location.search + location.hash,
2332
+ state: location.state,
2333
+ key: location.key
2334
+ };
2335
+ },
2336
+ navigate: location => {
2337
+ const next = router.buildNext(location);
2338
+ return router.__.commitLocation(next, location.replace);
2339
+ },
2340
+ buildLocation: function buildLocation(dest) {
2341
+ var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
2206
2342
 
2207
- return next;
2208
- } // Copied from: https://github.com/jonschlinkert/is-plain-object
2343
+ if (dest === void 0) {
2344
+ dest = {};
2345
+ }
2209
2346
 
2210
- function isPlainObject(o) {
2211
- if (!hasObjectPrototype(o)) {
2212
- return false;
2213
- } // If has modified constructor
2347
+ // const resolvedFrom: Location = {
2348
+ // ...router.location,
2349
+ const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
2214
2350
 
2351
+ let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
2215
2352
 
2216
- const ctor = o.constructor;
2353
+ const fromMatches = router.matchRoutes(router.location.pathname, {
2354
+ strictParseParams: true
2355
+ });
2356
+ const toMatches = router.matchRoutes(pathname);
2217
2357
 
2218
- if (typeof ctor === 'undefined') {
2219
- return true;
2220
- } // If has modified prototype
2358
+ const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
2221
2359
 
2360
+ let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
2222
2361
 
2223
- const prot = ctor.prototype;
2362
+ if (nextParams) {
2363
+ toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
2364
+ Object.assign({}, nextParams, fn(nextParams));
2365
+ });
2366
+ }
2224
2367
 
2225
- if (!hasObjectPrototype(prot)) {
2226
- return false;
2227
- } // If constructor does not have an Object-specific method
2368
+ pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
2228
2369
 
2370
+ 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
2229
2371
 
2230
- if (!prot.hasOwnProperty('isPrototypeOf')) {
2231
- return false;
2232
- } // Most likely a plain Object
2372
+ const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
2373
+ : dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
2374
+ : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
2375
+ : {}; // Then post filters
2233
2376
 
2377
+ const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
2378
+ const search = replaceEqualDeep(router.location.search, postFilteredSearch);
2379
+ const searchStr = router.options.stringifySearch(search);
2380
+ let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
2381
+ hash = hash ? "#" + hash : '';
2382
+ return {
2383
+ pathname,
2384
+ search,
2385
+ searchStr,
2386
+ state: router.location.state,
2387
+ hash,
2388
+ href: "" + pathname + searchStr + hash,
2389
+ key: dest.key
2390
+ };
2391
+ },
2392
+ commitLocation: (next, replace) => {
2393
+ const id = '' + Date.now() + Math.random();
2394
+ if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
2395
+ let nextAction = 'replace';
2234
2396
 
2235
- return true;
2236
- }
2397
+ if (!replace) {
2398
+ nextAction = 'push';
2399
+ }
2237
2400
 
2238
- function hasObjectPrototype(o) {
2239
- return Object.prototype.toString.call(o) === '[object Object]';
2240
- }
2401
+ const isSameUrl = router.__.parseLocation(history.location).href === next.href;
2241
2402
 
2242
- const defaultParseSearch = parseSearchWith(JSON.parse);
2243
- const defaultStringifySearch = stringifySearchWith(JSON.stringify);
2244
- function parseSearchWith(parser) {
2245
- return searchStr => {
2246
- if (searchStr.substring(0, 1) === '?') {
2247
- searchStr = searchStr.substring(1);
2248
- }
2403
+ if (isSameUrl && !next.key) {
2404
+ nextAction = 'replace';
2405
+ }
2249
2406
 
2250
- let query = decode(searchStr); // Try to parse any query params that might be json
2407
+ if (nextAction === 'replace') {
2408
+ history.replace({
2409
+ pathname: next.pathname,
2410
+ hash: next.hash,
2411
+ search: next.searchStr
2412
+ }, {
2413
+ id
2414
+ });
2415
+ } else {
2416
+ history.push({
2417
+ pathname: next.pathname,
2418
+ hash: next.hash,
2419
+ search: next.searchStr
2420
+ }, {
2421
+ id
2422
+ });
2423
+ }
2251
2424
 
2252
- for (let key in query) {
2253
- const value = query[key];
2425
+ router.navigationPromise = new Promise(resolve => {
2426
+ const previousNavigationResolve = router.resolveNavigation;
2254
2427
 
2255
- if (typeof value === 'string') {
2256
- try {
2257
- query[key] = parser(value);
2258
- } catch (err) {//
2259
- }
2428
+ router.resolveNavigation = () => {
2429
+ previousNavigationResolve();
2430
+ resolve();
2431
+ };
2432
+ });
2433
+ return router.navigationPromise;
2260
2434
  }
2261
2435
  }
2262
-
2263
- return query;
2264
2436
  };
2265
- }
2266
- function stringifySearchWith(stringify) {
2267
- return search => {
2268
- search = _extends$1({}, search);
2269
-
2270
- if (search) {
2271
- Object.keys(search).forEach(key => {
2272
- const val = search[key];
2273
-
2274
- if (typeof val === 'undefined' || val === undefined) {
2275
- delete search[key];
2276
- } else if (val && typeof val === 'object' && val !== null) {
2277
- try {
2278
- search[key] = stringify(val);
2279
- } catch (err) {// silent
2280
- }
2281
- }
2282
- });
2283
- }
2437
+ router.location = router.__.parseLocation(history.location);
2438
+ router.state.location = router.location;
2439
+ router.update(userOptions); // Allow frameworks to hook into the router creation
2284
2440
 
2285
- const searchStr = encode(search).toString();
2286
- return searchStr ? "?" + searchStr : '';
2287
- };
2441
+ router.options.createRouter == null ? void 0 : router.options.createRouter(router);
2442
+ return router;
2288
2443
  }
2289
2444
 
2290
2445
  function isCtrlEvent(e) {
2291
2446
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
2292
2447
  }
2293
2448
 
2294
- function last(arr) {
2295
- return arr[arr.length - 1];
2296
- }
2297
-
2449
+ exports.cascadeLoaderData = cascadeLoaderData;
2450
+ exports.cleanPath = cleanPath;
2298
2451
  exports.createBrowserHistory = createBrowserHistory;
2299
2452
  exports.createHashHistory = createHashHistory;
2300
2453
  exports.createMemoryHistory = createMemoryHistory;
@@ -2302,18 +2455,26 @@
2302
2455
  exports.createRouteConfig = createRouteConfig;
2303
2456
  exports.createRouteMatch = createRouteMatch;
2304
2457
  exports.createRouter = createRouter;
2458
+ exports.decode = decode;
2305
2459
  exports.defaultParseSearch = defaultParseSearch;
2306
2460
  exports.defaultStringifySearch = defaultStringifySearch;
2461
+ exports.encode = encode;
2307
2462
  exports.functionalUpdate = functionalUpdate;
2463
+ exports.interpolatePath = interpolatePath;
2464
+ exports.invariant = invariant;
2465
+ exports.joinPaths = joinPaths;
2308
2466
  exports.last = last;
2309
2467
  exports.matchByPath = matchByPath;
2310
2468
  exports.matchPathname = matchPathname;
2311
2469
  exports.parsePathname = parsePathname;
2312
2470
  exports.parseSearchWith = parseSearchWith;
2313
2471
  exports.replaceEqualDeep = replaceEqualDeep;
2314
- exports.resolvePath = _resolvePath;
2472
+ exports.resolvePath = resolvePath;
2315
2473
  exports.rootRouteId = rootRouteId;
2316
2474
  exports.stringifySearchWith = stringifySearchWith;
2475
+ exports.trimPath = trimPath;
2476
+ exports.trimPathLeft = trimPathLeft;
2477
+ exports.trimPathRight = trimPathRight;
2317
2478
  exports.warning = warning;
2318
2479
 
2319
2480
  Object.defineProperty(exports, '__esModule', { value: true });