react-location
Version:
1,444 lines (1,199 loc) • 54.3 kB
JavaScript
/**
* react-location
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
import * as React from 'react';
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _extends$1() {
_extends$1 = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends$1.apply(this, arguments);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
var r,B=r||(r={});B.Pop="POP";B.Push="PUSH";B.Replace="REPLACE";var C="production"!==process.env.NODE_ENV?function(b){return Object.freeze(b)}:function(b){return b};function D(b,h){if(!b){"undefined"!==typeof console&&console.warn(h);try{throw Error(h);}catch(k){}}}function E(b){b.preventDefault();b.returnValue="";}
function F(){var b=[];return {get length(){return b.length},push:function(h){b.push(h);return function(){b=b.filter(function(k){return k!==h});}},call:function(h){b.forEach(function(k){return k&&k(h)});}}}function H(){return Math.random().toString(36).substr(2,8)}function I(b){var h=b.pathname,k=b.search;b=b.hash;return (void 0===h?"/":h)+(void 0===k?"":k)+(void 0===b?"":b)}
function J(b){var h={};if(b){var k=b.indexOf("#");0<=k&&(h.hash=b.substr(k),b=b.substr(0,k));k=b.indexOf("?");0<=k&&(h.search=b.substr(k),b=b.substr(0,k));b&&(h.pathname=b);}return h}
function createBrowserHistory(b){function h(){var c=p.location,a=m.state||{};return [a.idx,C({pathname:c.pathname,search:c.search,hash:c.hash,state:a.usr||null,key:a.key||"default"})]}function k(c){return "string"===typeof c?c:I(c)}function x(c,a){void 0===a&&(a=null);return C(_extends({},q,"string"===typeof c?J(c):c,{state:a,key:H()}))}function z(c){t=c;c=h();v=c[0];q=c[1];d.call({action:t,location:q});}function A(c,a){function e(){A(c,a);}var l=r.Push,g=x(c,a);if(!f.length||(f.call({action:l,
location:g,retry:e}),!1)){var n=[{usr:g.state,key:g.key,idx:v+1},k(g)];g=n[0];n=n[1];try{m.pushState(g,"",n);}catch(G){p.location.assign(n);}z(l);}}function y(c,a){function e(){y(c,a);}var l=r.Replace,g=x(c,a);f.length&&(f.call({action:l,location:g,retry:e}),1)||(g=[{usr:g.state,key:g.key,idx:v},k(g)],m.replaceState(g[0],"",g[1]),z(l));}function w(c){m.go(c);}void 0===b&&(b={});b=b.window;var p=void 0===b?document.defaultView:b,m=p.history,u=null;p.addEventListener("popstate",function(){if(u)f.call(u),
u=null;else {var c=r.Pop,a=h(),e=a[0];a=a[1];if(f.length)if(null!=e){var l=v-e;l&&(u={action:c,location:a,retry:function(){w(-1*l);}},w(l));}else "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):void 0;else z(c);}});var t=
r.Pop;b=h();var v=b[0],q=b[1],d=F(),f=F();null==v&&(v=0,m.replaceState(_extends({},m.state,{idx:v}),""));return {get action(){return t},get location(){return q},createHref:k,push:A,replace:y,go:w,back:function(){w(-1);},forward:function(){w(1);},listen:function(c){return d.push(c)},block:function(c){var a=f.push(c);1===f.length&&p.addEventListener("beforeunload",E);return function(){a();f.length||p.removeEventListener("beforeunload",E);}}}}function createHashHistory(b){function h(){var a=J(m.location.hash.substr(1)),e=a.pathname,l=a.search;a=a.hash;var g=u.state||{};return [g.idx,C({pathname:void 0===e?"/":e,search:void 0===l?"":l,hash:void 0===a?"":a,state:g.usr||null,key:g.key||"default"})]}function k(){if(t)c.call(t),t=null;else {var a=r.Pop,e=h(),l=e[0];e=e[1];if(c.length)if(null!=l){var g=q-l;g&&(t={action:a,location:e,retry:function(){p(-1*g);}},p(g));}else "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):
void 0;else A(a);}}function x(a){var e=document.querySelector("base"),l="";e&&e.getAttribute("href")&&(e=m.location.href,l=e.indexOf("#"),l=-1===l?e:e.slice(0,l));return l+"#"+("string"===typeof a?a:I(a))}function z(a,e){void 0===e&&(e=null);return C(_extends({},d,"string"===typeof a?J(a):a,{state:e,key:H()}))}function A(a){v=a;a=h();q=a[0];d=a[1];f.call({action:v,location:d});}function y(a,e){function l(){y(a,e);}var g=r.Push,n=z(a,e);"production"!==process.env.NODE_ENV?D("/"===n.pathname.charAt(0),
"Relative pathnames are not supported in hash history.push("+JSON.stringify(a)+")"):void 0;if(!c.length||(c.call({action:g,location:n,retry:l}),!1)){var G=[{usr:n.state,key:n.key,idx:q+1},x(n)];n=G[0];G=G[1];try{u.pushState(n,"",G);}catch(K){m.location.assign(G);}A(g);}}function w(a,e){function l(){w(a,e);}var g=r.Replace,n=z(a,e);"production"!==process.env.NODE_ENV?D("/"===n.pathname.charAt(0),"Relative pathnames are not supported in hash history.replace("+JSON.stringify(a)+")"):void 0;c.length&&(c.call({action:g,
location:n,retry:l}),1)||(n=[{usr:n.state,key:n.key,idx:q},x(n)],u.replaceState(n[0],"",n[1]),A(g));}function p(a){u.go(a);}void 0===b&&(b={});b=b.window;var m=void 0===b?document.defaultView:b,u=m.history,t=null;m.addEventListener("popstate",k);m.addEventListener("hashchange",function(){var a=h()[1];I(a)!==I(d)&&k();});var v=r.Pop;b=h();var q=b[0],d=b[1],f=F(),c=F();null==q&&(q=0,u.replaceState(_extends({},u.state,{idx:q}),""));return {get action(){return v},get location(){return d},createHref:x,push:y,
replace:w,go:p,back:function(){p(-1);},forward:function(){p(1);},listen:function(a){return f.push(a)},block:function(a){var e=c.push(a);1===c.length&&m.addEventListener("beforeunload",E);return function(){e();c.length||m.removeEventListener("beforeunload",E);}}}}function createMemoryHistory(b){function h(d,f){void 0===f&&(f=null);return C(_extends({},t,"string"===typeof d?J(d):d,{state:f,key:H()}))}function k(d,f,c){return !q.length||(q.call({action:d,location:f,retry:c}),!1)}function x(d,f){u=d;t=f;v.call({action:u,location:t});}function z(d,f){var c=r.Push,a=h(d,f);"production"!==process.env.NODE_ENV?D("/"===t.pathname.charAt(0),"Relative pathnames are not supported in memory history.push("+JSON.stringify(d)+")"):void 0;k(c,a,function(){z(d,f);})&&
(m+=1,p.splice(m,p.length,a),x(c,a));}function A(d,f){var c=r.Replace,a=h(d,f);"production"!==process.env.NODE_ENV?D("/"===t.pathname.charAt(0),"Relative pathnames are not supported in memory history.replace("+JSON.stringify(d)+")"):void 0;k(c,a,function(){A(d,f);})&&(p[m]=a,x(c,a));}function y(d){var f=Math.min(Math.max(m+d,0),p.length-1),c=r.Pop,a=p[f];k(c,a,function(){y(d);})&&(m=f,x(c,a));}void 0===b&&(b={});var w=b;b=w.initialEntries;w=w.initialIndex;var p=(void 0===b?["/"]:b).map(function(d){var f=
C(_extends({pathname:"/",search:"",hash:"",state:null,key:H()},"string"===typeof d?J(d):d));"production"!==process.env.NODE_ENV?D("/"===f.pathname.charAt(0),"Relative pathnames are not supported in createMemoryHistory({ initialEntries }) (invalid entry: "+JSON.stringify(d)+")"):void 0;return f}),m=Math.min(Math.max(null==w?p.length-1:w,0),p.length-1),u=r.Pop,t=p[m],v=F(),q=F();return {get index(){return m},get action(){return u},get location(){return t},createHref:function(d){return "string"===typeof d?
d:I(d)},push:z,replace:A,go:y,back:function(){y(-1);},forward:function(){y(1);},listen:function(d){return v.push(d)},block:function(d){return q.push(d)}}}
var _excluded = ["children", "location"],
_excluded2 = ["location"],
_excluded3 = ["basepath", "routes"],
_excluded4 = ["to", "search", "hash", "children", "target", "style", "replace", "onClick", "onMouseEnter", "className", "getActiveProps", "getInactiveProps", "activeOptions", "preload", "disabled", "_ref"],
_excluded5 = ["style", "className"],
_excluded6 = ["style", "className"],
_excluded7 = ["pending"],
_excluded8 = ["children"];
function _await(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _catch(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
} // Types
function _empty() {}
function _continueIgnored(value) {
if (value && value.then) {
return value.then(_empty);
}
}
function _async(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
// Source
var LocationContext = /*#__PURE__*/React.createContext(null);
var MatchesContext = /*#__PURE__*/React.createContext(null);
var routerContext = /*#__PURE__*/React.createContext(null); // Detect if we're in the DOM
var isDOM = Boolean(typeof window !== 'undefined' && window.document && window.document.createElement);
var useLayoutEffect = isDOM ? React.useLayoutEffect : React.useEffect; // This is the default history object if none is defined
var createDefaultHistory = function createDefaultHistory() {
return isDOM ? createBrowserHistory() : createMemoryHistory();
};
var Subscribable = /*#__PURE__*/function () {
function Subscribable() {
this.listeners = [];
}
var _proto = Subscribable.prototype;
_proto.subscribe = function subscribe(listener) {
var _this = this;
this.listeners.push(listener);
return function () {
_this.listeners = _this.listeners.filter(function (x) {
return x !== listener;
});
};
};
_proto.notify = function notify() {
this.listeners.forEach(function (listener) {
return listener();
});
};
return Subscribable;
}();
var ReactLocation = /*#__PURE__*/function (_Subscribable) {
_inheritsLoose(ReactLocation, _Subscribable);
//
function ReactLocation(options) {
var _options$stringifySea, _options$parseSearch;
var _this2;
_this2 = _Subscribable.call(this) || this;
_this2.isTransitioning = false;
_this2.history = (options == null ? void 0 : options.history) || createDefaultHistory();
_this2.stringifySearch = (_options$stringifySea = options == null ? void 0 : options.stringifySearch) != null ? _options$stringifySea : defaultStringifySearch;
_this2.parseSearch = (_options$parseSearch = options == null ? void 0 : options.parseSearch) != null ? _options$parseSearch : defaultParseSearch;
_this2.current = _this2.parseLocation(_this2.history.location);
_this2.destroy = _this2.history.listen(function (event) {
_this2.current = _this2.parseLocation(event.location, _this2.current);
_this2.notify();
});
return _this2;
}
var _proto2 = ReactLocation.prototype;
_proto2.buildNext = function buildNext(basepath, dest) {
var _dest$to, _ref2, _dest$__searchFilters;
if (basepath === void 0) {
basepath = '/';
}
if (dest === void 0) {
dest = {};
}
var from = _extends$1({}, this.current, dest.from);
var pathname = resolvePath(basepath, from.pathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
var updatedSearch = (_ref2 = dest.search === true ? from.search : functionalUpdate(dest.search, from.search)) != null ? _ref2 : {};
var filteredSearch = (_dest$__searchFilters = dest.__searchFilters) != null && _dest$__searchFilters.length ? dest.__searchFilters.reduce(function (prev, next) {
return next(prev, updatedSearch);
}, from.search) : updatedSearch;
var search = replaceEqualDeep(from.search, filteredSearch);
var searchStr = this.stringifySearch(search);
var hash = functionalUpdate(dest.hash, from.hash);
hash = hash ? "#" + hash : '';
return {
pathname: pathname,
search: search,
searchStr: searchStr,
hash: hash,
href: "" + pathname + searchStr + hash,
key: dest.key
};
};
_proto2.navigate = function navigate(next, replace) {
var _this3 = this;
this.current = next;
if (this.navigateTimeout) clearTimeout(this.navigateTimeout);
var nextAction = 'replace';
if (!this.nextAction) {
nextAction = replace ? 'replace' : 'push';
}
if (!replace) {
nextAction = 'push';
}
this.nextAction = nextAction;
this.navigateTimeout = setTimeout(function () {
var nextAction = _this3.nextAction;
delete _this3.nextAction;
var isSameUrl = _this3.parseLocation(_this3.history.location).href === _this3.current.href;
if (isSameUrl && !_this3.current.key) {
nextAction = 'replace';
}
if (nextAction === 'replace') {
return _this3.history.replace({
pathname: _this3.current.pathname,
hash: _this3.current.hash,
search: _this3.current.searchStr
});
}
return _this3.history.push({
pathname: _this3.current.pathname,
hash: _this3.current.hash,
search: _this3.current.searchStr
});
}, 16);
};
_proto2.parseLocation = function parseLocation(location, previousLocation) {
var _location$hash$split$;
var parsedSearch = this.parseSearch(location.search);
return {
pathname: location.pathname,
searchStr: location.search,
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
href: "" + location.pathname + location.search + location.hash,
key: location.key
};
};
return ReactLocation;
}(Subscribable);
function MatchesProvider(props) {
return /*#__PURE__*/React.createElement(MatchesContext.Provider, props);
}
function Router(_ref3) {
var children = _ref3.children,
location = _ref3.location,
rest = _objectWithoutPropertiesLoose(_ref3, _excluded);
var routerRef = React.useRef(null);
if (!routerRef.current) {
routerRef.current = new RouterInstance({
location: location,
// snapshot,
routes: rest.routes
});
}
var router = routerRef.current;
var _React$useReducer = React.useReducer(function () {
return {};
}, {}),
nonce = _React$useReducer[0],
rerender = _React$useReducer[1];
router.update(rest);
useLayoutEffect(function () {
return router.subscribe(function () {
rerender();
});
}, []);
useLayoutEffect(function () {
return router.updateLocation(location.current).unsubscribe;
}, [location.current.key]);
var routerValue = React.useMemo(function () {
return {
router: router
};
}, [nonce]);
return /*#__PURE__*/React.createElement(LocationContext.Provider, {
value: {
location: location
}
}, /*#__PURE__*/React.createElement(routerContext.Provider, {
value: routerValue
}, /*#__PURE__*/React.createElement(MatchesProvider, {
value: [router.rootMatch].concat(router.state.matches)
}, children != null ? children : /*#__PURE__*/React.createElement(Outlet, null))));
}
var RouterInstance = /*#__PURE__*/function (_Subscribable2) {
_inheritsLoose(RouterInstance, _Subscribable2);
function RouterInstance(_ref4) {
var _this4;
var location = _ref4.location,
rest = _objectWithoutPropertiesLoose(_ref4, _excluded2);
_this4 = _Subscribable2.call(this) || this;
_this4.routesById = {};
_this4.update = function (_ref5) {
var basepath = _ref5.basepath,
routes = _ref5.routes,
opts = _objectWithoutPropertiesLoose(_ref5, _excluded3);
Object.assign(_assertThisInitialized(_this4), opts);
_this4.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
_this4.routesById = {};
var recurseRoutes = function recurseRoutes(routes, parent) {
return routes.map(function (route) {
var _route$path, _route$pendingMs, _route$pendingMinMs, _route$children;
var path = (_route$path = route.path) != null ? _route$path : '*';
var id = joinPaths([(parent == null ? void 0 : parent.id) === 'root' ? '' : parent == null ? void 0 : parent.id, "" + (path == null ? void 0 : path.replace(/(.)\/$/, '$1')) + (route.id ? "-" + route.id : '')]);
route = _extends$1({}, route, {
pendingMs: (_route$pendingMs = route.pendingMs) != null ? _route$pendingMs : opts == null ? void 0 : opts.defaultPendingMs,
pendingMinMs: (_route$pendingMinMs = route.pendingMinMs) != null ? _route$pendingMinMs : opts == null ? void 0 : opts.defaultPendingMinMs,
id: id
});
if (_this4.routesById[id]) {
if (process.env.NODE_ENV !== 'production') {
console.warn("Duplicate routes found with id: " + id, _this4.routesById, route);
}
throw new Error();
}
_this4.routesById[id] = route;
route.children = (_route$children = route.children) != null && _route$children.length ? recurseRoutes(route.children, route) : undefined;
return route;
});
};
_this4.routes = recurseRoutes(routes);
_this4.rootMatch = {
id: 'root',
params: {},
search: {},
pathname: _this4.basepath,
route: null,
ownData: {},
data: {},
isLoading: false,
status: 'resolved'
};
};
_this4.setState = function (updater) {
var newState = updater({
state: _this4.state,
pending: _this4.pending
});
_this4.state = newState.state;
_this4.pending = newState.pending;
_this4.cleanMatchCache();
_this4.notify();
};
_this4.matchCache = {};
_this4.cleanMatchCache = function () {
var _assertThisInitialize, _assertThisInitialize2, _assertThisInitialize3, _assertThisInitialize4, _assertThisInitialize5;
var activeMatchIds = [].concat((_assertThisInitialize = (_assertThisInitialize2 = _assertThisInitialized(_this4)) == null ? void 0 : _assertThisInitialize2.state.matches) != null ? _assertThisInitialize : [], (_assertThisInitialize3 = (_assertThisInitialize4 = _assertThisInitialized(_this4)) == null ? void 0 : (_assertThisInitialize5 = _assertThisInitialize4.pending) == null ? void 0 : _assertThisInitialize5.matches) != null ? _assertThisInitialize3 : []).map(function (d) {
return d.id;
});
Object.values(_this4.matchCache).forEach(function (match) {
var _match$updatedAt;
if (!match.updatedAt) {
return;
}
if (activeMatchIds.includes(match.id)) {
return;
}
var age = Date.now() - ((_match$updatedAt = match.updatedAt) != null ? _match$updatedAt : 0);
if (!match.maxAge || age > match.maxAge) {
if (match.route.unloader) {
match.route.unloader(match);
}
delete _this4.matchCache[match.id];
}
});
};
_this4.updateLocation = function (next) {
var unsubscribe;
var promise = new Promise(function (resolve) {
var matchLoader = new MatchLoader(_assertThisInitialized(_this4), next);
_this4.setState(function (old) {
return _extends$1({}, old, {
pending: {
location: matchLoader.location,
matches: matchLoader.matches
}
});
});
unsubscribe = matchLoader.subscribe(function () {
var currentMatches = _this4.state.matches;
currentMatches.filter(function (d) {
return !matchLoader.matches.find(function (dd) {
return dd.id === d.id;
});
}).forEach(function (d) {
d.onExit == null ? void 0 : d.onExit(d);
});
currentMatches.filter(function (d) {
return matchLoader.matches.find(function (dd) {
return dd.id === d.id;
});
}).forEach(function (d) {
d.route.onTransition == null ? void 0 : d.route.onTransition(d);
});
matchLoader.matches.filter(function (d) {
return !currentMatches.find(function (dd) {
return dd.id === d.id;
});
}).forEach(function (d) {
d.onExit = d.route.onMatch == null ? void 0 : d.route.onMatch(d);
});
_this4.setState(function (old) {
return _extends$1({}, old, {
state: {
location: matchLoader.location,
matches: matchLoader.matches
},
pending: undefined
});
});
resolve();
});
matchLoader.loadData();
matchLoader.startPending();
});
return {
promise: promise,
unsubscribe: unsubscribe
};
};
_this4.update(rest); // if (snapshot) {
// const matchLoader = new MatchLoader(this, location.current)
// matchLoader.matches.forEach((match, index) => {
// if (match.id !== snapshot.matches[index]?.id) {
// throw new Error(
// `Router hydration mismatch: ${match.id} !== ${snapshot.matches[index]?.id}`,
// )
// }
// match.ownData = snapshot.matches[index]?.ownData ?? {}
// })
// cascadeMatchData(matchLoader.matches)
// }
_this4.state = {
// location: snapshot?.location ?? location.current,
// matches: matchLoader.matches,
location: location.current,
matches: []
};
location.subscribe(function () {
return _this4.notify();
});
return _this4;
} // snapshot = (): RouterSnapshot<TGenerics> => {
// return {
// location: this.state.location,
// matches: this.state.matches.map(({ ownData, id }) => {
// return {
// id,
// ownData,
// }
// }),
// }
// }
return RouterInstance;
}(Subscribable);
function useLocation() {
// const getIsMounted = useGetIsMounted()
// const [, rerender] = React.useReducer((d) => d + 1, 0)
var context = React.useContext(LocationContext);
warning(!!context, 'useLocation must be used within a <ReactLocation />'); // useLayoutEffect(() => {
// return instance.subscribe(() => {
// // Rerender all subscribers in a microtask
// Promise.resolve().then(() => {
// // setTimeout(function renderAllLocationSubscribers() {
// if (getIsMounted()) {
// rerender()
// }
// // }, 0)
// })
// })
// }, [instance])
return context.location;
}
var RouteMatch = function RouteMatch(unloadedMatch) {
var _this5 = this;
this.status = 'loading';
this.ownData = {};
this.data = {};
this.isLoading = false;
this.notify = function (isSoft) {
var _this5$matchLoader;
(_this5$matchLoader = _this5.matchLoader) == null ? void 0 : _this5$matchLoader.preNotify(isSoft);
};
this.assignMatchLoader = function (matchLoader) {
_this5.matchLoader = matchLoader;
};
this.startPending = function () {
if (_this5.pendingTimeout) {
clearTimeout(_this5.pendingTimeout);
}
if (_this5.route.pendingMs !== undefined) {
_this5.pendingTimeout = setTimeout(function () {
if (_this5.status === 'loading') {
_this5.status = 'pending';
}
_this5.notify == null ? void 0 : _this5.notify();
if (typeof _this5.route.pendingMinMs !== 'undefined') {
_this5.pendingMinPromise = new Promise(function (r) {
return setTimeout(r, _this5.route.pendingMinMs);
});
}
}, _this5.route.pendingMs);
}
};
this.load = function (opts) {
var _ref6, _opts$maxAge;
_this5.maxAge = (_ref6 = (_opts$maxAge = opts.maxAge) != null ? _opts$maxAge : _this5.route.loaderMaxAge) != null ? _ref6 : opts.router.defaultLoaderMaxAge;
if (_this5.loaderPromise) {
return;
}
var importer = _this5.route["import"]; // First, run any importers
_this5.loaderPromise = (!importer ? Promise.resolve() : importer({
params: _this5.params,
search: _this5.search
}).then(function (imported) {
_this5.route = _extends$1({}, _this5.route, imported);
}) // then run all element and data loaders in parallel
).then(function () {
var elementPromises = []; // For each element type, potentially load it asynchronously
var elementTypes = ['element', 'errorElement', 'pendingElement'];
elementTypes.forEach(function (type) {
var routeElement = _this5.route[type];
if (_this5[type]) {
return;
}
if (typeof routeElement === 'function') {
elementPromises.push(routeElement(_this5).then(function (res) {
_this5[type] = res;
}));
} else {
_this5[type] = _this5.route[type];
}
});
var loader = _this5.route.loader;
var dataPromise = !loader ? Promise.resolve().then(function () {
_this5.status = 'resolved';
}) : new Promise(_async(function (resolveLoader) {
var pendingTimeout;
var resolve = function resolve(data) {
_this5.status = 'resolved';
_this5.ownData = data;
_this5.error = undefined;
};
var reject = function reject(err) {
console.error(err);
_this5.status = 'rejected';
_this5.error = err;
};
var finish = function finish() {
_this5.isLoading = false;
_this5.startPending = undefined;
clearTimeout(pendingTimeout);
resolveLoader(_this5.ownData);
_this5.notify == null ? void 0 : _this5.notify(true);
};
return _continueIgnored(_catch(function () {
_this5.isLoading = true;
return _await(loader(_this5, {
parentMatch: opts.parentMatch,
dispatch: _async(function (event) {
if (event.type === 'resolve') {
resolve(event.data);
} else if (event.type === 'reject') {
reject(event.error);
} else if (event.type === 'loading') {
_this5.isLoading = true;
} else if (event.type === 'maxAge') {
_this5.maxAge = event.maxAge;
}
_this5.updatedAt = Date.now();
_this5.notify == null ? void 0 : _this5.notify(true);
return _await();
})
}), function (_loader) {
resolve(_loader);
return _await(_this5.pendingMinPromise, function () {
finish();
});
});
}, function (err) {
reject(err);
finish();
}));
}));
return Promise.all([].concat(elementPromises, [dataPromise])).then(function () {
_this5.updatedAt = Date.now();
});
}).then(function () {
return _this5.ownData;
});
};
Object.assign(this, unloadedMatch);
};
var MatchLoader = /*#__PURE__*/function (_Subscribable3) {
_inheritsLoose(MatchLoader, _Subscribable3);
function MatchLoader(router, nextLocation) {
var _this6;
_this6 = _Subscribable3.call(this) || this;
_this6.status = 'pending';
_this6.preNotify = function (isSoft) {
if (!isSoft) {
_this6.status = 'resolved';
}
cascadeMatchData(_this6.matches);
_this6.notify();
};
_this6.loadData = _async(function (_temp) {
var _this6$matches;
var _ref7 = _temp === void 0 ? {} : _temp,
maxAge = _ref7.maxAge;
_this6.router.cleanMatchCache();
if (!((_this6$matches = _this6.matches) != null && _this6$matches.length)) {
_this6.preNotify();
return;
}
_this6.firstRenderPromises = [];
_this6.matches.forEach(function (match, index) {
var _this6$matches2, _this6$firstRenderPro;
var parentMatch = (_this6$matches2 = _this6.matches) == null ? void 0 : _this6$matches2[index - 1];
match.assignMatchLoader == null ? void 0 : match.assignMatchLoader(_assertThisInitialized(_this6));
match.load == null ? void 0 : match.load({
maxAge: maxAge,
parentMatch: parentMatch,
router: _this6.router
});
(_this6$firstRenderPro = _this6.firstRenderPromises) == null ? void 0 : _this6$firstRenderPro.push(match.loaderPromise);
});
return Promise.all(_this6.firstRenderPromises).then(function () {
_this6.preNotify();
return _this6.matches;
});
});
_this6.load = _async(function (_temp2) {
var _ref8 = _temp2 === void 0 ? {} : _temp2,
maxAge = _ref8.maxAge;
return _this6.loadData({
maxAge: maxAge
});
});
_this6.startPending = _async(function () {
_this6.matches.forEach(function (match) {
return match.startPending == null ? void 0 : match.startPending();
});
return _await();
});
_this6.router = router;
_this6.location = nextLocation;
_this6.matches = [];
var unloadedMatches = matchRoutes(_this6.router, _this6.location);
_this6.matches = unloadedMatches == null ? void 0 : unloadedMatches.map(function (unloadedMatch) {
if (!_this6.router.matchCache[unloadedMatch.id]) {
_this6.router.matchCache[unloadedMatch.id] = new RouteMatch(unloadedMatch);
}
return _this6.router.matchCache[unloadedMatch.id];
});
return _this6;
}
return MatchLoader;
}(Subscribable);
function cascadeMatchData(matches) {
matches == null ? void 0 : matches.forEach(function (match, index) {
var _parentMatch$data;
var parentMatch = matches == null ? void 0 : matches[index - 1];
match.data = _extends$1({}, (_parentMatch$data = parentMatch == null ? void 0 : parentMatch.data) != null ? _parentMatch$data : {}, match.ownData);
});
}
function useRouter() {
var value = React.useContext(routerContext);
if (!value) {
warning(true, 'You are trying to use useRouter() outside of ReactLocation!');
throw new Error();
}
return value.router;
}
function matchRoutes(router, currentLocation) {
if (!router.routes.length) {
return [];
}
var matches = [];
var recurse = _async(function (routes, parentMatch) {
var _route$children3;
var pathname = parentMatch.pathname,
params = parentMatch.params;
var filteredRoutes = router != null && router.filterRoutes ? router == null ? void 0 : router.filterRoutes(routes) : routes;
var route = filteredRoutes.find(function (route) {
var _route$children2, _route$caseSensitive;
var fullRoutePathName = joinPaths([pathname, route.path]);
var fuzzy = !!(route.path !== '/' || (_route$children2 = route.children) != null && _route$children2.length);
var matchParams = matchRoute(currentLocation, {
to: fullRoutePathName,
search: route.search,
fuzzy: fuzzy,
caseSensitive: (_route$caseSensitive = route.caseSensitive) != null ? _route$caseSensitive : router.caseSensitive
});
if (matchParams) {
params = _extends$1({}, params, matchParams);
}
return !!matchParams;
});
if (!route) {
return;
}
var interpolatedPath = interpolatePath(route.path, params);
pathname = joinPaths([pathname, interpolatedPath]);
var interpolatedId = interpolatePath(route.id, params, true);
var match = {
id: interpolatedId,
route: route,
params: params,
pathname: pathname,
search: currentLocation.search
};
matches.push(match);
if ((_route$children3 = route.children) != null && _route$children3.length) {
recurse(route.children, match);
}
return _await();
});
recurse(router.routes, router.rootMatch);
return matches;
}
function interpolatePath(path, params, leaveWildcard) {
var interpolatedPathSegments = parsePathname(path);
return joinPaths(interpolatedPathSegments.map(function (segment) {
if (segment.value === '*' && !leaveWildcard) {
return '';
}
if (segment.type === 'param') {
var _segment$value$substr;
return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
}
return segment.value;
}));
}
function useLoadRoute() {
var location = useLocation();
var match = useMatch();
var router = useRouter();
var buildNext = useBuildNext();
return useLatestCallback(_async(function (navigate, opts) {
var _navigate$from;
if (navigate === undefined) navigate = location.current;
var next = buildNext(_extends$1({}, navigate, {
from: (_navigate$from = navigate.from) != null ? _navigate$from : {
pathname: match.pathname
}
}));
var matchLoader = new MatchLoader(router, next);
return matchLoader.load(opts);
}));
}
function useParentMatches() {
var router = useRouter();
var match = useMatch();
var matches = router.state.matches;
return matches.slice(0, matches.findIndex(function (d) {
return d.id === match.id;
}) - 1);
}
function useMatches() {
return React.useContext(MatchesContext);
}
function useMatch() {
var _useMatches;
return (_useMatches = useMatches()) == null ? void 0 : _useMatches[0];
}
function useNavigate() {
var location = useLocation();
var match = useMatch();
var buildNext = useBuildNext();
function navigate(_ref9) {
var _fromCurrent;
var search = _ref9.search,
hash = _ref9.hash,
replace = _ref9.replace,
from = _ref9.from,
to = _ref9.to,
fromCurrent = _ref9.fromCurrent;
fromCurrent = (_fromCurrent = fromCurrent) != null ? _fromCurrent : typeof to === 'undefined';
var next = buildNext({
to: to,
search: search,
hash: hash,
from: fromCurrent ? location.current : from != null ? from : {
pathname: match.pathname
}
});
location.navigate(next, replace);
}
return useLatestCallback(navigate);
}
function Navigate(options) {
var navigate = useNavigate();
useLayoutEffect(function () {
navigate(options);
}, [navigate]);
return null;
}
function useBuildNext() {
var location = useLocation();
var router = useRouter();
var buildNext = function buildNext(opts) {
var next = location.buildNext(router.basepath, opts);
var matches = matchRoutes(router, next);
var __searchFilters = matches.map(function (match) {
var _match$route$searchFi;
return (_match$route$searchFi = match.route.searchFilters) != null ? _match$route$searchFi : [];
}).flat().filter(Boolean);
return location.buildNext(router.basepath, _extends$1({}, opts, {
__searchFilters: __searchFilters
}));
};
return useLatestCallback(buildNext);
}
var Link = function Link(_ref10) {
var _preload;
var _ref10$to = _ref10.to,
to = _ref10$to === void 0 ? '.' : _ref10$to,
search = _ref10.search,
hash = _ref10.hash,
children = _ref10.children,
target = _ref10.target,
_ref10$style = _ref10.style,
style = _ref10$style === void 0 ? {} : _ref10$style,
replace = _ref10.replace,
onClick = _ref10.onClick,
onMouseEnter = _ref10.onMouseEnter,
_ref10$className = _ref10.className,
className = _ref10$className === void 0 ? '' : _ref10$className,
_ref10$getActiveProps = _ref10.getActiveProps,
getActiveProps = _ref10$getActiveProps === void 0 ? function () {
return {};
} : _ref10$getActiveProps,
_ref10$getInactivePro = _ref10.getInactiveProps,
getInactiveProps = _ref10$getInactivePro === void 0 ? function () {
return {};
} : _ref10$getInactivePro,
activeOptions = _ref10.activeOptions,
preload = _ref10.preload,
disabled = _ref10.disabled,
_ref = _ref10._ref,
rest = _objectWithoutPropertiesLoose(_ref10, _excluded4);
var loadRoute = useLoadRoute();
var match = useMatch();
var location = useLocation();
var router = useRouter();
var navigate = useNavigate();
var buildNext = useBuildNext();
preload = (_preload = preload) != null ? _preload : router.defaultLinkPreloadMaxAge; // If this `to` is a valid external URL, log a warning
try {
var url = new URL("" + to);
warning(false, "<Link /> should not be used for external URLs like: " + url.href);
} catch (e) {}
var next = buildNext({
to: to,
search: search,
hash: hash,
from: {
pathname: match.pathname
}
}); // The click handler
var handleClick = function handleClick(e) {
if (onClick) onClick(e);
if (!isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
e.preventDefault(); // All is well? Navigate!
navigate({
to: to,
search: search,
hash: hash,
replace: replace,
from: {
pathname: match.pathname
}
});
}
}; // The click handler
var handleMouseEnter = function handleMouseEnter(e) {
if (onMouseEnter) onMouseEnter(e);
if (preload && preload > 0) {
loadRoute({
to: to,
search: search,
hash: hash
}, {
maxAge: preload
});
}
}; // Compare path/hash for matches
var pathIsEqual = location.current.pathname === next.pathname;
var currentPathSplit = location.current.pathname.split('/');
var nextPathSplit = next.pathname.split('/');
var pathIsFuzzyEqual = nextPathSplit.every(function (d, i) {
return d === currentPathSplit[i];
});
var hashIsEqual = location.current.hash === next.hash; // Combine the matches based on user options
var pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
var hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
var isActive = pathTest && hashTest; // Get the active props
var _ref11 = isActive ? getActiveProps() : {},
_ref11$style = _ref11.style,
activeStyle = _ref11$style === void 0 ? {} : _ref11$style,
_ref11$className = _ref11.className,
activeClassName = _ref11$className === void 0 ? '' : _ref11$className,
activeRest = _objectWithoutPropertiesLoose(_ref11, _excluded5); // Get the inactive props
var _ref12 = isActive ? {} : getInactiveProps(),
_ref12$style = _ref12.style,
inactiveStyle = _ref12$style === void 0 ? {} : _ref12$style,
_ref12$className = _ref12.className,
inactiveClassName = _ref12$className === void 0 ? '' : _ref12$className,
inactiveRest = _objectWithoutPropertiesLoose(_ref12, _excluded6);
return /*#__PURE__*/React.createElement("a", _extends$1({
ref: _ref,
href: disabled ? undefined : next.href,
onClick: handleClick,
onMouseEnter: handleMouseEnter,
target: target,
style: _extends$1({}, style, activeStyle, inactiveStyle),
className: [className, activeClassName, inactiveClassName].filter(Boolean).join(' ') || undefined
}, disabled ? {
role: 'link',
'aria-disabled': true
} : undefined, rest, activeRest, inactiveRest, {
children: typeof children === 'function' ? children({
isActive: isActive
}) : children
}));
};
function Outlet() {
var _match$errorElement;
var router = useRouter();
var _useMatches2 = useMatches();
_useMatches2[0];
var matches = _useMatches2.slice(1);
var match = matches[0];
if (!match) {
return null;
}
var errorElement = (_match$errorElement = match.errorElement) != null ? _match$errorElement : router.defaultErrorElement;
var element = function () {
var _match$pendingElement, _match$element;
if (match.status === 'rejected') {
if (errorElement) {
return errorElement;
}
if (!router.useErrorBoundary) {
if (process.env.NODE_ENV !== 'production') {
var preStyle = {
whiteSpace: 'normal',
display: 'inline-block',
background: 'rgba(0,0,0,.1)',
padding: '.1rem .2rem',
margin: '.1rem',
lineHeight: '1',
borderRadius: '.25rem'
};
return /*#__PURE__*/React.createElement("div", {
style: {
lineHeight: '1.7'
}
}, /*#__PURE__*/React.createElement("strong", null, "The following error occured in the loader for you route at:", ' ', /*#__PURE__*/React.createElement("pre", {
style: preStyle
}, match.pathname)), ".", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("pre", {
style: _extends$1({}, preStyle, {
display: 'block',
padding: '.5rem',
borderRadius: '.5rem'
})
}, match.error.toString()), /*#__PURE__*/React.createElement("br", null), "Your users won't see this message in production, but they will see", ' ', /*#__PURE__*/React.createElement("strong", null, "\"An unknown error occured!\""), ", which is at least better than breaking your entire app. \uD83D\uDE0A For a better UX, please specify an ", /*#__PURE__*/React.createElement("pre", {
style: preStyle
}, "errorElement"), " for all of your routes that contain asynchronous behavior, or at least provide your own", /*#__PURE__*/React.createElement("pre", {
style: preStyle
}, "ErrorBoundary"), " wrapper around your renders to both the elements rendered by", ' ', /*#__PURE__*/React.createElement("pre", {
style: preStyle
}, 'useRoutes(routes, { useErrorBoundary: true })'), ' ', "and ", /*#__PURE__*/React.createElement("pre", {
style: preStyle
}, '<Router useErrorBoundary />'), ".", ' ', /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null));
}
return 'An unknown error occured!';
}
throw match.error;
}
var pendingElement = (_match$pendingElement = match.pendingElement) != null ? _match$pendingElement : router.defaultPendingElement;
if (match.status === 'loading') {
return null;
}
if (match.status === 'pending') {
if (match.route.pendingMs || pendingElement) {
return pendingElement != null ? pendingElement : null;
}
}
var matchElement = (_match$element = match.element) != null ? _match$element : router.defaultElement;
return matchElement != null ? matchElement : /*#__PURE__*/React.createElement(Outlet, null);
}();
return /*#__PURE__*/React.createElement(MatchesProvider, {
value: matches
}, element);
}
function useResolvePath() {
var router = useRouter();
var match = useMatch();
return useLatestCallback(function (path) {
return resolvePath(router.basepath, match.pathname, cleanPath(path));
});
}
function useSearch() {
var location = useLocation();
return location.current.search;
}
function matchRoute(currentLocation, matchLocation) {
var pathParams = matchByPath(currentLocation, matchLocation);
var searchMatched = matchBySearch(currentLocation, matchLocation);
if (matchLocation.to && !pathParams) {
return;
}
if (matchLocation.search && !searchMatched) {
return;
}
return pathParams != null ? pathParams : {};
}
function useMatchRoute() {
var router = useRouter();
var resolvePath = useResolvePath();
return useLatestCallback(function (_ref13) {
var pending = _ref13.pending,
matchLocation = _objectWithoutPropertiesLoose(_ref13, _excluded7);
matchLocation = _extends$1({}, matchLocation, {
to: matchLocation.to ? resolvePath("" + matchLocation.to) : undefined
});
if (pending) {
var _router$pending;
if (!((_router$pending = router.pending) != null && _router$pending.location)) {
return undefined;
}
return matchRoute(router.pending.location, matchLocation);
}
return matchRoute(router.state.location, matchLocation);
});
}
function MatchRoute(_ref14) {
var children = _ref14.children,
rest = _objectWithoutPropertiesLoose(_ref14, _excluded8);
var matchRoute = useMatchRoute();
var match = matchRoute(rest);
if (typeof children === 'function') {
return children(match);
}
return match ? children : null;
}
function usePrompt(message, when) {
var location = useLocation();
React.useEffect(function () {
if (!when) return;
var unblock = location.history.block(function (transition) {
if (window.confirm(message)) {
unblock();
transition.retry();
} else {
location.current.pathname = window.location.pathname;
}
});
return unblock;
}, [when, location, message]);
}
function Prompt(_ref15) {
var message = _ref15.message,
when = _ref15.when,
children = _ref15.children;
usePrompt(message, when != null ? when : true);
return children != null ? children : null;
}
function warning(cond, message) {
if (!cond) {
if (typeof console !== 'undefined') console.warn(message);
try {
throw new Error(message);
} catch (_unused) {}
}
}
function isFunction(d) {
return typeof d === 'function';
}
function functionalUpdate(updater, previous) {
if (isFunction(updater)) {
return updater(previous);
}
return updater;
}
function joinPaths(paths) {
return cleanPath(paths.filter(Boolean).join('/'));
}
function cleanPath(path) {
// remove double slashes
return ("" + path).replace(/\/{2,}/g, '/');
}
function matchByPath(currentLocation, matchLocation) {
var _matchLocation$to;
var baseSegments = parsePathname(currentLocation.pathname);
var routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
var params = {};
var isMatch = function () {
for (var i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
var baseSegment = baseSegments[i];
var routeSegment = routeSegments[i];
var isLastRouteSegment = i === routeSegments.length - 1;
var isLastBaseSegment = i === baseSegments.length - 1;
if (routeSegment) {
if (routeSegment.type === 'wildcard') {
if (baseSegment != null && baseSegment.value) {
params['*'] = joinPaths(baseSegments.slice(i).map(function (d) {
return d.value;
}));
return true;
}
return false;
}
if (routeSegment.type === 'pathname') {
if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
return true;
}
if (baseSegment) {
if (matchLocation.caseSensitive) {
if (routeSegment.value !== baseSegment.value) {
return false;
}
} else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
return false;
}
}
}
if (!baseSegment) {
return false;
}
if (routeSegment.type === 'param') {
params[routeSegment.value.substring(1)] = baseSegment.value;
}
}
if (isLastRouteSegment && !isLastBaseSegment) {
return !!matchLocation.fuzzy;
}
}
return true;
}();
return isMatch ? params : undefined;
}
function matchBySearch(currentLocation, matchLocation) {
return !!(matchLocation.search && matchLocation.search(currentLocation.search));
}
function parsePathname(pathname) {
if (!pathname) {
return [];
}
pathname = cleanPath(pathname);
var segments = [];
if (pathname.slice(0, 1) === '/') {
pathname = pathname.substring(1);
segments.push({
type: 'pathname',
value: '/'
});
}
if (!pathname) {
return segments;
} // Remove empty segments and '.' segments
var split = pathname.split('/').filter(Boolean);
segments.push.apply(segments, split.map(function (part) {
if (part.startsWith('*')) {
return {
type: 'wildcard',
value: part
};
}
if (part.charAt(0) === ':') {
return {
type: 'param',
value: part
};
}
return {
type: 'pathname',
value: part
};
}));
if (pathname.slice(-1) === '/') {
pathname = pathname.substring(1);
segments.push({
type: